Опубликован: 13.09.2006 | Уровень: для всех | Доступ: свободно
Лекция 7:

Создание интерактивных офисных документов в Excel

Раздел "Реквизиты заказчика"

Сама по себе задача формирования этой части бланка достаточно простая. Необходимо в соответствующие поля бланка занести информацию о покупателе, - его реквизиты. Однако, учитывая, что большинство заказчиков офиса РР давно с ним сотрудничают, то информация о них хранится в базе данных. Поэтому, как уже говорилось, не следует заново заполнять соответствующие поля вручную, а следует перенести в них данные, взятые из базы данных.

С другой стороны, при появлении нового заказчика данные о нем поневоле придется вводить вручную в поля бланка, создавая тем самым новую информацию. Крайне важно, чтобы новая информация не пропала, а сохранилась в базе данных. Это общие принципы работы с интерактивными документами.

Для организации обмена данными между документом и базой данных давайте добавим в раздел четыре командные кнопки, по нажатию которых будут решаться следующие задачи:

  • Выбор заказчика.
  • Поиск заказчика.
  • Сохранение реквизитов.
  • Чистка полей реквизитов.

Вот как выглядит теперь этот раздел документа с добавленными кнопками:

Раздел "Реквизиты заказчика" с добавленными кнопками

увеличить изображение
Рис. 7.2. Раздел "Реквизиты заказчика" с добавленными кнопками

Рассмотрим подробнее суть каждой из этих задач, и то, что должен делать обработчик события, происходящего при нажатии соответствующей командной кнопки.

Выбор заказчика

Я напомню, что в спроектированной в предыдущих главах базе данных офиса РР хранятся сведения о заказчиках, в частности, есть таблица "Заказчики", имеются и стандартные запросы, связанные с заказчиками. Чтобы нужные данные извлечь из базы данных и затем перенести в поля бланка, первым делом нужно задать ключ поиска. Проще всего в качестве такового указать название организации, напомню, что это поле является ключевым для таблицы "Заказчики". Поэтому один из возможных подходов к решению проблемы состоит в том, чтобы сформировать список всех организаций, хранящихся в базе данных, и дать возможность пользователю выбрать нужную организацию. Выбор пользователя определяет ключ поиска, а уж извлечение по ключу данных из базы и перенос их в поля бланка является делом техники.

Таким образом, задача выбора заказчика сводится к следующим подзадачам:

  • Формирование и показ списка названий заказчиков.
  • Формирование запроса на поиск в базе данных
  • Перенос результатов запроса в поля бланка.

А теперь взгляните, как выглядит обработчик события Click командной кнопки "Выбрать", вызываемый при нажатии этой кнопки:

Private Sub CommandButton1_Click()
	'выбор заказчика из базы данных
	Choose
End Sub	
Public Sub Choose()
	'Данные о заказчиках выбираются из базы данных
	CreateListCustomers
	FormListCustomers
	Customers.Show
End Sub

Сохраняя свой стиль, обработчик события свожу к вызову соответствующей процедуры стандартного модуля. Замечу, что в этом стиле имеется и определенный резон, поскольку процедуру, заданную обработчиком, можно вызывать не только при нажатии командной кнопки. В частности, именно так обстоит дело с процедурой Choose, которая будет вызываться по ходу решения задачи в одной из процедур стандартного модуля.

Сама по себе процедура Choose не решает полностью задачу выбора заказчика. Две процедуры, вызываемые в процедуре Choose, решают лишь первую подзадачу, завершая свои действия показом формы со списком. Дальнейшие действия определяются пользователем и зависят от его выбора. Но, прежде чем говорить о решении других подзадач, давайте более подробно разберемся с тем, что делается в процедуре Choose.

Формирование и показ списка

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

Форма Customers, позволяющая сделать выбор в списке заказчиков

Рис. 7.3. Форма Customers, позволяющая сделать выбор в списке заказчиков

Решать задачу формирования списка нужно начинать с получения из базы данных набора записей, содержащих названия заказчиков. Возможно, Вы помните, что в спроектированной нами базе данных содержится стандартный запрос с именем "Список заказчиков", решающий именно эту задачу. Уже тогда, при проектировании базы было понятно, что такой запрос может понадобиться. Поэтому теперь единственное, что нужно сделать, - получить набор записей, соответствующий этому запросу. Как это реализовать с помощью объектов ADO, - подробно описывалось в предыдущих главах. Так что осталось взглянуть на текст соответствующей процедуры CreateListCustomers, которая первой вызывается в процедуре Choose:

Public Sub CreateListCustomers()
	'Создание	и выполнение команды,
	'позволяющей получить данные о заказчиках
	Dim strSQL1 As String
	strSQL1 = "Select * FROM [Список заказчиков]"
	'задание объекта Command
	Cmd1.CommandText = strSQL1
	'вызов команды на исполнение методом Execute
	Set Rst1 = Cmd1.Execute
