Форма WorkEdit в Visual FoxPro
« Назад В форме WorkEdit (рис. 2.28) книга, к которой относится произведение, и вид произведения выбираются из раскрывающихся списков. Рис. 2.28. Выбор вида произведения в форме WorkEdit Источниками данных списков "Книга" и "Вид" являются соответственно поле Book таблицы Books (рис. 2.29) и поле WorkType таблицы WorkTypes. Рис. 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.; запись данных выполнена не будет. |