|
|
|
Очень нужно - объясните про буфферизацию!
|
|||
|---|---|---|---|
|
#18+
Прошу прощения, но никак не могу разобраться с буферизацией. Имеется форма на которой находится pageframe, допустим, с двумя страничками и парочкой editbox'ов на каждой. 1) Когда и где надо объявлять буфферизацию? В Init формы? 2) Нужно ли прописывать controlsource для editbox? (Объявив буфферизацию 5, я не прописывала ничего, и похоже работала с нужной таблицей) 3) Как правильно организовать процедуру сохранения? у меня получалось, что если я ввожу что-то только на первой странице и никуда не переключаюсь, то все сохраняется. стоит уйти на вторую - и все, ничего не сохраняется. 4) База проиндексирована по LEFT(ALLTRIM(cfam),5)+LEFT(ALLTRIM(cimm),3)+LEFT(ALLTRIM(cott),3). Хочется сделать так, чтобы введя фамилию, имя и отчество происходила проверка, есть ли такой человек в базе. Если есть - в остальных editbox должны выводится имеющиеся на него данные. Если делать поиск через if seek (LEFT(thisForm.PageFrame1.Page1.txtFam.value,5)+thisForm.PageFrame1.Page1.txtNam.value+thisForm.PageFrame1.Page1.txtOtt.value), то запись находится, но вот как организовать вывод найденных данных я не представляю. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 01.12.2005, 08:12 |
|
||
|
Очень нужно - объясните про буфферизацию!
|
|||
|---|---|---|---|
|
#18+
>Когда и где надо объявлять буфферизацию? В Init формы? Можно в Init-е, можно в Load-е Все зависит от того как ты открываешь таблицы. Я обычно там где открываю там и указываю буферизацию. DE не пользуюсь. >) Нужно ли прописывать controlsource для editbox? Ну, если хочешь показывать там содержимое полей таблицы то неплохобы:) Или руками присваивать Value правильные значения >запись находится, но вот как организовать вывод найденных данных я не представляю. Вот когда пропишешь в качестве controlsource поля своей таблицы то после Seek-а достаточно буде дать Refresh нужным контролам ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 01.12.2005, 10:23 |
|
||
|
Очень нужно - объясните про буфферизацию!
|
|||
|---|---|---|---|
|
#18+
katry1) Когда и где надо объявлять буфферизацию? В Init формы? Когда? До того, как начнешь вносить изменения в таблицу. А "где", не имеет принципиального значения. katry2) Нужно ли прописывать controlsource для editbox? Да. Нужно. katry(Объявив буфферизацию 5, я не прописывала ничего, и похоже работала с нужной таблицей) Это значит, что ControlSource был присвоен данному объекту автоматически. Например, при перетаскивании поля из DataEnvironment в область формы. Если ControlSource объекта не заполнено, то модификация содержимого объекта не попадет в соответствующее поле таблицы автоматически. Необходимо будет программная обработка. Т.е. явная команда REPLACE. katry3) Как правильно организовать процедуру сохранения? Зависит от конкретной задачи. katryу меня получалось, что если я ввожу что-то только на первой странице и никуда не переключаюсь, то все сохраняется. стоит уйти на вторую - и все, ничего не сохраняется. К сожалению, я не сижу у тебя за спиной и не вижу, что означют все эти слова. Какое отношение имеют страницы (видимо, речь идет о PageFrame ?) к процедуре сохранения (как и где она запускается, что находится на страницах, что записано в процедуре сохранения и т.д. и т.п.) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 01.12.2005, 11:55 |
|
||
|
Очень нужно - объясните про буфферизацию!
|
|||
|---|---|---|---|
|
#18+
ВладимирМ katry2) Нужно ли прописывать controlsource для editbox? Да. Нужно. Каждому editbox отдельно прописывать в controlsource имя соответствующего поля таблицы? Или это можно сделать глобально - если да, то где именно? В том же Init? katry3) Как правильно организовать процедуру сохранения? Зависит от конкретной задачи. ВладимирМ katryу меня получалось, что если я ввожу что-то только на первой странице и никуда не переключаюсь, то все сохраняется. стоит уйти на вторую - и все, ничего не сохраняется. К сожалению, я не сижу у тебя за спиной и не вижу, что означют все эти слова. Какое отношение имеют страницы (видимо, речь идет о PageFrame ?) к процедуре сохранения (как и где она запускается, что находится на страницах, что записано в процедуре сохранения и т.д. и т.п.) Да, речь идет именно о pageframe (я писала вначале). Получалось, перед вызовом формы, я выполняю select имя базы. Значит, объявив в init формы буфферизацию 5, я по умолчанию использовала нужные поля базы? Потом вводила данные на первой странице pageframe. Делала для проверки ввод данных через tableupdate(). Данные добавлялись. Но если я заполняла первую страничку и переходила на вторую, работала там, а потом пыталась сохранить - ничего не получалось. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 01.12.2005, 13:24 |
|
||
|
Очень нужно - объясните про буфферизацию!
|
|||
|---|---|---|---|
|
#18+
katry Каждому editbox отдельно прописывать в controlsource имя соответствующего поля таблицы? Или это можно сделать глобально - если да, то где именно? В том же Init? Можно сделать и то и другое. Правда, одной командой установить ControlSource для всех объектов не получиться. Ведь для каждого объекта необходимо указать свое поле. Программно, это выглядит примерно так: Код: plaintext katryПолучалось, перед вызовом формы, я выполняю select имя базы. Значит, объявив в init формы буфферизацию 5, я по умолчанию использовала нужные поля базы? Нет. Буферизация к этому вообще никакого отношения не имеет. Команда Select-SQL создает временную таблицу (курсор). Выбор режима буферизации определяет способ контроля пользователя за процессом сброса буфера и разрешением конфликтов совместного доступа. Использование нужных полей таблицы - это работа программиста. "Автоматически" никакие поля никуда не подставляются. Это исключительно "ручная" работа. katryПотом вводила данные на первой странице pageframe. Делала для проверки ввод данных через tableupdate(). Данные добавлялись. Но если я заполняла первую страничку и переходила на вторую, работала там, а потом пыталась сохранить - ничего не получалось. Команда TableUpdate() сбрасывает буфер в указанной (третий параметр) или текущей рабочей области (если не указан третий параметр). Если произошло переключение на другую рабочую область, то сбрасывать может оказаться нечего. При работе с TableUpdate() надо всегда следить, буфер чего (какой рабочей области) пытаешся сбросить. Кроме того, контролировать сам факт выполнения и анализировать возможные причины отказа: Код: plaintext 1. 2. 3. 4. 5. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 01.12.2005, 13:50 |
|
||
|
Очень нужно - объясните про буфферизацию!
|
|||
|---|---|---|---|
|
#18+
ВладимирМ Буфферизация, как я понимаю, по умолчанию предусматривает именно редактирование базы данных. А если мне нужно ввести новую запись? Ведь хочется, не сразу тупо делать append blank, а потом заполнять появившуюся строку. Значит, мне нужно завести два экземпляра формы, один - для редактирования, второй - для ввода данных? А с pageframe ситуация интересная - как только я убрала поля-словари (поля, к которым привязаны словарные базы), все стало нормально сохраняться. Но мне-то они нужны. Это и есть переключение на другую рабочую область? А как такое решать - производить TABLEUPDATE() сначала словарной базы, а потом основной? Если да, то каким образом? А если словарные базы не обновляются, т.е. выводится значение, которое там уже есть? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 02.12.2005, 09:46 |
|
||
|
Очень нужно - объясните про буфферизацию!
|
|||
|---|---|---|---|
|
#18+
ВладимирМ ...Правда, одной командой установить ControlSource для всех объектов не получиться. Ведь для каждого объекта необходимо указать свое поле. ... Уважаемая katry, чтоб Вас не запутать, Вам лучше не читать мое нижеследующее сообщение... В принципе, можно сэмулировать такую возможность, хотя это будет не очень красиво (обычно я делаю это в методе refresh() формы, так как по умолчанию у меня данных на форме нет, они запрашиваются через Web servise): 1. Назвать, например, texbox(s) каким-то осмысленным именем, в какой-то части совпадающими с именами полей в источнике данных, например txt_myfield 2. В методе refresh формы пишем следующий код: Код: plaintext 1. 2. 3. 4. 5. 6. 7. Думаю, что Вы легко переделаете этот код под Ваши нужды, но это всего-лишь один из многих подходов к организации ввода данных в форме... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 02.12.2005, 10:30 |
|
||
|
Очень нужно - объясните про буфферизацию!
|
|||
|---|---|---|---|
|
#18+
katry Буфферизация, как я понимаю, по умолчанию предусматривает именно редактирование базы данных. А если мне нужно ввести новую запись? Да. Только под термином "редактирование" в этом случае следует понимать любую модификацию содержимого таблицы. В том числе и создание (или удаление) записей. Это значит, что если Вы находитесь в режиме буферизации, то новая запись сначала будет создана в буфере. И только после сброса буфера она физически будет добавлена в саму таблицу. katryА с pageframe ситуация интересная - как только я убрала поля-словари (поля, к которым привязаны словарные базы), все стало нормально сохраняться. Но мне-то они нужны. Это и есть переключение на другую рабочую область? А как такое решать - производить TABLEUPDATE() сначала словарной базы, а потом основной? Если да, то каким образом? А если словарные базы не обновляются, т.е. выводится значение, которое там уже есть? Почитали бы Вы какую-нибудь книжку для начала. Ну, или вот это: Таблица Дело в том, что термины, используемые в FoxPro означают не совсем то, что кажется, если воспринимать их буквально. Точнее, в HELP по FoxPro все пишется достаточно корректно. Но когда переходят к объяснениям, то для краткости, начинают пользоваться несколько другими терминами. Это я к тому, что когда говорят о том, что изменили ту или иную таблицу, то в реальности обычно речь идет о рабочей области. Как правило, это не важно, поскольку обычно таблицу открывают только в одной рабочей области. Но в данном случае подобная замена приводит к недоразумению. Я уже обращал Ваше внимание на 3 параметр в команде TableUpdate(). Т.е. "по хорошему" надо бы писать команду примерно так: Код: plaintext 1. 2. Здесь третим параметром явно указывается алиас той рабочей области, где необходимо произвести сброс буфера. Если этого не сделать, то попытка сброса буфера будет предприниматься в текущей рабочей области. И вовсе не факт, что в текущей рабочей области открыта именно нужная таблица. Переключение между рабочими областями осуществляется командой SELECT (не надо путать ее с командой Select-SQL). Примерно так: Код: plaintext 1. 2. 3. 4. Но это явное переключение. Однако FoxPro, при определенных обстоятельствах, может сделать переключение на другую рабочую область самостоятельно. Видимо именно это и произошло при использовании справочников, а Вы не сделали ни указания 3-го параметра в TableUpdate() ни явного переключения в нужную рабочую область. Вот и "не сохранились" изменения. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 02.12.2005, 12:52 |
|
||
|
Очень нужно - объясните про буфферизацию!
|
|||
|---|---|---|---|
|
#18+
Sergey Ch ВладимирМ ...Правда, одной командой установить ControlSource для всех объектов не получиться. Ведь для каждого объекта необходимо указать свое поле. ... Уважаемая katry, чтоб Вас не запутать, Вам лучше не читать мое нижеследующее сообщение... В принципе, можно сэмулировать такую возможность, хотя это будет не очень красиво... Повторю фразу Сергея. Уважаемая katry, чтоб Вас не запутать, Вам лучше не читать мое нижеследующее сообщение... Сергей, я примерно представляю, как это можно сделать. Но, во-первых, одной командой этого не сделать в принципе. Т.е., да, конечно, можно создать некий метод (или набор методов) и одной командой вызывать этот метод. Но внутри метода все-равно будет достаточно сложный алгоритм. Во-вторых, количество сопутствующих проблем достаточно велико. Например, расположение объектов в контейнерах и как следствие - рекурсия. Причем, придется анализировать типы объектов и факт наличия у них коллекций Controls или Objects. Ну, и ряд других проблем. Т.е. без крайней необходимости я бы этого делать не стал. Тем более, в данном случае объяснение строится для новика, который не понимает базовых основ языка. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 02.12.2005, 13:02 |
|
||
|
Очень нужно - объясните про буфферизацию!
|
|||
|---|---|---|---|
|
#18+
ВладимирМ Sergey Ch сообщения не читала :) Burn>запись находится, но вот как организовать вывод найденных данных я не представляю. Вот когда пропишешь в качестве controlsource поля своей таблицы то после Seek-а достаточно буде дать Refresh нужным контролам Пожалуйста, напишите в виде примера. А то у меня получается следующее: В Init формы запихиваю append blank (иначе все поля формы недоступны для редактирования). Заполняю "Фамилия", "Имя" и "Отчество". При попытке перехода на следущее поле в LostFocus "Отчества" запихиваю поиск по If !Seek (LEFT(Alltrim(ThisForm.PageFrame1.Page1.txtFam.value),5)+LEFT(Alltrim(thisForm.PageFrame1.Page1.txtNam.value),5)+LEFT(Alltrim(thisForm.PageFrame1.Page1.txtOtt.value),3)) выплевывается сообщение "НЕ найдено!". Дальше я нажимаю кнопку "ОК" - и все поля в форме, за исключением заполненных перед началом поиска становятся неактивными. Если я добавляю после этого еще раз append blank, то потом, при сохранении в базу переносятся все заполненные поля, за исключением "Фамилии", "Имени" и "Отчества". Приходится делать присвоение значений через Repalce. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 03.12.2005, 07:54 |
|
||
|
Очень нужно - объясните про буфферизацию!
|
|||
|---|---|---|---|
|
#18+
FoxPro - это файл-серверная СУБД. Т.е. FoxPro работает с файлами. У файла (таблицы) DBF существует такое понятие, как "указатель записи". В серверных хранилищах данных (SQL Server, Oracle и т.п.) такого понятия не существует. Указатель записи - это та запись, которая просматривается (редактируется) в текущий момент времени. Его значение можно получить, используя функцию Recno(). "Родные" команды поиска типа SEEK(), LOCATE в процессе поиска сканируют всю таблицу, перемещаясь по записям. Но после завершения поиска они не возвращают указатель записи в исходной положение. Он остается там, где поиск был завершен. Итак, у тебя получилось следующее: APPEND BLANK - создала новую запись SEEK() - просканировал всю таблицу и переместил указатель записи. Куда? Это зависит от результата поиска. Почитай HELP по этой функции. В результате, ты оказалась на другой записи. Не той, которая была создана командой APPEND BLANK. Отсюда такие странные эффекты. Чтобы этого избежать, в данном случае, можно воспользоваться функцией INDEXSEEK(). Примерно так: Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. Здесь второй параметр функции IndexSeek() говорит о том, что не надо перемещать указатель записи. Третий параметр - это алиса той таблицы, по которой производится поиск Четвертый параметр - это имя индексного тэга этой таблицы, в соответствии с выражением которого и производится поиск. Использовать конструкцию LEFT(AllTrim(...),5) + LEFT(AllTrim(...),5) - нельзя . Как минимум, надо заменить LEFT() на PADR(). Поясню на примере: Код: plaintext 1. 2. 3. 4. Если использовать конструкцию LEFT(AllTrim(...),5) + LEFT(AllTrim(...),5), то и для переменных a1, a2 и для переменных b1,b2 получим одно и то же значение: "12345" Почему? Да потому, что LEFT() возьмет первые 5 символов из имеющихся . А функция AllTrim() отбросит ведущие и концевые пробелы. Если использовать конструкцию PADR(AllTrim(...),5) + PADR(AllTrim(...),5), то для переменных a1, a2 имеем Код: plaintext а для переменных b1, b2 имеем Код: plaintext Т.е. дейстьвительно разные значения. Но, как говорят в рекламных роликах, это еще не все! Можно серьезно упростить весь код, если в свойствах TextBox установить значение реквизита: TextBox.Format = "T" Если делать эту настройку в дизайнере формы, а не программно, то кавычки не нужны. Эта настройка сама, автоматически, будет отбрасывать ведущие пробелы по окночании ввода значения. Если общая длина этих полей те же 5 символов, то формирование ключа для поиска будет совсем простым: Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. Т.е. не понадобяться вообще никакие преобразования для введенных значений. Их можно взять "как есть" =================================== Это все замечательно, но абсолютно бессмысленно. Дело в том, что если все твои TextBox привязаны к соответствующим полям таблицы (настроены ControlSource). То ввод данных в эти TextBox означает автоматический ввод в соответствующие поля таблицы (или в буфер этой таблицы, если настроена буферизация). Таким образом, эти данные сразу же попадают в индекс и будут найдены функциями SEEK() или IndexSeek()! Т.е. у тебя всегда будет выдаваться сообщение о том, что такая запись существует. Контроль уникальности осуществляется другими способами: 1) Индекс типа Candidat по выражению, уникальность которого проверяется. Такой индекс просто не даст создать повторяющееся значение. 2) Использовать триггер на Insert и Update в которых проверять уникальность данных. Обе стартегии имеют достоинства и недостатки. Первый - проще в реализации (особенно для новичков), но сложнее перехватить системное сообщение об ошибке и приводит к увеличению размера индексного файла (CDX) Второй - проще в смысле контроля сообщений об ошибках, но сложнее в реализации. Если пока нет желания возиться с такими способами контроля, то для поиска возможных дублей используй команду Select-SQL. По умолчанию, эта команда не видит записей созданных или измененных в буфере таблицы. Работает только с тем, что есть реально в таблице. Кроме того, эта команда не перемещает указатель записи. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 03.12.2005, 12:16 |
|
||
|
Очень нужно - объясните про буфферизацию!
|
|||
|---|---|---|---|
|
#18+
Hi ВладимирМ! > расположение объектов в контейнерах и как следствие - рекурсия Это можно обойти через SetAll для специального свойства-триггера, в Assign_ которого и будет логика "найти поле совпадающее с моим именем, и прицепиться к нему". При этом даже можно позволять себе кой какие вольности, типа - поля нету - мы прячем контрол, или блокируем его, введя в качестве Value какое-нить "не влазь убъёт" :) Я отчасти понимаю Сергея - есть существенные проблемы со "статическим" присваиванием ControlSource - например невозможно нормально обработать ошибку "некорректности" такого ControlSource - т.к. его реально устанавливает не какой-то определённый код, а исполняющая среда, при "считывании" описания класса или формы в память. Эти проблемы ЧАСТИЧНО решаются через свойство Form.BindControls - но акцентирую ещё раз - ЧАСТИЧНО... Также есть проблемы если источник данных открывается заметно позже инициализации этого контрола - конечно это можно обойти путём создания в Load или в DE курсора-шаблона т.е. пустого курсора, который потом (уже после инициализации и даже возможно после ввода данных в какие-то поля-условия филтьтрации) заменится на реальный заполненный курсор. И кстати использование механизма CursorAdapter тут должно сильно помочь - т.к. там уже есть "схема", и можно сразу-же создать пустой "шаблон" курсора... Posted via ActualForum NNTP Server 1.3 ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 03.12.2005, 16:16 |
|
||
|
Очень нужно - объясните про буфферизацию!
|
|||
|---|---|---|---|
|
#18+
katryВ Init формы запихиваю append blank (иначе все поля формы недоступны для редактирования). Заполняю "Фамилия", "Имя" и "Отчество". При попытке перехода на следущее поле в LostFocus "Отчества" запихиваю поиск по If !Seek (LEFT(Alltrim(ThisForm.PageFrame1.Page1.txtFam.value),5)+LEFT(Alltrim(thisForm.PageFrame1.Page1.txtNam.value),5)+LEFT(Alltrim(thisForm.PageFrame1.Page1.txtOtt.value),3)) выплевывается сообщение "НЕ найдено!". Дальше я нажимаю кнопку "ОК" - и все поля в форме, за исключением заполненных перед началом поиска становятся неактивными. Если я добавляю после этого еще раз append blank, то потом, при сохранении в базу переносятся все заполненные поля, за исключением "Фамилии", "Имени" и "Отчества". Приходится делать присвоение значений через Repalce. Подход в корне неверный. Что получается - добавили запись, заполнили поля и ищем значения, беря их из контрола привязаного к полю таблицы. Что при этом получается один бог знает. Можно конечно вместо Seek() использовать IndexSeek() - она не передергивает записи. Но все равно запись с такими значениями уже есть в таблице - вы ведь уже ее только что добавили. Логичней былобы в INIT-е создать курсор из одной записи, запихнуть туда значения, проверку делать в кнопке OK а не по выходу, после проверки просто скопировать запись из курсора в таблицу и убить курсор. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 03.12.2005, 20:35 |
|
||
|
Очень нужно - объясните про буфферизацию!
|
|||
|---|---|---|---|
|
#18+
Спасибо всем за советы. Медленно, но верно до меня доходит. С переходом указателя в SEEK() - это был мой личный глюк, исправила. То, что он всегда находит запись, потому что я её создаю - меня вполне устроило. Если убрать все MessageBox'ы и добавить в индекс еще и дату рождения (для более полной идентификации записи), то будет все чудесно -если запись в базе была до этого, она вызывается на редактирование. Если её не было - ну и ладно, будем вводить новую. Очередной вопрос - а как организовать поиск по нескольким базам? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 06.12.2005, 10:57 |
|
||
|
|

start [/forum/topic.php?fid=41&msg=33411061&tid=1592863]: |
0ms |
get settings: |
6ms |
get forum list: |
11ms |
check forum access: |
3ms |
check topic access: |
3ms |
track hit: |
191ms |
get topic data: |
9ms |
get forum data: |
2ms |
get page messages: |
37ms |
get tp. blocked users: |
1ms |
| others: | 191ms |
| total: | 454ms |

| 0 / 0 |