End Sub

Как видите, получить нужный набор записей достаточно просто. Конечно, нужно иметь в виду, что глобальные объекты Con1, Cmd1, Rst1 уже созданы, соединение с базой данных и конфигурирование команды - объекта Cmd1 выполнено при инициализации документа. Так что в данной процедуре осталось задать лишь текст команды, который в данном случае сводится к выполнению стандартного запроса "Список заказчиков". При выполнении команды формируется объект Rst1, который и содержит названия заказчиков.

Назначение следующей процедуры состоит в том, чтобы данные из набора записей - объекта Rst1 - перенести в список спроектированной формы Customers. Все делается совершенно просто и естественно:

Public Sub FormListCustomers()
	'Перенос данных о заказчиках из набора записей
	'в список формы Customers
	 With Rst1
		.MoveFirst
		Customers.ListBox1.Clear
		Do While Not .EOF
			'Текущая запись переносится в список
			Customers.ListBox1.AddItem .Fields(0)
			.MoveNext
		Loop
	End With
End Sub

Заметьте, схема прохождения набора записей обсуждалась в главе 5, а о работе с элементами управления, в частности, с объектами класса ListBox я подробно рассказывал в предыдущих книгах этой серии, например, в книге [1]. Может быть, стоит лишь напомнить, что запрос "Список заказчиков" возвращает запись, содержащую одно поле с названием организации заказчика. Содержимое этого поля и переносится в список.

Теперь, когда данные о заказчиках получены, список с названиями организаций сформирован, осталось предъявить форму Customers пользователю. Эту операцию и выполняет метод Show объекта Customers, что отражено в последнем выполняемом операторе процедуры Choose. Форма, появляющаяся на экране и показана на рис. 7.3. В открывшейся форме пользователь может выбрать из списка нужного заказчика, после чего нажать командную кнопку "Выбери меня". Обработчик события Click этой кнопки и отвечает за последующие действия, позволяя решить следующую упоминавшуюся подзадачу - поиск по ключу в базе данных сведений о реквизитах выбранного заказчика. Вот текст этого обработчика:

Private Sub CommandButton1_Click()
	'Данные о заказчике, выбранном из списка,
	'ищутся в базе данных и затем переносятся
	'из набора записей в поля бланка Счет-фактура
	FromListToFields
	
End Sub

Содержательные действия выполняет процедура FromListToFields, которая и реализует решение подзадачи по формированию запроса на поиск.

Формирование запроса на поиск

Выбрав заказчика из списка, пользователь тем самым задает ключ, позволяющий отобрать нужную запись в таблице базы данных "Заказчики". Формирование запроса на поиск в базе данных, когда ключ поиска известен, технически сводится к корректному заданию SQL-оператора. Получение набора записей по динамически сформированному запросу принципиально не сложнее, чем уже рассмотренная задача, когда использовался стандартный запрос. Вот как все это решается в процедуре FromListToFields:

Public Sub FromListToFields()
	'Данные о заказчике, выбранном из списка,
	'ищутся в базе данных и затем переносятся
	'из набора записей в поля бланка Счет-фактура.
	Const Кавычка = "'"
	Dim Key As String
	Dim strSQL1 As String
	If Customers.ListBox1.ListIndex >= 0 Then 'Выбор сделан.
		'Формирование запроса к базе данных.
		Key = Customers.ListBox1.List(Customers.ListBox1.ListIndex)
		strSQL1 = "Select * FROM [Заказчики]WHERE [Название]= " _
			& Кавычка & Key & Кавычка
		'Изменение описания команды.
		Cmd1.CommandText = strSQL1
		Set Rst1 = Cmd1.Execute
		
		'Перенос данных из набора записей в поля бланка.
		FromRstToFields
	 'Форма сделала свое дело - форма закрывается.
	 Customers.Hide
	Else
		MsgBox ("Выберите заказчика!")
	End If
End Sub

Как видите, все происходит по задуманному плану. Формируется строка с ключом, строка с SQL-запросом, изменяется текст команды у объекта Command и при запуске его метода Execute формируется нужный набор записей, состоящий в данном случае из одной записи, содержащей все реквизиты заказчика.

Вызов процедуры FromRstToFields позволяет решить последнюю подзадачу в этом пункте по переносу данных из полей текущей записи объекта Rst1 в поля бланка. Последний выполняемый оператор этой процедуры - Customers.Hide прячет форму Customers, которая сделала свое дело и должна быть закрыта.

Ольга Гафарова
Ольга Гафарова
Непонятен ход решения задачи
Серегй Лушников
Серегй Лушников
Может ли объект Recordset быть потомком объекта Record?
Геннадий Шестаков
Геннадий Шестаков
Беларусь, Орша
Светлана Ведяева
Светлана Ведяева
Россия, Саратов