Форма "Книги" в Visual FoxPro
« Назад Предназначена для ввода книг; для выбранной книги в форме указываются ее авторы (рис. 2.23). Рис. 2.23. Форма "Книги" Форма работает с 3-я таблицами – Authors, Books и BooksAuthors, внесенными в окружение данных формы. Таблица Books, отображаемая в сетке Grid1 формы, упорядочена по полю Book (столбец "Книга" сетки). В целом процесс ввода и редактирования таблицы Books организован так же, как и таблицы Authors, и поэтому не рассматривается. В списке List1 выводятся данные об авторах выбранной книги. Источником данных списка является глобальный двумерный массив aAuthors. Массив создается в обработчике события Init формы Books: && Обработчик события Init формы "Книги" && set order to Book in Books This.AutoCenter = .T. This.Grid1.ReadOnly = .T. public aAuthors(20, 3) Заполняется массив в обработчике события AfterRowColChange поля сетки таким образом, что при смене строки сетки в него попадают авторы выбранной книги. В первом столбце массива проставляется звездочка, если выбранная из таблицы Authors запись имеет пометку удаления, или пробел – в противном случае. && Обработчик события AfterRowColChange сетки Grid1 формы "Книги" && lparameters nColIndex if nColIndex > 0 then with ThisForm if Deleted( ) then .Command2.Enabled = .F. Command3.Caption = "Возвратить" else Command2.Enabled = .T. .Command3.Caption = "Удалить" endif endwith endif && && Выбираем все записи, как с пометкой удаления, так и без нее set deleted off dimension aAuthors(20, 3) aAuthors = '' && Инициализация массива && && Заносим в массив данные об авторах книги с кодом Books.BookId select Authors.AuthorId, Authors.AuthorId, Author from Authors, BooksAuthors; where Authors.AuthorId = BooksAuthors.AuthorId; and BooksAuthors.BookId = Books.BookId; order by Author; into array aAuthors && if Empty(aAuthors(1, 2)) then && В массиве нет записей (авторы для выбранной книги не указаны), && поэтому список List1 делаем недоступным ThisForm.List1.Enabled = .F. else && Заносим сведения о пометке удаления выбранных записей && в первый столбец массива aAuthors select BooksAuthors set order to AuthorId for iRow = 1 to Alen(aAuthors, 1) au_Id = aAuthors(iRow, 2) seek au_Id do while AuthorId = au_Id and not Eof( ) if BookId = Books.BookId then exit endif skip && Переход на новую запись enddo aAuthors(iRow, 1) = Iif(Deleted('BooksAuthors'), '*', ' ') next ThisForm.List1.ListIndex = 1 ThisForm.List1.Enabled = .T. && Позиционируемся на первой строке списка List1 ThisForm.List1.ListIndex = 1 endif ThisForm.List1.Refresh Свойства списка List1 установлены в окне редактирования свойств объекта. При их программном определении в обработчик события Init формы "Книги" пришлось бы добавить следующие строки кода: && Значения свойств списка List1 && with ThisForm.List1 .RowSourceType = 5 && Тип источника данных – массив .RowSource = "aAuthors" .ColumnCount = 3 && Число столбцов в списке .ColumnWidths = "10,40,280" && Ширина столбцов в пикселях endWith Добавляется автор в список List1 в результате его выбора в форме "Авторы", открываемой обработчиком события Click кнопки "Авторы" формы "Книги". && Обработчик события Click кнопки "Авторы" формы "Книги" && local formName, listInd, рAuthorId, authorSelected formName = appPath + 'Forms\Authors' listInd = ThisForm.List1.ListIndex рAuthorId = Iif(listInd = 0, 0, aAuthors(listInd, 2)) рAuthorId = Iif(Vartype(рAuthorId) = "C", 0, рAuthorId) && && Открываем форму "Авторы". Передаем ей код выбранного в списке List1 && автора, чтобы позиционироваться на нем в форме "Авторы" && Если автор будет выбран, authorSelected получит значение .T. && do form (formName) with рAuthorId to authorSelected && && Проверяем, выбран ли авторы. Если да, то добавляем запись в BooksAuthors if authorSelected then insert into BooksAuthors (BookId, AuthorId); values (Books.BookId, Authors.AuthorId) endif ThisForm.Grid1.SetFocus Если автор выбран, то в таблицу BooksAuthors добавляется новая запись – код текущей книги и код выбранного автора. Если в форме "Авторы", открытой из формы "Книги", нужный автор не обнаружен, то его можно сразу же и добавить. Редактирование записей таблицы BooksAuthors не предусмотрено. Если запись не подходит, то она удаляется, а взамен ее заносится новая. Пометка удаления записи BooksAuthors проставляется обработчиком события Click кнопки "Пометка": local ind && && Находим соответствующую запись в таблице BooksAuthors && Для этого первоначально используем поиск по коду автора, && а затем среди записей, относящихся к одному автору, ищем код текущей книги select BooksAuthors set order to AuthorId ind = ThisForm.List1.ListIndex au_Id = aAuthors(ind, 2) seek au_Id flag = .F. do while AuthorId = au_Id and not Eof( ) if BookId = Books.BookId then flag = .T. exit endif skip && Переход на новую запись enddo && && Обрабатываем результаты поиска if flag then if Deleted('BooksAuthors') then recall && Снимаем пометку удаления aAuthors(ind, 1) = ' ' && и отражаем этот факт в массиве aAuthors else delete aAuthors(ind, 1) = '*' endif else MessageBox("Запись, соответствующая List1, в BooksAuthors не найдена") endif ThisForm.List1.Refresh select Books Одна из маловероятных причин неудачного поиска – это изменение таблицы BooksAuthors другим пользователем в промежуток времени начиная с момента формирования массива aAuthors вплоть до нажатия на кнопку "Пометка". При завершении работы с формой глобальный массив aAuthors освобождается (удаляется из памяти). Это выполняет обработчик события Unload формы, содержащий один оператор: release aAuthors && Обработчик события Unload формы "Книги". |