powered by simpleCommunicator - 2.0.60     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / FoxPro, Visual FoxPro [игнор отключен] [закрыт для гостей] / Оператор
21 сообщений из 21, страница 1 из 1
Оператор
    #32340377
Tyro
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Люди, а кто-нибудь знает есть-ли такой оператор в Fox'e, который определяет было ли изменено содержимое ячеек или была ли изменена таблица, или что-либо подобное.
...
Рейтинг: 0 / 0
Оператор
    #32340395
Brather
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
цитата для visual foxpro 3.0 и выше
-------
функция UPDATE()
Возвращает значение "истина" (.T.), если в ходе выполнения текущей команды READ какие-либо данные были изменены в интерактивном режиме. Включена для совместимости с предыдущими версиями. Используйте вместо нее событие InteractiveChange или ProgrammaticChange.
...
Рейтинг: 0 / 0
Оператор
    #32340417
Фотография ВладимирМ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Это все есть для буферизированных данных. Читай описание функций:

GetFldState() - стутус изменения полей текущей записи таблицы
GetNextModified() - физический номер записи, которая была изменена
OldVal() - значение, которое было в поле до начала изменений
CurVal() - значение, которое имеет сейчас данное поле в исходной таблице (но не в буфере)

Все эти функции помогают установить факт того было ли изменение в буферизированных данных с момент включения буферизации и до момент сброса буфера.

Если речь идет о многократном редактировании одной и той же ячейки буферизированных данных до сброса буфера. И при этом необходимо отлавливать факт каждого изменения ячейки то стандартных функций на такой случай не предусмотрено. Есть 2 пути решения:

1) Запоминать занчение ячейки при входе (When или SetFocus) и сравнивать его с текущем значением при выходе (Valid или LostFocus)

2) Использовать функцию SetFldState() при выходе (Valid или LostFocus) примерно так:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
* Определяю значение флага изменения
LOCAL lnState
lnState=GetFldState(JustExt(This.ControlSource),JustStem(This.ControlSource))
IF InList(m.lnState, 2 , 4 )
* Данные были изменены
* Сбрасываю флаг изменения
SetFldState(JustExt(This.ControlSource),m.lnState- 1 ,JustStem(This.ControlSource))
ENDIF


В коде я предполагаю, что ControlSource объекта записан в виде MyTable.MyField

Изменение статуса по SetFldState() никак не повлияет на буфер и работу других функций с буфером. Он окажеть исключительно влияние на значение возвращаемое по GetFldState() и все.
...
Рейтинг: 0 / 0
Оператор
    #32341066
Tyro
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Возникла новая проблема. На сколько я знаю, BeforeRowColChange имеет место перед тем, как поль-ль изменяет активную строку или столбец, т.е. по сути дела, если:
mActiveCellValue = This.Columns(nColIndex).ControlSource , то
mActiveCellValue будет иметь то значение, которое имела было в акт. ячейке до изменения. Или я чего-то не догоняю.
...
Рейтинг: 0 / 0
Оператор
    #32341153
Фотография ВладимирМ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Теоретически, да, должно работать. Но практически не проверял. А что, так трудно проверить?
...
Рейтинг: 0 / 0
Оператор
    #32341167
Tyro
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Дык, в том то и дело, что проверил, но почему-то не работает.
Выдает уже измененное значение.
...
Рейтинг: 0 / 0
Оператор
    #32341462
Попутали вы немного: BeforeRowColChage имеет место быть не при изменении значения ControlSource активной ячейки, а при потере фокуса активной ячейкой и при перемещении фокуса на другую ячейку
...
Рейтинг: 0 / 0
Оператор
    #32341850
Tyro
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Нет, ничего я не попутал.
При переходе на другую колоку nColIndex - изменяется и, соответственно, изменяется ControlSource и, соответственно, изменяется значение
m.ActiveCellValue при
m.ActiveCellValue = This.Columns(nColIndex).ControlSource,

если переход осуществляется по одной колонке то ни nColIndex ни ControlSource не изменяются, но изменяется значение &m.ActiveCellValue

