Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Foxpro/Clipper/Dbase > Заполнить Grid значениями из справочника


Автор: rubey 28.4.2012, 10:54
Пробую слепить учебные  программки и наткнулся на  проблему заполнения колонки Grid.
Есть форма с Grid  к которому  подключена таблица PERSONAL с кодами должностей  ID_DOL
а в  справочнике STUFF находятся  коды и  наименования должностей ID_DOL, NAM_DOL. Как 
мне  теперь сформировать Grid с выводом в колонку должностей изх названий из справочника.
Буду благодарен за  помощь.

Автор: Reese 28.4.2012, 13:39
select p1.*, nvl(s1.NAM_DOL,"") as NAM_DOL;
 from PERSONAL p1 ;
 left join STUFF s1 on s1.id_dol==p1.id_dol ;
 into cursor tmp_cursor nofilter 

А к гриду цепляем уже tmp_cursor 

Автор: rubey 3.5.2012, 10:19
Воспроизвел предложенный код и  привязал  курсор к Grid следующим макаром
RecordSourceType= 1 
RecordSource="TMP_CURSOR"
но  при запуске формы Grid  ничего не показывает - белый фон без ишформации.
Видно что-то с  привязкой курсора не але, но чт именно - не  пойму.

Автор: Reese 3.5.2012, 17:04
Сначала просто выполните запрос, чтобы убедиться что он работает.
А во вторых как вы привязываете? В коде или в дизайнере?

Если вы сделали в дизайнере, то его все равно надо будет перепривязать.

И, кстати, в каком месте данный код вызываете?


Автор: rubey 4.5.2012, 09:57
Селект  работает. Это  я  проверил добавив  в  код команду
 SELECT * FROM tmp_cursor TO proba_cur.dbf  и  на  экране  отображаются  значения  курсора.
Правда  таблицу PROBA_CUR    FOX   не  может почему-то  открыть. Говорить, что это  не  таблица.
Код я разместил в методе INIT  формы,  а  привязал курсор в  свойствах Grid
RecordSourceType= 1 
RecordSource="TMP_CURSOR"
но  видно  не  все  по  неграмотности  учел.

Автор: Reese 4.5.2012, 12:10
В Init формы после команды select добавьте 
thisform.Grid1.RecordSource="TMP_CURSOR"
А в дизайнере сбросьте RecordSource в значение по умолчанию.

Grid1 - это ваш объект Grid. У вас он может называться по другому.

Цитата

SELECT * FROM tmp_cursor TO proba_cur.dbf

Используйте лучше не TO а INTO.
И добавляйте в конце NOFILTER, иначе фокс пытается сначала просто фильтр наложить на таблицу

Автор: rubey 7.5.2012, 10:49
       Спасибо за советы. Все заработала. Ошибка была где-то  в привязке курсора через дизайнер. Создал  форму с нуля ( с учетом всех ваших советов )  и все получилось как надо.
       Поскольку ваши подсказки оказались весьма ценными для меня, как новичка, то осмелюсь чуть развить тему этой учебной формы дальше.
       Хотелось бы попробовать  реализовать методику изменения таблицы PERSONAL через имеющийся  GRID с курсором.
       По моему надо создать еще одну форму и вызывать ее по кнопкам “Вставить” “Изменить” “Удалить ” на основной   форме и соответственно изменять PERSONAL и обновлять GRID с курсором. Это первое что пришло в голову. Вот только не хватает знаний и опыта  реализовать это все. 
       Возникли следующие вопросы :
       Как отобразить в GRID  выборочные поля из курсора , а не все.
       Как синхронизировать код выбранной записи из  курсора с нужной записью в таблице PERSONAL.
       Как обновлять курсор, чтобы на экране отображалось уже измененное состояние.
       Если на форме корректировки выбирать должности из справочника через ComboBox, то как изменять код должности в курсоре и таблице.

      Это первые вопросы, которые возникли перед решением этой задачи. Может еще что добавится. Буду благодарен за подсказки по возникшим вопросам.  

