
- •Экзаменационные вопросы
- •Глава 1. Архитектура экономических информационных систем
- •1) Между микропроцессором и основной памятью
- •2) Между микропроцессором и портами ввода - вывода внешних устройств
- •3) Между основной памятью и портами ввода - вывода внешних устройств (в режиме прямого доступа к памяти)
- •2. Классическая архитектура эвм и принципы фон Неймана
- •30 Минут
- •66 Часть I. Пятница. Вечер
- •1.2.1 Категории типов данных
- •Int double
- •1.2.2. Целый тип данных
- •Int c; (подразумевается signed int c );
- •1.2.4. Указатели
- •Void *addres;
- •1.2.5. Переменные перечислимого типа
- •1.2.6. Массивы
- •Int a[2][3]; /* представлено в виде матрицы
- •1.2.7. Структуры
- •1.2.8. Объединения (смеси)
- •Int vozrast;
- •Int telefon; } inform;
- •1.2.9. Поля битов
- •1.2.10. Переменные с изменяемой структурой
- •Int type; /* признак компонента */
- •Int age; /* возраст */
- •Int no_children;
- •1.2.11. Определение объектов и типов
- •1.2.12. Инициализация данных
- •Var a, b : intmas;
- •Var a, b : array [1 .. N] of integer;
- •Var a : array [1 .. N] of real;
- •I : integer;
- •Var a : array [1 .. N] of integer;
- •I, j, nmin, buf : integer;
- •Var a : array [1 .. M, 1 .. N] of integer;
- •I, j, n_pos_el : integer;
- •11 Мая 2008 года
- •Index Флаг, указывающий индексировать или нет документы данного ресурса.
- •Модели баз данных Концептуальная модель
- •Инфологическая модель данных "Сущность-связь"
- •Реляционная модель
- •Язык sql, быстрый старт.
- •База данных платежного поручения
- •31 И дальше отдельными файлами
Var a : array [1 .. M, 1 .. N] of integer;
I, j, n_pos_el : integer;
sred : real;
begin
for i := 1 to m do
for j := 1 to n do read(a[i, j]);
sred := 0;
for i := 1 to m do begin
n_pos_el := 0;
for j := 1 to n do begin
sred := sred + a[i, j];
if a[i, j] > 0 then inc(n_pos_el);
end;
writeln('В ', i, '-й строке ', n_pos_el,
' положительных элементов');
end;
sred := sred / m / n;
writeln('Среднее арифметическое: ', sred:6:2);
end.
22
Динамические и статические массивы
11 Мая 2008 года
Я собираюсь рассказать об одном нетривиальном эффекте, заключающемся в существенном замедлении работы программ при переходе от статических массивов к динамическим в некоторых ситуациях. С этим эффектом можно столкнуться при программировании на многих компилируемых языках (в том числе в Visual Studio или Delphi) для архитектуры IA-32. 64-битная архитектура еще не скоро займет лидирующее место, поэтому данная статья будет оставаться актуальной продолжительное время.
Обычно, когда программа должна принимать входные данные меняющегося размера, новички используют статический массив с заведомо большим размером. Более опытные используют динамическое выделение памяти, например, функцией malloc. С идеологической точки зрения всё ясно — метод со статическим массивом, разумеется, некорректен. Однако с сегодняшними компьютерами на памяти можно особенно не экономить. Рассмотрим оба метода с другой точки зрения — сравним их быстродействие.
Некоторое время назад я писал программу, моделирующую движение системы материальных точек. Каждая точка имела ряд характеристик — масса, заряд, три координаты, три проекции скорости. Сначала, на этапе отладки, все данные хранились в статическом массиве. Потом, когда я перешел к динамическим массивам, быстродействие программы упало примерно на треть. Я подумал, что использовал не самый лучший вариант организации массивов. Перепробовал все имевшиеся методы. Скорость не увеличилась — терялись те же 30% производительности.
Такому, казалось бы, странному эффекту есть достаточно простое объяснение. Его с легкостью поймет тот, кто когда-нибудь программировал на ассемблере, или хотя бы представляет себе в самых общих чертах, как работает 386 процессор.
На уровне процессора обращение к элементам статического массива a происходит так. Адрес начала массива известен еще при компиляции. Чтобы получить адрес элемента массива a[i], к адресу начала прибавляется индекс i, умноженный на размер одного элемента в байтах. Затем по вычисленному адресу идет обращение в память.
К элементам динамического массива получить доступ сложнее. На этапе компиляции адрес начала массива не известен. После выделения памяти он хранится в специальной переменной (указателе). Чтобы получить адрес элемента массива a[i], нужно сначала обратиться к памяти (взять значение указателя) и получить адрес начала массива. Потом к нему прибавить индекс, умноженный на размер элемента, и по вычисленному адресу элемента массива снова обратиться к памяти. Как видим, получается два обращения к памяти против одного у статических массивов.
Разумеется, компиляторы проводят оптимизацию. Адрес начала массива они могут запомнить в регистре до обращений к элементам массива. Но при этом в программе с динамическими массивами занимается на один регистр больше.
А что произойдет, например, при обработке всех элементов массива в цикле? Если цикл оперирует с маленьким набором данных, адреса массивов и используемые переменные можно хранить в регистрах. С добавлением новых обрабатываемых данных количество свободных регистров уменьшается, и на каком-то этапе в теле цикла появится дополнительное обращение к памяти (прочитайте про такую вещь, как latency, если вы не видите в этом ничего плохого). Понятно, что это произойдет тогда, когда все доступные регистры будут использованы. Именно в этих условиях переход от статического массива к динамическому может привести к существенному замедлению программы.
Такая ситуация и сложилась в моей программе. Разобравшись с ней, я стал немного глубже разбираться в тонкостях работы компьютера.
Умение программировать на ассемблере позволяет писать более оптимизированный и оптимизируемый код и на языках высокого уровня. Например, можно дать такой совет: лучше использовать массив структур, а не несколько разных массивов. Такой совет оправдан не только описанной логикой освобождения регистров и уменьшения количества обращений к памяти, но и логикой работы процессорного кеша. Да и в файл сохранять такие данные проще. Или еще один совет: лучше использовать локальные переменные, а не глобальные. Это оправдано не только идеологически; компилятор может разместить локальные переменные не в памяти, а в регистрах.
Относительно архитектуры x64 можно заметить следующее. Хоть в ней появилось 8 новых регистров, теоретически описанная ситуация не исключена. Было бы интересно проверить на практике, появляется ли такой эффект, и на сколько падает быстродействие.
Вывод: встречаются такие ситуации (причем не где-то и когда-то, такая ситуация у меня была при разработке вполне конкретной настоящей программы), в которых использование динамических массивов может существенно снизить быстродействие (в упомянутом случае скорость работы падала примерно на треть).
23
Если необходимо сохранить все данные или часть данных из одного или нескольких листов Excel в приложении Access, следует импортировать содержимое листа в новую или существующую базу данных Access. При импорте данных в приложении Access создается копия данных в новой или существующей таблице без изменения исходного файла Excel.
Вот несколько типичных ситуаций, при которых возникает необходимость импорта данных Excel в приложение Access:
Вы уже продолжительное время используете Excel и теперь подумываете о переходе на Access. Можно начать с импорта ваших листов Excel в одну или несколько баз данных Access.
Вы являетесь менеджером, получающим отчеты от служащих в формате Excel. Вам требуется перенести эти отчеты в существующую базу данных, чтобы обновить ее содержимое.
Вы являетесь менеджером, и ваши служащие еженедельно отправляют вам отчеты в файлах Excel. Вам требуется автоматизировать операцию импорта, чтобы сэкономить время.
Вы разрабатываете приложение, в котором вам требуется запрограммировать импорт данных Excel в приложение Access.
Если вы впервые импортируете данные Excel, вам будут полезны следующие замечания:
Не пытайтесь сохранить лист Excel как базу данных Access. В приложении Microsoft Excel не поддерживается средство «сохранить как» для создания базы данных Access на основе данных Excel.
Прежде чем начать операцию импорта, следует открыть базу данных Access. Если необходимо импортировать данные в новую базу данных, перед началом операции импорта надо создать пустую базу данных (не содержащую ни таблиц, ни форм, ни отчетов).
Данные, импортируемые из листа, сохраняются в новой или существующей таблице в текущей базе данных. Если вы не знакомы с таблицами или со структурой баз данных, см. разделы Таблицы (MDB) и Разработка базы данных.
Когда вы открываете лист Excel в приложении Access (для этого в диалоговом окне Открытие файла базы данных в поле со списком Тип файлов перейдите к Microsoft Excel и выберите необходимый файл), в приложении Access вместо импорта данных создается связь с листом Excel. Создание связи с листом отличается от импорта листа в базу данных. Дополнительные сведения о связи см. далее в подразделе Связь с данными Excel.
Приступая к работе с операцией импорта
Шаг 1. Определите, какие данные следует импортировать
Шаг 2. Определите конечные базу данных и таблицу
Шаг 3. Подготовьте данные для операции импорта
Шаг 4. Перед импортом некоторых элементов и типов данных обратите внимание на следующее
Шаг 5. Запустите операцию импорта
Шаг 6. Просмотрите импортированные данные и таблицу журнала ошибок и выполните корректирующие действия
Другие способы переноса данных Excel в приложение Access
Кроме импорта применяются и другие методы переноса данных из Excel в Access:
Связь с данными Excel. При связывании в приложении Access копии данных не создается, но при этом можно использовать Access для просмотра и изменения данных на листе Excel. Дополнительные сведения об установке связи с листом см. в подразделе Связь с данными Excel текущего раздела.
Вырезание или копирование данных в приложении Excel и вставка их в таблицу Access. Дополнительные сведения о том, как вырезать и копировать данные на листе, см. в справке Excel.
Импорт данных средствами программирования. Можно написать макрос или процедуру на языке Visual Basic for Applications (VBA) для программного импорта данных. Сведения о том, как это сделать, см. в разделе Программный импорт данных.
Экспорт данных Microsoft Excel в файл, записанный на языке XML
(Extensible Markup Language), который затем может быть импортирован в Access. Дополнительные сведения о том, как импортировать XML-данные, см. в подразделе «Импорт данных и схем из файла XML» раздела Импорт или связывание данных и объектов.
Связь с данными Excel
Если копирование данных в базу данных Access нежелательно, вместо этого можно установить связь с листом Excel. Связывание позволяет подключить данные из другой программы, не выполняя их импорта. При этом можно просматривать и редактировать данные как в исходной программе, так и в файле Access.
При установке связи с листом или именованным диапазоном в приложении Access создается новая таблица, связанная с исходными ячейками. Любые изменения данных в таблице приводят к изменению исходного файла Excel. Связывание полезно, когда необходимо организовать совместную работу с данными Excel для пользователей, работающих в Excel и Access.
Если вы впервые выполняете связь с листом Excel, вам будут полезны следующие замечания:
Нельзя установить связь с базой данных Access в приложении Excel.
Нельзя связать данные Excel с существующей таблицей в базе данных. При связывании в приложении Access создается новая таблица, часто называемая связанной таблицей. В этой таблице отображаются данные из листа или именованного диапазона, но фактически эти данные в базе данных не хранятся.
В базе данных может быть несколько связанных таблиц.
Любые изменения данных в Excel автоматически отображаются в связанной таблице. Любые изменения данных в связанной таблице автоматически сохраняются в исходном файле Excel.
Когда вы открываете лист Excel в приложении Access (для этого в диалоговом окне Открытие файла базы данных в поле со списком Тип файлов перейдите к Microsoft Excel и выберите необходимый файл), в приложении Access создается пустая база данных и автоматически запускается мастер связи с электронной таблицей.
Дополнительные сведения о связывании данных см. в разделе Связывание данных и объектов базы данных.
Приступая к работе с операцией связывания
Шаг 1. Определите, с какими данными следует установить связь
Шаг 2. Определите конечные базу данных и таблицу
Шаг 3. Подготовьте данные для операции связывания
Шаг 4. Перед связыванием с некоторыми элементами и типами данных обратите внимание на следующее
Шаг 5. Запустите операцию связывания
Шаг 6. Просмотрите связанную таблицу и выполните корректирующие действия
Экспорт данных Access в приложение Excel
Часто встречается ситуация, когда данные, хранящиеся в Access, необходимо перенести или скопировать в Excel. Например, может потребоваться распространить отчет группе пользователей, предпочитающих работать с приложением Excel. Вам также может потребоваться проанализировать данные Access с использованием возможностей анализа данных, имеющихся в приложении Excel. В таких случаях следует экспортировать содержимое базы данных Access в лист Excel.
В Excel можно экспортировать следующие объекты:
Данные из таблиц, запросов, форм и отчетов.
На приведенном ниже рисунке показано, как выглядит отчет «Каталог» из учебной базы данных «Борей» после экспорта в приложение Excel:
Все или некоторые из строк и столбцов в режиме таблицы
На приведенном ниже рисунке показано, как выглядит часть таблицы «Сотрудники» в режиме таблицы после экспорта в приложение Excel:
Примечание. Нельзя экспортировать несколько объектов в ходе одной операции экспорта. Можно, однако, объединить данные, содержащиеся на различных листах и в различных книгах после завершения отдельных операций экспорта. Дополнительные сведения см. в разделах Объединение книг и Перемещение (вырезание) и копирование ячеек и данных из ячеек в справке Excel.
Приступая к работе с операцией экспорта
Шаг 1. Определите, какие данные следует экспортировать
Шаг 2. Выберите, откуда запустить операцию экспорта
Шаг 3. Определение файла назначения для операции экспорта
Шаг 4. Перед экспортом некоторых типов данных и элементов управления обратите внимание на следующее
Шаг 5. Запустите операцию экспорта
Шаг 6. Просмотрите лист Excel
Другие способы переноса данных Access в приложение Excel
Кроме экспорта применяются и другие методы переноса данных из Access в Excel:
Вырезание или копирование данных в приложении Access и вставка их в таблицу Excel. Дополнительные сведения о том, как это делается, см. в подразделе «Копирование или перемещение записей или данных из нескольких полей Microsoft Access в другое приложение» раздела Копирование и перемещение данных.
Экспорт данных средствами программирования. Можно написать макрос или процедуру на языке Visual Basic for Applications (VBA) для программного экспорта данных. Сведения о том, как это сделать, см. в разделе Программный экспорт данных.
Загрузка данных Access в приложение Excel.
Инструкции
Экспорт данных Microsoft Access в файл, записанный на языке XML
(Extensible Markup Language), который затем может быть импортирован в Excel. Дополнительные сведения о том, как экспортировать данные Access в формате XML, см. в разделе Экспорт данных Microsoft Access в формате документа XML.
Разрешение вопросов
Если возникают затруднения при выполнении каких-либо из этих операций, воспользуйтесь приведенными ниже рекомендациями. Вам будут полезны ссылки, приведенные на шаге 4 и на шаге 6.
См. раздел «Устранение неполадок, связанных с экспортом в Microsoft Access» или «Разрешение вопросов, связанных с импортом и связыванием» в списке См. также в этом разделе.
Воспользуйтесь ссылками, приведенными на шаге 4 в любом из трех подразделов «Приступая к работе» этого раздела, чтобы узнать о возможных проблемах и способах их решения.
Типичная неполадка импорта — усечение данных
Воспользуйтесь ссылками, приведенными на шаге 6, чтобы получить рекомендации по интерпретации содержимого таблицы журнала ошибок в приложении Access или ошибок на импортируемом листе Excel.
24 - 27
Взаимодействие с пользователем в VBA, функции MsgBox() и InputBox()
Во многих программах VBA необходимо обеспечить взаимодействие с пользователем — проинформировать его о чем-то и (возможно) получить от него ответную реакцию. В принципе, для пользователя можно просто вывести текст в окне приложения (например, в текущем документе Word) или воспользоваться формой и элементами управления. Как это делается — мы узнаем в соответствующих главах. В этой части мы рассмотрим только применение для этой цели встроенных функций VBA.
Самой простой способ вывести информацию пользователю — воспользоваться встроенной функцией VBA MsgBox(). Примеров применения этой функции в нашей книге уже было множество, а полный ее синтаксис выглядит так:
MsgBox(Текст[,кнопки] [,заголовок окна] [, файл справки, метка в файле справки])
Возможностей у MsgBox() достаточно много:
можно отображать разное кол-во кнопок (OK, Cancel, Abort, Retry, Ignore, Yes, No),
можно показывать символы Critical, Warning, Question, Information,
можно выбирать кнопку по умолчанию,
можно делать окно модальным или обычным.
В зависимости от того, на какую пользователь кнопку нажал, такое значение возвращается приложению (всего 7 вариантов). Подробнее — в справке по VBA. Пример возврата значения от MsgBox():
Dim nVar As Integer
nVar = MsgBox ("Будем делать?", 65, "Демонстрационное окно сообщения")
Если значение nVar равно 1, то пользователь нажал OK, если 2, то Cancel.
Иногда (например, при пакетной обработке данных) хотелось бы, чтобы окно сообщения через некоторое время закрывалось само собой. Это можно сделать при помощи метода Popup() объекта Wscript.Shell. Для этого в проект через меню References нужно добавить ссылку на Windows Script Host Object Model (файл C:\WINNT\system32\wshom.ocx), а после этого использовать следующий код:
Dim oShell As New WshShell
oShell.Popup "Test", 5
В остальном функциональность получившего окна одинакова с MsgBox(). Код возврата, если пользователь не нажал ни на какую кнопку, равен -1.
Самый простой способ принять информацию от пользователя — воспользоваться функцией InputBox(). Все очень просто :
Dim Input
Input = InputBox("Введите Ваше имя: ")
MsgBox (" Вы ввели: " & Input )
Для InputBox() можно указать текст приглашения, заголовок окна, значение по умолчанию, местонахождение окна и файл справки. Не забывайте, что все вводимое пользователем InputBox() автоматически переводит в тип данных String — может потребоваться выполнить преобразование.
Можно привлечь внимание пользователем звуковым сигналом. Для этой цели используется оператор Beep:
Dim I
For I = 1 To 3
Beep
Next I
Если нужно обеспечить более сложное взаимодействие с пользователем, необходимо использовать форму, сам документ или помощника (Office Assistant). Очень мощные возможности обеспечивает и применение объектной модели Internet Explorer.
28
Архив
29
Структура таблицы serverrec_id Уникальный идентификатор записи.
enabled Флаг включения записи для загрузки при старте indexer.
url URL или его фрагмент или шаблон, указываемый в соответствующей команде.
tag Значение тэга для этого ресурса.
category Ссылка на запись в наблице categories, соответсвующей категории для данного ресурса.
command
=S - тип записи сервер
=F - типа записи фильтр
ordre Ключ сортировки, задающий порядок загрузки записей таблицы server при запуске indexer.
parent Если значение не ноль, запись содержит в поле url имя сервера, добавленного автоматически при индексировании. Значение этого поля равно url_id записи этой таблицы, на основании которой дабавлена эта запись.
weight Вес данной записи при подсчёте рейтинга популярности документов.
pop_weight Вес одной ссылки со страниц данного русурса. Рассчитывается автоматически. Изменнеие значения вручную никакого влияния не оказывает.
Остальные параметры серверов хранятся в таблице srvinfo, аналогичной по структуре таблице urlinfo. Значения некоторых параметров приведены в таблице ниже.
Таблица 9-2. Значения некоторых параметров серверов в таблице srvinfoЗначение sname Возможные значения sval.
Alias Алиас для указанного в поле server.url.
Period Интервал между повторными индексированиями этого ресурса, задаваемый в секундах.
DeleteOlder Задаёт сколько времени хранить проиндексированные документы в базе.
RemoteCharset Значение кодировки документа по умолчанию для данного ресурса.
DefaultLang Значение языка документа по умолчанию для данного русурса.
Request.Authorization Учётные данные, используемые для доступа с использованием авторизации.
Request.Proxy Имя прокси-сервера, используемое при доступе через прокси-сервер.
Request.Proxy-Authorization Авторизация на прокси-сервере.
MaxHops Максимальная глубина перехода по ссылкам от корневого индеска.