Вообщем, все, что я хочу сделать, это, чтобы при изменении значения ячейки в поле YEAR, Fox проверял бы соответствует ли данное введенное значение условиям типа YEAR > 2001 и изменял бы ег на 2002, если это не так.
Я в BeforeRowColChange сохраняю начальное значение ячейки (теперь работает), затем в AfterRowColChange осуществляю проверку
If YEAR > 2001.... При переходе с одной ячейки на другую слева направо, т.е на другую колонку, Fox проверяет измененное значение и, если оно не соответствует критерию, меняет его на 2002. При переходе же с ячейки на ячейку по одной и той же колонке проверка не осуществляется и, соответственно, значение остается не соответствующим критерию.
Как можно сделать так, чтобы Fox проверял значение при движении вниз-вверх
...
Рейтинг: 0 / 0
Оператор
    #32341867
zobr
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Попробуйте сохранить значение в When а проверять в Valid объекта
...
Рейтинг: 0 / 0
Оператор
    #32342035
Tyro
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Но, на сколько я знаю, Valid и When для Grida не будут работать для ячеек.
...
Рейтинг: 0 / 0
Оператор
    #32342071
Brather
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
А для GRIDa и не надо. Используй энти события для каждой ячейки.
...
Рейтинг: 0 / 0
Оператор
    #32342074
Фотография ВладимирМ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Имелось в виду использовать Valid и When того объекта, который расположен внутри соответсвующей ячейки.

Как правило, просто делают свой класс, например, TextBox-а с нужным кодом и вставляют его в колонки вместо стандартного TextBox-а

Запись можно делать в свойство TAG. Это свойство не оказывает никакого влияния на собственно работу объекта. Это просто комментарий. Единственное ограничение - TAG принитмает только символьные данные.
...
Рейтинг: 0 / 0
Оператор
    #32342126
Tyro
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Вы знаете, я Fox только начинаю изучать. Сижу каждый день с кучей литературы. Но пока не понимаю каким образом я могу использовать Valid и When для каждой ячейки, у меня даже такого объекта не существует как ячейка или даже колонка (Grid так построен, что всегда загружаются новые таблицы, он каждый раз перерисовывается).
Хотя, как я понял (по словам Владимира М), можно создать свой класс на базе ячейки, но не знаю я пока, как классы создавать (если только Вы не подскажете)
...
Рейтинг: 0 / 0
Оператор
    #32342153
Фотография ВладимирМ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
На подробный ответ меня не хватит. Поэтому только намеки :)

1) Чтобы при изменении источника данных для Grid не происходил сброс настроек столбцов необходимо предварительно обнулить источник данных

ThisForm.Grid1.RecordSource=""

ThisForm.Grid1.RecordSource="NewTable"
ThisForm.Grid1.Column1.ControlSource="NewTable.Field1"
ThisForm.Grid1.Column2.ControlSource="NewTable.Field2"
ThisForm.Grid1.Column3.ControlSource="NewTable.Field3"

При таком способе замены источника настройки (и самое главное коды событий и методов) столбцов и объектов внутри столбцов сохраняются

2) Классы в FoxPro можно создавать программно (команда DEFINE CLASS) и визуально (Пункт главного меню File->New->Class). Классы для некоторых объектов невозможно создать визуально (например для Column или Header)

3) Вставить любой другой объект в Grid вместо стандартного TextBox можно как в дезайнере формы, так и программно.
...
Рейтинг: 0 / 0
Оператор
    #32342179
Tyro
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Я делел вот так:
THISFORM.Grid1.RECORDSOURCE= m.TableName
lcColumn = 'thisform.Grid1.column'+m.ColNumb
with &lcColumn
.CONTROLSOURCE=6
.CONTROLSOURCE=m.CSource (в колонку могут загружаться данные из
нескольких таблиц)
.Еще всякие разные свойства
Или таким образом заполнять Grid не советуете.
...
Рейтинг: 0 / 0
Оператор
    #32342226
Tyro
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Да, а команду Define Class нужно писать в inite формы или как ?
...
Рейтинг: 0 / 0
Оператор
    #32342334
Фотография ВладимирМ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Для объяснение идеологии объектно-ориентированного подхода пишутся здоровенные книги, а Вы хотите, чтобы я тут вкратце поснил :)

