Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Методичка. Базы данных (ПОВТ) 2009

.pdf
Скачиваний:
54
Добавлен:
14.02.2015
Размер:
2.1 Mб
Скачать

Однако, поскольку пользователь, захвативший запись, может удерживать ее неопределенное время (даже при наличии опции TIMEOUT в команде READ), это может сделать затруднительной

работу всейсистемывцелом. Ввидуэтогоредактирование информации непосредственно в базе никогда не выполняется. Изменение данных осуществляется с использованием временных переменных. С записи из базы командой SCATTER делается копия, которая и подвергается обработке. Собственно изменение данных в базе выполняется командами присваивания REPLACE или GATHER. Это позволяет выполнить контроль доступности и захват нужных записей при сведении к минимуму времени "занятости" записей из базы коллективного пользования.

При работе в сети практически исключается ввод/редактирование данных с помощью командыBROWSE/CHANGE (конечно, еслипользователемнезаблокированавсябазацеликом). Вэтой команде фактом начала редактирования считается ввод любого символа в поле. Если в это же время другой пользователь пытается редактировать ту же запись, произойдет прерывание. Вместе с тем допускается использование команды для просмотра данных. При этом, однако, можно предусмотреть возможность (параллельного или поверх BROWSE) вызова пользователем READ-окна для вводаредактирования. С тем, чтобы пользователь мог получить информацию об актуальных данных, следует периодически использовать команду SHOW WINDOW <окно> REFRESH. При этом в BROWSE-окно "засасывается" текущая на данныймоментинформация.

Обычнотехникадоступакотдельнойзаписибазывсетивключаетследующие(возможноне все) элементы:

1.С помощью команды SCATTER во временных переменных создаются дубликаты полей редактируемой записи. Именно эти переменные, а не сами поля, пользователь будет в дальнейшем редактировать, азатемисохранятьвбазе. Назовемэтипеременныерабочими.

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

3.Строится интерфейс для редактирования рабочих переменных с помощью команды READ ивыполняетсяихредактирование.

4.По завершении редактирования делается попытка блокирования оригинальной записи в базе. Если она удалась, оригинал записи сравнивается с хранящимся эталоном и в зависимости от результатасравненияпринимаетсяодноиздвухрешений.

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

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

5.Если заблокировать запись не удалось, пользователь должен иметь возможность продолжить эти попытки, а еще лучше, чтобы приложение само выполняло попытки захвата зиписей, а пользователь, наоборот, мог бы их прервать в нужный (надоело ждать!) момент.

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

41

Например, уже рассмотренная ситуация в банке. Положим клиент пришел в банк и потребовал снять со своего счета некоторую сумму. Операционистка вызывает данные, относящиеся к этому клиенту и вслучае, еслиимеющаяся сумма не меньше запрошенной, вводит значение изымаемой суммы. По завершении переговоров с клиентом и ввода реквизитов платежного требования, операционистка дает команду системе на снятие денег. В этот момент сначала запрашивается текущее содержимое записи и обнаруживается, например, что она уже не такая, как вмомент первоначального обращения. Действия операционистки могутбыть разными в зависимости от того, что она увидела. Если, положим, оказался измененным почтовый адрес клиента, то его вероятно изменил другой работник банка, контролирующий реквизиты клиентов. Беспокоиться здесь не о чем - деньги могут быть сняты. Если же изменилась сумма на счету (например, вследствие одновременного обращения к этому счету другого клиента с другого рабочего места в банке), операционистка (и/или прикладная система) должна убедиться, что она покрывает запросы вкладчика и снятие возможно. В противном случае, клиенту должно быть отказано.

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

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

Коллективный доступ к базам возможен только при задании установки

SET EXCLUSIVE ON | OFF

