Мир объектов Excel 2000

         

База данных офиса "Родная Речь"


В качестве тестовой базы данных я рассмотрю базу данных гипотетического офиса "Родная Речь", который в дальнейшем буду называть офисом РР. Офис РР занимается издательской деятельностью и имеет отделы (группы), которые непосредственно готовят и издают книги, занимаются маркетингом и рекламой, распространением и сбытом книг. С издательством сотрудничают авторы, переводчики, книготоргующие организации.



Фильтрация записей


Под фильтрацией понимается выделение из таблицы записей, удовлетворяющих условиям запроса. Фильтровать записи можно как вручную, так и программно. В Excel есть два метода фильтрации записей списка: AutoFilter и AdvancedFilter. Первый фильтрует записи на том же месте, где находится сам список. Критерии отбора записей можно задать только для одного поля. В результате его работы исходный список делается невидимым, показываются только отобранные фильтром записи. При работе вручную можно просмотреть эти записи, в случае необходимости скорректировать их или скопировать. При программировании чаще используется метод AdavncedFilter, позволяющий не только фильтровать записи на месте, но и копировать результаты в указанное место. Важнее, что он позволяет задавать довольно сложные условия отбора записей, накладываемые, при желании, на все поля списка. Рассмотрим подробнее работу этих методов. Синтаксис метода AutoFilter таков:

expression.AutoFilter(Field, Criteria1, Operator, Criteria2, VisibleDropDown)

Выражение Expression должно возвращать Range-объект, задающий список. Параметры метода имеют следующий смысл:

Field - задает порядковый номер поля списка, используемого для отбора записей; критерии отбора накладываются именно на это поле;Criteria1 и Criteria2 - задают два возможных условия, накладываемых на поле. Если заданы оба эти параметра, то параметр Operator может принимать значение xlAnd или xlOr. Каждый из параметров представляет собой строку вида

<знак операции отношения><значение>",

где могут быть использованы все обычные знаки операции отношения: " >, >=, <, <=, =, <>". Если опущен знак операции, - подразумевается "равенство"; если опущено значение, а знак операции - "=" или "<>", условие означает проверку поля на пустоту. Если параметры Criteria1 и Criteria2 опущены, то никакие условия не накладываются и выбираются все записи. Чаще всего опускается один параметр - Criteria2. В этом случае могут быть заданы дополнительные условия выборки. Можно выбрать первые N записей, имеющих максимальные или минимальные значения. Параметр Critria1 указывает тогда число N, а значение параметра Operator указывает, задает ли N число записей или число процентов записей, максимальные или минимальные значения которых будут отбираться.Operator - принимает одно из значений: xlAnd, xlOr, xlBottom10Items, xlTop10Items, xlBottom10Percent, xlTop10Percent; первые два используются, если заданы оба критерия, остальные задаются, если задан только первый критерий и он определяет не отношение, а специальные условия выборки записей. По умолчанию значение параметра Operator - xlAnd.VisibleDropDown - булев параметр, значение True которого позволяет сделать видимым поле фильтрации. Для этого подсвечивается стрелка выпадающего списка, связанного с именем поля.Если метод AutoFilter вызывается без параметров, он отключает результаты предыдущей фильтрации и список показывается полностью в обычном виде.

Я создал некоторый список и хочу поэкспериментировать с ним:


увеличить изображение
Рис. 4.22.  Список до начала фильтрации его записей


Я создал некоторый список и хочу поэкспериментировать с ним:


увеличить изображение
Рис. 4.22.  Список до начала фильтрации его записей

Ниже Вы видите процедуру, в которой проводятся эксперименты по фильтрации записей этого списка. Конечно, предполагается пошаговое ее выполнение, чтобы видеть результат каждой фильтрации.

Sub Автовыбор() 'Эксперименты с автофильтрацией Range("B1").Select 'Эксперимент 1. 'Выбор 3-х элементов с максимальными значениями 2-го поля. Selection.AutoFilter Field:=2, Criteria1:="3", _ Operator:=xlTop10Items, VisibleDropDown:=True

'Эксперимент 2. 'Типичное условие выбора с двумя критериями Selection.AutoFilter Selection.AutoFilter Field:=2, Criteria1:="<12", _ Operator:=xlOr, Criteria2:=">30", VisibleDropDown:=False

'Эксперимент 3. 'Условие выбора эквивалентно True. Выбираются все записи. Selection.AutoFilter Selection.AutoFilter Field:=2, Criteria1:="<>12", _ Operator:=xlOr, Criteria2:="<>35", VisibleDropDown:=True

'Эксперимент 4. 'Будут выбраны 5 записей из списка Selection.AutoFilter Range("B1").Select Selection.AutoFilter Field:=2, Criteria1:="12", _ Operator:=xlOr, Criteria2:=">30" End Sub

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


увеличить изображение
Рис. 4.23.  Результаты фильтрации списка

Обратите внимание, в результате последней фильтрации из списка выбраны 5 записей, имеющие номера: 2, 3, 4, 7, 8. Только эти записи отображаются на рабочей странице, остальные записи недоступны, пока фильтр остается включенным.

