Распечатать страницу

Форма WorkEdit в Visual FoxPro

« Назад

В форме WorkEdit (рис. 2.28) книга, к которой относится произведение, и вид произведения выбираются из раскрывающихся списков.

19.1.-Выбор-вида-произведения-в-форме-WorkEdit

Рис. 2.28. Выбор вида произведения в форме WorkEdit

Источниками данных списков "Книга" и "Вид" являются соответственно поле Book таблицы Books (рис. 2.29) и поле WorkType таблицы WorkTypes.

19.2.-Задание-для-списка-Книга-источника-данных-и-его-вида

Рис. 2.29. Задание для списка "Книга"источника данных и его вида

Первая таблица упорядочена по названию книги (поле Book), вторая по названию вида произведения (поле WorkType). Поиск нужной записи производится по первой букве названия в открытом списке. Повторный ввод той же буквы, если не задан нарастающий поиск (свойство IncrementalSearch списка имеет значение . F.), перемещает список на следующее название, начинающееся с этой буквы.

Если же свойство IncrementalSearch имеет значение .T. (задано по умолчанию), то выполняется поиск с уточнением: после ввода очередного символа ищется набранная подстрока.

Замечания:

1. При поиске с уточнением временной интервал между нажатиями на клавиши клавиатуры, не должен превышать величины, задаваемой системной переменной _INCSEEK. Если это значение превышено, то начинается новый поиск. Значение _INCSEEK задается в диапазоне от 0.05 до 5.5 с. Значение по умолчанию – 0.5 с.

2. Характер поиска в раскрывающемся списке также зависит от значения его свойства Style. Если Style – это 0 (по умолчанию), то поиск выполняется только после раскрытия списка, ели же Style = 2, то поиск можно выполнять сразу после позиционирования на поле со списком.

Значения свойств IncrementalSearch и Style списков формы WorkEdit задаются в обработчике его события Init:

&& Обработчик события Init формы WorkEdit

&&

&& Списки "Книга" и "Вид" имеют соответственно имена Combo1 и Combo2

lparameters oPr

This.WindowType = 1        && Открываем форму модально

This.AutoCenter = .T.         && и располагаем ее по центру экрана

if not Used('BooksContent') or not Used('Books') or not Used('WorkType') then

MessageBox("Открыты не все таблицы!")

This.Combo1.RowSource = ""

This.Combo2.RowSource = ""

This.Command1.Enabled = .F.        && Кнопка "Сохранить"

return

else

This.Combo1.RowSource = "Books.Book"

This.Combo2.RowSource = "WorkType.WorkType"

endif

if Pcount( ) = 0 then

oPr = 'new'

endif

set order to tag WorkType in WorkType

select BooksContent

with This

.Op = oPr                            && Op - новое свойство формы

if oPr = 'new' then               && Новая запись

&& Заголовок формы

.Caption = 'Новая запись'

.WorkName.Value = ""

.Combo1.Value = Books.Book

Combo2.Value = WorkType.WorkType

else                                      && Редактирование записи

seek BooksContent.BookId order tag BookId in Books

.Caption = 'Редактирование записи'

WorkName.Value = BooksContent.Name

Combo1.Value = Books.Book

Combo2.Value = WorkType.WorkType

endif

Combo1.IncrementalSearch = .T.

.Combo1.Style = 2

&& Отказываемся от нарастающего поиска в списке Combo2

.Combo2.IncrementalSearch = .F.

.Combo2.Style = 0

endWith

Список Combo2 раскрывается сразу, как только он оказывается в фокусе. Это обеспечивает обработчик его события GotFocus:

&& Обработчик события GotFocus раскрывающегося списка Combo2

&&

fName = ThisForm.Name   && Имя формы

&& Запоминаем координаты (в пикселях) указателя мыши

nRowMouse = Mrow(fName, 3)

nColMouse = Mcol(fName, 3)

&& Находим координаты раскрывающей список стрелочки ()

&& Координаты вычисляются в пикселях относительно левого верхнего угла формы

nRowDown = Objtoclient(this, 1) + 2

nColDown = Objtoclient(this, 2) + Objtoclient(this, 3) – 2

&& Инициируем удар мышью по раскрывающей список стрелочке

mouse click at nRowDown, nColDown window (fName) pixels

&& Восстанавливаем положение указателя мыши

mouse at nRowMouse, nColMouse window (fName) pixels

Замечание. Если длина текста элемента списка Listbox или ComboBox превышает ширину списка, то текст будет отображаться целиком в виде подсказки, если свойство ItemTips списка установить в .T. В случае ComboBox подсказка выводится в раскрытом сниске. Если Listbox имеет несколько столбцов, то подсказка показывается только для элементов первого столбца.

Кнопки "Сохранить" форм BookEdit и WorkEdit имеют практические одинаковые обработчики события Error. Разница в том, что в таблице BooksContent контролируется уникальность индекса BookIdName: не разрешается иметь в одной книге произведения с одинаковыми названиями. Эта разница отражается в тексте, выводимом при обнаружении совпадающих названий.

&& Обработчик события Error кнопки "Сохранить" формы WorkEdit

&&

lparameters nError, cMethod, nLine

if nError = 1884 then

MessageBox("Произведение " + Trim(ThisForm.WorkName.Value) ;

+ " в книге уже имеется", 48)

else

MessageBox("Ошибка № " + Transform(nError) + " в строке " ;

+ Transform(nLine) + " метода " + cMethod, 48)

endif

ThisForm.NoError = .F.

При возникновении ошибки с номером 1884 – нарушение уникальности кандидатного индекса BookIdName и последующем нажатии в рассматриваемой форме на "Отказ" позиция таблицы BooksContent не меняется. Это обеспечивается командой GO recOld IN 'BooksContent' обработчика события Click кнопки "Сохранить" формы WorkEdit.

&& Обработчик события Click кнопки "Сохранить" формы WorkEdit

&&

&& Проверяем, все ли поля формы заполнены

if not ThisForm.CheckFields( ) then

return

endif

local isDone

isDone = .T.

ThisForm.NoError = .T.

&&

&& Запоминаем текущую запись таблицы BooksContent

recOld = Recno('BooksContent')

&&

begin transaction                 && Начинаем транзакцию

if ThisForm.Op = 'new' then

insert into BooksContent (BookId, Name, TypeId);

values(Books.BookId, ;

Ltrim(ThisForm.WorkName.Value), ;

WorkType.TypeId)

else

if IsRlocked( ) or not Rlock( )

MessageBox("Запись недоступна!")

isDone = .F.

else

replace BooksContent.BookId with Books.BookId, ;

BooksContent.Name with Ltrim(ThisForm.WorkName.Value) ;

BooksContent.TypeId with WorkType.TypeId

endif

unlock record Recno( )

endif

if isDone and ThisForm.NoError then

end transaction                         && Завершаем транзакцию

ThisForm.Release

else

&& Отмена изменений при обнаружении ошибки

rollback

if not ThisForm.NoError then

&& В случае ошибки возвращаем таблицу к записи recOld

go recOld in 'BooksContent'

endif

endif

Все три поля формы перед сохранением данных должны быть заполнены. Это требование контролируется добавленным в форму методом CheckFields. При обнаружении пустого поля метод выдаст соответствующее предупреждение и вернет .F.; запись данных выполнена не будет.