Значит так. Вне зависимости от выбранного источника данных для Grid надо думать, что ряд настроек останется все-равно неизменной. Ну например, количество столбцов, ширина каждого столбца, название заголовков столбцов, способы обработки и т.п.

Значит, все это неизменяемое богатство надо описать непосредственно в конструкторе формы (начни с задания количества столбцов Grid.ColumnCount=6)

Если я правильно понял, динамически изменяться будет только имя таблицы-источника и имена полей-источников столбцов.

Вот для того, чтобы эти изменения не привели к сбросу настроек сделанных в конструкторе формы перед изменением источника следует дать команду на сброс источника данных для Grid

ThisForm.Grid1.RecordSource=""

Эта команда обнуляет источник данных (т.е. в Grid ничего не отображается), но при этом все настройки Grid сделанные ранее остаются в силе (в том числе и коды событий When, Valid сделанных для объектов внутри колонок). Вот теперь можно приступить к восстановлению (назначению) источника данных для Grid как у Вас и написано.

Команду DEFINE CLASS обычно пишут в процедурных файлах. Процедурные файлы подключаются по команде SET PROCEDURE. Но вообще-то, поскольку Вы только начинаете, используйте визуальные классы, которые создаются через построитель. С ними проще работать.
...
Рейтинг: 0 / 0
Оператор
    #32342377
Brather
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
public defaultcolumnwidth
         defaultcolumnwidth =  70 
DEFINE CLASS myColumn as Column
   width =  40 
   readonly = .t.
   ADD OBJECT header1 as header WITH alignment =  2 
   ADD OBJECT text1 as myText
   PROCEDURE resize
     IF EMPTY(this.header1.caption)
        this.width = defaultcolumnwidth
     ENDIF
   ENDPROC
   visible = .t.
   currentcontrol = 'text1'
ENDDEFINE

DEFINE CLASS myText as textbox
   specialeffect =  0 
   borderstyle =  0 
   seltext = ''
   visible = .t.
   readonly = .t.
   m_row =  0 
   m_col =  0 
   PROCEDURE gotfocus
      WITH this.Parent.parent.parent
         .oboz_class1.visible = .f.
         .command1.visible = .f.
         .calendar_class1.visible = .f.
         thisform.caption = 'Табель работников предприятия'
      endwith
   endproc
   PROCEDURE mousedown
     LPARAMETERS nButton, nShift, nXCoord, nYCoord
     this.m_col = nXCoord
     this.m_row = nYCoord
   endproc
   PROCEDURE rightclick
      PRIVATE ddd
      WITH this.Parent.parent.parent.oboz_class1
         .m_col = this.m_col
         .m_row = this.m_row
         .nday = ALLTRIM(this.Parent.header1.caption)
         thisform.caption = ALLTRIM(tab_cursor->fio)+' ('+.nday+'.'+;
                            inttostr(.parent.calendar_class1.mesac)+'.'+inttostr(.parent.calendar_class1.god)+')'
         ddd = 'tab_cursor->den' + .nday
         .stroka = ALLTRIM(&ddd)
         .visible = .t.
      ENDWITH
      this.Parent.parent.parent.command1.visible = .t.
   endproc
enddefine
DEFINE CLASS myColumn as Column
   width =  40 
   readonly = .t.
   ADD OBJECT header1 as header WITH alignment =  2 
   ADD OBJECT text1 as myText
   PROCEDURE resize
     IF EMPTY(this.header1.caption)
        this.width = defaultcolumnwidth
     ENDIF
   ENDPROC
   visible = .t.
   currentcontrol = 'text1'
ENDDEFINE