Я хочу теперь рассказать еще об одном объекте, связанном с автофильтрацией. Напомню, что каждый список следует располагать на отдельном листе, и методы фильтрации могут быть применены только к единственному списку на листе. В терминах объектов это означает, что объект Worksheet имеет свойство AutoFilter, возвращающее одноименный объект. Объект AutoFilter хранит информацию о фильтрах, применяемых к списку. Главное свойство этого объекта - Filters возвращает одноименную коллекцию, элементы которой являются объектами класса Filter. Число элементов в коллекции совпадает с числом полей списка. Каждый из объектов Filter сохраняет параметры фильтра, применяемого к соответствующему столбцу списка. Я покажу на примере, какими свойствами обладают эти объекты. Кроме свойства Filters можно еще отметить и свойство Range объекта AutoFilter, возвращающее, по существу, область, занятую списком.

Вот пример работы с объектом AutoFilter:

Public Sub FilterAuto() 'Работа с объектом AutoFilter и результатами фильтрации Dim Myf As AutoFilter, filt As Filter 'Определить объект AutoFilter, связанный со страницей Set Myf = ThisWorkbook.Worksheets("Лист2").AutoFilter Debug.Print "Число фильтров = ", Myf.Filters.Count For Each filt In Myf.Filters Debug.Print "Включен = ", filt.On If filt.On Then Debug.Print "Фильтр:", filt.Criteria1, _ filt.Operator, filt.Criteria2 End If Next filt



End Sub

Вот результаты отладочной печати:

Число фильтров = 4 Включен = False Включен = True Фильтр: =12 2 >30 Включен = False Включен = False

Как видите, булево свойство On объекта AutoFilter позволяет определить, включен ли фильтр. Свойства Criteria1, Criteria2 и Operator возвращают одноименные параметры фильтра.

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

Public Sub FilterRes() 'Работа с результатами фильтрации Dim Myf As AutoFilter Dim Myr As Range, Myr1 As Range Dim MyrBeg As Range, MyrEnd As Range Dim cel As Range 'Определить объект AutoFilter, связанный со страницей Set Myf = ThisWorkbook.Worksheets("Лист2").AutoFilter 'Область списка Set Myr = Myf.Range 'Отрезаю строку заголовков списка Set MyrBeg = Myr.Offset(1, 0).Cells(1, 1) Set MyrEnd = Myr.Cells(Myr.Rows.Count, Myr.Columns.Count) Set Myr = Range(MyrBeg, MyrEnd) 'Выделяю область фильтрации Myr.Select Myr.Copy 'Получаю на другом листе результаты фильтрации Set Myr1 = Range("Лист3!F2") Myr1.PasteSpecial Set Myr1 = Myr1.CurrentRegion 'Объект Myr содержит все данные списка, 'Объект Myr1 содержит только отфильтрованные данные. Debug.Print "Число ячеек исходной области = ", Myr.Cells.Count Debug.Print "Число ячеек области фильтрации = ", Myr1.Cells.Count 'Обработка результатов фильтрации For Each cell In Myr1.Cells Debug.Print cell Next cell

End Sub



Цель этой программы показать, как можно получить результаты применения фильтра и программно работать с ними. Для этого я первым делом получаю в объекте Myr область, занятую списком, для чего использую метод Range объекта Autofilter. Затем я отрезаю строку, занятую заголовками списка, после чего копирую содержимое объекта Myr в буфер. Заметьте, хотя объект Myr содержит всю область списка, в буфер передается только видимая часть списка - результаты фильтрации. Так что, скопировав результаты из буфера в объект Myr1, я получаю результаты фильтрации и могу с ними работать, так как мне нужно, - для простоты я их просто печатаю. Обратите внимание, результаты я копирую на новый лист рабочей книги, иначе они будут восприниматься как список. Таким образом, в объекте Myr у меня хранятся результаты до фильтрации, а в объекте Myr1 - после фильтрации. Вот результаты отладочной печати:

Число ячеек исходной области = 32 Число ячеек области фильтрации = 20 Anna 12 5 low Mary 12 7 low Anna 12 5 low Петр 35 18 middle Петр 37 18 high


Импорт списков Excel в приложении Access


Приложение Access позволяет импортировать внешние данные, и я воспользуюсь этой возможностью для переноса списков Excel. Я создал в Access новую, пока что пустую базу данных, дал ей имя "dbPPnew" и занялся выполнением операции импорта, выбрав из меню "Файл" команду "Внешние данные | Импорт…". В открывшемся окне Импорта я, как обычно, в окошке "тип файла" выбрал из большого раскрывающегося списка нужный мне тип - Microsoft Excel - затем в поле "Папка" выбрал нужную папку, выбрал файл с книгой Excel, содержащей базу данных и нажал кнопку "Импорт". В результате, Мастер Импорта начинает свою работу. Вот первое окно, которое открывает этот Мастер, предлагая импортировать рабочие листы или именованные диапазоны книги Excel:


Рис. 4.18.  Импорт списков Excel

Обратите внимание, я предпочел работать с именованными диапазонами, а не с листами книги. Дело в том, что Мастер импорта не слишком интеллектуален и не может разобраться, где на рабочем листе начинается список Excel. Он предполагает, что заголовки полей списка начинаются в первой строке. Я же рабочий лист начинал с некоторого общего заголовка, и только потом уже размещал список. По этой причине, прежде чем заниматься импортом списков, я ввел именованные диапазоны для списков, назвав каждый диапазон по имени списка. Это позволит Мастеру Импорта разобраться с именами полей списка и сделать их именами полей таблицы Access, при условии, что на втором шаге работы Мастера будет включен флажок "Первая строка содержит заголовки столбцов". Я включил этот флажок, а на третьем шаге работы включил переключатель "В новой таблице", поскольку речь идет не о добавлении данных в существующую таблицу, а о создании новой таблицы. Вот как выглядит следующее окно Мастера Импорта, позволяющего уточнить характеристики полей таблицы:


Рис. 4.19.  Мастер Импорта уточняет характеристики полей таблицы

На следующем шаге можно указать Мастеру, какое поле является ключевым или добавить в таблицу поле счетчика, которое и будет играть роль ключа. Единственная проблема возникает в случае составного ключа, - Мастеру можно задать лишь одно ключевое поле, остальную работу по уточнению состава ключа придется выполнить уже в Access. Наконец, на последнем шаге работы можно указать не только имя таблицы, но и включить два флажка, один из которых вызывает Мастера Анализа таблиц, который позволяет провести проверку эффективности (с точки зрения этого Мастера) качества проектирования таблицы и определить целесообразность ее возможного разбиения на несколько таблиц.


Рис. 4.20.  Последний шаг работы Мастера Импорта

Я не стал вызывать Мастера Анализа таблиц, но надеюсь, что еще придет его время, и я расскажу подробнее о шагах его работы. Таблица "Книги" была успешно перенесена из Excel в Access. Аналогичным образом можно было бы импортировать и другие списки Excel, преобразуя их в таблицы базы данных Access. Но следующий список "Заказчики" я перенесу из Excel в Access, используя команду "Перенести в MS Access", которая появляется в меню Excel при включенной надстройке "AccessLinks".



Изменение данных в списке


Расширенный фильтр позволяет выделить из списка записи, удовлетворяющие некоторому критерию. Дальше с этими записями можно работать, используя обычные методы работы с Range -объектами. Но как быть, если необходимо провести корректировку выделенных записей. Понятно, что эту корректировку чаще всего нужно делать непосредственно в базе данных, т. е. в исходном списке. Но у нас нет информации о том, какой порядковый номер в списке имеет первая выделенная запись. Как всегда, в таких ситуациях нечего надеяться на систему и следует самому позаботиться о себе. Включайте в каждый список первым полем порядковый номер записи (во многих таблицах обычная практика, когда первым идет счетчик). Тогда в каждой выделенной записи есть поле, задающее ее порядковый номер, а этого достаточно, чтобы добраться до записи в списке и изменить ее нужным образом. В заключение заметим, что если стандартных методов сортировки и фильтрации данных списков не хватает, то на VBA можно написать обработку любого сколь угодно сл ожного запроса. В последующих главах будут продемонстрированы способы работы с офисными документами, значительное внимание при этом будет уделено различным запросам на выбор данных, вопросам динамического пополнения базы данных в процессе появления новых документов, также как и использованию информации, хранящейся в базе данных для создания документов.



Экспорт таблиц Access


Если база данных в Access уже создана, то ее можно без труда экспортировать в Excel. Этим мы сейчас и займемся. Поскольку операции по экспорту можно выполнять по-разному, то я рассмотрю несколько способов. Начну с самого простого, основанного на классическом использовании буфера при переносе тех или иных данных из одного приложения Office 2000 в другое. Вот краткое описание моих действий по переносу таблицы "Сотрудники". Прежде напомню, что к моменту начала переноса таблицы у меня уже создана книга Excel, страницы которой будут хранить базу данных, и первая таблица этой базы была только что создана. Так что мне осталось сделать следующее:

Открыть БД офиса РР, сделанную на Access.Открыть таблицу "Сотрудники" в режиме таблицы, выделить и скопировать в буфер ее содержимое. Перейти на страницу "Сотрудники" рабочей книги Excel и выполнить операцию "Специальная вставка" из буфера, вставляя содержимое как текст в формате Unicode.Отформатировать подходящим образом вставленную таблицу. Замечу, что для единообразия использовалось форматирование уже созданной таблицы "Книги". Вся работа заняла несколько минут. Вот как выглядит таблица "Сотрудники" после ее переноса на соответствующий лист рабочей книги:


Рис. 4.15.  Копирование таблицы "Сотрудники" из Access в Excel



Метод AdvancedFilter


Перейдем теперь к рассмотрению более полезного для программистов и в любом случае более универсального метода фильтрации записей - AdvancedFilter. Вот его синтаксис:

Function AdvancedFilter(Action As XlFilterAction, [CriteriaRange], [CopyToRange], [Unique])

Это метод вызывается объектами Range и возвращает объект Range, задающий список. Параметры метода имеют следующий смысл:

Action - может принимать одно из двух значений: xlFilterInPlace, xlFilterCopy.; первое из них указывает, что список фильтруется на месте, второе - задает возможность копирования результатов на новое место. О недостатках фильтрации на месте я уже говорил, поэтому при программировании целесообразно копировать значения, - это облегчает доступ к выбранным записям.CriteriaRange - задает область, в которой можно записать логическую формулу, задающую условие выбора записей. Заметьте, что здесь формула позволяет задать условия, одновременно налагаемые на все поля записи. О том, что собой представляет область критериев и как строится формула, задающая условие, я скажу чуть ниже.CopyToRange - задает область копирования результатов фильтрации.Unique - булев параметр, значение True которого позволяет отобрать только один экземпляр записи в случае, когда она многократно встречается в списке. Если параметр имеет значение False, то выдаются все имеющиеся экземпляры записи.