В файл CONFIG.FP или непосредственно в программу (прежде команд открытия баз данных) должна быть включена команда SET EXCLUSIVE OFF (в CONFIG.FP - директива EXCLUSIVE=OFF). По умолчанию - ON. Все базы, открываемые с этого момента, будут доступны всем пользователям. Базы, открытые до того, своего статуса не изменят. В файлах, открытых монопольно, далее не нужно выполнять каких-либо блокировок. Монопольный режим используется оченьредко, обычнотолькоадминистраторомбазывовнерабочеедлядругихпользователейвремя. Да и установить монопольный доступ невозможно, если база/базы открыты другими пользователями.

Установление монопольного режима может быть совмещено с открытием базы данных, есликомандаUSE используетопциюEXCLUSIVE, т.е.

USE <файл> EXCLUSIVE

Функция

FLOCK([область])

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

Функция

LOCK | RLOCK([<область>] | [<вырC>,<область>])

осуществляет блокировку записи/записей текущей (или из указанной области) базы данных. Если она удалась (запись не захвачена другим пользователем), возвращается значение .Т.. Заблокированныезаписидоступны для чтения и изменения только пользователю, установившему блокировку. Остальные пользователи сети эти записи могут только читать. В противном случае функциявозвращает.F..

42

Допускается множественная блокировка записей. Их номера, перечисленные через запятую, включаются в <вырС>, например: LOCK('26,27,34','kadr'). Если некоторые из записей не удалось заблокировать, возвращается значение .F.. Однако остальные записи останутся заблокированными.

Возможностьмножественной блокировкидоступна, толькоеслиустановлено

SET MULTILOCKS ON

По умолчанию SET MULTILOCKS OFF - разрешено блокировать только одну запись. Допускается одновременная блокировка около8000 записейвкаждойрабочейобласти.

Команда

UNLOCK [IN <область> | ALL]

снимает блокировки записей/файлов в текущей или указанной рабочей области. Команда действует только на блокировки, установленные данным пользователем. Параметр ALL снимаетблокировкисовсехбазвовсехрабочихобластях. Команданевлияетнастатусбаз, открытых монопольно. Изменение установки MULTILOCKS из ON в OFF или наоборот автоматически выполняетUNLOCK ALL.

При интенсивном обращении к сетевой базе командой READ LOCK часто может возникать ситуация, когда пользователю временно запрещается доступ к записи/файлу, захваченной другим пользователем. Чтобы избежать необходимости раздражающего "ручного" повторения обращения к данным, может использоваться режим автоматического повтора попыток блокировки в течение заданноговремениилизаданноечислораз.

Этотрежимопределяетсякомандой

SET REPROCESS TO <вырN> [SECONDS] | TO AUTOMATIC

где:

<вырN> - числоповторныхпопытокблокировки,

<вырN> SECONDS - количество секунд, в течение которых будут выполняться эти попытки.

<вырN> может принимать целые значения от 1 до 32 000. По умолчанию <вырN>=0. Попытки блокировки повторяются 18.3 раза всекунду. Нажатие клавиши Escape при этом не прерывает попыток захвата данных, даже если установлено SET ESC APE ON.

AUTOMATIC - попытки блокировки будут выполняться непрерывно. При этом на экране будет предъявлено системное сообщение "Attempting to lock... Press ESC to Cancel" (Попытка блокировки.. Отказ - нажатие Esc). Если пользователю надоест ожидать захвата данных, он может нажать клавишу Escape. Если захват удался - сообщение исчезнет само. Для отечественного пользователя это сообщение можно перевести на русский, найдя его непосредственно в модуле самой СУБД. Теперь рассмотрим пример. В следующей задаче (WOD.PRG) осуществляется редактирование данных в базе KADR.DBF в сетевом режиме. При этом контролируется изменения данных другими пользователями. На момент, когда пользователем сделана попытка сохранить данные и обнаружено, что за время его работы с записьюкто-тоизменилтабельныйномерсотрудника.