DEFINE CLASS myText as textbox
   specialeffect =  0 
   borderstyle =  0 
   seltext = ''
   visible = .t.
   readonly = .t.
   m_row =  0 
   m_col =  0 
   PROCEDURE gotfocus
      WITH this.Parent.parent.parent
         .oboz_class1.visible = .f.
         .command1.visible = .f.
         .calendar_class1.visible = .f.
         thisform.caption = 'Табель работников предприятия'
      endwith
   endproc
   PROCEDURE mousedown
     LPARAMETERS nButton, nShift, nXCoord, nYCoord
     this.m_col = nXCoord
     this.m_row = nYCoord
   endproc
   PROCEDURE rightclick
      PRIVATE ddd
      WITH this.Parent.parent.parent.oboz_class1
         .m_col = this.m_col
         .m_row = this.m_row
         .nday = ALLTRIM(this.Parent.header1.caption)
         thisform.caption = ALLTRIM(tab_cursor->fio)+' ('+.nday+'.'+;
                            inttostr(.parent.calendar_class1.mesac)+'.'+inttostr(.parent.calendar_class1.god)+')'
         ddd = 'tab_cursor->den' + .nday
         .stroka = ALLTRIM(&ddd)
         .visible = .t.
      ENDWITH
      this.Parent.parent.parent.command1.visible = .t.
   endproc
enddefine

предудущее описание классов для одной колонки таблицы
где-нить (ну например в главной процедуре)
это описание не выполняется,а определяется 1 раз
(т.е. в программе больше повторятся не должно)

далее использование этого в проседуре grid.init

PRIVATE i,area,pfn,dobj,fc
WITH this
area = .parent.areagrids
fc = FCOUNT(area)
.ColumnCount = -1
FOR i = 4 TO fc
pfn = FIELD(i,area)
dobj = 'Column'+inttostr(i-3)
.Addobject(dobj,'MyColumn')
dobj = '.' + dobj
WITH &dobj
.Header1.Caption = ''
IF UPPER(SUBSTR(pfn,1,3))='DEN'
.Header1.Caption = inttostr(objectindex(pfn))
ENDIF
IF EMPTY(.Header1.Caption)
.width = defaultcolumnwidth
IF .parent.colindex = 0
.parent.colindex = i-3
endif
ENDIF
STORE area+'.'+pfn TO .ControlSource
ENDWITH
ENDFOR
.parent.columncount = fc-3
ENDWITH

я прекрасно понимаю, что код практически не читаем.
Но может быть структура поможет.
Просто это совсем, совсем свежее все, но в рабочем состоянии
...
Рейтинг: 0 / 0
Оператор
    #32347868
Tyro
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
To: ВладимирМ
Если это принципиально, то изменяются не только имя таблицы-источника и имена полей-источников столбцов, но и их количество и структура.

THISFORM.Grid2.COLUMNCOUNT= n_column
THISFORM.Grid2.RECORDSOURCE= m.filedbf

Brather я прекрасно понимаю, что код практически не читаем.
мда...так оно и есть
...
Рейтинг: 0 / 0
Оператор
    #32358499
Tyro
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Мне тут подсказали, что если добавить в Data Environment таблицу (желательно пустую и с большим количеством полей), то при любой загружаемой таблице в Грид (с постоянно измен. recordsource) визуально отображаются TextBox'Ы. т.е нет необходимости создавать класс на основе TextBox'ов и вставлять TextBox's в Грид взамен старых.

Посмотрел. Попробовал. Вроде бы работает. Но остается вопрос :
а стоит ли так делать, какие сложности могут возникнуть в процессе работы, как может измениться работоспособность системы ?

Поможите кто чем может.
...
Рейтинг: 0 / 0
Оператор
    #32365415
Фотография MaestroEv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вот...Вот .... Вот....

И нас убеждают, что VISUALные средства ускоряют процесс программирования и легче всем.....

Простые вещи стали описывать "трехэтажным" языком...
Начинающему программисту, сразу прочитавшему книжки по визуальному программированию, уже ничем помочь нельзя...(ну или очень трудно)
Мы теряем его... Это я вам как учитель информатики....

Многие вопросы начинающих в конфе - результат визуализирования FOXa.
Из за картинок сути не видать, механики процессов, так сказать. И HELP стал такой огромный, что редкий "МЭТР" дочитает его до середины. :))

Что-то надо делать.....
...
Рейтинг: 0 / 0
21 сообщений из 21, страница 1 из 1
Форумы / FoxPro, Visual FoxPro [игнор отключен] [закрыт для гостей] / Оператор
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]