Чтобы понять, как работает метод, нужно четко представлять, что собой представляет область критериев и как в ней формируется условие выбора. Этим мы сейчас и займемся. Для создания области критериев нужно выбрать любую свободную область листа и задать в ней имена полей. Заметьте, в этой области имя одного и того же поля может появиться дважды. На следующем шаге следует задать логическую формулу, накладывающую ограничения на поля выбираемых записей. Для тех, кто знаком с логикой, скажем, что эта формула записана в дизъюнктивной нормальной форме и представляет собой дизъюнкцию конъюнктов. Каждый конъюнкт записывается в отдельной строке под именами полей. Все члены в одной строке соединены знаком конъюнкции "And", а отдельные строки - знаком дизъюнкции "Or". Теперь попробуем сказать то же самое, но проще. Условия выбора можно задавать в нескольких строчках. Если есть две строки и условие в первой из них обозначить через F1, а во второй - F2 , то общее условие будет иметь вид F1 Or F2. Сами условия F1 и F2 могут быть достаточно сложными. Они объединяют знаком "And" элементарные условия, накладываемые на каждое поле в отдельности. Элементарные условия - это известные нам по методу AutoFilter отношения ">, <, = и т. д.". Поэтому в области критериев имена полей могут встречаться дважды, чтобы была возможность задать условие вида "(Поле1 > 10) And (Поле1<= 20)".

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

Если в образце используется символ "?", то в записи ему соответствует любой символ; образцу "к?т" соответствуют, например, записи с полями "кит" и "кот".Если в образце используется символ "*", то в записи ему соответствует любая последовательность символов. Так, образцу "*он" соответствуют записи "он", "кон" и "Наполеон".Чтобы символы "?" и "*" могли использоваться как обычные, им должен предшествовать символ тильда "~"; образцу "Кто~?" соответствует строка "Кто?".Любому образцу соответствуют все строки, чьим префиксом он является. Так, образцу "Петр" соответствуют строки: Петр, Петрушка, Петрович. Чтобы задать точное соответствие, условие сравнения нужно ввести в виде: ="=Петр".


Внимательно взгляните на рисунок, где показан слегка видоизмененный список из предыдущего примера. Здесь же показаны две области, отведенные под критерии, и результаты двух запросов, реализуемых двумя вызовами метода AdvancedFilter:


увеличить изображение
Рис. 4.24.  Результаты работы расширенного фильтра

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

Sub РасширенныйВыбор() 'Сложное условие фильтрации. Range("МойСписок").AdvancedFilter Action:=xlFilterCopy, _ CriteriaRange:=Range("F7:K14"), _ CopyToRange:=Range("A13:D13"), Unique:=True 'Здесь условие проще. Range("МойСписок").AdvancedFilter Action:=xlFilterCopy, _ CriteriaRange:=Range("F16:G21"), _ CopyToRange:=Range("I16:L16"), Unique:=False End Sub

Первый вызов метода AdvancedFilter стоит обсудить подробнее. Метод вызывается объектом Range, задающим список. Как мы говорили ранее, список целесообразно именовать. В нашем примере его имя - "МойСписок". Результаты фильтрации копируются в область, заданную параметром CopyToRange. Размер этой области заранее не известен, но знать его и не нужно - достаточно указать диапазон для записи заголовков полей. Под строкой заголовков будут располагаться записи, выбранные при фильтрации. А вот область, отведенную для критериев, следует указать точно. При этом не следует ее именовать, как рекомендовано в документации. Во всяком случае, этого не стоит делать, если предполагается несколько различных запросов или они будут модифицироваться.

Что же записано в области "F7:K14", задающей условие выборки? В строке заголовков - имена полей, причем имена второго и третьего полей повторены дважды. Хотя исходный список содержит 4 поля, область критериев имеет 6 столбцов. Ниже строки заголовков расположены 7 строк, каждая из которых задает некоторое условие выбора записей. Выпишем явно условие, которое задают строки этой области. Вы можете проверить запись формулы, глядя на предыдущий рисунок. Конечно, для меня на самом деле исходной являлась эта формула, в соответствии с ней заполнялись ячейки в области критериев. Вот эта довольно сложная формула:

( (Поле3 >=5) And (Поле3 < 7) And (Поле4 = "low") ) OR ( (Поле1 = "Мария") And (Поле4 = "high") ) OR (Поле2 = 37) OR ( (Поле2 > 20) And (Поле3 < 20) And (Поле3 > 15) And (Поле4 ="middle") ) OR ( (Поле1 = "Анна") And (Поле4 = "high") ) OR ( (Поле1 = "Петр") And (Поле4 = "low") ) OR ( (Поле1 = "Алиса") And (Поле2 = 24) And (Поле4 = "low") )



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

первый - выделяет из списка две одинаковые записи со значением Anna в первом поле. Однако, поскольку параметр Unique имеет значение True, выбираться будет только одна уникальная запись.второй дизъюнкт выделяет из списка запись с именем Мария, имеющей в 4-м поле значение high;третий - самый простой: он должен выделить записи, имеющие в поле 2 значение 37; такая запись есть в списке, это запись с именем Петр (high);четвертый дизъюнкт правильно выделяет запись со значением middle -это запись с именем Петр (middle);пятый - выделяет запись с именем Анна (high);шестой дизъюнкт выделяет две записи с именами Петр (low) и Петрович (low);седьмой - выделяет еще одну запись.

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


Перенос списков из Excel в Access