Автор: rubey 8.5.2012, 09:54
       Спасибо за советы. Все заработала. Ошибка была где-то  в привязке курсора через дизайнер. Создал  форму с нуля ( с учетом всех ваших советов )  и все получилось как надо.
       Поскольку ваши подсказки оказались весьма ценными для меня, как новичка, то осмелюсь чуть развить тему этой учебной формы дальше.
       Хотелось бы попробовать  реализовать методику изменения таблицы PERSONAL через имеющийся  GRID с курсором.
       По моему надо создать еще одну форму и вызывать ее по кнопкам “Вставить” “Изменить” “Удалить ” на основной   форме и соответственно изменять PERSONAL и обновлять GRID с курсором. Это первое что пришло в голову. Вот только не хватает знаний и опыта  реализовать это все. 
       Возникли следующие вопросы :
        Как отобразить в GRID  выборочные поля из курсора , а не все.   
        Как синхронизировать код выбранной записи из  курсора с нужной записью в таблице PERSONAL.
        Как обновлять курсор, чтобы на экране отображалось уже измененное состояние.
        Если на форме корректировки выбирать должности из справочника через ComboBox, то как изменять код должности в курсоре и таблице.

      Это первые вопросы, которые возникли перед решением этой задачи. Может еще что добавится. Буду благодарен за подсказки по возникшим вопросам.  

Автор: Reese 12.5.2012, 10:21
Ну начнем с малого.
Цитата

По моему надо создать еще одну форму и вызывать ее по кнопкам “Вставить” “Изменить” “Удалить ” на основной   форме и соответственно изменять PERSONAL и обновлять GRID с курсором.

Мысль хорошая. Предлагаю сделать так. Создаем форму, в Init формы добавим два параметра
lparam ln_typeoper, ln_id
Первый параметр - это у нас будет тип операции (Допустим, будет так 0 - Вставить, 1 - Изменить)
вторым параметром будет id записи
Добавляем форме свойство typeoper после чего пишем
thisform.typeoper = ln_typeoper

На форме с гридом добавляем кнопки “Вставить” и  “Изменить” (я бы их правда назвал "Добавить" и "Редактировать")
на клике этих кнопок пишем примерно следующее

для изменения

local ln_id
ln_id = tmp_cursor.id && tmp_cursor - наш курсор из предыдущего примера. id - уникальный идентификатор записи (я не знаю как у вас это поле называется)

do form editform with 1, ln_id 

для добавления

do form editform with 0, 0

На форме (я ее тут назвал editform) 
в Init пишем

if used("cur_edit")
 use in cur_edit
endif
select * from PERSONAL where id==ln_id into cursor cur_edit nofilter readwrite

после чего добавляем контролы и привязываем их к курсору cur_edit 
В методе Click кнопки сохранить (ее еще надо добавить) пишем что-то вроде
if thisform.typeoper = 0 
insert into personal select * from cur_edit && Написано приблизительно. Конкретно см. хелп по команде insert-sql
else
update personal set ...  from cur_edit where personal.id==cur_edit.id && Написано приблизительно. Конкретно см. хелп по команде update-sql

Тут уже надо пробовать.
Вместо курсора можно использовать объект или просто переменные, см. команды scatter gather

Автор: rubey 22.6.2012, 14:30
Воспроизвел  предложенное и на мое удивление  вся конструкция заработала,  но получилось не  совсем то, что задумывалось.  В  результате  селекта  
thisform.typeoper=vcTypeoper
thisform.in_kod=vcid_dol
IF USED("Cur_Edit")
   USE IN cur_edit
ENDIF
SELECT * FROM personal WHERE id_dol==id_dol INTO CURSOR cur_edit NOFILTER readwrite
****************************************
*** Получаем  в  результате  следующий  курсор
*** Код -  1   ПИБ   -  Иванов
***        2            Феофанов
***        3            Ионкин  ............
***************************************  
Из этого  мне  не  сов сем  ясно  как  через  форму  EditForm   откорректировать  Должность  работника. Мне  представлялось, что  при  выборе  строки  Grida  на  форме  EditForm  в  контролах  отобразятся  все  значения  по  работнику  и  через  TextBox  откорректируется  фамилия  и  адрес,  а  через  CheckBox  -  должность и  заменится  в  Гриде  и  таблице, но  из  полученного  курсора не   ясно  как это  сделать.
Спасибо

Автор: Reese 22.6.2012, 17:02
Цитата

SELECT * FROM personal WHERE id_dol==id_dol INTO CURSOR cur_edit NOFILTER readwrite

Вот где проблема. 
Во первых
Цитата

id_dol==id_dol 