Здесь редактируются только четыре первых поля базы. Интерфейс содержит три раздела. В первом отображаются рабочие переменные, которые и подвергаются редактированию. Эти переменныесоздаютсякомандойSCATTER иимеютимена, совпадающиесименамисоответствующих полей базы (например M.FAM). Во втором - эталонные переменные, содержащие текущие значения базы (имена заканчиваются знаком подчеркивания, например M.FAMJ. В третьем - переменные, фиксирующие внимание пользователя на полях, которые оказались измененными другими пользователями(флагизменения). Ихименазаканчиваютсянаноль(напримерM.FAMO).

Из средств управления предусмотрены только две кнопки. Кнопка <Сохранить> первоначально заглушена и активируется только в случае изменения пользователем каких-либо рабочих данных. Выбор этой кнопки вызывает процесс сравнения эталонных переменных с значениямисоответствующихполейвбазеданных.

43

Если не обнаруживается ни одного несовпадения, в течение неограниченного времени делаются попытки заблокировать запись и, если они удаются, запись обновляется (GATHER MEMVAR) данными из рабочих переменных. Повторение попыток захвата записи организуется здесь путем включения функции LOCKQ в бесконечный цикл, который пользователь может прервать, нажав клавишу Escape. Чтобы он в это время не подумал, что машина "умерла", в WAIT-окно непрерывно выводится число выполненных попыток I. Кроме того, здесь предусмотрена задержка в полсекунды для снижения интенсивности обращения к серверу. Необходимость программирования организации повторных попыток блокировок вызвана тем, что установки SET REPROCESS TO не влияют на действиефункцийFLOCK()/LOCK().

Если обнаружены изменения базы с момента создания рабочих переменных, эталонные переменные получают эти новые значения, переменные-флаги устанавливаются в fl, сохранение не производится и пользователь возвращается в окно ввода для обдумывания этого факта. Если обнаруженные им изменения не существенны, он может повторить выбор кнопки <Сохранить>. Кнопка <0бновить> предназначена только для обновления эталонных переменных, если пользовательхочетпосмотреть, чтослучилосьсзаписьюзатовремя, покаонобедал.

Дополнение/удалениезаписейвбазе. Обычные действия, совершаемые приложением при дополнении базы новой записью - исполнение пары команд APPEND BLANK и REPLACE | GATHER. Однако в многопользовательской системе это не лучший вариант. Дело в том, что команда APPEND BLANK при своем исполнении, как сказано в документации, "блокирует заголовок" базы данных. Это означает, что никакая другая команада, изменяющая заголовок (прежде всего другая команда APPEND BLANK), не может быть выполнена в данный момент. Поскольку вFoxPro нет средств захвата именно заголовка базы, получается, что мы должны блокировать весь файл целиком. При незначительном числе рабочих станций это возможное решение, однако, если пользователей несколько десятков, многочисленные блокировки файла/файловмогутпарализоватьвсюсистему.

В арсенале FoxPro имеется удобное средство для этих целей - команда INSERT языка SQL. Эта команда выполняет сразу дополнение базы новой записью с новыми данными. При этом оказывается (по крайней мере, в сетях NetWare), что нет необходимости в какой-либо блокировке. Команда проходит гладко и в случае одновременных попыток с нескольких рабочих мест выполнить INSERT. Все такие команды выполняются по очереди, не беспокоя пользователя пугающими сообщениями об ошибках. При необходимости убедиться в том, что дополнениепроизошло, можновоспользоватьсяфункциямиRECNO() иRECCOUNT().

Пометка записей к удалению является точно таким же действием по редактированию данных, как, например, команда REPLACE и для ее осуществления следуeт обычным образом воспользоваться функциейLOCK().

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

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

44

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

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

При создании приложений, обычно, рекомендуется все значимые базы открывать сразу в начале программы. Далее они остаются открытымидоконца сеанса. Удобно все командыоткрытия поместить в специальную процедуру. Это упростит повторное открытие баз после упаковки. Сказанное относится как к однопользовательским, так и к сетевым приложениям. В сетевой задаче открытие первой базы должно сопровождаться обработкой ошибок (аналогично тому, как это сделановпримере) наслучай, есликто-тоужеоткрылеевмонопольномрежиме.

Расположение компонентов приложения. Если все данные и все результаты (вновь созданные базы данных, файлы отчетов и др.), а также, возможно, и само приложение находятся на сервере, то программисту нет необходимости специально заботиться о розыске каких-то материалов. Сетевая директория объявляется директорией по умолчанию командой SET DEFAULT TO <путь> или (что удобнее) установкой DEFAULT=<путь> в CONFIG.FP и все будет происходить только в ней. Аналогичный эффект происходит в случае, если вы стартуете из этойдиректории. Однакочащеинформация находится в нескольких местах. В этом случае, пути доступа можнозадатькомандой

SET PATH ТО<путь>

Она указывает, где программа может искать еще данные, кроме директории, принятой по умолчанию. Она, как и все почти SET-команды, может быть включена в CONFIG.FP в форме РАТН=<путь>. Если после обследования путей, заданных в команде, нужный файл не найден, используются DOS-пути, перечисленныевCONFIG.SYS.

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

Взаключениеприведемкодысетевыхошибокисоответствующиеимсистемныесообщения. 108. File is in use by another - попытка захвата записи/файла, если файл заблокирован

другимпользователем.

109.Record is in use by another - попытка редактирования записи, заблокированной другим пользователем.

110.Exclusive open of file is required - требуется монопольное открытие файла. Ошибка возникает при попытке исполнить команду, не допускающую других пользователей (например, командуPACK).

45

Работа с отчетами

Отчеты устроены таким образом, что данные в них доступны только для чтения. Один из распространенных видов отчета — этикетка, в которой элементы форматирования установлены так, чтобы ее можно было легко напечатать и использовать, например для почтового конверта. Причем в качестве данных могут использоваться результаты выполнения запроса, представления или текущий набор записей (объект типа Cursor). Поскольку результаты выполнения запроса или поиска можно отсортировать, отфильтровать или сгруппировать, именно они, как правило, применяются в качестве источника данных отчета.

Проще всего в качестве источника использовать представления, поскольку для этого их достаточно разместить в окне среды данных отчета, тогда как файл формата QPR требует наличия двух строк кода: DO <имя_файла>. QPR и REPORT FORM <имя_отчета>. Оба подхода приемлемы в большинстве случаев.

Возможны следующие способы формирования отчетов:

средствами Visual FoxPro; через Microsoft Word; через Microsoft Excel;

В Visual FoxPro предусмотрено пять основных типов отчета.

Columnar reports (Отчет ). В этих отчетах записи располагаются по строкам, а поля по столбцам. В целом этот отчет напоминает таблицу, так что его можно принять его за распечатку электронной таблицы.

В Visual FoxPro для создания таких отчетов предусмотрено средство Group/Total Report Wizard (Мастер итоговых отчетов).

Отчеты по столбцам удобны и полезны для составления итоговых отчетов с вычислениями и группировками.

Row reports (Отчет по строкам). Такой отчет содержит столбец записей с вертикально размешенными в нем полями и может использоваться для составления списков, например как перечень описаний отдельных деталей.

Form reports (Отчеты в виде формы). Эти отчеты внешне напоминают форму ввода данных в распечатанном виде.

Для создания такого отчета в Visual FoxPro предусмотрено средство One-to-Many Report Wizard (Мастер отчетов один-ко-многим).

Отчеты в виде формы содержат данные из одной записи, а если в отчете определено отношение один-ко-многим — все данные, связанные с этой записью. Такие отчеты удобно составлять для заказов, счетов, справок и т.д.

Multicolumn reports (Многоколонные отчеты). В таких отчетах записи могут располагаться в нескольких столбцах, а поля размещаются вертикально.

Многоколонный отчет можно легко создать с помощью средства Multi-Column Report Wizard (Мастер многоколонных отчетов).

Такие отчеты удобны для создания визитных карточек или телефонного справочника.

Label (Этикетка). Этот отчет имеет некоторое сходство с многоколонным, поскольку в нем также содержится несколько столбцов записей с расположенными вертикально и повторяющимися для каждой записи полями. Для создания этикеток в Visual FoxPro предусмотрено средство Label Report Wizard (Мастер этикеток).

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

В Visual FoxPro предусмотрено три основных способа создания отчетов.

Quick Reports (Быстрое создание отчетов). В этом случае можно создать очень простой отчет по столбцам или по строкам.

46

При быстром создании отчета все внесенные в него изменения будут касаться только раздела данных. Этот способ удобен для проверки распечатываемых данных, поскольку при этом не требуется тратить время на оформление. Однако в других целях лучше использовать другие способы.

Report Wizards (Мастер отчетов). Для создания отчетов в Visual FoxPro предусмотрено четыре средства: Multi-column Report Wizard (Мастер многоколонных отчетов), СгоирЯо1а1 Report Wizard (Мастер итоговых отчетов), One-to-Many Report Wizard (Мастер отчетов один-ко-многим) и Label Report Wizard (Мастер этикеток).

Report Designer (Конструктор отчетов). Это довольно мощное средство для создания отчетов, которое обладает всеми достоинствами, присущими конструкторам отчетов в предыдущих версиях программы.

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

При создании отчета его макет сохраняется в FRX-файле. В этом файле определяются свойства размещения и форматирования данных, но не сами данные. Используемые данные следует устанавливать непосредственно перед печатью отчета. Данные из memo-полей сохраняются в этом случае в FRT-файле.

Перечисленные выше отчеты можно выполнить набрав команду REPORT FORM

<имя отчета>.

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

Необходимо использовать отчеты Visual FoxPro в случае, если объем печати велик и время печати ограничено, т.к. скорость формирования отчета велика.

В случае, если отчет небольшой и существуют определенные требования по его оформлению, то лучше воспользоваться средствами Open Office. Если у отчета нет определенной жесткой структуры, то можно воспользоваться Writer, в противном случае – Calc. Время формирования таких отчетов достаточно велико, но при таком подходе можно воспользоваться всей мощью офисных пакетов для оформления и печати отчета. Работа с отчетами и в том, и в другом случае заключается в следующем:

1. создание соответствующего объекта;

2. отображение этого объекта на экране;

3. использование встроенных команд используемого приложения для формирования отчета, его оформления и печати (при необходимости );

4. уничтожение соответствующего объекта.

Рассмотрим пример формирования отчета с использованием Calc.

CLEAR ALL

ServiceManager = CreateObject("com.sun.star.ServiceManager")

&& Создаем объекты для работы с Open Office

Desktop = ServiceManager.createInstance("com.sun.star.frame.Desktop")

Dispatcher = ServiceManager.createInstance("com.sun.star.frame.DispatchHelper")

CoreReflection = ServiceManager.createInstance("com.sun.star.reflection.CoreReflection")

CoreReflection.forName("com.sun.star.beans.PropertyValue")

m.FilePath = "private:factory/scalc"

&& Указываем пустой файл, аналог XLS

m.lcFile= FULLPATH("")+"liderspc.xls"

&& Указываем существующий файл

LOCAL laArgs(1)

loProperty =CREATEOBJECT( "Empty" )

47

CoreReflection.forName("com.sun.star.beans.PropertyValue").CREATEOBJECT(@loProperty) laArgs(1) = loProperty

laArgs(1).NAME = "Hidden" laArgs(1).VALUE = .F.

*Document1 = Desktop.LoadComponentFromURL( ConvertToURL(lcFile),"_blank",0,@laArgs)

&& Открываем существующий файл

Document = Desktop.LoadComponentFromURL( FilePath,"_blank",0,@laArgs)

&& Создаем новый пустой файл

Sheets = Document.getSheets

&& Получаем ссылку на листы

Sheet = Sheets.getByName("Лист1")

&& Получаем ссылку на Лист1

*Cell = Sheet.getCellByPosition( col, row )

*У ячейки есть три метода для записи данных: setString, setValue, setFormula.

Cell = Sheet.getCellByPosition( 0, 0 )

&& Получаем ссылку на ячейку

Cell.setString("Проба пера")

&& Пишем в неё

Cell = Sheet.getCellByPosition( 0, 1 )

Cell.setString(DTOC(DATE()))

Cell = Sheet.getCellByPosition( 0, 2 )

Cell.setValue(22)

*Получение типа содержимого ячейки:

m.TType=Cell.getType

*Возвращаемые данной функцией значения:

*0 - пустое значение;

*1 - число;

*2 - текст;

*3 - формула.

WAIT WINDOW "Тип ячейки: "+STR(m.TType)

Sheet.COLUMNS(0).OptimalWidth =.T.

&& Для столбца с номером 0 автоматически подбираем

ширину

loCol=Sheet.getColumns().getbyindex(3)

&& Получем ссылку на столбец по номеру

*loCol=Sheet.getColumns().getbyName(lnColumn)

&& Получем ссылку на столбец по имени

Document.getCurrentController().SELECT(loCol)

&& Выделяем столбец

loProperty =CREATEOBJECT( "Empty" ) CoreReflection.forName("com.sun.star.beans.PropertyValue").CREATEOBJECT(@loProperty) laArgs(1) = loProperty

laArgs(1).NAME = "ColumnWidth" laArgs(1).VALUE = 1000

Dispatcher.executeDispatch(Document.CurrentController.Frame, ".uno:ColumnWidth", "", 0, @laArgs) &&

Устанавливаем ширину столбца 1см

48

loCol=Sheet.getColumns().getbyindex(0) Document.getCurrentController().SELECT(loCol)

loProperty =CREATEOBJECT( "Empty" ) CoreReflection.forName("com.sun.star.beans.PropertyValue").CREATEOBJECT(@loProperty) laArgs(1) = loProperty

laArgs(1).NAME = "ToPoint"

 

laArgs(1).VALUE = "$A$1:$C$1"

&& Выбираем диапазон ячеек A1:C1

dispatcher.executeDispatch(Document.CurrentController.Frame, ".uno:GoToCell", "", 0, @laArgs) dispatcher.executeDispatch(Document.CurrentController.Frame, ".uno:ToggleMergeCells", "", 0, @laArgs) &&

Объединяем выбранные ячейки

loProperty =CREATEOBJECT( "Empty" ) CoreReflection.forName("com.sun.star.beans.PropertyValue").CREATEOBJECT(@loProperty) laArgs(1) = loProperty

laArgs(1).NAME = "HorizontalAlignment" laArgs(1).VALUE = 2

dispatcher.executeDispatch(Document.CurrentController.Frame, ".uno:HorizontalAlignment", "", 0, @laArgs) &&

Центрируем значение внутри ролученной ячейки

loProperty =CREATEOBJECT( "Empty" ) CoreReflection.forName("com.sun.star.beans.PropertyValue").CREATEOBJECT(@loProperty) laArgs(1) = loProperty

laArgs(1).NAME = "ToPoint" laArgs(1).VALUE = "$A$2:$C$2"

dispatcher.executeDispatch(Document.CurrentController.Frame, ".uno:GoToCell", "", 0, @laArgs) dispatcher.executeDispatch(Document.CurrentController.Frame, ".uno:ToggleMergeCells", "", 0, @laArgs)

loProperty =CREATEOBJECT( "Empty" ) CoreReflection.forName("com.sun.star.beans.PropertyValue").CREATEOBJECT(@loProperty) laArgs(1) = loProperty

laArgs(1).NAME = "HorizontalAlignment" laArgs(1).VALUE = 2

dispatcher.executeDispatch(Document.CurrentController.Frame, ".uno:HorizontalAlignment", "", 0, @laArgs)

loProperty =CREATEOBJECT( "Empty" ) CoreReflection.forName("com.sun.star.beans.PropertyValue").CREATEOBJECT(@loProperty) laArgs(1) = loProperty

laArgs(1).NAME = "ToPoint" laArgs(1).VALUE = "$A$3:$C$3"

dispatcher.executeDispatch(Document.CurrentController.Frame, ".uno:GoToCell", "", 0, @laArgs) dispatcher.executeDispatch(Document.CurrentController.Frame, ".uno:ToggleMergeCells", "", 0, @laArgs)

loProperty =CREATEOBJECT( "Empty" ) CoreReflection.forName("com.sun.star.beans.PropertyValue").CREATEOBJECT(@loProperty) laArgs(1) = loProperty

laArgs(1).NAME = "HorizontalAlignment" laArgs(1).VALUE = 2

dispatcher.executeDispatch(Document.CurrentController.Frame, ".uno:HorizontalAlignment", "", 0, @laArgs)

Cell = Sheet.getCellByPosition( 0, 3 )

Cell.setString("№пп")

Document.getCurrentController().SELECT(Cell)

49

****Устанавливаем размер font'а loProperty =CREATEOBJECT( "Empty" )

CoreReflection.forName("com.sun.star.beans.PropertyValue").CREATEOBJECT(@loProperty) laArgs(1) = loProperty

laArgs(1).NAME = "FontHeight.Height" laArgs(1).VALUE = 14

Dispatcher.executeDispatch(Document.CurrentController.Frame, ".uno:FontHeight", "", 0, @laArgs)

****Устанавливаем font

loProperty =CREATEOBJECT( "Empty" ) CoreReflection.forName("com.sun.star.beans.PropertyValue").CREATEOBJECT(@loProperty) laArgs(1) = loProperty

laArgs(1).NAME = "CharFontName.FamilyName" laArgs(1).VALUE = "Courier New"

Dispatcher.executeDispatch(Document.CurrentController.Frame, ".uno:CharFontName", "", 0, @laArgs)

loProperty =CREATEOBJECT( "Empty" ) CoreReflection.forName("com.sun.star.beans.PropertyValue").CREATEOBJECT(@loProperty) laArgs(1) = loProperty

laArgs(1).NAME = "HorizontalAlignment" laArgs(1).VALUE = 2

dispatcher.executeDispatch(Document.CurrentController.Frame, ".uno:HorizontalAlignment", "", 0, @laArgs)

Cell = Sheet.getCellByPosition( 1, 3 ) Cell.setString("ФИО") Document.getCurrentController().SELECT(Cell) loProperty =CREATEOBJECT( "Empty" )

CoreReflection.forName("com.sun.star.beans.PropertyValue").CREATEOBJECT(@loProperty) laArgs(1) = loProperty

laArgs(1).NAME = "HorizontalAlignment" laArgs(1).VALUE = 2

dispatcher.executeDispatch(Document.CurrentController.Frame, ".uno:HorizontalAlignment", "", 0, @laArgs)

Cell = Sheet.getCellByPosition( 2, 3 ) Cell.setString("Балл") Document.getCurrentController().SELECT(Cell) loProperty =CREATEOBJECT( "Empty" )

CoreReflection.forName("com.sun.star.beans.PropertyValue").CREATEOBJECT(@loProperty) laArgs(1) = loProperty

laArgs(1).NAME = "HorizontalAlignment" laArgs(1).VALUE = 2

dispatcher.executeDispatch(Document.CurrentController.Frame, ".uno:HorizontalAlignment", "", 0, @laArgs)

Cell = Sheet.getCellByPosition( 0, 4 )

Cell.setValue(1)

Cell = Sheet.getCellByPosition( 1, 4 )

Cell.setString("Иванов Иван Иванович")

Cell = Sheet.getCellByPosition( 2, 4 )

Cell.setValue(25)

Cell = Sheet.getCellByPosition( 0, 5 )

Cell.setValue(2)

Cell = Sheet.getCellByPosition( 1, 5 )

Cell.setString("Петров Петр Петрович")

Cell = Sheet.getCellByPosition( 2, 5 )

Cell.setValue(50)

Cell = Sheet.getCellByPosition( 0, 6 )

Cell.setValue(3)

50