Специальная надстройка AccessLinks добавляет в меню Excel команды, позволяющие преобразовать списки Excel в объекты базы данных Access - таблицы, формы, отчеты. Если надстройка AccessLinks еще не подключена, то это следует сделать, выбрав команду "Надстройки" из меню "Сервис" и включив флажок соответствующей надстройки. При включенной надстройке в меню "Данные" появляются три команды: MS Access Form, MS Access Report, Convert to MS Access. Первые две из них позволяют по данным списка Excel построить форму и отчет базы данных Access, я не буду на них останавливаться, поскольку по существу все построение осуществляют известные в Access Мастера построения форм и отчетов. Давайте чуть более подробно рассмотрим лишь третью команду, преобразующую список в таблицу базы данных. Первое окно, которое появляется после вызова этой команды, позволяет указать базу данных Access:


Рис. 4.21.  Первый шаг Мастера Преобразований списка Excel в таблицу Access

А далее все возвращается на круги своя и работу продолжает уже знакомый нам Мастер Импорта, который и создает таблицу в базе данных Access. Замечу только, что поскольку работа начинается в Excel, то Excel способен распознать, где начинается список и передать точный список Мастеру Импорта без всяких пустых строк. Это, пожалуй, достаточно важная причина, по которой я рекомендовал бы перенос списков выполнять, используя именно этот способ работы. На этом я и закончу рассмотрение вопросов экспорта - импорта баз данных между Excel и Access.



Построение форм "Заказчики" и "Книги Редакции"


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


Рис. 4.3.  Форма "Заказчики"

Для второй формы избран более "скромный", но более экономичный вид, позволяющий одновременно видеть на экране больше деталей:


Рис. 4.4.  Форма "Книги редакции"

Вот еще одна форма, построенная по таблице "Заказчики", позволяющая просматривать адреса заказчиков:


Рис. 4.5.  Форма "Адреса заказчиков"

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


Рис. 4.6.  Установка свойств формы "Адреса Заказчиков"

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



Построение таблиц "Заказчики" и "Книги"


Access относится к реляционным базам данных, в которых основной формой представления данных являются таблицы. Таблицы связываются между собой за счет общих полей. Поскольку таблица еще и общечеловеческая форма представления данных, то ее создание интуитивно понятно всем. Запись (строку) таблицы можно рассматривать, как совокупность полей разного типа. Каждый столбец таблицы хранит значения одного поля. Так что каждая таблица задает некоторый набор записей, и каждая запись представляется одной строкой таблицы. Число полей записи однозначно определяет число столбцов таблицы. Access предоставляет различные средства, облегчающие задание структуры таблицы. Полагаю, что даже человек, не имеющий опыта работы с Access, работая в Конструкторе таблиц Access, без труда определит собственную таблицу. Отмечу лишь, что для каждого поля задается имя, выбирается его тип, и задаются другие свойства поля, например, описание. Свойства поля зависят не только от его типа, они включают такие характеристики, как указание на то, является ли поле индексируемым, имеет ли уникальное значение, должно ли обязательно присутствовать в записи. Они определяют также формат и маску, которой должно удовлетворять значение поля, и другие характеристики.

Я не буду сейчас останавливаться на средствах Access, позволяющих создавать таблицы визуально, они достаточно просты. Для нас сейчас важнее понимать структуру таблиц, входящих в состав базы данных. Начну с определения таблицы "Заказчики", хранящей информацию о заказчиках офиса РР. Каждая ее запись включает следующие поля: Код заказчика, Название, Адрес, Город, Телефон, Директор, Прочее, Email. Вот как выглядит определение таблицы в конструкторе Access, где для каждого поля задаются имя, тип, описание и другие характеристики:


Рис. 4.1.  Структура таблицы "Заказчики

Обратите внимание, обязательным условием определения таблицы базы данных является задание ключа. Ключом может быть одно поле или совокупность полей, требуется лишь, чтобы значение ключа было уникальным для каждой записи. Это требование позволяет однозначно найти запись в таблице, зная ее ключ. Требование существования ключа записей всегда выполнимо, поскольку при необходимости есть возможность добавить к исходным полям записи поле счетчика, которое может выступать в роли ключа, автоматически давая записи новый номер при добавлении ее в таблицу. На рисунке 4.1 можно видеть (ключевые поля отмечены соответствующим значком -

), что в таблице "Заказчики" в роли первичного ключа выступает поле "Название". Заметьте, ключ можно определить далеко не единственным способом, например, поле "Код заказчика" также могло играть роль первичного ключа.

Определим теперь структуру таблицы "Книги". Эта таблица содержит информацию о книгах, выпускаемых издательством "РР". Достаточно взглянуть на рисунок, чтобы увидеть, какие поля в нее включены:


Рис. 4.2.  Структура таблицы "Книги"

Две введенные таблицы "Заказчики" и "Книги" пока не связаны между собой, - они не имеют общих полей. Такая связь возникнет позже - при расширении базы данных. Она появится, когда заказчики начнут заказывать книги. Позже я добавлю в базу данных таблицу "Заказы", которая будет иметь общие поля, как с таблицей "Книги", так и с таблицей "Заказчики".



Построение запросов


Частью БД Access является совокупность "стандартных" запросов на поиск данных в базе. Запросы к базе данных могут возникать динамически в процессе работы пользователя и определяться его сиюминутными требованиями. Однако большое число запросов являются "стандартными" и их можно спроектировать заранее.

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