Т.е. вы выбираете все записи т.к. сравниваете поле с самим собой.
Во вторых id_dol. Я имел ввиду идентификатор таблицы PERSONAL. 

В результате должен получиться курсор с одной записью.
Ну а дальше на форму кидаем контролы и привязываем их к нашему курсору (см. ControlSource)

Автор: rubey 25.6.2012, 09:47
Спасибо  за  ответ, но  я  не  понял  как  мне  изменить  последний  Селект,  чтобы  получить  одну  выбранную  запись. Дело  в  том,  что  у  меня  и  основной  базе PERSONAL и  в  справочнике STUFF   код должности  одинаково  называется  - ID_DOL.

Автор: Reese 25.6.2012, 09:53
Да причем тут id_dol.
Вам же нужно выбрать уникальную запись из таблицы PERSONAL, следовательно и надо сравнивать с идентификатором таблицы PERSONAL. И сравнивать его надо с тем значением которое сохранили, т.е.  thisform.in_kod.

Автор: rubey 26.6.2012, 14:55
Я  понимаю Ваше  недовольство,  но для  меня  многое  в  новинку при  программировании на  isual Foxpro. Похожее  я  делал,  но  еще  в  древнем  Foxpro 2.6  и  это  меня  часто  сбивает  с толку.
Напутал я слегка  с  параметрами, но наконец разобрался  и все  наладилось. Теперь у  меня  в  курсоре  нужная  запись  со  всеми  реквизитами,  но  не  получается  повесить  на  нее  2  контрола - TextBox  для  фамилии  и ComboBox для  выбора  должности.
 Рылся  по  книжкам, но  не  наткнулся  на  похожий  пример ни в  одной.
Не  подкажете,  в  очередной  раз,  как реализовать  подключение  этих  контролов  к реквизитам курсора,  особенно  ComboBox.
Благодарю за  помощь.

Автор: Reese 26.6.2012, 16:53
Цитата

TextBox  для  фамилии  и ComboBox для  выбора  должности.

Нужны свойства ControlSource для обоих и RowSource для ComboBox 
Назначаем примерно так

Код

thisform.lastname.controlsource = cur_edit.fam && lastname - это имя нашего textbox-а, а fam - это поле фамилия

*dol  - это наш combobox
thisform.dol.rowsourcetype = 2 && могу ошибаться тут может и 6. Не помню точно. 
thisform.dol.BoundColumn = 2
thisform.dol.BoundTo = .T.
thisform.dol.rowsource = STUFF.name_dol,id_dol
thisform.dol.controlsource = cur_edit.id_dol

Автор: Reese 27.6.2012, 19:53
Можно попробовать второй вариант
на первой форме сделать 
Код

scatter name lo_person

т.е. создать объект на основе записи.
И вместо идентификатора передать этот объект во вторую форму
А во второй форме вместо привязки контролов к ControlSource, просто установить у них значение (value)

Автор: rubey 12.7.2012, 15:28
Все заработало. Спасибо .
Метода правильная, но с некоторыми мелкими деталями пришлось повозиться.
Осталось для меня темным пятнышком проблема показа в гриде не  всех  полей сформированного курсора, а только необходимых для работы с таблицей. Например в курсоре мне код записи нужен, 
но показывать его в гриде нет смысла. Так же и код должности. Как отфильтровать ненужные реквизиты из курсора, чтобы их не показывать - нигде не нашел способа.
Буду благодврен за подсказку.

Автор: rubey 13.7.2012, 15:55
Все  работает. Спасибо за помощь.
Метод оказался  правильным а  поморочиться  пришлось с некоторыми техническими деталями.
Вроде в основном со всеми  разобрался.
Осталось только одно темное пятнышко. Не  получается  вывести в GRID не  все вібранніе реквизиті  
курсора,  а  только  необходиміе для  работі с формой. Например нет надобности віводит в грид код работника и код должности, но в курсоре они нужны. Нигде не  встретил как вывести в GRID не весь курсор,  а  отдельные его реквизиты.
Буду благодарен за подсказку.

Автор: Reese 13.7.2012, 17:35
Один из самых простых способов пробежаться по массиву колонок и скрыть ненужные
Например так
Код

thisform.grid1.recordsource = "tmp"
for each lo_column in thisform.grid1.columns
    if(lo_column.controlsource=="tmp.id")
        lo_column.visible = .F.
    endif
endfor

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)