Рис. 4.7.  Конструирование запроса "Список Заказчиков"

А так выглядит результат его выполнения:


Рис. 4.8.  Результат выполнения запроса

Поскольку Access транслирует создаваемые запросы в SQL форму, то предоставляется возможность просматривать и корректировать запросы и в этой форме. Результат трансляции нашего запроса:

SELECT Заказчики.Название FROM Заказчики ORDER BY Заказчики.Название;

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

SELECT Книги.Автор, Книги.Название FROM Книги ORDER BY Книги.Автор;

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


Рис. 4.9.  Конструирование запроса с фильтром

SQL-форма этого запроса имеет вид:

SELECT Заказчики.Название FROM Заказчики WHERE (((Заказчики.Город)="Тверь")) ORDER BY Заказчики.Название;


Построенный только что запрос позволяет выбрать среди всех заказчиков тех, кто живет в Твери. Такой запрос является частным случаем общего запроса. Значительно чаще в подобных ситуациях строится запрос с параметром, в котором код города является параметром, задаваемым динамически в момент вызова запроса. Визуально запросы с параметрами строятся, как обычные. Чтобы предыдущий запрос превратить в запрос с параметрами, в поле запроса, где задавался город ("Тверь"), достаточно записать в квадратных скобках строку, запрашивающую имя параметра, например: [город?] или [Town]. Скобки - признак того, что задается параметр запроса, они сигнализируют о необходимости добавления элемента в коллекцию Parameters, связанную с запросом. Аналогично создаются запросы с несколькими параметрами.

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


Рис. 4.10.  Запрос с двумя параметрами

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

SELECT Заказчики.Название FROM Заказчики WHERE (((Заказчики.Город)=[город?]) AND ((Заказчики.Директор)=[директор?])) ORDER BY Заказчики.Название;

Заметьте, хотя в явном виде предложение Parameters в операторе SELECT не отображается, но соответствующая коллекция Parameters, связанная с запросом формируется.


Преобразование списков Excel в базу данных Access


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

Понятно, что обратное преобразование данных Excel в Access выполняется сложнее по той простой причине, что база данных Access устроена значительно сложнее, чем списки Excel. Поэтому нет многих возможностей, которые есть при переносе данных из Access в Excel. Нельзя, например, сохранить таблицу Excel в виде mdb-файла в формате базы данных Access. Тем не менее, существуют, по крайней мере, два способа переноса данных. Первый из них позволяет начать работу по переносу данных в Excel, используя его команду "Перенести в MS Access", являющейся аналогом рассмотренной выше команды Access - "Связи с Office - Анализ в MS Excel". Второй способ использует возможности Access по импорту внешних данных. Я рассмотрю сейчас оба эти способа и выполню обратный перенос созданной базы данных офиса РР в Excel в базу данных Access, создав под другим именем новую копию существующей базы данных.



Сохранение в базе данных информации о заказах


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

зе данных.

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

Заказы. Эта таблица имеет следующие поля: КодЗаказа, Заказчик, Сотрудник, ДатаЗаказа, Стоимость. Код заказа играет роль ключа и является уникальным полем, автоматически заполняемым в момент записи заказа в базу данных. Следующие два поля совпадают с соответствующими полями таблиц "Заказчики" и "Сотрудники" и, тем самым, связывают эти таблицы. Я неявно предполагаю, что база данных офиса РР уже частично расширена за счет естественного добавления таблицы "Сотрудники". Действительно, было бы странно хранить информацию о заказчиках и не иметь информации о собственных сотрудниках. Поэтому каждый заказ хранит информацию не только о заказчике, но и о сотруднике офиса РР, оформляющего этот заказ. Следующие два поля - ДатаЗаказа и Стоимость (общая стоимость заказа) не требуют особых пояснений. Так выглядит общая информация о заказе.Заказано. Эта таблица имеет следующие поля: КодЗаказа, НазваниеКниги, Количество, Стоимость. Как я уже говорил, в этой таблице одному заказу будет соответствовать, как правило, несколько записей. Каждая запись - строка таблицы - содержит данные об одной из заказываемых книг. Все записи одного заказа будут иметь один и тот же код заказа, совпадающий с кодом заказа таблицы "Заказы". Поле "КодЗаказа" связывает между собой таблицы "Заказы" и "Заказано". Заметьте, повторяющийся код заказа не может быть ключом для таблицы "Заказано". Роль ключа в этой таблице играют два поля - КодЗаказа и НазваниеКниги, которые в совокупности являются уникальными для каждой записи таблицы "Заказано", хотя каждое из них в отдельности уникальным полем не является и может многократно повторяться в записях таблицы. Поля этой таблицы - Количество и Стоимость - задают количество экземпляров заказываемой книги и их суммарную стоимость.


Вот как выглядит определение этих таблиц в Конструкторе Access:


Рис. 4.11.  Определение таблицы "Заказы" в конструкторе


Рис. 4.12.  Определение таблицы "Заказано" в конструкторе

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


Рис. 4.13.  Схема связей между таблицами базы данных офиса РР

Заметьте, все связи между таблицами имеют тип "один ко многим". Так, например, одному коду заказа из таблицы "Заказы" соответствуют несколько записей с аналогичным кодом в таблице "Заказано". Аналогично, одной фамилии (полю ФИО) из таблицы "Сотрудники" соответствует несколько записей в таблице "Заказы", поскольку понятно, что один сотрудник может оформлять множество заказов.



Вот как выглядит определение этих таблиц в Конструкторе Access:


Рис. 4.11.  Определение таблицы "Заказы" в конструкторе


Рис. 4.12.  Определение таблицы "Заказано" в конструкторе

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


Рис. 4.13.  Схема связей между таблицами базы данных офиса РР

Заметьте, все связи между таблицами имеют тип "один ко многим". Так, например, одному коду заказа из таблицы "Заказы" соответствуют несколько записей с аналогичным кодом в таблице "Заказано". Аналогично, одной фамилии (полю ФИО) из таблицы "Сотрудники" соответствует несколько записей в таблице "Заказы", поскольку понятно, что один сотрудник может оформлять множество заказов.


Сортировка списков


Мы уже рассмотрели вопросы создания списков Excel, представляющих локальную базу данных, рассмотрели взаимное преобразование между списками Excel и объектами базы данных Access. Теперь пришла пора заняться специальными операциями, которые облегчают работу с данными, хранящимися в этой локальной базе данных. При этом я буду рассматривать, как визуальные методы работы со списками, так и программные. Сортировка списков - одна из основных операций, которые выполняются над данными, хранящимися в базе. Эту операцию, конечно, можно выполнять вручную. При программировании следует пользоваться методом Sort объекта Range. Приведем синтаксис этого метода:

Function Sort([Key1], [Order1 As XlSortOrder = xlAscending], [Key2], [Type], [Order2 As XlSortOrder = xlAscending], [Key3], [Order3 As XlSortOrder = xlAscending], [Header As XlYesNoGuess = xlNo], [OrderCustom], [MatchCase], [Orientation As XlSortOrientation = xlSortRows], [SortMethod As XlSortMethod = xlPinYin])

Рассмотрим параметры метода и поясним его работу:

Key1, Key2 и Key3 - задают имена полей, по которым сортируется список, так что одновременно можно отсортировать список не более чем по трем полям.Order1, Order2 и Order3 задают порядок сортировки - по возрастанию или убыванию независимо по каждому полю; значение для полей по умолчанию - "по возрастанию" (xlAscendinig).Type - задается только при сортировке сводных таблиц и указывает тип сортируемых значений, задаваемых константами: xlSortLabels и xlSortValues.Header - указывает, есть ли в списке строка с именами полей; если его значение - xlGuess, система сама должна определить, есть ли заголовки у полей (для этого они должны отличаться форматом).Значение параметра OrderCustom, отличное от 1, используется, когда список сортируется в порядке, заданном пользовательским списком или некоторым стандартным, специальным списком, например, с названиями месяцев. Приведу пример, поясняющий ситуацию. Представьте себе, что значениями некоторого поля таблицы являются названия основных цветов радуги. Вы хотите отсортировать эти значения в порядке следования цвета в радуге: "красный, оранжевый, …, фиолетовый". Тогда следует создать пользовательский список, задающий порядок следования цвета, и добавить его в коллекцию списков методом AddCustomList: Application.AddCustomList ListArray:=Range("F1:F7")


Здесь предполагается, что область "F1:F7" содержит значения цветов радуги. При добавлении списка в коллекцию он получит свой номер, который и указывается, как значение параметра OrderCustom.MatchCase (булев) - имеет значение False, если при сортировке регистр не учитывается, большие и малые буквы не различаются.Orientation - задает ориентацию при перестановке сортируемых значений таблицы: сверху вниз (переставляются строки) или слева направо (переставляются столбцы).SortMethod - позволяет выбрать порядок, заданный на символах алфавита. Он может задаваться соответствующей кодовой страницей или являться стандартным алфавитным порядком, в котором цифры предшествуют буквам, а латынь - кириллице.

Вот пример вызова этого метода для сортировки списка "Заказчики", показанного на рис. 4.17. Список сортируется по двум полям, - вначале упорядочиваются города, а затем организации каждого города:

Public Sub Sorting() 'Сортировка таблицы Заказчики по двум полям: 'вначале по полю "город", затем - "организация" Selection.Sort Key1:=Range("D5"), Order1:=xlAscending, _ Key2:=Range("B5"), Order2:=xlAscending, _ Header:=xlGuess, OrderCustom:=1, MatchCase:=False, _ Orientation:=xlTopToBottom End Sub

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


Создание базы данных в Excel


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


увеличить изображение
Рис. 4.14.  Таблица "Книги", спроектированная в Excel



Создание в приложении Access базы данных офиса "РР"


Для пользователей Microsoft Office 2000 создание базы данных именно в Access самая естественная вещь. Этот параграф может служить предварительным знакомством с Access для тех, кто действительно не знаком с этим замечательным приложением. Создание базы данных в Access помимо прочего обладает двумя несомненными достоинствами:

Допускается создание и ведение базы данных простыми и интуитивно понятными средствами в визуальном стиле. Даже человек, далекий от этой весьма специфической области программирования, способен после предварительного непродолжительного знакомства начать создавать свою собственную базу данных.В любом из приложений Office 2000 (Word, Excel, PowerPoint) легко получить доступ к БД Access.

В первом приближении БД Access можно рассматривать как совокупность взаимосвязанных таблиц с данными, запросов к ним, форм и отчетов, облегчающих ввод данных в таблицы и вывод информации из них в удобном для конечного пользователя виде, а также программных компонентов, выполняющих различные операции над данными.

Построение БД офиса РР начну с введения минимально необходимых средств. По мере необходимости база будет расширяться.



Специальные средства экспорта таблиц Access в Excel


Вместе с тем Access имеет специальные, развитые средства экспорта таблиц БД и других своих объектов - запросов, форм, отчетов. Таблицу "Заказы" я переместил в Excel, используя следующий способ:

В окне базы данных Access выбрал имя таблицы "Заказы".В меню Сервис выбрал команду "Связи с Office" и подкоманду "Анализ в MS Excel". Результатом ее выполнения стало автоматическое создание новой книги Excel с единственной страницей "Заказы", содержащей требуемую таблицу с подходящим форматированием. Заметьте, что команда Связи с Office имеет и другие подкоманды - Слияние с MS Word, Публикация в MS Word, - позволяющие передавать таблицу Access в приложение Word. Все подкоманды команды Связи с Office позволяют выполнять операции не только с таблицами, но и с частями таблиц, запросами, формами, отчетами.Получив на предыдущем шаге нужную мне таблицу в Excel, я использовал далее средства Excel для перемещения таблицы в нужное место имеющейся у меня книги. После чего я применил собственное форматирование, чтобы сохранить единый стиль всех страниц моей книги, хранящей базу данных.


увеличить изображение
Рис. 4.16.  Экспорт таблицы "Заказы" с использованием команды Анализ в MS Excel

Наконец, я рассмотрю еще один возможный способ экспорта таблицы Access, основанный на широких возможностях Access по сохранению его объектов в виде файлов самых различных форматов. Например, таблицы, запросы, формы, отчеты можно экспортировать в формат HTML. Таблицы и запросы можно экспортировать в БД, удовлетворяющие стандарту ODBC, их можно экспортировать в текстовые файлы, в ASP-страницы, в базы данных Paradox или dBase и во многие другие форматы. Естественно, среди форматов присутствуют и форматы файлов Excel различных версий. Вот как выглядят мои действия по экспорту таблицы "Заказчики":

Открыл БД Access и выбрал нужную мне таблицу "Заказчики".В меню "Файл" выбрал команду "Сохранить как", а затем - "Экспорт".В появившемся диалоговом окне Экспорта выбрал папку, согласился с предложенным именем файла, совпадающим с названием таблицы, в окошке "тип файла" из раскрывающегося списка, задающего многочисленные возможности по экспорту таблицы, выбрал тип "Microsoft Excel 97-2000". Затем включил флажок "Сохранить формат" и щелкнул кнопку OK. Хочу обратить внимание на то, что при выполнении этой операции следует быть осторожным поскольку, если задать имя существующего файла в папке, то все его содержимое заменится новой единственной страницей. В результате этих действий автоматически создается новая книга Excel с заданным именем файла, на единственный лист которой и записывается сохраняемая таблица. Результат этих действий немногим отличается от предыдущего случая, когда использовалась команда Связи с Office. Также как и в предыдущем случае экспорта таблицы, получив файл Excel, я занялся перемещением полученной таблицы, используя средства Excel для перемещения таблицы в нужное место имеющейся у меня книги. После чего применил собственное форматирование, чтобы сохранить единый стиль всех страниц моей книги, хранящей базу данных.

Вот окончательный результат моих действий:


увеличить изображение
Рис. 4.17.  Экспорт таблицы "Заказчики"

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



Списки Excel, как локальная база данных


Говоря об Excel и базах данных нельзя не упомянуть и о такой возможности Excel, как ведение собственной локальной базы данных, не использующей никаких внешних источников данных. Небольшие базы данных можно вести непосредственно на Excel. Такую базу данных можно представлять как совокупность таблиц. Таблицы естественны для Excel и их создание не вызывает никаких трудностей. Для поиска данных в таблицах, их отбору, сортировке предусмотрены специальные средства. Когда объем данных невелик и нет необходимости в сложных запросах, требующих одновременной работы с несколькими таблицами, работать с данными в Excel проще и быстрее. Умение вести базу данных на Excel особенно важно для тех, кто не имеет доступа к другим базам данных и работает с версией Office 2000, не содержащей Access.

Базу данных Excel удобнее всего располагать на нескольких листах по числу таблиц, хранящих данные. На каждом листе обычно располагается одна таблица. Это ограничение накладывает метод AdvancedFilter, без которого, как правило, не обходится обработка данных в таблице. Многие запросы к таблице можно реализовать с помощью этого метода. Таблицу, хранящую данные, в Excel принято называть списком. Список, как и всякая таблица, состоит из строк и столбцов. Столбцы - это поля списка (таблицы БД). Первая строка списка обычно содержит имена полей. Вот несколько правил, которым должны удовлетворять списки, часть из них носит рекомендательный характер:

для имен полей следует задать формат (шрифт, цвет фона), отличный от формата ячеек, хранящих значения полей: это позволит системе автоматически отличать имена полей от их значений;значения, хранящиеся в одном столбце (значения одного поля), должны иметь один и тот же тип;рекомендуется именовать лист названием списка, возможно, с некоторым префиксом;области ячеек, отведенной для списка (вместе с первой строкой, хранящей названия полей), целесообразно дать имя; эту область нужно выделить по максимуму, так чтобы она допускала дальнейшее пополнение списка;список отделяется от остальной части рабочего листа пустыми строками и столбцами. Поэтому не рекомендуется, чтобы пустые строки и столбцы встречались в середине списка, т. е. записи, все поля которых пусты, нежелательны, - иногда это может привести к неприятностям.