Профессиональная разработка в системе «1С:Предприятие 8» В двух томах Том 1 Москва «1С-Паблишинг» 2012
Электронная вер...
141 downloads
2135 Views
118MB Size
Report
This content was uploaded by our users and we assume good faith they have the permission to share this book. If you own the copyright to this book and it is wrongfully on our website, we offer a simple DMCA procedure to remove your content from our site. Start by pressing the button below!
Report copyright / DMCA form
Профессиональная разработка в системе «1С:Предприятие 8» В двух томах Том 1 Москва «1С-Паблишинг» 2012
Электронная версия книги «Профессиональная разработка в системе 1С:Предприятие 8» (издание 2) Том 1
© ООО «1С-Паблишинг», 2012
Материалы предназначены для личного индивидуального использования приобретателем книги «Профессиональная разработка в системе 1С:Предприятие 8», 2 издание (Москва, «1С-Паблишинг», ISBN 978-5-9677-1790-8, 2012). Запрещено тиражирование, распространение материалов, предоставление доступа по сети к материалам без письменного разрешения правообладателей. Разрешено копирование фрагментов программного кода для использования в разрабатываемых прикладных решениях.
Оглавление
Оглавление Введение....................................................................................7 От редактора...........................................................................................................................7 Благодарности........................................................................................................................7 Особенности книги..................................................................................................................7 Как читать книгу......................................................................................................................8 Что находится на компакт-диске...........................................................................................8 Скажите нам, что вы думаете . .............................................................................................8
Глава 1. Архитектура «1С:Предприятия»............................. 9 Платформа и прикладные решения......................................................................................9 Средства разработки в составе платформы........................................................................9 Метаданные – способ описания прикладного решения....................................................10 Метаданные и встроенный язык....................................................................................................10 Подсистемы.....................................................................................................................................10
Создание прикладных решений на основе модели...........................................................11 Объектные и необъектные данные.....................................................................................12 Три способа представления данных...................................................................................12 Сквозная типизация..............................................................................................................13 Поддержка составных типов данных..................................................................................13 Смешанный подход к манипулированию данными...........................................................13 Встроенный язык..................................................................................................................14 Язык запросов.......................................................................................................................14 Прикладные решения, независимые от используемого хранилища данных..................15 Управляемый интерфейс.....................................................................................................15
Командный интерфейс...................................................................................................................17 Ссылки.............................................................................................................................................18 История............................................................................................................................................20 Избранное........................................................................................................................................21 Использование информации из метаданных...............................................................................23 Расширения форм и элементов управления................................................................................23 Генерация форм по умолчанию.....................................................................................................23
Клиентские приложения ......................................................................................................24 Подключение через Интернет.............................................................................................24 Файловый и клиент-серверный варианты работы.............................................................25
Кластер серверов «1С:Предприятия»...........................................................................................25 Выполнение основной функциональности на сервере................................................................26
Том 1
Поддержка различных хранилищ данных..........................................................................26 Работа под управлением различных операционных систем ...........................................27 Обновление прикладных решений......................................................................................27 Интернационализация..........................................................................................................27
Глава 2. Функциональность «1С:Предприятия»............... 29 Обзор функциональности прикладных решений...............................................................29 Справочники....................................................................................................................................29 Документы.......................................................................................................................................29 Механизм характеристик................................................................................................................29 Механизм сведений........................................................................................................................30 Механизм учета движения средств...............................................................................................30 Механизм бухгалтерского учета....................................................................................................30 Механизм сложных периодических расчетов...............................................................................30 Механизм бизнес-процессов..........................................................................................................31 Механизм анализа данных и прогнозирования............................................................................31 Сложные отчеты, использующие систему компоновки данных..................................................31 Механизмы презентации текстовых и аналитических данных....................................................32 Средства интеграции и механизмы обмена данными.................................................................34 Web-сервисы...................................................................................................................................34 Web-расширение.............................................................................................................................35 Механизм полнотекстового поиска................................................................................................35 Механизм криптографии.................................................................................................................36 Механизм разделения данных.......................................................................................................36 Внешние источники данных...........................................................................................................36
Обзор функциональности средств разработки..................................................................36
Объекты конфигурации и инструменты для их редактирования................................................37 Конструкторы и редакторы.............................................................................................................37 Синтакс-помощник..........................................................................................................................38 Отладчик и режим замера производительности..........................................................................38 Проверка конфигурации.................................................................................................................39 Редактирование текстов интерфейса...........................................................................................39 Групповая разработка прикладных решений...............................................................................39 Поставка и поддержка прикладных решений...............................................................................39 Создание дистрибутивов................................................................................................................39 Функциональные опции..................................................................................................................39 Показатели производительности и режим имитации задержек при вызове сервера...............40 «1С:Библиотека стандартных подсистем 8.2».............................................................................40
3
Оглавление Обзор функциональности средств администрирования...................................................40 Список пользователей....................................................................................................................41 Механизмы аутентификации . .......................................................................................................41 Механизм заданий..........................................................................................................................41 Система прав доступа....................................................................................................................41 Ограничение прав на уровне записей и полей.............................................................................42 Журнал регистрации.......................................................................................................................42 Загрузка/выгрузка информационной базы....................................................................................42 Утилита администрирования кластера серверов.........................................................................42 «1С:Корпоративный инструментальный пакет» ..........................................................................43
Глава 3. Использование встроенного языка..................... 45 Модули конфигурации..........................................................................................................46 Контекст исполнения модулей.......................................................................................................47 Общий модуль.................................................................................................................................48 Модуль управляемого приложения...............................................................................................48 Модуль сеанса.................................................................................................................................50 Модуль внешнего соединения.......................................................................................................50 Модуль объекта...............................................................................................................................51 Модуль менеджера объекта...........................................................................................................52 Модуль управляемой формы.........................................................................................................53 Модуль команды.............................................................................................................................57
Работа встроенного языка на сервере...............................................................................58
Организация выполнения кода на сервере или на клиенте........................................................58 Вызов процедур из серверных модулей ......................................................................................59 Передача параметров на сервер и возврат значений.................................................................60 Привилегированный и безопасный режимы исполнения кода...................................................60
Работа с метаданными........................................................................................................61
Глава 4. Работа с данными................................................... 65 Объектные и необъектные данные.....................................................................................65 Объектные данные.........................................................................................................................65 Необъектные данные.....................................................................................................................75
Система типов.......................................................................................................................79
Типы значений и типы данных.......................................................................................................79 Типы значений.................................................................................................................................80 Типы данных....................................................................................................................................99
Транзакции..........................................................................................................................104
Использование явного вызова транзакций.................................................................................105 Обработка ошибок базы данных в транзакции...........................................................................105 Вложенный вызов транзакций.....................................................................................................107 Влияние транзакций на работу программных объектов............................................................108
Механизм управляемых блокировок................................................................................. 111
Возможные проблемы при многопользовательском доступе к одним и тем же данным....... 111 Уровни изоляции транзакций....................................................................................................... 113
4
Режим управляемых блокировок................................................................................................. 113 Установка управляемых блокировок........................................................................................... 114
Глава 5. Клиент-серверный вариант работы.................. 119 Общие сведения ................................................................................................................119 Программные компоненты клиент-серверной архитектуры «1С:Предприятия»..................... 119 Варианты использования.............................................................................................................121 Работа под управлением различных операционных систем ...................................................122
Кластер серверов...............................................................................................................122
Состав кластера............................................................................................................................122 Сеансы и соединения...................................................................................................................123
Масштабируемость и отказоустойчивость.......................................................................126
Масштабируемость кластера.......................................................................................................126 Устойчивость клиентских приложений........................................................................................127 Использование протокола HTTP..................................................................................................127 Отказоустойчивость кластера......................................................................................................128 Динамическое перераспределение нагрузки..............................................................................130
Безопасность.......................................................................................................................130
Многоуровневая аутентификация...............................................................................................130 Шифрование передаваемых данных..........................................................................................131
Глава 6. Установка и администрирование системы...... 135 Несколько дистрибутивов..................................................................................................135 Установка, обновление и запуск........................................................................................135 Запуск.............................................................................................................................................135 Установка.......................................................................................................................................137 Обновление...................................................................................................................................138
Управление кластером серверов......................................................................................139
Работа со списком администраторов центрального сервера...................................................139 Работа со списком кластеров центрального сервера................................................................139 Работа со списком менеджеров кластера..................................................................................140 Работа со списком администраторов кластера..........................................................................140 Работа со списком рабочих серверов кластера.........................................................................141 Работа со списком рабочих процессов.......................................................................................141 Работа со списком информационных баз...................................................................................142 Работа со списком сеансов..........................................................................................................142 Работа со списком соединений....................................................................................................143
Программные средства администрирования кластера серверов..................................143
Глава 7. Командный интерфейс прикладных решений.......................................... 145 Пользователь, интерфейс, команда.................................................................................145 Командный интерфейс системы.......................................................................................146 Команды «1С:Предприятия»........................................................................................................146 Структура командного интерфейса.............................................................................................147
Профессиональная разработка в системе «1С:Предприятие 8»
Оглавление Формирование состава командного интерфейса.......................................................................149 Краткие итоги.................................................................................................................................154
Настраиваем состав команд..............................................................................................154
Постановка задачи........................................................................................................................154 Системные команды.....................................................................................................................155 Состав разделов...........................................................................................................................155 Стандартные команды..................................................................................................................157 Основные действия для создания командного интерфейса.....................................................161
Настраиваем доступность команд по ролям....................................................................161
Система прав доступа..................................................................................................................161 Система управления пользователями........................................................................................165
Редактирование командного интерфейса........................................................................168
Автоматическое размещение и видимость команд....................................................................168 Система настройки командного интерфейса..............................................................................174
Влияние функциональных опций на командный интерфейс..........................................183
Механизм функциональных опций..............................................................................................183 Отключаем неиспользуемые команды........................................................................................184
Пользовательская настройка интерфейса.......................................................................187
Настройка области системных команд.......................................................................................187 Настройка командного интерфейса.............................................................................................188
Настраиваем представление команд................................................................................190 Модель разработки глобального командного интерфейса.............................................192 Создаем произвольные команды......................................................................................193
Произвольные команды...............................................................................................................193 Особенности размещения............................................................................................................196 Развитие функциональности ценообразования.........................................................................197
«Командуем» формами......................................................................................................210
Необходимые сведения о формах..............................................................................................210 Функциональность по умолчанию................................................................................................ 211 Команды формы............................................................................................................................ 211 Способы формирования состава команд формы......................................................................215 Автоматическое формирование состава команд формы..........................................................215 Доступность команд формы для пользователя.........................................................................219 Управляем командами формы.....................................................................................................221 Если не хватает стандартных команд.........................................................................................230 Краткие итоги.................................................................................................................................232
Глава 8. Разработка форм................................................... 233 Конструирование форм......................................................................................................233 Форма «1С:Предприятия»............................................................................................................233 Создание формы...........................................................................................................................235 Редактирование формы...............................................................................................................240 Влияние объектов конфигурации на форму...............................................................................253 Реквизиты формы.........................................................................................................................258 Командный интерфейс формы....................................................................................................259
Том 1
Управление видимостью элементов формы..............................................................................261 Окно сообщений формы...............................................................................................................268 Примеры конструирования форм................................................................................................269 Рабочий стол.................................................................................................................................279
Программирование форм..................................................................................................283 Форма как элемент клиент-серверного взаимодействия...........................................................283 Параметры и реквизиты формы..................................................................................................284 Открытие форм.............................................................................................................................285 Преобразование прикладных данных в данные формы...........................................................294 Контекстные и внеконтекстные серверные вызовы...................................................................296 Работа с данными объекта в форме...........................................................................................297 Последовательность событий при открытии формы объекта..................................................299 Последовательность событий при записи объекта из формы..................................................301 Начальное заполнение.................................................................................................................305 Проверка заполнения...................................................................................................................310 Сообщения пользователю...........................................................................................................321 Способы информирования пользователя..................................................................................327 Обновление данных в динамических списках............................................................................329 Оформление списков....................................................................................................................332 Дополнительные колонки в списках............................................................................................341 Работа с таблицей в форме.........................................................................................................347 Работа с файлами и картинками.................................................................................................351 Ввод по строке...............................................................................................................................364 Программное изменение формы.................................................................................................372 Настройки пользователей ...........................................................................................................380
Оптимизация клиент-серверного взаимодействия в формах.........................................391
Общие рекомендации по оптимизации клиент-серверного взаимодействия..........................391 Инструменты, используемые при оптимизации клиент-серверного взаимодействия............392 Примеры оптимизации клиент-серверного взаимодействия....................................................397
Глава 9. Хранение информации......................................... 435 Задачи хранения информации..........................................................................................435 Варианты подходов к решению задач хранения информации.......................................438 Хранение информации, общей для информационной базы.....................................................438 Хранение единичных значений условно-постоянной информации..........................................439 Использование перечислений ...................................................................................................440 Использование предопределенных элементов..........................................................................442 Хранение информации объектных и необъектных сущностей.................................................443 Хранение информации в самих объектах или в других объектах............................................444 Хранение иерархической информации.......................................................................................446 Хранение информации, имеющей привязку ко времени...........................................................453 Использование объекта «ХранилищеЗначения».......................................................................454
Хранение информации в регистрах сведений.................................................................455
Уникальность записей регистра сведений..................................................................................455 Периодические регистры сведений.............................................................................................457 Подчинение записей регистратору..............................................................................................457
5
Оглавление Структура регистра сведений......................................................................................................459 Создание, изменение, удаление записей регистра сведений...................................................462 Получение данных из регистров сведений.................................................................................470 Проектирование структуры регистров сведений........................................................................479
Хранение дополнительных характеристик.......................................................................480
Хранение дополнительных характеристик определенного типа..............................................481 Хранение дополнительных характеристик произвольного типа . ............................................483
Глава 10. Документы и последовательности.................. 495 Место документов в концепции системы «1С:Предприятие».........................................495 Документы...........................................................................................................................496 Функциональность документов....................................................................................................496 Состав документов........................................................................................................................503 Отдельные вопросы типового использования документов.......................................................505 Специальные случаи использования документов. Ручная операция......................................529
Журналы документов.........................................................................................................531
Состав журналов...........................................................................................................................532 Заполнение журналов...................................................................................................................533
Последовательности документов......................................................................................533
Устройство последовательностей...............................................................................................535 Работа с последовательностями.................................................................................................536 Параллельный ввод документов, участвующих в последовательности..................................543
Получение оборотов.....................................................................................................................580 Получение остатков и оборотов в одной таблице......................................................................592 Применение отборов в запросах, использующих виртуальные таблицы регистров накопления . ................................................................................................................602 Когда следует использовать запрос вместо объектной модели обращения при получении данных регистров накопления............................................................................604
Отдельные вопросы использования регистров накопления...........................................605
Работа с регистрами при отображении динамических данных.................................................605 Получение остатков при проведении документов......................................................................609
Глава 12. Бухгалтерский учет............................................. 613 Диаграмма взаимодействия объектов..............................................................................613 План счетов и его основные свойства..............................................................................614 Коды счетов...................................................................................................................................617 Упорядочивание счетов в плане счетов.....................................................................................618 Иерархичность плана счетов.......................................................................................................620 Предопределенные и пользовательские счета..........................................................................623 Основы организации аналитического учета...............................................................................624 Принятие решений при организации аналитического учета.....................................................632
Предназначение регистра бухгалтерии............................................................................634 Объект «Регистр бухгалтерии».........................................................................................636
Основные свойства регистра бухгалтерии.................................................................................637 Данные регистра бухгалтерии.....................................................................................................638
Глава 11. Учет движения средств...................................... 545
Запись движений в регистр бухгалтерии..........................................................................646
Оперативный учет. Описание задач, решаемых регистрами накопления.....................545 Структура регистра накопления........................................................................................547 Механизмы заполнения таблиц регистров накопления в базе данных.........................550
Интерактивно: ручная операция..................................................................................................647 Программно при проведении документа.....................................................................................650 Программно без проведения документа.....................................................................................653
Запись данных в таблицу движений регистра накопления.......................................................551 Свойство «Движения» объекта документа ................................................................................552 Запись набора записей регистра без использования свойства «Движения»..........................560 Механизмы заполнения таблицы итогов регистра накопления................................................563
Получение данных из регистров накопления...................................................................568
Получение движений регистров накопления..............................................................................568 Получение остатков......................................................................................................................573
6
Чтение данных регистра бухгалтерии...............................................................................654
Таблицы регистра бухгалтерии...................................................................................................654
Вопросы производительности регистра бухгалтерии......................................................678
Физические таблицы регистра бухгалтерии...............................................................................678 Индексы таблиц итогов регистра бухгалтерии...........................................................................681 Построение виртуальных таблиц регистра бухгалтерии...........................................................684 Зависимость производительности от настроек субконто счета................................................689
Профессиональная разработка в системе «1С:Предприятие 8»
Введение
Введение От редактора
Благодарности
Идея этой книги заключается в том, чтобы собрать воедино и систематизировать наиболее важную информацию, которая может понадобиться разработчику прикладных решений «1С:Предприятия 8.2». Уровень изложения материала предполагает, с одной стороны, что разработчик уже знаком с системой «1С:Предприятие 8.2», а с другой стороны – что в этой книге он сможет найти ответ даже на довольно сложные вопросы, возникающие в процессе разработки.
Написание такой книги, как эта, всегда требует совместных усилий. Поэтому кроме авторов в ее создании приняло участие большое количество специалистов.
В одной книге, пусть даже такой большой, невозможно охватить абсолютно все ситуации, которые могут возникнуть при разработке прикладных решений. Однако на подавляющее большинство вопросов, возникающих перед разработчиками, книга дает ответы. Причем книга будет одинаково интересна как начинающим разработчикам, так и более «продвинутым». Как правило, прикладные разработчики имеют достаточно четко определенную специализацию, сосредотачивая свои усилия на решении задач одной предметной области. Вместе с этим довольно часто возникают ситуации, когда приходится осваивать «смежные» прикладные области, чтобы внести небольшие исправления в существующее решение или, наоборот, создать новую подсистему. Поэтому книга, помимо собственно глубокого изложения прикладных механизмов, содержит общие сведения как о самих механизмах, так и об автоматизируемой предметной области. Благодаря этому разработчик, хорошо знакомый с системой, но специализирующийся, например, на решении задач оперативного учета, всегда сможет быстро разобраться с задачами начисления заработной платы и понять работу механизмов, которые используются для решения этих задач. При написании этой книги мы стремились, чтобы она стала серьезным инструментом для серьезных разработчиков, книгой, к которой всегда можно обратиться в случае затруднений и которую просто интересно прочитать, чтобы узнать что-то новое о хорошо известной предметной области или познакомиться с новым взглядом на привычные вещи. От себя лично и от всех авторов этой книги хочу пожелать вам успехов в изучении системы «1С:Предприятие» и повышения вашего мастерства! Максим Радченко
Том 1
Мы выражаем признательность всем, кто высказал свои замечания по тем или иным разделам книги: Александру Алексееву, Александру Безбородову, Александру Виноградову, Андрею Волкову, Геннадию Дамье, Одею Деруту, Дмитрию Зарецкому, Сергею Копиенко, Максиму Лейбовичу, Евгению Митрошкину, Сергею Мурзину, Сергею Нуралиеву, Константину Рупасову, Павлу Чикову и Андрею Чичерину. Хочется поблагодарить Одея Дерута, Дмитрия Русанова и Виталия Филиппова, которые оказали помощь авторам в разборе сложных вопросов по реализации и функционированию системы. При создании книги с разрешения фирмы «1С» использовались материалы информационно-технологического сопровождения и материалы докладов партнерских конференций. Мы выражаем признательность авторам этих материалов и выступлений. Также мы благодарим Евгения Медведева, Сергея Позднякова и Павла Чикова, которые выступили в качестве «бета-тестеров» некоторых глав и разделов книги.
Особенности книги Существует ряд особенностей, отличающих эту книгу от других книг, посвященных системе «1С:Предприятие 8.2». Прежде всего, это освещение вопросов, которые обычно остаются в тени, когда речь идет о прикладных разработках. Например, такие вопросы, как общая концепция системы, описание используемых таблиц и принципы хранения информации системы. При описании тех или иных прикладных механизмов авторы стремились дать общее представление о механизме, его месте в системе, показать идеологию его работы. По мнению авторов, это поможет разработчику строить эффективные решения исходя из понимания идеологии работы механизма, выбирать те или иные варианты реализации, основываясь на знании принципов работы механизма.
7
Введение Довольно много внимания в книге уделено методическим вопросам разработки прикладных решений, когда разработка ведется коллективом разработчиков. Рассматривается использование механизма групповой разработки. Также излагается методика настройки производительности прикладного решения, рассматриваются конкретные шаги и инструменты, используемые на каждом из уровней, которые следует использовать в обычной практике. Применительно к методике создания прикладных решений рассматриваются механизмы интернационализации, содержащиеся в системе, их влияние и использование в каждом из элементов системы. Этот раздел дает целостное представление обо всех средствах интернационализации, которые содержит «1С:Предприятие 8.2». При подготовке этой книги были использованы самые различные источники информации: ■■ опыт преподавания на учебных курсах по платформе и прикладным решениям «1С:Предприятия 8»; ■■ опыт внедрения прикладных решений; ■■ опыт, накопленный разработчиками фирмы «1С»; ■■ материалы информационно-технологической поддержки (ИТС); ■■ материалы форума партнеров-разработчиков на http://partners.v8.1c.ru; ■■ общение на партнерских семинарах, проводимых фирмой «1С».
или доработать любую имеющуюся конфигурацию. При этом учебная версия имеет ряд технических ограничений и не может быть использована для ведения реального учета на предприятии. Ограничения учебной версии платформы перечислены на сайте http://v8.1c.ru/edu/. Для учебной версии платформы периодически выпускаются обновления с тем, чтобы она соответствовала текущим возможностям, используемым в прикладных решениях. Обновить учебную версию платформы можно через сайт поддержки пользователей. Для этого необходимо: ■■ зарегистрироваться на сайте поддержки пользователей (ввести регистрационный номер, PIN-код и другую информацию); ■■ скачать новую учебную версию платформы. Регистрационная анкета и конверт с PIN-кодом входят в состав данного продукта. Адрес сайта поддержки пользователей – http://users.v8.1c.ru. Кроме учебной версии платформы на диске содержится более шестидесяти демонстрационных конфигураций, которые используются в ходе изложения различных глав книги. Все демонстрационные конфигурации содержатся на компакт-диске в виде одного дистрибутива. После его запуска (первый пункт меню диска) шаблоны конфигураций устанавливаются в текущий каталог шаблонов. Конфигурации созданы в версии «1С:Предприятия» 8.2.15.317.
Как читать книгу
Также на компакт-диске находится электронная версия этой книги в формате PDF. Ее можно использовать для быстрого поиска в тексте книги, а также для копирования фрагментов программного кода.
Книга построена таким образом, чтобы можно было читать главы как подряд, так и выборочно.
Кроме этого, на диске содержатся вспомогательные файлы, которые используются в некоторых примерах.
Чтение глав по порядку позволяет получить целостное представление о системе и ее возможностях, постепенно переходя от общих архитектурных решений к более конкретным прикладным механизмам и их реализации. В то же время книгу можно читать отдельными главами, если требуется изучить работу какого-то конкретного прикладного механизма или понять принципы работы системных механизмов. Книга содержит достаточно подробное оглавление, что позволяет обращаться к отдельным разделам книги в тех случаях, когда нужно разобраться в конкретных особенностях работы того или иного механизма или просто освежить их в памяти.
Что находится на компакт-диске К книге прилагается компакт-диск, который содержит материалы, предназначенные для самостоятельного изучения и использования. Прежде всего, это учебная версия платформы «1С:Предприятие 8.2». Она не имеет аппаратной или программной защиты и позволяет создать
8
Скажите нам, что вы думаете В процессе подготовки этой книги мы прилагали значительные усилия для того, чтобы устранить возможные неточности и опечатки, однако не можем гарантировать их отсутствие на 100 %. Мы понимаем, сколько негативных эмоций может доставить пример, который не работает, например, потому, что в имени переменной допущена ошибка. Поэтому сообщить об обнаруженных неточностях вы можете в форуме по адресу DevTrainingForum.v8.1c.ru. Здесь же вы можете написать свои впечатления от этой книги и пожелания по ее совершенствованию. Мы ценим обратную связь с читателями, и с благодарностью примем как слова критики, так и слова одобрения и учтем их в работе над будущими изданиями.
Профессиональная разработка в системе «1С:Предприятие 8»
Платформа и прикладные решения
Глава 1. Архитектура «1С:Предприятия» Система «1С:Предприятие» в широком смысле представляет собой совокупность четырех составляющих (рис. 1.1): ■■ технологической платформы; ■■ прикладных решений различного масштаба и различной направленности, созданных на основе технологической платформы; ■■ методики создания прикладных решений; ■■ информационно-технологической поддержки пользователей и разработчиков.
Платформа и прикладные решения Основным концептуальным решением, отличающим систему «1С:Предприятие» от универсальных средств программирования, является четкое разделение на платформу и прикладное решение. Прикладное решение «1С:Предприятия» является самостоятельной сущностью и может выступать в качестве отдельного программного продукта. Однако создание, модификация и собственно функционирование прикладного решения невозможны без использования технологий и механизмов платформы. Поэтому платформа поставляется с каждым комплектом «1С:Предприятия».
Средства разработки в составе платформы Рис. 1.1. Структура «1С:Предприятия»
Такая архитектура продиктована прежде всего задачами, которые призвана решать система «1С:Предприятие». Во-первых, система должна обеспечивать высокий уровень адаптируемости прикладных решений под требования заказчика. Во-вторых, система должна обеспечивать изменение готового прикладного решения разработчиком, не участвовавшим в его создании. Это особенно важно для прикладных решений в сфере экономических задач, где существенная часть разработчиков не создает собственные прикладные решения, а дорабатывает и развивает существующие типовые решения. В-третьих, система должна обеспечивать эффективное использование компьютерных технологий и платформ, не требуя при этом глубоких специальных знаний от разработчика.
Прикладные решения «1С:Предприятия» являются открытыми. Благодаря этому клиент с помощью разработчика или собственными силами может модифицировать и настраивать любое прикладное решение под себя. Исключение составляют прикладные решения, которые выпускаются в так называемой «базовой версии». Кроме прочих ограничений это означает невозможность самостоятельной модификации прикладного решения пользователем. Для модификации прикладных решений не требуется использовать какие-либо отдельные программные продукты – все средства разработки входят в состав технологической платформы. Можно сказать, что платформа состоит из двух составляющих (рис. 1.2): ■■ среда исполнения, ■■ среда разработки.
В-четвертых, система должна обеспечивать стандартизацию разработки. Таким образом, можно сказать, что «1С:Предприятие» не является универсальным средством программирования. Система обладает достаточно широкими возможностями, однако ее архитектура и конкретная реализация механизмов и технологий платформы продиктованы прежде всего необходимостью решения специализированных задач по созданию бизнесприложений и требованиями, предъявляемыми к самой системе. Том 1
Рис. 1.2. Структура технологической платформы «1С:Предприятия»
9
Глава 1. Архитектура «1С:Предприятия» Таким образом обеспечивается высокий уровень адаптируемости прикладных решений под требования заказчика.
Среда исполнения «1С:Предприятия» исполняет, «проигрывает» метаданные, аналогично тому, как операционная система исполняет код привычной программы.
Метаданные – способ описания прикладного решения
Отличительной особенностью технологии метаданных является использование визуального конструирования прикладного решения. Вместо кропотливого написания кода разработчик просто добавляет визуальными средствами новый объект конфигурации в прикладное решение и получает сразу же описание нужных типов, структур данных, описание наборов прав, связей между объектами, информацию об особенностях их поведения, визуального представления и т. д.
Прикладное решение «1С:Предприятия» не пишется в прямом смысле слова на языке программирования. При создании прикладных решений «1С:Предприятия» используется более абстрактная технология – технология метаданных. Метаданные представляют собой иерархическую структуру объектов, полностью описывающую все прикладное решение. Эта структура называется «дерево объектов конфигурации» (рис. 1.3).
Метаданные и встроенный язык Все прикладное решение представляется не в виде строк с инструкциями на языке программирования, а в виде иерархической структуры объектов конфигурации. При этом разработчик использует встроенный язык и язык запросов для того, чтобы описать специфические алгоритмы поведения тех или иных объектов конфигурации в различные моменты исполнения прикладного решения. Использование встроенного языка при разработке прикладных решений ограничено в основном решением тех задач, которые действительно требуют алгоритмического описания, например, расчета налогов, проверки корректности введенных данных и пр. Основная же структура прикладного решения описывается структурой объектов конфигурации. Почти все объекты конфигурации содержат модули, в которых и могут быть описаны алгоритмы на встроенном языке. Эти модули будут вызываться средой исполнения в конкретные, заранее определенные моменты работы прикладного решения – события. Таким образом, можно сказать, что использование встроенного языка в прикладных решениях носит событийный характер.
Подсистемы Платформа «1С:Предприятие» позволяет выделить в прикладном решении отдельные функциональные части – подсистемы, в совокупности представляющие все прикладное решение. Подсистемы могут иметь иерархическую структуру, т. е. одна подсистема может включать в себя несколько других подсистем. Структура подсистем определяет всю функциональность прикладного решения и служит основой для построения глобального командного интерфейса приложения (рис. 1.4). Рис. 1.3. Дерево объектов конфигурации прикладного решения
10
Разработка практически любого прикладного решения начинается с проектирования состава подсистем, так как структура подсистем Профессиональная разработка в системе «1С:Предприятие 8»
Метаданные – способ описания прикладного решения (разделов в интерфейсе приложения) – это первое, что увидит пользователь при знакомстве с прикладным решением.
Каждый такой шаблон (прототип) содержит определенную базовую реализацию объекта конфигурации (рис. 1.5).
Рис. 1.5. Состав прототипа (шаблона) объекта конфигурации
Рис. 1.4. Глобальный интерфейс прикладного решения
Когда разработчик добавляет в дерево объектов конфигурации новый объект конфигурации, этот объект наследует базовую реализацию прототипа (рис. 1.6):
Каждый объект конфигурации, описывающий данное прикладное решение, может быть отнесен к одной или нескольким подсистемам. Таким образом, наличие подсистем позволяет распределить объекты конфигурации по логически связанным с ними разделам и предоставить пользователю удобный интерфейс, в котором ему будут видны только те объекты (т. е. та функциональность прикладного решения), с которыми он работает.
Создание прикладных решений на основе модели Важной особенностью системы «1С:Предприятие» является то, что для описания структуры прикладного решения разработчик использует не произвольные, а строго определенные объекты конфигурации. Платформа «1С:Предприятие» содержит ограниченный набор прототипов (шаблонов) объектов конфигурации. Среди этих шаблонов есть, например, шаблон справочника, документа, регистра накопления, бизнеспроцесса и т. д. Том 1
Рис. 1.6. Добавление нового объекта конфигурации
11
Глава 1. Архитектура «1С:Предприятия» При добавлении нового объекта конфигурации платформа основывается на «знаниях» о базовом классе объектов (рис. 1.7): ■■ платформа «знает», какие таблицы (состав полей, количество таблиц, их взаимная связь) нужно будет создать в хранилище данных при сохранении конфигурации; ■■ сразу же добавляются новые типы встроенного языка, позволяющие работать с данными создаваемого объекта, причем состав этих типов может быть разным для различных шаблонов (прототипов); ■■ сразу же создается набор прав, которые будут использоваться для данного объекта, причем наборы прав также могут быть различными для разных шаблонов (прототипов), поскольку различается их базовая функциональность; ■■ определяются стандартные действия, которые система может выполнять с данными этого объекта конфигурации; ■■ и т. д.
Объектные и необъектные данные В «1С:Предприятии» принято разделять все прикладные данные на те, которые имеют объектную природу (объектные данные) и не имеют объектной природы (необъектные данные). Примерами объектных данных могут служить данные справочников, документов. Необъектными данными являются, например, данные регистров. Подобное деление определяет два различных подхода к работе с данными. Данные, имеющие объектную природу, хранятся в базе данных в виде объектов. Например, объектом является элемент справочника или конкретный документ. Каждый объект ценен для системы уже одним фактом своего существования и имеет уникальный идентификатор – ссылку. Могут измениться любые данные объекта, но это будет все тот же объект. Удалив объект, его нельзя создать заново. Даже если для нового объекта будут установлены те же данные, это будет уже другой объект с точки зрения «1С:Предприятия», обладающий другим уникальным идентификатором. Данные, имеющие необъектную природу, хранятся в базе данных в виде записей. Каждая запись полностью описывается значениями своих полей и не имеет какого-либо уникального идентификатора. Поэтому для «1С:Предприятия» собственно факт существования записи не важен. Можно удалить запись, а затем создать новую, с такими же значениями полей – состояние базы данных с точки зрения логики прикладного решения от этого не изменится. Подробнее
Рис. 1.7. Добавление нового объекта конфигурации
Благодаря этому разработчик, не производя никаких дополнительных действий, тут же может запустить прикладное решение и работать с только что добавленным объектом – базовая реализация объекта, унаследованная от прототипа (шаблона), обеспечит выполнение всех необходимых типовых действий. Таким образом, несмотря на то, что каждое прикладное решение обладает собственной «индивидуальностью», все они созданы по определенной модели, с использованием объектов конфигурации, которые обладают одинаковой базовой реализацией. Такой подход значительно упрощает модификацию прикладных решений разработчиками, которые не участвовали в их создании.
Раздел «Объектные и необъектные данные», стр. 65.
Три способа представления данных Для всех прикладных данных (как объектных, так и необъектных) «1С:Предприятие» поддерживает три способа представления данных (рис. 1.8): ■■ хранение в базе данных, ■■ представление во встроенном языке, ■■ отображение в формате XML. В базе данных информация хранится в виде объектов базы данных или в виде отдельных записей (в зависимости от ее природы – объектной или необъектной). Данные, хранимые в базе данных, могут быть считаны в объекты встроенного языка для их просмотра или изменения и записаны обратно в базу данных.
12
Профессиональная разработка в системе «1С:Предприятие 8»
Три способа представления данных
Поддержка составных типов данных
Рис. 1.8. Три способа представления данных
В то же время объекты встроенного языка могут быть сериализованы в/из элементы/ов XML. Представление данных в формате XML используется при обмене данными в распределенных информационных базах, а также может использоваться при взаимодействии с другими информационными системами. Важно отметить, что все три способа представления данных используют одну и ту же систему понятий, благодаря чему от разработчика не требуется специальных усилий для преобразования данных из одного представления в другое.
Сквозная типизация Важной особенностью работы с данными является то, что в «1С:Предприятии» реализована общая система типов встроенного языка, полей баз данных и интерфейса. Иными словами, разработчик одинаковым образом определяет поля базы данных, переменные встроенного языка, реквизиты форм и одинаковым образом работает с ними (рис. 1.9).
Важной особенностью модели данных «1С:Предприятия» является возможность использования реквизитов объектов конфигурации, имеющих составной тип. Например, в расходной накладной в качестве покупателя может быть указано либо юридическое лицо из справочника организаций, либо физическое лицо из справочника частных лиц. Соответственно, при проектировании базы данных разработчик может определить реквизит, который будет хранить значение любого из этих типов. Подробнее
Раздел «Составной тип данных», стр. 101.
Смешанный подход к манипулированию данными «1С:Предприятие» обеспечивает два способа доступа к данным – объектный (для чтения и записи) и табличный (только для чтения). В объектной модели разработчик оперирует объектами встроенного языка. В этой модели обращения к объекту, например документу, происходят как к единому целому – он полностью загружается в память, вместе с вложенными таблицами, к которым можно обращаться средствами встроенного языка как к коллекциям записей и т. д. (рис. 1.10).
Рис. 1.9. Общая система типов
Рис. 1.10. Объектный доступ к данным
В результате разработчику не приходится заботиться о преобразованиях между типами данных, поддерживаемыми той или иной СУБД, типами, поддерживаемыми встроенным языком, и типами, используемыми для построения интерфейсных решений.
При манипулировании данными в объектной модели обеспечивается сохранение целостности объектов, кеширование объектов, вызов соответствующих обработчиков событий и т. д.
Подробнее
Раздел «Система типов», стр. 79.
Том 1
В табличной модели все множество объектов того или иного класса представляется как совокупность связанных между собой таблиц, к которым можно обращаться при помощи запросов – как к отдельной таблице, так и к нескольким таблицам во взаимосвязи (рис. 1.11).
13
Глава 1. Архитектура «1С:Предприятия»
Язык запросов Язык запросов основан на SQL, но при этом содержит значительное количество расширений, ориентированных на отражение специфики финансово-экономических задач и на максимальное сокращение усилий по разработке прикладных решений. Важной особенностью языка запросов является то, что он предоставляет доступ к данным только на чтение и использует те же типы данных, что и встроенный язык. Рис. 1.11. Табличный доступ к данным
В этом случае разработчик получает доступ к данным сразу нескольких объектов, что очень удобно для анализа больших объемов данных, например, при создании отчетов. Однако в силу того, что данные, выбираемые таким способом, содержат не все, а лишь некоторые реквизиты анализируемых объектов, табличный способ доступа не позволяет изменять эти данные. Сочетание табличного и объектного доступа к данным позволяет, с одной стороны, сделать разработку прикладных решений простой и наглядной, а с другой стороны, получать сколь угодно сложные выборки данных и использовать возможности агрегирования полученных данных.
Встроенный язык Встроенный язык имеет много общих черт с другими языками, такими как Pascal, Java Script, Basic, что облегчает его освоение начинающими разработчиками. Однако он не является прямым аналогом какого-либо перечисленного языка. Вот лишь некоторые наиболее значимые особенности встроенного языка: ■■ мягкая типизация (тип переменной определяется типом значения, которое она содержит, и может изменяться в процессе работы); ■■ отсутствие программного описания прикладных типов (они создаются при добавлении объектов метаданных); ■■ не требуется предварительное описание процедур/функций, если их вызов выполняется раньше их описания; ■■ событийная ориентированность встроенного языка; ■■ поддерживается обработка исключительных ситуаций; ■■ все операторы имеют как русское, так и английское написание, которое можно использовать одновременно; ■■ используется интерпретатор с предварительной компиляцией (перед исполнением модули, содержащие текст на встроенном языке, преобразуются во внутренний код); ■■ кеширование скомпилированных модулей в памяти.
14
Можно перечислить наиболее существенные возможности, реализуемые языком запросов: ■■ Обращение к подчиненным полям через точку. Если поля какой-либо таблицы имеют ссылочный тип (хранят ссылки на объекты другой таблицы), разработчик может в тексте запроса ссылаться на них через точку («.»). При этом количество уровней вложенности таких ссылок система не ограничивает; ■■ Обращение к вложенным таблицам (например, табличным частям документов и элементов справочников). К вложенным табличным частям можно обращаться и как к отдельным таблицам, и как к целым полям одной таблицы; ■■ Автоматическое упорядочивание. Режим автоматического упорядочивания позволяет выводить информацию в наиболее правильном («естественном») порядке; ■■ Многомерное и многоуровневое формирование итогов. Итоги и подытоги формируются с учетом группировки и иерархии, обход уровней может выполняться в произвольном порядке с подведением подытогов. Обеспечивается корректное построение итогов по временным измерениям; ■■ Поддержка виртуальных таблиц. Виртуальные таблицы, предоставляемые системой, позволяют получить практически готовые данные для большинства прикладных решений без необходимости составления сложных запросов. Например, такая виртуальная таблица может предоставить данные по остаткам товаров в разрезе периодов на какой-то момент времени. При этом виртуальные таблицы максимально используют хранимую информацию, например, ранее рассчитанные итоги и т. д.; ■■ Стандартные SQL операции. В языке запросов поддерживаются стандартные для SQL операции, такие как объединение (Union), соединение (Join) и т. д.; ■■ Использование временных таблиц. Временные таблицы позволяют повысить производительность запросов, в некоторых случаях снизить количество блокировок и сделать текст запроса более легким для восприятия; Профессиональная разработка в системе «1С:Предприятие 8»
Язык запросов ■■ Пакетные запросы. Пакетные запросы позволяют более удобно работать с временными таблицами за счет того, что создание временной таблицы и ее использование помещаются в один запрос. Пакетный запрос представляет собой последовательность запросов, разделенных символом «;». Запросы исполняются один за другим. Результатом выполнения пакетного запроса в зависимости от используемого метода будет являться либо результат, возвращаемый последним запросом пакета, либо массив результатов всех запросов пакета в той последовательности, в которой следуют запросы в пакете.
Прикладные решения, независимые от используемого хранилища данных
Пользовательский интерфейс «1С:Предприятия» можно охарактеризовать как задаче-ориентированный, позволяющий в каждом отдельном окне приложения (основном или вспомогательном) решать конкретную задачу. Основное окно приложения предназначено для навигации по прикладному решению и вызова различных команд. Вспомогательное окно предназначено для работы с объектами информационной базы (например, с документами или элементами справочников), построения отчетов или выполнения обработок данных. В основном окне приложения пользователю предоставляется вся структура прикладного решения (панель разделов) и рабочий стол (рис. 1.12).
Платформа изолирует разработчика от понятий и подробностей более низкоуровневых технологий. При создании прикладных решений разработчик «1С:Предприятия» не обращается к базе данных напрямую. Непосредственно он работает с платформой «1С:Предприятие». При этом он может: ■■ описывать структуры данных в конфигураторе; ■■ манипулировать данными с помощью объектов встроенного языка; ■■ составлять запросы к данным, используя язык запросов. Платформа «1С:Предприятие» обеспечивает операции исполнения запросов, описания структур данных и манипулирования данными, транслируя их в соответствующие команды. Это могут быть команды одной из сторонних СУБД, поддерживаемых «1С:Предприятием», в случае клиент-серверного варианта работы или команды собственной СУБД для файлового варианта работы.
Управляемый интерфейс В платформе «1С:Предприятие» реализован современный эргономичный пользовательский интерфейс, рассчитанный на комфортную работу с системой в течение продолжительного времени, в том числе и неподготовленных пользователей, имеющих небольшой опыт работы с компьютером. Удобный и интуитивно понятный интерфейс позволяет пользователям выполнять большой объем функционала, даже не пользуясь при этом инструкциями и документацией. Пользовательский интерфейс «1С:Предприятия» построен по принципу декларативного описания. Он называется «управляемым» потому, что с помощью прав и ролей пользователей, функциональных опций и настроек пользователя платформа автоматически строит командный интерфейс, управляемые формы и отчеты. Том 1
Рис. 1.12. Основное окно приложения
Рабочий стол – это стандартный раздел программы, содержащий часто используемые документы, отчеты, справочники и т. п. Этот раздел автоматически активизируется при запуске прикладного решения. Это своеобразный «помощник» пользователя. Рабочий стол вводит пользователя в курс дел, отвечает на его вопросы и позволяет ему быстро включиться в работу. Панель разделов – это наиболее крупное разделение функциональности прикладного решения. Она расположена в верхней части основного окна
15
Глава 1. Архитектура «1С:Предприятия» и соответствует верхнему уровню подсистем, добавленных в конфигурацию. С ее помощью осуществляется переход к другим разделам программы.
отчетов и обработок. Эти окна отображаются на экране компьютера независимо от основного окна приложения (рис. 1.14).
При активизации раздела вся функциональность соответствующей подсистемы, включая вложенные подсистемы, представляется пользователю в виде команд в двух панелях: панели навигации и панели действий (рис. 1.13).
Рис. 1.13. Основное окно приложения
Панель навигации содержит своеобразное «оглавление» раздела. Она включает навигационные команды, которые позволяют перейти к той или иной точке этого раздела. Как правило, это команды перехода к каким-либо спискам. При вызове навигационной команды соответствующий ей список отображается в рабочей области раздела, замещая прежнее содержимое рабочей области. Панель действий содержит наиболее востребованные в повседневной работе команды, позволяющие быстро создавать новые объекты, выполнять типовые обработки или строить популярные отчеты. Такие команды называются командами действия, поскольку их вызов приводит к открытию нового, вспомогательного окна приложения и на некоторое время переключает пользователя на выполнение другой задачи. Вспомогательные окна приложения открываются при вызове команд ввода новых и редактирования существующих объектов, а также при открытии
16
Рис. 1.14. Основное и вспомогательное окна приложения
Пользователь может открывать любое необходимое ему количество вспомогательных окон. Для удобства ввода данных и защиты от ошибок вспомогательное окно может быть открыто в режиме блокирования окнавладельца. Основное окно приложения также включает в себя главное меню системы и набор вспомогательных команд (калькулятор, календарь и пр.). А также предоставляет различные сервисные возможности, такие как: просмотр истории работы пользователя и возможность перемещаться по разделам прикладного решения, с которыми уже работал пользователь; добавление разделов, списков, объектов базы данных, отчетов и обработок в избранное; отображение в информационной панели (внизу окна) оповещений о последних действиях пользователя; возможность получить ссылку на любые разделы, списки, объекты базы данных, отчеты и обработки и перейти по полученной ссылке к этим данным и т. д. Профессиональная разработка в системе «1С:Предприятие 8»
Управляемый интерфейс
Командный интерфейс Командный интерфейс – это основное средство навигации пользователя по функциональности прикладного решения. Формирование командного интерфейса выполняется платформой автоматически в зависимости от прав пользователя, видимости команд по ролям, функциональных опций приложения и настроек самого пользователя. Глобальный командный интерфейс в системе «1С:Предприятие» строится на основе иерархии подсистем, созданных разработчиком в конфигурации. Состав подсистем верхнего уровня иерархии отражает наиболее общее разделение функциональности прикладного решения, в интерфейсе приложения он образует разделы глобального командного интерфейса. Структура подсистем определяет всю функциональность прикладного решения и служит основой для построения глобального командного интерфейса приложения (рис. 1.15).
Рис. 1.15. Глобальный интерфейс прикладного решения
Если подсистема имеет подчиненную подсистему, то для нее формируется подраздел, отображаемый группой в панели навигации раздела. Все прикладные объекты конфигурации (справочники, документы, отчеты и т. д.) привязываются разработчиком конфигурации к подсистемам. На основе этой информации (структуры подсистем и привязки объектов к подсистемам) платформа автоматически строит командный интерфейс Том 1
для пользователя. Пользователю отображается структура прикладного решения (иерархия подсистем) и предоставляются стандартные команды доступа к функциональности прикладных объектов (вызов списков справочников, документов, открытие отчетов, обработок и т. д.). При этом разработчик может по своему усмотрению отредактировать предлагаемое системой построение командного интерфейса (изменить порядок, видимость команд). Кроме того, разработчик может создать свои команды (общие для конфигурации или подчиненные прикладным объектам), которые будут включаться в командный интерфейс. При запуске прикладного решения платформа «превращает» полный командный интерфейс приложения в командный интерфейс пользователя, запустившего прикладное решение. Этот процесс включает несколько этапов (рис. 1.16): ■■ Автоматический учет ролей/прав. Прежде всего, при построении интерфейса автоматически анализируются права этого пользователя на доступ к данным. Например, из командного интерфейса исключаются команды для доступа к объектам, которые пользователю недоступны. Кроме того, в системе существует возможность установки прав на отдельные реквизиты объектов. Используя эту информацию, платформа сама исключает или делает недоступными для редактирования соответствующие поля в формах, а также исключает колонки из списков и отчетов; ■■ Видимость по умолчанию. Для различных интерфейсных элементов системы (команд, элементов формы) настраивается видимость по умолчанию для отдельных ролей. Это позволяет, в зависимости от ролей пользователя, предоставить ему наиболее важную часть функциональности. При этом у пользователя есть возможность включения видимости тех элементов, которые изначально были отключены разработчиком; ■■ Значения функциональных опций. Механизм функциональных опций позволяет определить в конфигурации ту функциональность, которая может использоваться или нет при внедрении в зависимости от потребностей конкретной организации. Различные элементы конфигурации (объекты, реквизиты, команды) могут быть привязаны к функциональным опциям. При внедрении можно управлять включением и выключением функциональных опций в конкретной информационной базе. Платформа при этом будет автоматически включать и выключать отображение всех элементов интерфейса (полей, команд, колонок списков, элементов отчетов), связанных с этими функциональными опциями; ■■ Пользовательская настройка. Платформа предоставляет пользователю возможность донастроить внешний вид командного интерфейса в соответствии со своими предпочтениями. Возможна настройка всех
17
Глава 1. Архитектура «1С:Предприятия» основных элементов интерфейса: панели разделов, рабочего стола, панели навигации и панели действий. Пользовательская настройка запоминается и учитывается при следующем запуске приложения этим пользователем.
□□ □□ □□ □□
реквизит табличной части объекта информационной базы; запись регистра информационной базы; реквизит записи регистра информационной базы; временное хранилище.
Интерактивные ссылки Эти ссылки можно запоминать для дальнейшего использования, например, чтобы быстро перейти к определенному документу. Этими ссылками можно обмениваться: например, передать сотруднику ссылку на неправильно оформленный документ. Получивший ссылку сотрудник может просто ввести текстовую ссылку, и нужный документ сразу откроется. Например, навигационная ссылка может выглядеть следующим образом (листинг 1.1). Рис. 1.16. Автоматическое формирование платформой командного интерфейса для пользователя
Подробнее
Глава 7 «Командный интерфейс прикладных решений», стр. 145.
Ссылки В системе «1С:Предприятие» реализован механизм ссылок. Значительная часть этого механизма реализована в режиме 1С:Предприятие и доступна пользователю интерактивно. В полном же объеме механизм доступен из встроенного языка. Общий смысл этого механизма заключается в том, что в режиме 1С:Предприятие можно получать текстовые ссылки на данные, хранящиеся в информационной базе, на точки навигации и на отчеты и обработки. Условно такие ссылки можно разделить на два «вида» – интерактивные и неинтерактивные: ■■ интерактивные ссылки: □□ на объекты информационной базы – на элементы справочников, документы и т. д.; □□ отчеты; □□ обработки; □□ точки навигации – на разделы, формы списков, открывающиеся в основном окне; ■■ неинтерактивные ссылки: □□ на реквизит объекта информационной базы (например, реквизит элемента справочника);
18
Листинг 1.1. Навигационная ссылка
e1cib/data/Документ.ПриходТовара?ref="a9b800055d49b45e11dbb50561cf0dac"
Правила, по которым формируются ссылки, описаны в документации. Формат текстовых ссылок соответствует стандартам RFC 1738, 1808, 2368, 2396, и для того чтобы отличать ссылки «1С:Предприятия» от других (например, http или file), используется идентификатор схемы e1c. Подробнее
Документация «1С:Предприятие 8.2. Руководство разработчика», Приложение 2 «Форматы навигационных ссылок».
Заметим, что одна и та же ссылка может быть представлена как внутренняя (относительно какой-то информационной базы) или внешняя, то есть включающая в себя сведения о конкретной информационной базе. Пример внутренней и внешней ссылки приведен в листинге 1.2. Листинг 1.2. Внутренняя и внешняя ссылка
// Внутренняя ссылка e1cib/data/Документ.ПриходТовара?ref="a9b800055d49b45e11dbb50561cf0dac" // Внешняя ссылка e1c://filev/C/Bases/Platform82Demo#e1cib/data/Документ.ПриходТовара?ref= "a9b800055d49b45e11dbb50561cf0dac"
Как видно, разница только в начальной части ссылки. У внешней ссылки добавляется идентификатор конкретной базы данных. В примере это файловая база данных (e1c://filev/), расположенная в каталоге C/Bases/Platform82Demo. Профессиональная разработка в системе «1С:Предприятие 8»
Управляемый интерфейс С точки зрения пользователя, существует три способа использования таких ссылок: ■■ любые ссылки (и внешние, и внутренние) можно добавлять в избранное, чтобы затем, при необходимости, быстро вернуться к этому документу или списку.
В диалоге получения ссылки можно сразу же скопировать ее в буфер обмена или переключить представление ссылки с внутренней на внешнюю. Чтобы перейти по полученной ссылке, нужно выполнить команду Перейти по ссылке в основном или во вспомогательном окне (рис. 1.18).
Подробнее
Раздел «Избранное», стр. 21.
■■ внутренние ссылки можно использовать внутри конкретной информационной базы. При этом не важно, каким клиентом пользователи подключены к этой информационной базе. Один пользователь может получить внутреннюю ссылку, передать ее другому пользователю, например, по электронной почте. Другой пользователь может перейти по этой ссылке; ■■ внешние ссылки задуманы для использования вне «1С:Предприятия». Внешние ссылки имеет смысл использовать только для веб-клиента. Один пользователь, подключенный к информационной базе веб-клиентом или тонким клиентом по протоколу http, может получить внешнюю ссылку и передать ее другому пользователю. Другой пользователь может ввести эту ссылку в строку веб-браузера. В результате будет запущен веб-клиент, выполнено соединение с нужной информационной базой и выполнен переход по ссылке. В режиме 1С:Предприятие ссылку можно получить по команде Получить ссылку в основном или во вспомогательном окне (рис. 1.17). Рис. 1.18. Команда «Перейти по ссылке»
Встроенный язык поддерживает работу со ссылками. Для этого в глобальном контексте есть ряд методов: ■■ ■■ ■■ ■■ ■■
ПолучитьНавигационнуюСсылку(), ПолучитьНавигационнуюСсылкуИнформационнойБазы(), ПолучитьПредставленияНавигационныхСсылок(), ПерейтиПоНавигационнойСсылке(), НайтиОкноПоНавигационнойСсылке().
Неинтерактивные ссылки Неинтерактивные ссылки предназначены для использования во встроенном языке. Например, они могут использоваться для отображения картинок в форме, когда нужная картинка находится во временном хранилище или в реквизите объекта информационной базы. Рис. 1.17. Команда «Получить ссылку»
Том 1
19
Глава 1. Архитектура «1С:Предприятия»
История Платформа «1С:Предприятие» сохраняет историю работы пользователя. При интерактивном добавлении или изменении объектов информационной базы (например, документов, элементов справочников) информация об этом автоматически сохраняется системой.
Кроме этого, последние оповещения об изменении объектов информационной базы отображаются в правой части информационной панели для быстрого доступа к ним (рис. 1.21).
Пользователь всегда может открыть список этих изменений и перейти к любому из объектов, перечисленных в этом списке. Например, для того, чтобы уточнить, правильно ли он изменил данные (рис. 1.19).
Рис. 1.19. История работы пользователя
Перейти к окну История можно с помощью кнопки История в информационной панели или через Главное меню Сервис История в основном или вспомогательных окнах приложения (рис. 1.20). Рис. 1.21. Последние измененные объекты в информационной панели
История хранится в служебной таблице информационной базы. Если один и тот же объект информационной базы изменялся несколько раз, то в истории будет храниться только одна запись о последнем изменении этого объекта. Если изменялись необъектные данные (например, запись регистра сведений), то история будет хранить записи о каждом изменении данных в ключевых полях этой записи. История хранит не более 200 записей. При добавлении новых записей в историю старые записи автоматически удаляются. Автоматически записи в историю попадают только при интерактивном изменении объектов. Если объекты изменяются программно (например, средствами встроенного языка с помощью внешней обработки), то стандартно при этом не появляется оповещение в правом нижнем углу основного окна приложения и не появляется записи в истории.
Рис. 1.20. Переход к истории работы пользователя
20
Но разработчик может при необходимости принудительно вызвать появление оповещения и может занести запись в историю работы пользователя. Профессиональная разработка в системе «1С:Предприятие 8»
Управляемый интерфейс Во встроенном языке для работы с историей используется менеджер истории работы пользователя. Его можно получить с помощью свойства глобального контекста ИсторияРаботыПользователя. Для показа оповещения используется метод глобального контекста ПоказатьОповещениеПользователя(). В качестве примера рассмотрим программное изменение элементов справочника. При программном изменении автоматически записи в историю не добавляются. Поэтому мы будем добавлять их самостоятельно, из встроенного языка. А при завершении работы выведем оповещение о том, что элементы справочника были изменены. Подробнее
Этот пример можно посмотреть в демонстрационной конфигурации «Архитектура 1С:Предприятия».
В новой информационной базе добавим в конфигурацию справочник Товары и создадим его форму списка. Расположим ее на рабочем столе. В эту форму добавим команду ИзменитьТовары. В обработчике действия команды напишем следующий код (листинг 1.3): Листинг 1.3. Обработчик команды «ИзменитьТовары»
&НаКлиенте Процедура ИзменитьТовары(Команда) Количество = ИзменитьЭлементы(); Элементы.Список.Обновить(); ПоказатьОповещениеПользователя("Обработано " + Количество + " элемента", "e1cib/navigationpoint/desktop", "Список товаров"); КонецПроцедуры
Сначала вызовем функцию ИзменитьЭлементы(). Ее пока нет, мы ее напишем позже. Она будет изменять наименование элементов справочника Товары и вернет нам количество измененных элементов. После этого мы обновим список справочника, расположенный в форме, чтобы увидеть новые наименования – Элементы.Список.Обновить(). И в заключение мы выведем оповещение, которое сообщит пользователю количество измененных элементов и будет содержать ссылку на рабочий стол – e1cib/navigationpoint/desktop, чтобы пользователь, если он находится в другом разделе программы, мог быстро перейти к рабочему столу и посмотреть выполненные изменения. Подробнее
Раздел «Ссылки», стр. 18.
Том 1
После этого добавим недостающую функцию листинг 1.4.
ИзменитьЭлементы(),
Листинг 1.4. Функция «ИзменитьЭлементы()»
&НаСервереБезКонтекста Функция ИзменитьЭлементы() Экспорт Количество = 0; Выборка = Справочники.Товары.Выбрать( , , , "Код"); Пока Выборка.Следующий() Цикл ОбъектТовар = Выборка.ПолучитьОбъект(); ОбъектТовар.Наименование = "Новый товар" + Количество; ОбъектТовар.Записать(); ИсторияРаботыПользователя.Добавить(Выборка.Ссылка); Количество = Количество + 1; КонецЦикла; Возврат Количество; КонецФункции
Функция очень простая. Выбираются все элементы справочника Товары. Каждому элементу изменяется наименование, и он записывается. После этого в историю добавляется запись об изменении этого элемента справочника – ИсторияРаботыПользователя.Добавить(Выборка.Ссылка). Функция возвращает количество измененных элементов. Теперь в результате выполнения команды ИзменитьТовары в списке справочника Товары наименования всех товаров будут изменены. Запись об изменении каждого товара будет добавлена в историю, а в конце работы будет выведено одно оповещение. Можно было бы выводить оповещения каждый раз после изменения очередного элемента справочника, но это бессмысленно, так как визуально все эти оповещения «сольются» в одно. Поэтому выводится одно «итоговое» оповещение в конце работы.
Избранное Платформа «1С:Предприятие» позволяет пользователю вести собственный список избранных ссылок. В этот список пользователь самостоятельно может добавить ссылки на точки навигации: на разделы программы, списки, открывающиеся в основном окне, отчеты, обработки и объекты информационной базы – на элементы справочников, документы и т. д. Предполагается, что пользователь будет добавлять в этот список важные для него ссылки или ссылки, которыми он часто пользуется, для того чтобы быстро переходить к ним.
21
Глава 1. Архитектура «1С:Предприятия» Подробнее
Раздел «Ссылки», стр. 18.
Также ссылки в избранное можно добавить с помощью команды главного меню – Сервис Добавить в избранное (рис. 1.24).
Чтобы увидеть список избранного, нужно открыть меню Избранное в основном или во вспомогательном окне приложения (рис. 1.22).
Рис. 1.24. Добавление ссылок с помощью команды главного меню
Рис. 1.22. Список избранного
Еще один способ добавления ссылок – с помощью кнопки Добавить в избранное, которая есть в диалогах получения ссылки и перехода по ссылке (рис. 1.25).
Ссылки в избранное можно добавить с помощью команды Добавить в избранное. Эта команда находится в меню Избранное, в области системных команд в основном и во вспомогательных окнах приложения (рис. 1.23).
Рис. 1.25. Добавление ссылки из диалога получения ссылки
Рис. 1.23. Добавление ссылок в избранное
22
Пользователь имеет возможность управлять списком избранного – менять ссылки местами, удалять ненужные ссылки. Профессиональная разработка в системе «1С:Предприятие 8»
Управляемый интерфейс Это возможно в окне настройки избранного, которое открывается по команде Настройка избранного из меню избранного основного или вспомогательного окна приложения (рис. 1.26).
Использование информации из метаданных Интерфейсные механизмы «1С:Предприятия» широко используют информацию из метаданных для того, чтобы автоматизировать процесс разработки интерфейса и уменьшить необходимость детальной настройки, выполняемой разработчиком. Объекты конфигурации имеют множество интерфейсных свойств (таких как Представление объекта, Представление списка, Маска, Формат и пр.). Настроив их, разработчик может управлять отображением объекта в интерфейсе и его интерактивным поведением в процессе работы прикладного решения.
Расширения форм и элементов управления «1С:Предприятие» использует механизм расширений форм и элементов управления. Расширения содержат набор свойств, методов и событий, которыми дополняется стандартное поведение элементов управления и формы после того, как они связываются с данными. В зависимости от того, какой тип данных отображает элемент управления или форма, платформа будет использовать то или иное расширение. Такой подход позволяет реализовывать индивидуальные особенности поведения формы и элементов управления при работе с различными типами данных. Рис. 1.26. Настройка избранного
Избранное хранится в хранилище системных настроек. Подробнее
Раздел «Настройки пользователей», стр. 380. Документация «1С:Предприятие 8.2. Руководство разработчика»: ■■ глава 5 «Объекты конфигурации», ■■ Приложение 4 «Перечень автоматически сохраняемых настроек».
Содержимым избранного можно управлять программно с помощью объекта встроенного языка ИзбранноеРаботыПользователя. Особенностью является то, что доступ к этому объекту не предоставляется через свойство глобального контекста, как, например, к истории работы пользователя. Для того чтобы получить доступ к избранному, нужно прочитать из системного хранилища настроек избранное, добавить в него новый элемент с нужной ссылкой и сохранить избранное обратно в системное хранилище настроек.
Том 1
Командный интерфейс также наряду с командами, общими для данного элемента управления или формы, содержит и индивидуальный набор команд, определяемый конкретным типом данных, с которыми связан элемент управления или форма. Например, в форме документа содержится команда Провести, а в форме справочника – нет.
Генерация форм по умолчанию Важной особенностью системы «1С:Предприятие» является механизм форм по умолчанию. Этот механизм освобождает разработчика от необходимости создания всех возможных форм для каждого объекта прикладного решения. Разработчику достаточно создать новый объект прикладного решения, а система сама сгенерирует в нужные моменты работы пользователя необходимые формы по умолчанию для работы с данными, содержащимися в этом объекте. Таким образом, разработчику нужно создавать собственные формы объектов прикладного решения лишь в том случае, если они должны иметь отличия (другой дизайн или специфическое поведение) от форм, генерируемых системой по умолчанию.
23
Глава 1. Архитектура «1С:Предприятия»
Клиентские приложения
Подключение через Интернет
Клиентское приложение – это программа, работающая на компьютере пользователя и обеспечивающая интерактивное взаимодействие системы «1С:Предприятие» с пользователем. В системе «1С:Предприятие» существуют три клиентских приложения: толстый клиент, тонкий клиент и веб-клиент.
Подключение через Интернет позволяет обеспечить удаленную online работу пользователей с информационными базами. Это возможно благодаря использованию тонкого клиента и веб-клиента. Они подключаются к специальным образом настроенному веб-серверу, который осуществляет их взаимодействие с кластером серверов «1С:Предприятия» или с файловой информационной базой (рис. 1.27).
Толстый клиент позволяет реализовывать полные возможности «1С:Предприятия», как в плане разработки, администрирования, так и в плане исполнения прикладного кода. Однако он не поддерживает работу с информационными базами через Интернет, требует предварительной установки на компьютер пользователя и имеет довольно внушительный объем дистрибутива. Тонкий клиент не позволяет разрабатывать и администрировать прикладные решения, однако может работать с информационными базами через Интернет. Он также требует предварительной установки на компьютер пользователя, но имеет значительно меньший размер дистрибутива, чем толстый клиент. Веб-клиент не требует какой-либо предварительной установки на компьютер. В отличие от толстого и тонкого клиентов, он исполняется не в среде операционной системы компьютера, а в среде интернетбраузера (Windows Internet Explorer, Mozilla Firefox, Google Chrome или Safari). В веб-клиенте невозможна разработка прикладных решений. В сводном виде возможности этих клиентских приложений можно представить следующим образом (табл. 1.1). Таблица 1.1. Возможности клиентских приложений Толстый клиент Тонкий клиент Веб-клиент
Разработка прикладных решений Работа в локальной сети Работа через Интернет Необходимость предварительной установки
Да Да Нет Да, большой дистрибутив
Нет Да Да Да, маленький дистрибутив
Нет Да Да Нет
Независимо от режима работы (толстый, тонкий, веб-клиент) вся разработка прикладного решения ведется полностью в конфигураторе «1С:Предприятия», серверный и клиентский код пишется на встроенном языке. Однако работа в конфигураторе доступна только в режиме толстого клиента, тонкий и веб-клиент поддерживают работу только в пользовательском режиме 1С:Предприятие.
Рис. 1.27. Подключение к Интернету через веб-сервер в клиент-серверном варианте работы
Прикладные решения не требуют какой-либо доработки для того, чтобы работать с ними через Интернет. И тонкий, и веб-клиент самостоятельно обеспечивают функционирование интерфейса «1С:Предприятия» на компьютере пользователя. Клиенты могут использовать различные способы выхода в Интернет. Это могут быть высокоскоростные подключения по выделенным линиям или через локальную сеть. А могут быть низкоскоростные подключения, например, через мобильное GPRS-соединение. Специально для таких случаев, когда работа с информационной базой осуществляется через низкоскоростные каналы связи, тонкий клиент и веб-клиент имеют специальный режим запуска – режим низкой скорости соединения. В результате даже на низкоскоростных каналах связи платформа обеспечивает приемлемую скорость работы пользователей.
Подробнее
Раздел «Программные компоненты клиент-серверной архитектуры «1С:Предприятия», стр. 119.
24
Профессиональная разработка в системе «1С:Предприятие 8»
Файловый и клиент-серверный варианты работы
Файловый и клиент-серверный варианты работы «1С:Предприятие» может работать в двух вариантах: ■■ файловый, ■■ клиент-серверный. И в том, и в другом варианте все прикладные решения работают полностью идентично, что позволяет выбирать один или другой вариант работы без изменения существующего прикладного решения. Файловый вариант работы рассчитан на персональную работу одного пользователя или работу небольшого количества пользователей в локальной сети. В этом варианте все данные информационной базы (конфигурация, база данных, административная информация) располагаются в одном файле – файловой базе данных. Работу с этой базой данных осуществляет файловая СУБД, разработанная фирмой «1С» и являющаяся частью платформы (рис. 1.28).
Рис. 1.29. Клиент-серверный вариант работы
Подробнее
Глава 5 «Клиент-серверный вариант работы», стр. 119.
Кластер серверов «1С:Предприятия» Кластер серверов «1С:Предприятия» – основной компонент платформы, обеспечивающий взаимодействие между пользователями и системой управления базами данных в клиент-серверном варианте работы. Наличие кластера позволяет обеспечить бесперебойную, отказоустойчивую, конкурентную работу большого количества пользователей с крупными информационными базами. Рис. 1.28. Файловый вариант работы
Такой вариант работы обеспечивает легкость установки и эксплуатации прикладного решения. При этом для работы с информационной базой не требуются дополнительные программные средства, достаточно иметь операционную систему и «1С:Предприятие». Клиент-серверный вариант предназначен для использования в рабочих группах или в масштабе предприятия. Он реализован на основе трехуровневой архитектуры «клиент-сервер» (рис. 1.29). Клиентское приложение, работающее у пользователя (толстый клиент, тонкий клиент или веб-клиент), взаимодействует с кластером серверов «1С:Предприятия», а кластер при необходимости обращается к серверу баз данных (Microsoft SQL Server, PostgreSQL, IBM DB2 или Oracle Database). При этом физически кластер серверов «1С:Предприятия» и сервер баз данных могут располагаться как на одном компьютере, так и на разных. Это позволяет администратору при необходимости распределять нагрузку между серверами.
Использование кластера серверов позволяет сосредоточить на нем выполнение наиболее объемных операций по обработке данных. Например, при выполнении даже весьма сложных запросов программа, работающая у пользователя, будет получать только необходимую ей выборку, а вся промежуточная обработка будет выполняться на сервере. Кластер серверов «1С:Предприятия» отличают следующие свойства: ■■ Масштабируемость – позволяет перераспределить нагрузку между менеджерами кластера и тем самым разгрузить главный менеджер кластера; ■■ Отказоустойчивость – позволяет обеспечить бесперебойную работу пользователей при программных и аппаратных сбоях в кластере серверов; ■■ Динамическое распределение нагрузки – автоматически переключает пользователя на более производительный рабочий процесс, что обеспечит его более эффективную работу, причем такое переключение будет совершенно незаметно для пользователя. Подробнее
Раздел «Кластер серверов», стр. 122.
Том 1
25
Глава 1. Архитектура «1С:Предприятия»
Выполнение основной функциональности на сервере Вся работа с прикладными объектами, чтение и запись базы данных выполняются только на сервере. Функциональность форм и командного интерфейса также реализована на сервере. Это позволяет увеличить производительность и надежность работы прикладного решения. На сервере выполняется подготовка данных форм, расположение элементов, запись данных форм после изменения. На клиенте отображается уже подготовленная на сервере форма, выполняется ввод данных и вызовы сервера для записи введенных данных и других необходимых действий. Командный интерфейс и отчеты также полностью формируются на сервере и отображаются на клиенте (рис. 1.30).
Использование встроенного языка на клиенте Управлять функциональностью форм можно не только на сервере, но и на клиенте. На клиенте также поддерживается работа встроенного языка, но в строго ограниченном объеме. Он используется в тех случаях, когда необходимо провести расчеты, связанные с отображенной на экране формой, например, быстро (без обращения к серверу) подсчитать сумму строки документа на основе цены и количества, задать пользователю вопрос и обработать ответ, прочитать файл из файловой системы компьютера и отправить его на сервер. Клиентские процедуры в модулях в явном виде отделяются от серверных, и в них используется ограниченный состав объектной модели встроенного языка. На клиенте не допускается непосредственная работа с базой данных, а также работа непосредственно с прикладными объектами, например, недоступны такие типы встроенного языка, как СправочникОбъект.<имя>. На клиенте невозможно использовать запросы. При необходимости вызова действий с данными в клиентском коде нужно вызывать серверные процедуры, которые, в свою очередь, будут обращаться к данным.
Поддержка различных хранилищ данных В различных вариантах работы (файловый или клиент-серверный) «1С:Предприятие» использует различные хранилища данных. В файловом варианте работы все данные информационной базы хранятся в одном файле – 1Cv8.1CD. Этот файл имеет специальный формат, поддерживаемый системой «1С:Предприятие». Рис. 1.30. Выполнение основной функциональности на сервере
При этом механизмы платформы ориентированы на минимизацию объема данных, передаваемых на клиентский компьютер. Например, данные списков, табличных частей и отчетов передаются с сервера не сразу, а по мере просмотра их пользователем или использования во встроенном языке. На сервере выполняются: запросы к базе данных, запись данных, проведение документов, различные расчеты, выполнение обработок, формирование отчетов, подготовка форм к отображению. На клиенте выполняется: получение и открытие форм, отображение форм, «общение» с пользователем (предупреждения, вопросы…), небольшие расчеты в формах, требующие быстрой реакции (например, умножение цены на количество), работа с локальными файлами, работа с торговым оборудованием.
26
В клиент-серверном варианте работы все данные хранятся в базах данных Microsoft SQL Server, PostgreSQL, IBM DB2 или Oracle Database. Бесспорным преимуществом файловой базы данных является простота ее использования и обслуживания, однако она не рассчитана на интенсивную конкурентную работу большого числа пользователей и хранение значительных объемов данных. В то же время использование сторонних СУБД, поддерживаемых «1С:Предприятием», позволяет обеспечить большую пропускную способность системы, хранение значительных объемов данных и надежность использования. Оборотной стороной этих преимуществ является более сложное, по сравнению с файловой базой данных, обслуживание и необходимость использования дополнительного программного обеспечения (в качестве сервера баз данных используются сторонние СУБД, поддерживаемые «1С:Предприятием»).
Профессиональная разработка в системе «1С:Предприятие 8»
Интернационализация
Работа под управлением различных операционных систем Архитектура «1С:Предприятия» поддерживает многоплатформенность, то есть способность системы работать под управлением различных операционных систем. Все основные компоненты платформы способны функционировать как под управлением операционной системы Windows, так и под управлением операционной системы Linux. Благодаря тому, что взаимодействие процессов между собой осуществляется по протоколу TCP/IP, в составе системы могут присутствовать компоненты с различными операционными системами. В общем случае архитектура «1С:Предприятия» позволяет смешивать в одной системе элементы, работающие под управлением различных операционных систем, например, в одной системе может работать тонкий клиент под управлением операционной системы Windows, веб-клиент под управлением Linux в интернет-браузере Mozilla Firefox и веб-клиент под управлением Windows в браузере Internet Explorer (рис. 1.31).
Обновление прикладных решений Одним из важных архитектурных решений «1С:Предприятия» является наличие механизмов обновления прикладных решений. Эти механизмы обеспечивают синхронизацию изменений, сделанных поставщиком прикладного решения, с изменениями, внесенными при внедрении на конкретном предприятии. Они предоставляют мощные функции сравнения и анализа изменений, а также средства управления их синхронизацией. Администратор или разработчик может детально настроить синхронизацию обновлений вплоть до отдельных объектов, отдельных свойств и отдельных процедур модулей. Например, если специалист, отвечающий за сопровождение прикладного решения на предприятии, отметит объекты, которые намерен поддерживать самостоятельно, они не будут в дальнейшем обновляться при установке очередного обновления от поставщика. Если объекты необходимо объединить, то для упрощения синхронизации изменений можно настроить приоритеты такого объединения. В то же время если прикладное решение не изменялось у клиента, то обновление может быть выполнено полностью в автоматическом режиме. Подробнее
Том 2, глава 21, раздел «Механизм поставки и поддержки прикладных решений».
Интернационализация Механизмы интернационализации, заложенные в технологическую платформу «1С:Предприятие», позволяют использовать различные языки, как при разработке прикладного решения, так и при работе пользователей прикладного решения. Кроме этого, на уровне технологической платформы поддерживаются национальные стандарты представления дат, чисел и т. д. Благодаря этому в «1С:Предприятии» возможно создание многоязычных прикладных решений, в которых различные пользователи работают с одной и той же информационной базой, используя интерфейсы на различных языках. Подробнее
Том 2, глава 22, раздел «Многоязычные прикладные решения».
Рис. 1.31. Элементы системы «1С:Предприятие», работающие под управлением различных операционных систем
Том 1
27
Глава 1. Архитектура «1С:Предприятия»
28
Профессиональная разработка в системе «1С:Предприятие 8»
Обзор функциональности прикладных решений
Глава 2. Функциональность «1С:Предприятия» Обзор функциональности прикладных решений
Документы
Значительная часть функциональности прикладных решений, создаваемых на платформе «1С:Предприятие», определяется теми возможностями, которые содержит базовая реализация используемых объектов конфигурации. Не претендуя на полное и глубокое изложение, рассмотрим лишь основные функциональные возможности некоторых объектов конфигурации.
Документы отражают в системе события, происходящие в жизни предприятия: поступление материалов, перечисление денег через банк, прием сотрудника на работу и т. д. Прототип (шаблон) документа обеспечивает их отражение в различных учетных механизмах, поддерживает контроль последовательности обработки событий, реализует сквозную нумерацию объектов разного типа и т. д.
Кроме этого, рассмотрим также и некоторые общие объекты технологической платформы, не реализующие конкретной прикладной специфики, но обеспечивающие важные функциональные возможности для прикладных решений.
Одним из важных функциональных механизмов системы является механизм проведения документов. Он предлагает разработчику стандартную модель организации связи между информацией о событиях, происходящих на предприятии, и различными учетными механизмами. Любая вводимая пользователем в виде документов информация может отражаться в любых учетных механизмах (планировании, управленческом учете, бухгалтерском учете и т. д.). Разработчик должен только указать в свойствах метаданных связь между документами и учетными механизмами, а также описать алгоритм проведения документа.
Справочники Справочники описывают каталоги, содержимое которых более или менее постоянно. Это может быть, например, перечень выпускаемой продукции, список клиентов компании, перечень валют и т. д. Справочники обеспечивают поддержку иерархических структур, позволяют относить данные к отдельным объектам и их группам, предоставляют ряд других сервисных возможностей. Многоуровневая иерархия, поддерживаемая справочниками, включается простой активизацией соответствующего свойства в метаданных. При этом поддержка иерархии распространяется сразу на все аспекты использования прикладного объекта. Например, прототип (шаблон) справочника обеспечивает поддержку необходимых свойств и методов в объектной модели манипулирования данными (определение уровня объекта, контроль зацикливания иерархии и т. д.). В интерфейсных механизмах реализуется представление данных в виде иерархического списка или дерева с навигацией по уровням и интерактивным изменениям иерархии. В механизмах отчетов обеспечивается формирование иерархических документов такого рода и получение многоуровневой иерархии итогов в любых отчетах, в которых объекты этого типа выступают в качестве параметров для группировки. Подробнее
Глава 9 «Хранение информации», стр. 435.
Том 1
Все необходимые действия по проведению и отмене проведения система будет выполнять автоматически. При этом системой предоставляются дополнительные возможности, такие как поддержка отражения событий в реальном времени, поддержка восстановления последовательности отражения событий, происходящих на предприятии, при изменении их задним числом и т. д. В результате предоставляется единая модель связи исходных данных и учетных механизмов, которая не просто облегчает разработку, но и обеспечивает единообразное предсказуемое поведение всех прикладных решений, что существенно облегчает их освоение и поддержку. Подробнее
Глава 10 «Документы и последовательности», стр. 495.
Механизм характеристик Механизм описания характеристик позволяет организовать хранение свойств объектов (справочников, документов и т. д.), которые еще не известны на момент разработки прикладного решения. Таким образом, например, для номенклатуры пользователь сможет самостоятельно вводить новые свойства: цвет, размер, габариты, мощность и т. д.
29
Глава 2. Функциональность «1С:Предприятия» Для каждой группы номенклатуры может быть создан свой набор свойств: для холодильников – объем морозильной камеры, число компрессоров, уровень шума; для компьютеров – объем оперативной памяти, объем жесткого диска; для одежды – размер, рост, цвет. Платформа «1С:Предприятие» позволяет описать дополнительные характеристики объектов конфигурации прямо в дереве метаданных один раз и хранить их в свойстве Характеристики. В дальнейшем на основе этих характеристик можно строить отчеты, анализировать объемы продаж, получать другую информацию для принятия решений. Подробнее
Раздел «Использование плана видов характеристик», стр. 483.
Механизм сведений Механизм хранения сведений, реализованный в платформе «1С:Предприятие», позволяет хранить в прикладном решении произвольные данные в разрезе нескольких измерений. Например, можно хранить курсы валют в разрезе валют или цены предприятия в разрезе номенклатуры и типа цен. Кроме этого, может быть задана различная периодичность хранения сведений, что позволяет хранить не только сами значения, но и историю их изменения. Подробнее
Раздел «Хранение информации в регистрах сведений», стр. 455.
Механизм учета движения средств Механизм учета движения средств (финансов, товаров, материалов и т. д.) позволяет автоматизировать такие направления, как складской учет, взаиморасчеты, планирование. Основу этого механизма составляют регистры накопления. Регистр накопления образует многомерную систему измерений и позволяет «накапливать» числовые данные в разрезе нескольких измерений. Например, в таком регистре можно накапливать информацию об остатках товаров в разрезе номенклатуры и склада или информацию об объемах продаж в разрезе номенклатуры и подразделения компании. Информация из регистров используется в основном в различных экономических и аналитических отчетах. Для более быстрого и эффективного формирования отчетов в платформе реализован механизм агрегатов для оборотных регистров накопления. Это особенно важно для больших информационных баз, содержащих сотни тысяч и миллионы записей
30
в регистрах. Используя механизм агрегатов, система автоматически оценивает интенсивность работы пользователей с теми или иными разрезами информации и на основе накопленной статистики выбирает оптимальный состав поддерживаемых агрегатов. Подробнее
Глава 11 «Учет движения средств», стр. 545.
Механизм бухгалтерского учета Механизмы бухгалтерского учета позволяют реализовать систему двойной записи бухгалтерского учета. Они не навязывают разработчику собственно принципов ведения бухгалтерского учета и позволяют создавать модели учета, применимые как в России, так и в других странах. Можно перечислить следующие основные возможности, реализуемые механизмами бухгалтерского учета: ■■ ведение многоуровневых планов счетов с произвольной иерархией, в которых поддерживается фиксированная или переменная разрядность кодов счетов; ■■ ведение аналитического учета в нескольких разрезах и уровнях; ■■ ведение учета одновременно по нескольким планам счетов; ■■ ведение консолидированного учета по нескольким юридическим лицам; ■■ возможность указания для отдельных разрезов аналитики произвольного числа видов учета, таких как количественный, суммовой, валютный учет и т. д. Подробнее
Глава 12 «Бухгалтерский учет», стр. 613.
Механизм сложных периодических расчетов Механизм сложных периодических расчетов позволяет реализовывать различные модели расчета заработной платы. Работа механизма основана на двух составляющих. С одной стороны, механизм сложных периодических расчетов содержит средства для описания различных видов расчета, которые будут использоваться в прикладном решении. Например, это могут быть такие виды расчета, как оклад, алименты, штраф и т. д. Помимо собственно описания этих видов расчета, существует возможность задать правила, по которым одни виды расчета будут влиять на другие виды расчета. Профессиональная разработка в системе «1С:Предприятие 8»
Обзор функциональности прикладных решений С другой стороны, этот механизм предоставляет возможность хранения промежуточных данных, которые используются для выполнения расчетов, и конечных результатов расчетов. Расчет зарплаты является наиболее типичным применением данного механизма, но сам механизм не имеет ориентации именно на эту задачу и успешно используется для решения других задач, требующих описания периодических расчетов со сложными взаимосвязями, например, расчета дивидендов, стоимости коммунальных услуг и т. д. Подробнее
Том 2, глава 13 «Сложные периодические расчеты».
Механизм бизнес-процессов Механизм бизнес-процессов позволяет описывать, создавать и управлять выполнением бизнес-процессов в прикладных решениях. Целью этого механизма является автоматизация цепочек связанных операций, направленных на достижение общей цели, обычно в контексте организационной структуры, определяющей функциональные роли и связи. Этот механизм включает средства для описания в прикладном решении схем бизнес-процессов и их ролевой маршрутизации для формирования заданий, выполняющихся в каждой точке маршрута, для управления бизнес-процессом и организации его связи с другими функциями прикладного решения. Важно отметить, что данный механизм предлагает готовую стратегию автоматизации совместной деятельности работников предприятия. Для описания простейших бизнес-процессов достаточно визуально задать схемы маршрута и указать условия ветвления в их узловых точках. Все остальные действия выполняются системой автоматически. При реализации сложных бизнес-процессов усилия разработчика требуются в основном для тесной их увязки с функциями прикладного решения. Подробнее
Том 2, глава 14 «Бизнес-процессы».
Механизм анализа данных и прогнозирования
Этот механизм поддерживает выполнение нескольких типов анализа данных, таких как общая статистика, поиск ассоциаций, дерево решений, поиск последовательностей, кластерный анализ. Подробнее
Том 2, глава 15 «Анализ данных и прогнозирование».
Сложные отчеты, использующие систему компоновки данных Для формирования сложных экономических и аналитических отчетов платформа «1С:Предприятие» содержит мощный и гибкий механизм – систему компоновки данных. Отчеты строятся на основе схемы компоновки данных – специального макета отчета, содержащего его декларативное описание. Схема компоновки данных создается разработчиком и содержит описание наборов данных (источников информации для отчета) и связей между ними, параметров получения данных, полей отчета и т. п., а также в ней разработчик задает стандартные настройки компоновки данных – структуру отчета, порядок, отбор и др. У каждого отчета разработчик может предусмотреть несколько вариантов настроек, представляющих данные в виде диаграммы, таблицы или группировок, имеющих другой состав полей, итогов и т. п. Разработчик может описать, какие настройки отчета будут доступны пользователю (пользовательские настройки) и какие из этих настроек будут присутствовать прямо в форме отчета (быстрые пользовательские настройки). С их помощью пользователь может настроить вариант отчета под себя и сохранить его для дальнейшего использования. Система компоновки данных предоставляет широкие возможности для настройки оформления отчета и его отдельных элементов – выбор макета оформления (в том числе и собственного), настройка вывода группировок, итогов, заголовка отчета и многое другое. Таким образом, большинство отчетов может быть описано и настроено разработчиком в схеме компоновки данных и не требует написания программного кода.
Механизм анализа данных и прогнозирования позволяет реализовывать в прикладных решениях инструменты для выявления закономерностей, которые обычно скрываются за большими объемами информации.
На основе описания в схеме компоновки данных и стандартных настроек система компоновки данных компонует отчет и выводит его пользователю в виде табличного документа (программным образом данные также можно вывести в таблицу значений, дерево значений и др.).
Например, проанализировав данные о продажах товаров, можно выявить группы товаров, которые обычно покупаются вместе, и при очередной покупке рекомендовать клиенту дополнительные товары, исходя из найденных закономерностей и тех товаров, которые клиент уже выбрал.
Пользователь может выбрать вариант отчета, являющийся с его точки зрения наиболее информативным, а может, при желании и соответствующей квалификации, задать собственные настройки и получить другой отчет, основанный на той же схеме компоновки данных.
Том 1
31
Глава 2. Функциональность «1С:Предприятия» Таким образом, система компоновки данных предоставляет пользователям возможность получать разнообразные необходимые им отчеты быстро, не обращаясь к разработчикам. Система компоновки данных позволяет использовать в отчетах произвольные характеристики объектов информационной базы, предоставляет возможность расшифровывать информацию, содержащуюся в отчете, выводить в отчет иерархические данные и многое другое. Подробнее
Том 2, глава 16 «Сложные аналитические отчеты».
Механизмы презентации текстовых и аналитических данных Технологическая платформа «1С:Предприятие» содержит целый ряд объектов, которые позволяют представлять итоговую информацию в удобном для пользователя виде, обеспечивая при этом в большей или меньшей степени интерактивное взаимодействие. Одним из мощных средств презентации любой информации и вывода ее на печать является табличный документ (рис. 2.1). Он обеспечивает не только эффективную подготовку печатных документов, но и просмотр их на экране в удобном для пользователя виде. Перечислим основные возможности табличного документа:
Рис. 2.1. Табличный документ
Используя форматированный документ, можно создавать фрагменты текста, содержащие различное шрифтовое, цветовое оформление, выравнивание, включающие картинки и гиперссылки. В основном он используется для редактирования в формах в тех случаях, когда текст должен содержать различное шрифтовое, цветовое оформление, гиперссылки и картинки. Например, в формах электронных писем (рис. 2.2).
■■ оформление отчета, включая тип и размер шрифта, цвет текста и фона, тип и цвет рамки, рисунки и т. д.; ■■ использование группировок (как вертикальных, так и горизонтальных), с помощью которых можно отражать промежуточные итоги; ■■ поддержка механизма расшифровок, когда при щелчке на строке или ячейке отчета формируется более детальный отчет или открывается объект базы данных; ■■ использование примечаний, содержащих дополнительную информацию о данных, расположенных в ячейке или области документа; ■■ поддержка сводных таблиц, которые позволяют отобразить многомерные данные в виде плоской таблицы с вложенными заголовками; ■■ поддержка диаграмм различного вида для наглядного представления экономической информации в графическом виде; ■■ возможность сохранения табличного документа в различных форматах; ■■ и др. Рис. 2.2. Форматированный документ
32
Профессиональная разработка в системе «1С:Предприятие 8»
Обзор функциональности прикладных решений Для представления итоговых данных в разрезе их географического положения в «1С:Предприятии» используется специальный объект – географическая схема (рис. 2.3). Она позволяет создавать отчеты, иллюстрирующие, например, объемы продаж тех или иных товаров в различных регионах страны. Также географическая схема может быть использована просто для отображения тех или иных географических данных, например, схемы проезда к офису или маршрута движения транспортного средства.
Рис. 2.3. Географическая схема
■■ ■■ ■■ ■■
круговая (обычная и объемная); биржевая (обычная и «свеча»); изометрическая (обычная, непрерывная и т. д.); поверхностная (каркасная, выпуклая, вогнутая поверхность, сотовая и др.); ■■ радарная (с областями, с накоплением, нормированная и др.); ■■ измерительная диаграмма.
Рис. 2.4. Графическая схема
Графическая схема (рис. 2.4) позволяет создавать различные организационные, структурные и другие схемы для графического оформления прикладного решения. Она предназначена для оформления форм и отчетов, в которых требуется представить те или иные организационные процессы, блок-схемы и пр. Кроме этого, графическая схема может быть использована как отдельный документ, являющийся частью оформления прикладного решения. С помощью графических схем удобно создавать иллюстрации, поясняющие состав тех или иных алгоритмов, структуру тех или иных процессов, организационные схемы и пр. Еще одним объектом, используемым для графического представления данных, является диаграмма (рис. 2.5). Платформа «1С:Предприятие» поддерживает работу с различными видами диаграмм, в том числе: ■■ график (обычный, по шагам, с областями и т. д.); ■■ гистограмма (обычная, с накоплением, объемная и т. д.); Том 1
Рис. 2.5. Круговая объемная диаграмма
33
Глава 2. Функциональность «1С:Предприятия» Диаграммы акцентируют внимание пользователя на динамике изменения данных и помогают быстро производить относительное сравнение данных. Кроме этого, специализированные виды диаграмм могут отражать закономерности, обычно скрытые за большими объемами данных. Одним из специальных видов диаграмм, поддерживаемых платформой, является диаграмма Ганта (рис. 2.6). Она содержит набор интервалов, расположенных на оси времени, и отражает использование объектами (точками) ресурсов (серий). Этот вид диаграммы широко используется для визуализации хода выполнения задач, планирования ресурсов, графика рабочего времени и других данных, которые представляются не конкретными числовыми значениями, а набором временных интервалов.
В системе «1С:Предприятие» имеется целый набор средств, с помощью которых можно: ■■ создавать, обрабатывать и обмениваться данными различных форматов; ■■ осуществлять доступ ко всем объектам системы «1С:Предприятие», реализующим ее функциональные возможности; ■■ поддерживать различные протоколы обмена; ■■ поддерживать стандарты взаимодействия с другими подсистемами; ■■ разрабатывать собственные интернет-решения. Механизмы обмена данными позволяют создавать территориально распределенные информационные системы на основе: ■■ «1С:Предприятия»; ■■ других информационных систем, не основанных на «1С:Предприятии». Обмен данными в системе «1С:Предприятие» реализуется благодаря использованию ряда средств технологической платформы, которые разработчик может применять как по отдельности, так и в различных комбинациях, в зависимости от конкретной решаемой задачи. Такой подход позволяет обеспечить гибкость механизмов обмена и их «настраиваемость» на решение как можно большего круга задач.
Рис. 2.6. Диаграмма Ганта
Диаграмма Ганта имеет гибкую структуру данных. Как точки, так и серии представляют собой иерархические коллекции, что позволяет, например, представить проект как набор связанных иерархических задач. Поддерживается возможность установки связей между различными интервалами диаграммы. Таким образом, окончание одного интервала может быть связано с началом следующего интервала диаграммы. Также поддерживается возможность интерактивного перемещения и растягивания интервалов диаграммы в режиме 1С:Предприятие при помощи мыши. Подробнее
Том 2, глава 17 «Средства графического представления данных».
Средства интеграции и механизмы обмена данными Система «1С:Предприятие» является открытой системой благодаря тому, что технологическая платформа предоставляет возможности для интеграции практически с любыми внешними программами и оборудованием на основе общепризнанных открытых стандартов и протоколов передачи данных.
34
Подробнее
Том 2, глава 18 «Интеграция с другими информационными системами», глава 19 «Обмен данными».
Web-сервисы Механизм Web-сервисов позволяет использовать систему «1С:Предприятие» как набор сервисов в сложных распределенных и гетерогенных системах, а также позволяет интегрировать ее с другими информационными системами с использованием сервис-ориентированной архитектуры (SOA). Конфигурация системы «1С:Предприятие» может экспортировать свою функциональность через Web-сервисы. Web-сервисы определяются в дереве объектов конфигурации и становятся доступны произвольным информационным системам после их публикации на веб-сервере. Кроме того, система «1С:Предприятие» может обращаться к Webсервисам сторонних производителей как через статические ссылки на Web-сервисы, определенные в дереве объектов конфигурации, так и используя динамические ссылки на Web-сервисы, создаваемые с помощью встроенного языка. Подробнее
Том 2, глава 18, раздел «Web-сервисы».
Профессиональная разработка в системе «1С:Предприятие 8»
Обзор функциональности прикладных решений
Web-расширение Одним из средств интеграции, позволяющим расширить сферу применения «1С:Предприятия», является Web-расширение. Данный программный продукт позволяет организовать доступ через веб-интерфейс к функциональности прикладных решений новых категорий пользователей, в том числе и тех, у которых на компьютерах не установлена платформа «1С:Предприятие». Это могут быть мобильные пользователи, сотрудники территориально удаленных подразделений, посетители интернет-магазинов и веб-порталов. Web-расширение позволяет встраивать доступ к данным «1С:Предприятия» в существующие веб-сайты и веб-приложения и создавать готовые веб-приложения и веб-сервисы, использующие информационную базу «1С:Предприятия». Механизмы Web-расширения могут использоваться для решения задач нескольких уровней, в различных комбинациях с другими системами: ■■ реализация веб-доступа к информационной базе «1С:Предприятия»; ■■ встраивание прикладной функциональности «1С:Предприятия» в существующие сайты; ■■ организация доступа к данным «1С:Предприятия» для решения других задач; ■■ организация программного доступа к «1С:Предприятию» из других систем. Подробнее
Том 2, глава 20 «Web-расширение».
Механизм полнотекстового поиска Механизм полнотекстового поиска предоставляет возможность пользователю быстро находить нужную информацию в информационной базе и в справочной системе. Например, позволяет найти все вхождения заданного слова или сочетания слов в данных информационной базы, при этом найденные слова выделяются цветом (рис. 2.7). Механизм полнотекстового поиска основан на использовании двух составляющих: ■■ полнотекстового индекса, ■■ средств выполнения полнотекстового поиска. Поиск осуществляется по тем данным, которые содержатся в полнотекстовом индексе. Полнотекстовый индекс создается один раз и затем должен периодически обновляться (в зависимости от частоты модификации информационной базы). Создание и обновление полнотекстового индекса может выполняться как интерактивно, в режиме 1С:Предприятие, так и программно, средствами встроенного языка. Том 1
Рис. 2.7. Поиск данных в информационной базе
В процессе работы информационной базы система отслеживает факт изменения данных в тех объектах конфигурации, которые могут участвовать в полнотекстовом поиске. Такими объектами являются, например, планы обмена, справочники, документы, планы видов характеристик, планы счетов, планы видов расчета, регистры (сведений, накопления, бухгалтерии, расчета), бизнес-процессы и задачи. Впоследствии при создании или обновлении полнотекстового индекса система анализирует данные, содержащиеся в реквизитах этих объектов, и включает эти данные в полнотекстовый индекс. При этом система «1С:Предприятие» позволяет осуществлять выборочное включение данных прикладных объектов и их реквизитов в полнотекстовый поиск. Также существует возможность ограничить область поиска данными только указанных объектов конфигурации. Собственно полнотекстовый поиск выполняется средствами встроенного языка, например, с помощью обработки. Полнотекстовый поиск выполняется в соответствии с правами пользователя. Таким образом, если какая-то информация недоступна данному пользователю, он не сможет получить ее и при помощи полнотекстового поиска. Результаты полнотекстового поиска возвращаются порциями, и, кроме того, они отсортированы в определенном порядке. Это сделано для того, чтобы с большой долей вероятности пользователь получал требуемые ему данные в начале первой порции результатов поиска.
35
Глава 2. Функциональность «1С:Предприятия» Механизм полнотекстового поиска предоставляет возможность нечеткого поиска с указанием порога нечеткости, выполнения поиска с учетом синонимов русского, английского и украинского языков, возможность использования дополнительных словарей полнотекстового поиска и многое другое.
Механизм криптографии Механизм криптографии позволяет прикладным решениям использовать криптографические операции для обработки данных, хранящихся в информационной базе. Криптографические операции включают методы зашифровывания/расшифровывания информации, системы электронной цифровой подписи и др. Таким образом, с помощью механизма криптографии система «1С:Предприятие» обеспечивает высокую конфиденциальность и аутентичность информации, хранящейся в информационной базе. Механизм криптографии не содержит собственных алгоритмов криптографии, но при этом обеспечивает набор объектов, позволяющих взаимодействовать с внешними модулями криптографии сторонних производителей – криптопровайдерами. Для взаимодействия с криптопровайдерами в операционной системе Windows используется интерфейс CryptoAPI. Таким образом, прикладные решения могут взаимодействовать с любыми криптопровайдерами, поддерживающими этот криптографический интерфейс. Для взаимодействия с модулями криптографии в операционной системе Linux используется непосредственное взаимодействие с установленными компонентами.
Механизм разделения данных Этот механизм позволяет, например, хранить в одной информационной базе данные нескольких независимых друг от друга организаций. При этом для работы с этими данными используется одна и та же конфигурация, находящаяся в этой же информационной базе. Механизм позволяет разделять данные как полностью, так и частично. Например, какая-то информация может быть общей для всех организаций (справочник банков), а какая-то – индивидуальной, видимой и доступной только данной конкретной организации. Например, информация о хозяйственной или финансовой деятельности. Такой подход значительно облегчает администрирование и обновление прикладных решений в тех случаях, когда одно и то же прикладное решение используется для ведения учета разных организаций. Например, когда фирма оказывает услуги по ведению бухгалтерского учета для многих небольших организаций, не имеющих собственной бухгалтерии.
36
Внешние источники данных Платформа «1С:Предприятие» позволяет работать с внешними источниками данных. Это может быть необходимо для использования средств платформы для работы с базами данных, уже существующими на предприятии или для разработки прикладных решений, которым нужно получать данные из внешних баз данных. Механизм работы с внешними источниками данных позволяет получать данные из различных ODBC-источников. При этом в случае получения данных из СУБД, поддерживаемых «1С:Предприятием» (SQL Server, PostgreSQL, IBM DB2 или Oracle Database), обеспечиваются полные возможности платформы в построении запросов, отчетов и т. д. В случае использования ODBC-источников для других СУБД эти возможности могут быть ограничены стандартами самой СУБД. Внешние источники данных описываются в конфигураторе в отдельной ветви объектов конфигурации. Каждый объект, описывающий внешний источник данных, включает таблицы, поля и связи между таблицами. Внешние источники данных поддерживаются в большинстве механизмов платформы: запросы, отчеты, основанные на системе компоновке данных, динамические списки, управляемые формы, встроенный язык и др. Данные внешних источников могут использоваться только на чтение и не могут быть изменены из встроенного языка. Реквизиты объектов конфигурации (например, реквизит справочника) могут иметь ссылочный тип и ссылаться на объектную таблицу внешнего источника данных. При подключении к внешнему источнику данных используются параметры соединения, которые задаются в параметрах сеанса, параметрах пользователя или в общих параметрах. Для управления процессом подключения/отключения и настройкой параметров соединения используется стандартная обработка Управление внешними источниками данных. Кроме того, подключение к внешнему источнику данных выполняется автоматически при обращении к данным внешнего источника, например, при выполнении запроса.
Обзор функциональности средств разработки Состав средств разработки достаточно широк и разнообразен. Это позволяет выполнять полный цикл действий, от создания конфигурации и до получения тиражируемого дистрибутива прикладного решения, не прибегая к помощи каких-либо продуктов сторонних производителей (рис. 2.8). Перечислим основные средства, используемые при разработке прикладных решений «1С:Предприятия». Профессиональная разработка в системе «1С:Предприятие 8»
Обзор функциональности средств разработки Дерево объектов конфигурации является одним из основных инструментов для работы с конфигурацией. Оно представляет состав конфигурации в виде древовидной структуры, каждая ветвь которой описывает определенную составляющую конфигурации и позволяет выполнять различные действия над отдельными объектами конфигурации. Окно редактирования объекта конфигурации позволяет выполнять в числе прочего последовательную установку свойств объекта, что удобно (особенно для начинающих разработчиков), т. к. позволяет задать в первую очередь те свойства объекта, которые могут определять наличие или отсутствие других свойств объекта. Палитра свойств также предоставляет возможность изменять свойства объекта и получать быстрый доступ к информации, связанной с данным объектом. Палитра свойств удобна в использовании для опытных разработчиков, а также тогда, когда необходимо просмотреть или изменить одноименные свойства у различных объектов конфигурации. Окно Дополнительно служит для отображения в едином списке свойств объекта, относящихся к различным объектам конфигурации. В этом окне можно настраивать вхождение команд объекта в командный интерфейс, просматривать и изменять включение объекта конфигурации в подсистемы, редактировать связи с функциональными опциями, настраивать права и выполнять другие действия.
Конструкторы и редакторы В состав средств разработки входит довольно большое количество конструкторов и редакторов. Конструкторы позволяют автоматизировать и облегчить создание некоторых часто используемых элементов прикладного решения, модификация которых может быть формализована. Как правило, эти элементы прикладного решения могут быть созданы и без использования конструктора, но конструктор позволяет сделать это быстрее и легче. Рис. 2.8. Состав средств разработки
Объекты конфигурации и инструменты для их редактирования Прежде всего, это, конечно же, сами объекты конфигурации и инструменты для их редактирования – дерево объектов конфигурации, окно редактирования объекта конфигурации, палитра свойств и окно Дополнительно. С помощью этих инструментов выполняется добавление, удаление объектов конфигурации, изменение их свойств, установка связей с другими объектами конфигурации и пр. Том 1
Например, текст запроса может быть полностью написан самим разработчиком. Для этого разработчик должен хорошо знать синтаксис языка запросов и понимать назначение различных предложений языка запросов. В то же время текст запроса можно создать с помощью конструктора запросов. При этом используется визуальное конструирование запроса, когда с помощью мыши необходимо выбрать и перетащить нужные таблицы, поля, установить связи между ними и т. д. После нажатия кнопки ОК конструктор запроса создаст синтаксически верный текст запроса. Кроме того, можно использовать конструктор запроса с обработкой результата, который позволяет создать готовый фрагмент кода для получения данных с помощью запроса и вывода их, например, в табличный документ.
37
Глава 2. Функциональность «1С:Предприятия» Можно перечислить, например, следующие конструкторы, присутствующие в интерфейсе разработки и администрирования: ■■ ■■ ■■ ■■ ■■ ■■ ■■ ■■ ■■ ■■ ■■ ■■ ■■ ■■
конструктор запроса, конструктор запроса с обработкой результата, конструктор движений регистров, конструктор печати, конструктор ввода на основании, конструктор форм объектов конфигурации, конструктор макета, конструктор форматной строки, конструктор строк на разных языках, конструктор агрегатов, конструктор схемы компоновки данных, конструктор настроек компоновки данных, конструктор макета оформления компоновки данных, конструктор ограничения доступа к данным.
Редакторы позволяют создавать и изменять элементы прикладного решения, модификацию которых затруднительно формализовать или для которых подобная формализация не имеет практического смысла. Например, конструктор форм объектов конфигурации позволяет создать некоторую типовую форму объекта, разместить на ней необходимые поля, назначить источники данных и т. д. Этот процесс легко формализуется и потому может быть выполнен конструктором. Однако дальнейшее редактирование формы, как правило, является процессом творческим и формализации не поддается. Поэтому платформа предоставляет в распоряжение разработчика редактор форм, с помощью которого он придает форме нужный вид, располагает дополнительные элементы управления, настраивает при необходимости привязки и т. д. в соответствии с конкретным назначением формы. Можно перечислить, например, следующие редакторы, реализованные в интерфейсе разработки и администрирования: ■■ ■■ ■■ ■■ ■■ ■■ ■■
редактор форм, редактор текстов и модулей, редактор командного интерфейса конфигурации, редактор рабочей области рабочего стола, редактор командного интерфейса рабочего стола, редактор командного интерфейса, редактор «Все подсистемы»,
38
■■ ■■ ■■ ■■ ■■ ■■ ■■
редактор роли, редактор «Все роли», редактор «Все ограничения доступа», редактор табличных документов, редактор графической схемы, редактор картинок, HTML-редактор.
Синтакс-помощник Синтакс-помощник позволяет получать справку по использованию конструкций встроенного языка, свойствам, методам и событиям объектов встроенного языка (как поставляемых непосредственно платформой, так и создаваемых наследованием от прототипов объектов конфигурации), а также справку по составу таблиц, являющихся источниками данных в языке запросов. Синтакс-помощник может быть использован как самостоятельно, так и в связке с редактором текстов и модулей. Находясь в тексте модуля, можно, используя сочетание клавиш, перейти к описанию соответствующего свойства, метода, функции и т. д. в синтакс-помощнике, а конструкции встроенного языка, описанные в синтакс-помощнике, в свою очередь, могут быть перенесены в текст модуля с помощью мыши.
Отладчик и режим замера производительности Среди средств разработки, используемых наиболее часто и интенсивно, можно отметить также отладчик и режим замера производительности. Отладчик позволяет проанализировать работу прикладного решения, выполнить остановку в указанном месте кода на встроенном языке, просмотреть значения переменных, состояние используемых объектов в определенные моменты работы, выполнить фрагмент кода по шагам и т. д. Режим замера производительности используется для того, чтобы проанализировать эффективность выполнения участка кода, узнать время, затраченное на выполнение каждой строки этого участка кода (как абсолютное, так и относительное, в процентах к общему времени выполнения всего участка). Таким образом можно определить операторы, выполнение которых занимает основное количество времени, и попытаться оптимизировать используемый алгоритм. Подробнее
Том 2, глава 22, раздел «Отладка прикладных решений».
Профессиональная разработка в системе «1С:Предприятие 8»
Обзор функциональности средств разработки
Проверка конфигурации
Групповая разработка прикладных решений
Режим проверки конфигурации позволяет выявить ошибки, которые не являются критичными для функционирования прикладного решения в принципе, но наличие которых может существенно снизить скорость работы прикладного решения или даже привести к возникновению ошибок при работе в некоторых специальных режимах. Использование этого режима не является обязательным, но может оказаться очень полезным, например, для проверки конфигурации перед поставкой заказчику, перед выпуском тиражного решения, для проверки после массированного удаления объектов или после объединения конфигураций.
Механизм групповой разработки позволяет вести и версионировать разработку прикладных решений группе разработчиков, внося изменения в конфигурацию одновременно, по мере выполнения каждым из них своего участка работы.
Сравнение/объединение конфигураций
Механизм поставки и поддержки прикладных решений служит для автоматизации процесса поддержки разработчиками прикладного решения, используемого пользователем. Задача поставки и поддержки заключается в создании новых версий прикладного решения и обновления той версии прикладного решения, которая находится у пользователей.
Механизм сравнения/объединения конфигураций позволяет выполнять, например, детальный анализ отличий между разными версиями одного и того же прикладного решения. Также с помощью этого механизма можно выполнять переход от одной версии прикладного решения к другой версии того же или другого прикладного решения. При этом разработчик имеет возможность задать различные правила объединения для различных элементов прикладного решения, указывая, какой элемент должен быть взят из новой версии, какой оставлен без изменений, а какие элементы, например, должны быть объединены и содержать как старый, так и новый варианты. После нажатия кнопки Выполнить платформа автоматически выполнит объединение в соответствии с правилами, заданными разработчиком. Использование механизма сравнения/объединения конфигураций позволяет избежать ручной модификации конфигурации (и связанного с этим большого количества ошибок) при переносе изменений из одной конфигурации в другую, а также значительно ускорить этот процесс.
Редактирование текстов интерфейса Платформа «1С:Предприятие» позволяет создавать многоязычные прикладные решения, в которых каждый пользователь может работать с интерфейсом на своем родном языке. Для того чтобы помочь разработчику при создании многоязычных прикладных решений, в состав средств разработки входит механизм редактирования текстов интерфейса. Этот механизм позволяет найти и сгруппировать все вхождения той или иной строки в конфигурации и в одно нажатие заменить их или добавить аналог этой строки на другом языке. Кроме этого, механизм позволяет переносить строки на разных языках из одного прикладного решения в другое. Подробнее
Том 2, глава 22, раздел «Редактирование текстов интерфейса».
Том 1
Подробнее
Том 2, глава 22, раздел «Групповая разработка прикладных решений».
Поставка и поддержка прикладных решений
Подробнее
Том 2, глава 21, раздел «Механизм поставки и поддержки прикладных решений».
Создание дистрибутивов Механизм создания дистрибутивов позволяет разработчику создать комплект поставки – набор файлов, предназначенных для установки на компьютере пользователя. Комплект поставки включает в себя программу установки Setup.exe и набор файлов поставки, сжатых в архив. Для установки прикладного решения пользователю достаточно запустить на своем компьютере программу установки, входящую в комплект поставки, и следовать инструкциям, появляющимся на экране. Программа установки имеет стандартный интерфейс и помогает пользователю установить все компоненты прикладного решения. Подробнее
Том 2, глава 21, раздел «Механизм создания комплектов поставки».
Функциональные опции Функциональные опции позволяют разработчику выделить некоторую часть функциональности прикладного решения, которую можно оперативно включать или выключать на этапе внедрения и/или в процессе работы системы. Объекты конфигурации и их реквизиты можно привязать к функциональным опциям, добавленным в конфигурацию. Отображение этих
39
Глава 2. Функциональность «1С:Предприятия» объектов в интерфейсе приложения зависит от того, включена связанная с ними функциональная опция или нет. Функциональные опции могут использоваться с параметрами. В этом случае вид конкретной формы может зависеть от значения параметра, выбранного в форме. Таким образом, в зависимости от потребностей конкретной организации внедренец или администратор прикладного решения в режиме 1С:Предприятие может включить или выключить определенные функциональные опции, ограничив тем самым функциональность прикладного решения задачами, решаемыми конкретным пользователем.
Показатели производительности и режим имитации задержек при вызове сервера В процессе отладки и работы конфигурации разработчик может использовать показатели производительности и режим имитации задержек при вызове сервера в качестве инструментов для оптимизации клиентсерверного взаимодействия в разрабатываемом прикладном решении. Показатели производительности прикладного решения позволяют разработчику оценить, насколько эффективно работает прикладное решение. Они отражают информацию о количестве текущих и накопленных вызовов сервера, длительности вызовов сервера, объеме принятых и отправленных данных. Окно показателей производительности всплывает в левом нижнем углу монитора при выполнении каких-либо действий, приводящих к вызову сервера в процессе работы «1С:Предприятия». Это окно можно мышью перетащить в любое другое место экрана. При запуске сеанса «1С:Предприятия» из конфигуратора отображение показателей производительности включено по умолчанию. В текущем сеансе в режиме 1С:Предприятие также можно включить отображение окна показателей производительности. Установить данный режим можно также при запуске «1С:Предприятия» из командной строки с соответствующим параметром. Режим имитации задержек при вызове сервера позволяет разработчику оценить реальную скорость работы его прикладного решения у клиента. При включении этого режима платформа (даже в файловом варианте на локальном компьютере) будет работать с теми временными задержками, с которыми работает реальный канал связи. Установка режима имитации задержек при вызове сервера позволяет разработчику превратить быстрый канал связи в медленный. Причем сделать это можно как при запуске приложения в настройках конфигуратора, так и в процессе его работы в режиме 1С:Предприятие. При этом режим,
40
в котором было запущено приложение, не изменится. Однако включить режим имитации задержек при вызове сервера можно только для тонкого клиента и толстого клиента, запущенного в режиме управляемого приложения. Установить данный режим можно также при запуске «1С:Предприятия» из командной строки с соответствующим параметром. Подробнее
Раздел «Инструменты, используемые при оптимизации клиентсерверного взаимодействия», стр. 392.
«1С:Библиотека стандартных подсистем 8.2» «1С:Библиотека стандартных подсистем 8.2» (БСП) – это инструмент, облегчающий разработку прикладных решений. Она содержит набор универсальных функциональных подсистем и технологию для разработки прикладных решений на платформе «1С:Предприятие 8.2». С помощью библиотеки стандартных подсистем можно быстро создавать новые конфигурации с уже готовой базовой функциональностью, а также включать готовые функциональные блоки в существующие конфигурации. Подсистемы, содержащиеся в библиотеке стандартных подсистем, включают различные области разработки: администрирование информационной базы, администрирование пользователей системы, настройка доступа к данным информационной базы, ведение различной нормативносправочной информации (адресный классификатор, курсы валют, календарные графики и пр.). БСП предоставляет базовые пользовательские и программные интерфейсы для работы с задачами и бизнес-процессами, прикрепляемыми файлами и электронными цифровыми подписями, контактной информацией, дополнительными реквизитами и сведениями, почтовыми сообщениями и пр. Они могут быть использованы в разрабатываемой конфигурации как все вместе, так и по отдельности.
Обзор функциональности средств администрирования Средства администрирования, входящие в состав интерфейса разработки и администрирования, позволяют управлять составом пользователей информационной базы, осуществлять регламентные операции по ее обслуживанию и выполнять другие административные действия (рис. 2.9). Перечислим основные средства, используемые для администрирования информационных баз «1С:Предприятия».
Профессиональная разработка в системе «1С:Предприятие 8»
Обзор функциональности средств администрирования Система поддерживает два вида аутентификации: аутентификация «1С:Предприятия» и аутентификация операционной системы, которые могут использоваться в зависимости от конкретных задач, стоящих перед администратором информационной базы. В случае аутентификации средствами «1С:Предприятия» в конфигураторе для каждого пользователя в списке задается пароль. Для выполнения аутентификации средствами «1С:Предприятия» пользователь при начале работы с прикладным решением должен выбрать (или ввести) имя пользователя и соответствующий этому имени пароль. В случае аутентификации средствами операционной системы в конфигураторе для пользователя выбирается один из пользователей операционной системы. Система анализирует, от имени какого пользователя операционной системы выполняется подключение к прикладному решению, и на основании этого определяет соответствующего пользователя «1С:Предприятия». При этом диалог аутентификации «1С:Предприятия» не отображается, если не указан специальный параметр командной строки.
Механизм заданий
Рис. 2.9. Состав средств администрирования
Список пользователей Платформа «1С:Предприятие» позволяет вести список пользователей, которым разрешена работа с данной информационной базой. Этот список не является частью прикладного решения, а создается отдельно, в каждой конкретной организации, в которой используется прикладное решение. Существует возможность добавлять, удалять пользователей системы, назначать им различные виды аутентификации, набор ролей, доступных в системе, режим запуска приложения, язык пользователя и пр.
Механизмы аутентификации Механизм аутентификации позволяет определить, кто именно из пользователей, перечисленных в списке пользователей, подключается к прикладному решению. Эта информация может быть в дальнейшем использована для выбора соответствующего командного интерфейса пользователя, разрешения доступа к той или иной информации и пр. Том 1
Механизм заданий предназначен для выполнения административных действий по расписанию. Механизм заданий включает в себя фоновые и регламентные задания. Каждое задание представляет собой некоторую последовательность действий, описанных с помощью встроенного языка, содержащуюся в общих модулях. Фоновые задания позволяют инициализировать выполнения процедур общих модулей асинхронно (без ожидания завершения). Регламентные задания позволяют организовать автоматический вызов процедур общих модулей по расписанию. Механизм фоновых заданий реализуется средствами встроенного языка. Регламентные задания описываются на этапе конфигурирования и являются составной частью конкретного прикладного решения.
Система прав доступа Для каждого конкретного прикладного решения система «1С:Предприятие» позволяет описать наборы прав, соответствующие должностям пользователей или виду деятельности. Структура прав определяется конкретным прикладным решением. Все права, поддерживаемые системой «1С:Предприятие», можно разделить на две большие группы: основные и интерактивные. Основные права описывают действия, выполняемые над элементами данных системы или над всей системой в целом, и проверяются всегда, независимо от способа
41
Глава 2. Функциональность «1С:Предприятия» обращения к данным. Интерактивные права описывают действия, которые могут быть выполнены пользователем интерактивно. Соответственно, проверяются они только при выполнении интерактивных операций стандартными способами, причем в клиент-серверном варианте все проверки прав (кроме интерактивных) выполняются на сервере.
какие документы изменялись определенным пользователем в заданный промежуток времени. Также журнал регистрации может быть полностью или частично выгружен в формат XML для программного анализа.
Ограничение прав на уровне записей и полей
Команды загрузки/выгрузки информационной базы позволяют сохранить информационную базу в файл на диске или загрузить информационную базу из файла. Эти команды используются, например, для того, чтобы перенести базу из файлового варианта в клиент-серверный и обратно.
Среди действий над объектами, хранящимися в базе данных, есть действия, отвечающие за чтение или изменение информации, хранящейся в базе данных. К таким действиям относятся: ■■ чтение – получение записей или их фрагментов из таблицы базы данных; ■■ добавление – добавление новых записей без изменения существующих; ■■ изменение – изменение существующих записей; ■■ удаление – удаление некоторых записей без внесения изменений в оставшиеся. Для этих действий могут быть заданы дополнительные условия на данные (ограничение доступа к данным). В этом случае над конкретным объектом, хранимым в базе данных, может быть выполнено запрошенное действие только в том случае, если ограничение доступа к данным для данных этого объекта принимает значение Истина. Аналогичные условия могут быть заданы и для таблиц базы данных, не имеющих объектной природы (регистров). Ограничение доступа к данным представляет собой условие, описанное на языке, который является подмножеством языка запросов. Это условие применяется для каждой записи таблицы базы данных, над которой выполняется операция. При просмотре списков и формировании отчетов существует возможность обеспечить отображение только тех данных, доступ к которым пользователю разрешен.
Журнал регистрации Для хранения информации о событиях, происходящих в информационной базе, система «1С:Предприятие» ведет журнал регистрации. Администратор информационной базы имеет возможность настроить уровень событий, которые будут отображаться в журнале регистрации (ошибки, и/или предупреждения, и/или информация, и/или примечания). Просмотр журнала регистрации может быть выполнен с помощью специального фильтра, позволяющего отбирать информацию по большому количеству критериев. Например, можно отобрать только информацию о том,
42
Загрузка/выгрузка информационной базы
Утилита администрирования кластера серверов Утилита администрирования кластера серверов используется при работе в клиент-серверном варианте и позволяет выполнять такие действия, как: ■■ создание, изменение и удаление кластеров серверов; ■■ модификация существующих кластеров: создание, изменение параметров и удаление рабочих серверов, рабочих процессов кластера, информационных баз, входящих в состав кластера; ■■ управление списками администраторов центральных серверов кластеров и списками администраторов кластеров; ■■ мониторинг соединений пользователей с информационными базами и служебных соединений; ■■ отключение пользователей от информационной базы; ■■ мониторинг объектных блокировок «1С:Предприятия» и блокировок клиентского соединения; ■■ оперативный анализ транзакционных блокировок системы управления базами данных; ■■ управление блокировкой установки соединений пользователей с информационной базой; ■■ управление блокировкой выполнения регламентных заданий. Утилита представляет собой подключаемый модуль MMC (Microsoft Management Console) и может быть использована на компьютерах, на которых установлено соответствующее программное обеспечение (для операционных систем Windows 2000/XP/Server 2003 это программное обеспечение является стандартным). Подробнее
Раздел «Управление кластером серверов», стр. 42.
Профессиональная разработка в системе «1С:Предприятие 8»
Обзор функциональности средств администрирования
«1С:Корпоративный инструментальный пакет» Этот продукт предназначен для повышения производительности, масштабируемости и надежности информационных систем на платформе «1С:Предприятие». Он используется для нагрузочного тестирования и последующего сопровождения крупных корпоративных систем. Продукт «1С:КИП» включает в себя следующие инструменты: ■■ 1С:Центр управления производительностью – инструмент мониторинга и анализа производительности информационных систем на платформе «1С:Предприятие». Этот инструмент предназначен для оценки производительности системы, сбора подробной технической информации об имеющихся проблемах производительности и анализа этой информации с целью дальнейшей оптимизации;
Том 1
■■ 1С:Тест-центр – инструмент автоматизации многопользовательских нагрузочных испытаний информационных систем на платформе «1С:Предприятие». С его помощью можно моделировать работу предприятия без участия реальных пользователей, что позволяет оценивать применимость, производительность и масштабируемость информационной системы в реальных условиях; ■■ 1С:Центр контроля качества. Инструмент позволяет гарантировать эффективную и надежную работу системы на платформе «1С:Предприятие» за счет своевременного и правильного технического обслуживания системы. Это особенно важно для внедрений с высокими требованиями по производительности и надежности системы.
43
Глава 2. Функциональность «1С:Предприятия»
44
Профессиональная разработка в системе «1С:Предприятие 8»
Модули конфигурации
Глава 3. Использование встроенного языка Как уже говорилось выше, прикладное решение «1С:Предприятия» представляет собой определенную структуру метаданных, которая исполняется технологической платформой. В то же время технологическая платформа содержит в себе интерфейс разработки и администрирования, позволяющий создавать новые и модифицировать существующие прикладные решения. Разработка прикладного решения заключается по большому счету в двух основных действиях: визуальном конструировании объектов конфигурации и описании специфического поведения системы с использованием встроенного языка и языка запросов. Создание нового прикладного решения начинается с добавления новой информационной базы в список баз «1С:Предприятия». При этом платформа создает некую «базовую» структуру метаданных, которая уже представляет собой работоспособное прикладное решение. В соответствии с этой структурой метаданных платформа также создает ряд информационных структур (таблиц), обеспечивающих работу этой конфигурации и хранение данных. Информационные структуры создаются в том варианте работы, который выбран пользователем (например, файловый или клиент-серверный). Таким образом, разработчик начинает создание прикладного решения не с нуля, а с некоторой «базовой» структуры метаданных (пустой конфигурации), которую он может изменять в соответствии со своими потребностями. Следующим шагом в разработке прикладного решения является, как правило, создание структур для хранения данных. Отличительной особенностью разработки в системе «1С:Предприятие» является то, что платформа изолирует разработчика от физических деталей хранения данных, предлагая более высокий уровень абстракции – уровень объектов метаданных. Другими словами, разработчик добавляет в структуру метаданных нужные ему объекты, определяет, например, какие реквизиты и табличные части будет содержать тот или иной объект. Платформа же анализирует изменения, выполняемые разработчиком, и создает в информационной базе соответствующие информационные структуры, позволяющие хранить и эффективно использовать данные. В результате, с точки зрения разработчика, процесс создания прикладного решения в файловом или в клиент-серверном варианте выглядит совершенно одинаково, так как он Том 1
не оперирует физическими таблицами базы данных, а имеет дело с более абстрактными сущностями – объектами метаданных. Таким образом, вся структура хранимых данных описывается средствами визуального конфигурирования и не может быть изменена в процессе работы прикладного решения (в реальном режиме времени). Такой подход позволяет платформе контролировать целостность информационной базы и данных, которые в ней хранятся. Платформе известно о назначении того или иного объекта конфигурации, она знает, в каких таблицах должны храниться данные этого объекта, и обладает информацией о том, как эти данные должны взаимодействовать с данными других объектов конфигурации. Таким образом, с одной стороны ограничивая разработчика в динамической модификации структуры информационной базы, она значительно облегчает задачу создания и модификации прикладного решения, избавляя разработчика от необходимости самостоятельно контролировать правильность таблиц информационной базы и их связей. Другим положительным моментом такого подхода является то, что структура прикладного решения становится прозрачной и легко читаемой. Любому разработчику, не принимавшему непосредственного участия в разработке данного решения, достаточно взглянуть на структуру объектов метаданных, чтобы понять в общих чертах, как оно устроено. Открыв конфигуратор, он увидит привычный набор объектов метаданных, назначение каждого из которых ему хорошо известно. Ограниченный набор объектов конфигурации, которые может использовать разработчик, является еще одной особенностью прикладных решений «1С:Предприятия». Платформа поддерживает фиксированный набор прототипов объектов метаданных (например, справочник, документ, регистр накопления, бизнес-процесс и т. д.). Разработчик не имеет возможности каким-либо образом создать собственный объект конфигурации (например, просто таблицу, содержащую набор колонок). Он может только добавить в прикладное решение новый объект конфигурации, соответствующий одному из прототипов, поддерживаемых системой (например, регистр сведений, обладающий набором реквизитов). Такой подход позволяет создать среду описания прикладных решений, состоящую из логических сущностей, одинаковых для всех прикладных решений (рис. 3.1).
45
Глава 3. Использование встроенного языка В этом случае разработчик имеет возможность использовать встроенный язык «1С:Предприятия» для того, чтобы определить поведение прикладного решения, отличное от стандартного. С помощью встроенного языка разработчик может «вмешиваться» в работу прикладного решения: выполнять какие-либо алгоритмы, обрабатывать и модифицировать данные, изменять или вообще отменять стандартные действия системы в зависимости от тех или иных результатов работы. Ключевым моментом здесь является то, что подобное «вмешательство» возможно не всегда, а только в определенные моменты работы прикладного решения. Таким образом, встроенный язык не является неким универсальным языком программирования, с помощью которого создаются прикладные решения, а служит лишь для описания особенных алгоритмов работы прикладного решения.
Модули конфигурации Для размещения текста программы на встроенном языке предназначены модули прикладного решения (например, модуль приложения, общие модули, модули объектов, модули форм, модули команд, модули менеджеров и т. д.). Эти модули располагаются в различных местах конфигурации и имеют различное назначение. Рис. 3.1. Сравнение логических уровней приложения
Добавление новых объектов конфигурации в прикладное решение сразу же позволяет использовать их для ввода и модификации информации. Технологическая платформа «знает», как работать с данными того или иного объекта конфигурации, и в определенные моменты работы прикладного решения самостоятельно может сгенерировать нужные формы для работы с данными. Таким образом, все объекты конфигурации, которые может использовать разработчик, обладают некоторым базовым поведением, которое реализуется платформой без участия разработчика. В простейшем варианте создание функционального и работоспособного прикладного решения возможно исключительно средствами визуального конструирования, без написания какого-либо текста программы. Платформа проанализирует состав объектов конфигурации и обеспечит все необходимые функции для работы с ними. Однако реальные задачи, решаемые с помощью системы «1С:Предприятие», всегда требуют наличия в прикладном решении некоторых алгоритмов, специфичных для автоматизируемой области. Это могут быть, например, различные алгоритмы расчета себестоимости, контроля остатков, распределения средств и т. д. Также возникает необходимость в создании специфических форм, обладающих нестандартным поведением, поскольку удобное визуальное представление информации является одной из наиболее важных задач для любого прикладного решения.
46
Большинство модулей привязано к определенным объектам конфигурации (например, к формам) или к самому прикладному решению (например, модуль управляемого приложения). Такие модули вызываются в определенные моменты работы прикладного решения (например, модуль управляемого приложения, который запускается при запуске системы «1С:Предприятие» в режиме управляемого приложения, или модуль объекта справочника Номенклатура, который запускается при создании объекта (элемента) справочника). Таким образом, если модуль содержит некоторый код, то этот код будет выполнен и работа прикладного решения продолжена. В таких модулях могут располагаться процедуры обработки событий, определенных для различных объектов прикладного решения. Эти процедуры также будут выполняться при наступлении соответствующего события. Наряду с модулями, вызываемыми в процессе работы прикладного решения, существуют общие модули, которые сами по себе не вызываются в процессе работы прикладного решения. Они служат лишь для размещения в них текстов функций и процедур, которые могут вызываться из других модулей прикладного решения. Таким образом, код, располагающийся в общих модулях, будет исполнен только тогда, когда к нему будет выполнено явное обращение из другого модуля конфигурации или из командного интерфейса. Каждый модуль связан с остальной частью конфигурации, и эта связь называется контекстом выполнения модуля. Контекст определяет Профессиональная разработка в системе «1С:Предприятие 8»
Модули конфигурации «программное окружение», в котором исполняется код модуля, – набор доступных для модуля объектов, переменных, процедур и функций. Для всех программных модулей доступен глобальный контекст задачи. Он образуется значениями свойств и методов глобального контекста, а также системными перечислениями и системными наборами значений. С другой стороны, почти все модули конфигурации (за исключением модуля сеанса и модуля команды), показанные на следующей схеме стрелками, поставляют в глобальный контекст свои экспортируемые процедуры/функции (рис. 3.2).
Рис. 3.3. Программные компоненты «1С:Предприятия» в клиент-серверном варианте работы
При этом физически все программные компоненты в клиент-серверном варианте работы «1С:Предприятия» могут располагаться как на одном компьютере, так и на разных. Подробнее
Глава 5 «Клиент-серверный вариант работы», раздел «Варианты использования», стр. 121.
Наличие серверного и клиентского контекста исполнения модулей определяет следующие особенности.
Рис. 3.2. Контексты прикладного решения
Локальный контекст модуля образуется тем конкретным местом конфигурации задачи, для которого использован программный модуль. Локальный контекст виден только конкретному программному модулю и определяет для модуля набор непосредственно доступных ему объектов, их свойств и методов. Подробнее
Документация «1С:Предприятие 8.2. Руководство разработчика», раздел 4.2 «Формат исходных текстов программных модулей».
Контекст исполнения модулей С точки зрения места исполнения модуля существует понятие «контекст исполнения модулей», определяющий программную среду, в которой выполняется модуль. Для клиент-серверного варианта работы «1С:Предприятия» таких контекстов два – контекст клиента и контекст сервера (рис. 3.3). Том 1
Во-первых, в контексте клиента (на клиенте) и в контексте сервера (на сервере) доступны разные свойства, методы и объекты встроенного языка. Все действия, связанные с доступом к данным (их чтение и запись), возможны только на сервере, а отображение этих данных пользователю и другие интерактивные действия возможны только на клиенте. Поэтому клиентские процедуры в модулях в явном виде отделяются от серверных, и в них используется ограниченный состав объектной модели встроенного языка. Во-вторых, реальным вариантом работы клиент-серверного варианта будет ситуация, когда все программные компоненты «1С:Предприятия» расположены на отдельных компьютерах. Как правило, сервер «1С:Предприятия» и сервер СУБД находятся в пределах одной локальной сети, а вот клиентский компьютер с клиентским приложением может находиться как в этой же сети, так и подключаться к серверу через Интернет с использованием самых разных каналов связи с разной скоростью передачи информации. В процессе работы «1С:Предприятия» клиентское приложение все время вызывает сервер для выполнения каких-либо действий, сервер выполняет их и возвращает управление и результат этих действий обратно, на клиента. Механизмы платформы оптимизируют клиент-серверное взаимодействие для того, чтобы обеспечить приемлемую скорость работы системы даже на низкоскоростных каналах связи. Поэтому разработчик, организующий клиент-серверное взаимодействие путем вызова серверных процедур
47
Глава 3. Использование встроенного языка из процедур, исполняющихся на клиенте, также должен стремиться к такой оптимизации. Подробнее
Раздел «Оптимизация клиент-серверного взаимодействия в формах», стр. 391.
Общий модуль В конфигурации может быть определено произвольное количество общих модулей, в том числе и ни одного. Контекст общего модуля образуется глобальным контекстом и локальным контекстом самого общего модуля, т. е. процедурами и функциями, определенными внутри общего модуля. Поскольку общий модуль не исполняется системой непосредственно, в нем отсутствует раздел описания переменных и раздел основной программы. Общий модуль может содержать только определения процедур и функций. Если процедуры или функции общего модуля определены как экспортируемые, то они становятся частью глобального контекста и будут доступны другим модулям прикладного решения (за некоторыми исключениями, о которых будет сказано далее). Если у общего модуля установлено свойство Глобальный, то экспортируемые методы общего модуля являются частью глобального контекста, и из встроенного языка можно обращаться к ним по имени, как к другим функциям, методам и свойствам глобального контекста. Если же модуль неглобальный, то при обращении к его экспортируемой процедуре или функции ее имя нужно указывать через точку от имени модуля (например, Обмен.ПолучитьПрефиксНомера()). Последний способ предпочтительнее, так как неглобальные общие модули компилируются по мере обращения к ним, а не при запуске системы, как глобальные. Поскольку общий модуль не привязан к какому-либо объекту конфигурации, а относится ко всему прикладному решению, имена экспортируемых процедур и функций должны быть различными в разных общих модулях. В противном случае будет выдана синтаксическая ошибка, т. к. глобальный контекст будет содержать повторяющиеся имена. С помощью свойств Клиент (управляемое приложение) и Сервер, а также указаний препроцессору можно организовывать выполнение различных процедур и функций общих модулей на сервере приложения или на клиентском месте. По умолчанию в свойствах общих модулей устанавливается флажок Сервер. Это означает, что все процедуры и функции общего модуля будут доступны только на сервере. Если при этом установить свойство Вызов сервера, то процедуры и функции этого общего модуля станут доступны
48
на клиенте. Соответственно, если у общего модуля установлены свойства Клиент (управляемое приложение) и/или Внешнее соединение, то экспортируемые (определенные с ключевым словом Экспорт) процедуры и функции этого общего модуля будут доступны на клиенте (тонком клиенте, веб-клиенте, толстом клиенте в режиме управляемого приложения) и/или во внешнем соединении. Если у неглобального общего модуля установлено свойство Клиент (управляемое приложение), то в контексте этого модуля будут доступны экспортируемые переменные, процедуры и функции модуля управляемого приложения. Если у неглобального общего модуля установлено свойство Внешнее соединение, то в контексте этого модуля будут доступны экспортируемые переменные, процедуры и функции модуля внешнего соединения. Также у неглобальных общих модулей доступно свойство Повторное использование возвращаемых значений. Установка этого свойства ускоряет выполнение экспортируемых функций (только функций, а не процедур) неглобальных общих модулей. Это происходит за счет использования механизма кеширования, так как значения параметров, переданных в функцию, и возвращенный ей при этом результат запоминаются и сохраняются для дальнейшего использования.
Модуль управляемого приложения Модуль управляемого приложения выполняется при запуске системы «1С:Предприятие» в управляемом режиме (свойство конфигурации Основной режим запуска установлено в значение Управляемое приложение, т. е. в режимах тонкого клиента, веб-клиента и толстого клиента в режиме управляемого приложения) или при обращении к приложению как к Automation-серверу (объект V82c.Application). Этот модуль предназначен для отработки действий, связанных с сеансом работы конечного пользователя. Помимо описания переменных и основной программы, модуль приложения может содержать описание процедуробработчиков событий, связанных с началом и окончанием сеанса работы пользователя. ПРИМЕЧАНИЕ
В конфигурации существует также модуль обычного приложения, который выполняется при запуске «1С:Предприятия» в обычном режиме. Он остался от прежних версий платформы и в рамках этой книги рассматриваться не будет. Далее везде речь пойдет об управляемом клиенте (тонком клиенте, веб-клиенте, толстом клиенте в режиме управляемого приложения), управляемом приложении и об управляемых формах, даже если слово «управляемое» опущено.
Профессиональная разработка в системе «1С:Предприятие 8»
Модули конфигурации В конфигурации всегда существует единственный модуль управляемого приложения, который располагается в корневом разделе конфигурации. Контекст модуля управляемого приложения (рис. 3.4) образуется: ■■ свойствами и методами глобального контекста, которые доступны в управляемых клиентах (тонкий клиент, веб-клиент, толстый клиент в режиме управляемого приложения); ■■ экспортируемыми функциями и процедурами клиентских общих модулей, у которых установлено свойство Клиент (управляемое приложение), и неглобальных серверных общих модулей, для которых установлено свойство Вызов сервера; ■■ локальным контекстом самого модуля управляемого приложения.
Рис. 3.5. Видимость модуля управляемого приложения
Модуль управляемого приложения недоступен для процедур, работающих на сервере. Также экспортируемые переменные, процедуры или функции модуля управляемого приложения недоступны для модуля внешнего соединения и глобальных общих модулей. Основными событиями, которые могут обрабатываться в модуле приложения, являются события начала и окончания работы приложения. Последовательность их вызова представлена на рис. 3.6.
Рис. 3.4. Контекст модуля управляемого приложения
Экспортируемые переменные, процедуры или функции модуля управляемого приложения (у которых в заголовке указано ключевое слово Экспорт) будут доступны (рис. 3.5): ■■ в неглобальных клиентских общих модулях с установленным свойством Клиент (управляемое приложение); ■■ клиентских процедурах и функциях модуля управляемой формы; ■■ клиентских процедурах и функциях модуля команды. Том 1
Рис. 3.6. Последовательность вызова событий модуля приложения
49
Глава 3. Использование встроенного языка Событие ПередНачаломРаботыСистемы возникает при запуске системы в управляемом режиме 1С:Предприятие до открытия главного окна. Обрабатывая это событие, разработчик имеет возможность отказаться от запуска системы в случае, если какие-либо условия не выполнены. Следует учитывать, что, поскольку это событие вызывается в тот момент, когда главное окно программы еще не открыто, будет недоступен ряд действий, требующих наличия главного окна (например, выдача сообщений, открытие форм и т. д.). Событие ПриНачалеРаботыСистемы возникает при запуске системы в управляемом режиме 1С:Предприятие после открытия главного окна. В обработчике этого события разработчик уже не может отказаться от запуска системы, зато может выполнить действия, которые обязательно должны быть выполнены при начале работы пользователя системы (например, открыть форму, содержащую справочную информацию, и т. д.). Событие ПередЗавершениемРаботыСистемы возникает при завершении работы системы в управляемом режиме 1С:Предприятие до закрытия главного окна. Обрабатывая это событие, разработчик имеет возможность отказаться от завершения работы, если какие-либо условия не выполнены. Событие ПриЗавершенииРаботыСистемы возникает при завершении работы системы в управляемом режиме 1С:Предприятие после закрытия главного окна. В обработчике этого события разработчик уже не может отказаться от закрытия приложения, но может выполнить действия, которые обязательно должны быть выполнены при окончании работы пользователя. Следует учитывать, что, поскольку это событие вызывается в тот момент, когда главное окно программы уже закрыто, будет недоступен ряд действий, требующих наличия главного окна (например, выдача сообщений, открытие форм и т. д.).
Модуль сеанса Модулем сеанса называется модуль, который автоматически выполняется при старте системы «1С:Предприятие» в момент загрузки конфигурации. Исполнение модуля сеанса происходит до начала исполнения модуля управляемого приложения или модуля внешнего соединения. Модуль сеанса предназначен для инициализации параметров сеанса и отработки действий, связанных с сеансом работы. Модуль сеанса всегда исполняется в привилегированном режиме сервера «1С:Предприятия». Установка параметров сеанса выполняется в обработчике события УстановкаПараметровСеанса().
Модуль внешнего соединения В конфигурации всегда существует единственный модуль внешнего соединения, который располагается в корневом разделе конфигурации. Контекст модуля внешнего соединения образуется: ■■ глобальным контекстом, в том числе экспортируемыми функциями и процедурами общих модулей (если для этих модулей установлено свойство Внешнее соединение); ■■ локальным контекстом самого модуля внешнего соединения. Модуль внешнего соединения выполняется при обращении к приложению как к COM-серверу (в режиме внешнего соединения). В режиме внешнего соединения запускается не полноценное приложение «1С:Предприятия», а «облегченный» вариант приложения, в котором недоступны все функции, так или иначе связанные с организацией пользовательского интерфейса. Поэтому в режиме внешнего соединения вместо модуля приложения исполняется модуль внешнего соединения. Этот модуль предназначен для отработки действий, связанных с сеансом работы с приложением «1С:Предприятия». Если переменные, процедуры или функции модуля внешнего соединения определены как экспортируемые, то они будут доступны другим модулям внешнего соединения, за исключением глобальных общих модулей, в которых они доступны не будут. Экспортируемые переменные, процедуры или функции модуля внешнего соединения также будут доступны для неглобальных общих модулей с установленным свойством Внешнее соединение. Помимо описания переменных и основной программы, модуль внешнего соединения может содержать описание двух процедур-обработчиков событий, связанных с началом и завершением работы: ПриНачалеРаботыСистемы и ПриЗавершенииРаботыСистемы. При работе в модуле внешнего соединения следует помнить о том, что ряд объектов встроенного языка, процедур и функций глобального контекста будет недоступен для использования, т. к. COM-сервер «1С:Предприятия» не содержит «интерфейсной» части приложения. Например, в режиме внешнего соединения нельзя использовать такие объекты, как диаграмма, табличный документ, недоступны функции для вызова диалога ввода данных и т. д. Точная информация о возможности использования объектов, процедур и функций в модуле внешнего соединения находится в документации, в описании конкретных объектов, процедур и функций.
Модуль сеанса может содержать только определения неэкспортируемых процедур и функций и может использовать процедуры из общих модулей конфигурации.
50
Профессиональная разработка в системе «1С:Предприятие 8»
Модули конфигурации
Модуль объекта Каждый прикладной объект конфигурации, данные которого могут быть модифицированы в режиме 1С:Предприятие, имеет свой модуль. Этот модуль исполняется при создании объекта встроенного языка, который позволяет модифицировать данные объекта конфигурации. Соответствующий объект встроенного языка создается, например, при вводе нового объекта, при копировании, при получении данных существующего объекта и т. д. Для различных объектов конфигурации этот модуль имеет разное название (табл. 3.1). Таблица 3.1. Название модуля объекта для различных объектов конфигурации Объект конфигурации
Название модуля
Константа Модуль менеджера значения Справочник Модуль объекта Документ Отчет Обработка План видов характеристик План счетов План видов расчета План обмена Бизнес-процесс Задача Последовательность Модуль набора записей Регистр сведений Регистр накопления Регистр бухгалтерии Регистр расчета Перерасчет
Объект встроенного языка, который расширяется модулем
КонстантаМенеджерЗначения.<имя> СправочникОбъект.<имя> ДокументОбъект.<имя> ОтчетОбъект.<имя> ОбработкаОбъект.<имя> ПланВидовХарактеристикОбъект.<имя> ПланСчетовОбъект.<имя> ПланВидовРасчетаОбъект.<имя> ПланОбменаОбъект.<имя> БизнесПроцессОбъект.<имя> ЗадачаОбъект.<имя> ПоследовательностьНаборЗаписей.<имя> РегистрСведенийНаборЗаписей.<имя> РегистрНакопленияНаборЗаписей.<имя> РегистрБухгалтерииНаборЗаписей.<имя> РегистрРасчетаНаборЗаписей.<имя> ПерерасчетНаборЗаписей.<имя>
Контекст модуля объекта (рис. 3.7) образуется: ■■ глобальным контекстом, в том числе экспортируемыми функциями и процедурами общих модулей, скомпилированных на сервере (для этих модулей установлено свойство Сервер); ■■ свойствами и методами объекта встроенного языка, контекст которого расширяется модулем; ■■ реквизитами объекта конфигурации, которому принадлежит модуль; ■■ локальным контекстом самого модуля объекта.
Рис. 3.7. Контекст модуля объекта
Если переменные, процедуры или функции модуля объекта определены как экспортируемые, то они будут доступны в качестве свойств и методов соответствующих объектов встроенного языка. Например, пусть в модуле справочника ТиповыеАнкеты определена экспортируемая процедура (листинг 3.1). Листинг 3.1. Экспортируемая процедура в модуле справочника
Процедура ПроверитьКорректностьЗаполненияАнкеты() Экспорт // Алгоритм вывода на экран печатной формы анкеты. // … КонецПроцедуры //
Тогда возможен следующий вызов этой процедуры, например, из модуля внешней обработки (листинг 3.2). Листинг 3.2. Пример вызова экспортируемой процедуры объекта справочника
Анкета = Справочники.ТиповыеАнкеты.НайтиПоКоду("000000001").ПолучитьОбъект(); Анкета.ПроверитьКорректностьЗаполненияАнкеты();
Помимо описания переменных и основной программы, модуль объекта может содержать описание процедур-обработчиков событий, связанных с данным объектом конфигурации. Состав этих событий различен Том 1
51
Глава 3. Использование встроенного языка для разных объектов, однако есть три события, которые вызываются для всех объектов, – ОбработкаПроверкиЗаполнения, ПередЗаписью и ПриЗаписи. Последовательность их вызова представлена на рис. 3.8.
Модуль менеджера объекта Для каждого прикладного объекта существует менеджер, предназначенный для управления этим объектом как объектом конфигурации. С помощью менеджера можно создавать объекты, работать с формами и макетами. Модуль менеджера позволяет расширить функциональность менеджеров, предоставляемых системой, за счет написания процедур и функций на встроенном языке. Фактически это позволяет описать методы для объекта конфигурации (например, справочника), которые относятся не к конкретному экземпляру объекта базы данных, а к самому объекту конфигурации. Контекст модуля менеджера (рис. 3.9) образуется: ■■ глобальным контекстом, в том числе экспортируемыми функциями и процедурами общих модулей, скомпилированных на сервере (для этих модулей установлено свойство Сервер); ■■ локальным контекстом самого модуля менеджера.
Рис. 3.8. Последовательность вызова событий модуля объекта
Событие ОбработкаПроверкиЗаполнения вызывается перед записью данных объекта, до начала транзакции записи. В обработчике этого события разработчик может реализовать собственные алгоритмы проверки заполнения реквизитов объекта, добавить в массив проверяемых реквизитов дополнительные реквизиты, чтобы платформа выполнила их проверку, или очистить массив проверяемых реквизитов, отказавшись от их стандартной проверки. Установив параметр Отказ в значение Истина, разработчик может отказаться от записи объекта, если, например, какие-то условия проверки не были выполнены. Событие ПередЗаписью вызывается перед записью данных, после начала транзакции записи, но до начала непосредственной записи данных в базу данных. В обработчике этого события разработчик имеет возможность отказаться от записи данных, если, например, не выполнены требуемые условия. Событие ПриЗаписи вызывается после того, как была выполнена запись данных в базу данных, но до окончания транзакции записи. В обработчике этого события выполняются действия над данными, неразрывно связанными с данными объекта, которые не могут быть изменены отдельно от основных данных. Здесь также разработчик может отказаться от записи данных, если, например, в результате записи этих данных в базу нарушаются какие-либо условия.
52
Рис. 3.9. Контекст модуля менеджера
Модуль менеджера исполняется только на сервере и не может иметь переменных и тела модуля. Если функции или процедуры модуля менеджера объявлены как экспортируемые, к ним можно будет получить доступ через менеджера объекта.
Профессиональная разработка в системе «1С:Предприятие 8»
Модули конфигурации Например, пусть в модуле менеджера справочника Контрагенты определена экспортируемая функция (листинг 3.3). Листинг 3.3. Экспортируемая функция в модуле менеджера справочника «Контрагенты»
Функция ПолучитьСписокДебиторов() Экспорт // … КонецФункции
Тогда возможен следующий вызов этой функции, например, из модуля внешней обработки (листинг 3.4). Листинг 3.4. Пример вызова экспортируемой функции справочника «Контрагенты»
Дебиторы = Справочники.Контрагенты.ПолучитьСписокДебиторов();
В модулях менеджеров объектов располагается обработчик события ОбработкаПолученияДанныхВыбора. Это событие возникает на сервере перед стандартным формированием списка при вводе по строке, автоподборе текста и быстром выборе.
Модуль управляемой формы Каждая форма, определенная в конфигурации, имеет свой собственный модуль.
■■ свойствами и методами расширения формы, определяемого основным реквизитом формы; ■■ свойствами и методами объекта УправляемаяФорма встроенного языка; ■■ реквизитами формы, которой «принадлежит» модуль; ■■ локальным контекстом самого модуля формы, скомпилированным в управляемых клиентах. Контекст серверных процедур и функций модуля управляемой формы (рис. 3.10) образуется: ■■ глобальным контекстом, в том числе экспортируемыми функциями и процедурами общих модулей, скомпилированных на сервере (для этих модулей установлено свойство Сервер); ■■ свойствами и методами расширения формы, определяемого основным реквизитом формы; ■■ свойствами и методами объекта УправляемаяФорма встроенного языка; ■■ реквизитами формы, которой «принадлежит» модуль; ■■ серверными процедурами и функциями самого модуля управляемой формы, а также переменными и телом модуля, скомпилированными на сервере.
Модуль управляемой формы исполняется при создании объекта УправляемаяФорма встроенного языка, а также может создаваться при открытии формы прикладного объекта (например, при открытии формы элемента справочника) либо явно получаться средствами встроенного языка (листинг 3.5). Листинг 3.5. Пример получения управляемой формы
ФормаСписка = ПолучитьФорму("Справочник.Номенклатура.ФормаСписка");
Контекст клиентских процедур и функций модуля управляемой формы (рис. 3.10) образуется: ■■ свойствами и методами глобального контекста, которые доступны в управляемых клиентах (тонкий клиент, веб-клиент, толстый клиент в режиме управляемого приложения); ■■ экспортируемыми функциями и процедурами клиентских общих модулей, у которых установлено свойство Клиент (управляемое приложение) и неглобальных серверных общих модулей, для которых установлено свойство Вызов сервера; ■■ экспортируемыми переменными, процедурами и функциями модуля управляемого приложения; Том 1
Рис. 3.10. Контекст модуля управляемой формы
53
Глава 3. Использование встроенного языка В контексте управляемой формы недоступны свойства и методы объекта, который назначен основным реквизитом формы. Получить к ним доступ можно только из серверной процедуры модуля формы, предварительно преобразовав данные формы в объект. Например, пусть в модуле объекта справочника определена экспортируемая процедура ПересчитатьЦены(), листинг 3.6. Листинг 3.6. Экспортируемая процедура в модуле объекта справочника
Процедура ПересчитатьЦены() Экспорт // … КонецПроцедура
Тогда в серверной контекстной процедуре модуля формы элемента этого справочника можно преобразовать данные формы в объект (РеквизитФормыВЗначение()) и выполнить метод этого объекта ПересчитатьЦены(). Затем, чтобы пересчитанные данные отразились в форме, нужно выполнить обратное преобразование (ЗначениеВРеквизитФормы()), конвертировав объект справочника в данные формы (листинг 3.7). Листинг 3.7. Пример вызова экспортируемой процедуры справочника из модуля формы
&НаСервере Процедура ОбновитьДанные() СправочникОбъект = РеквизитФормыВЗначение("Объект"); СправочникОбъект.ПересчитатьЦены(); ЗначениеВРеквизитФормы(СправочникОбъект, "Объект"); КонецПроцедуры
Исполнение модуля формы на клиенте и на сервере Основная особенность формы как программного объекта заключается в том, что она существует одновременно и на клиенте, и на сервере. Форма состоит из двух взаимодействующих между собой частей, каждая из которых выполняется в разных контекстах. Одна часть – в контексте сервера, а другая – в контексте клиента. По этой причине все процедуры и функции, создаваемые в модуле формы, должны иметь явное указание на то, в каком контексте они будут исполняться. Для этого используются директивы компиляции, набор которых определен во встроенном языке. Одна из возможных директив компиляции обязательно должна быть указана перед объявлением каждой процедуры или функции, находящейся в модуле формы. Например, директива компиляции и процедура могут выглядеть следующим образом (листинг 3.8).
54
Листинг 3.8. Процедура «ПриСозданииНаСервере»
&НаСервере Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка) Если Объект.Ссылка = ПланыОбмена.УдаленныеСклады.ЭтотУзел() Тогда Элементы.Главный.Доступность = Ложь; Элементы.Склад.Доступность = Ложь; Элементы.АдресОбмена.Доступность = Ложь; КонецЕсли; КонецПроцедуры
В приведенном примере стандартная процедура, выполняемая платформой при создании формы на сервере, предваряется соответствующей директивой компиляции &НаСервере. Поскольку стандартные события вызываются платформой в заранее известных контекстах (на клиенте или на сервере), то и директивы компиляции, указываемые перед обработчиками этих событий, должны соответствовать контексту события. Что же касается контекстов исполнения собственных процедур или функций – их определяет сам разработчик в зависимости от своих нужд. Вообще в модуле формы могут быть использованы четыре различные директивы компиляции: ■■ ■■ ■■ ■■
&НаКлиенте, &НаСервере, &НаСервереБезКонтекста, &НаКлиентеНаСервереБезКонтекста.
Директива &НаКлиенте указывает, что процедура или функция будет исполняться в контексте клиентского приложения. В этой процедуре будет доступен весь контекст формы: реквизиты, элементы и параметры формы. Эта директива используется для всех обработчиков клиентских событий формы, а также для процедур, описывающих локальные команды формы. Часто такие процедуры называют клиентскими процедурами формы. Директива &НаСервере аналогична предыдущей с той разницей, что исполнение кода происходит в контексте сервера. Эта директива используется для всех обработчиков серверных событий формы. Также эту директиву часто используют разработчики для собственных процедур, чтобы передать исполнение кода на сервер. Часто такие процедуры называют серверными процедурами формы. А вызов такой процедуры из клиентской процедуры называют контекстным серверным вызовом. Директива &НаСервереБезКонтекста также определяет, что код будет исполняться в контексте сервера, но при этом контекст формы (реквизиты, элементы, параметры) будет недоступен. Эту директиву также используют разработчики для собственных процедур, чтобы передать исполнение кода на сервер. Как и в предыдущем случае, такие процедуры Профессиональная разработка в системе «1С:Предприятие 8»
Модули конфигурации называют серверными процедурами формы. А вот вызов такой процедуры из клиентской процедуры называют внеконтекстным серверным вызовом. И последняя директива, &НаКлиентеНаСервереБезКонтекста, определяет, что процедура или функция может исполняться как в контексте клиента, так и в контексте сервера. Эта директива используется редко. Обычно она требуется в тех случаях, когда нужно выполнять одинаковые действия, как при создании формы, так и в процессе ее жизнедеятельности на клиенте. Тогда вместо двух одинаковых процедур, одна из которых исполняется на сервере, а другая – на клиенте, создается одна процедура с директивой &НаКлиентеНаСервереБезКонтекста. Если по ошибке никакая директива компиляции не указана, то платформа считает, что используется директива &НаСервере.
Переменные модуля формы В модуле формы директивы компиляции должны быть указаны не только перед определением процедур и функций, но и перед определением переменных. Если перед описанием переменной используется директива компиляции &НаКлиенте, то такая переменная будет существовать с момента создания формы до момента ее закрытия. Причем только в клиентской части формы. Из серверных процедур формы она доступна не будет. Если перед описанием переменной используется директива компиляции &НаСервере, то такая переменная будет существовать только на период вызова и исполнения какой-либо серверной процедуры или функции. После того как исполнение кода вернется на клиента, модуль, исполнявшийся на сервере, будет уничтожен вместе с этой переменной (рис. 3.11). Почему важно понимать эту особенность? Потому что порой переменные модуля объявляются в явном виде, без указания директивы компиляции. В этом случае, как уже говорилось выше, платформа будет использовать директиву &НаСервере. Можно пытаться в одной серверной процедуре устанавливать значение этой переменной и читать ее в другой. Но так получится только в том случае, если все эти процедуры выполняются в одном серверном вызове. Если серверные вызовы разные, переменная будет инициализироваться каждый раз заново. В то же время на клиенте можно использовать переменные модуля для хранения значений на все время жизни формы, но для этого при объявлении таких переменных обязательно должна быть указана директива компиляции &НаКлиенте. Том 1
Рис. 3.11. Однократная компиляция клиентской части модуля и многократная компиляция серверной части модуля
Передавать значения с клиента на сервер с помощью переменных модуля формы нельзя. Хранить значения на сервере в переменных модуля также не получится. Для этого нужно использовать либо реквизиты формы (и выполнять контекстные серверные вызовы), либо передавать значения в параметрах вызываемой процедуры/функции.
Экспортируемые процедуры формы Разработчик может создать в модуле формы экспортируемые процедуры или функции. Они будут доступны как методы программного объекта Форма во встроенном языке. Для таких процедур/функций также нужно указывать директивы компиляции. При этом практический смысл есть, наверное, в использовании лишь единственной директивы – &НаКлиенте. Поясним почему. Как мы уже знаем, объект формы создается методами ОткрытьФорму() или ПолучитьФорму(). Оба они доступны только в контексте клиента. Поэтому созданная форма также будет существовать в контексте клиента. Соответственно, в этом же контексте должны быть определены ее экспортируемые процедуры/функции.
55
Глава 3. Использование встроенного языка В принципе программный объект формы может существовать как на клиенте, так и на сервере. Однако для чего, в какой ситуации может потребоваться обращаться к нему «извне» на сервере – сложно представить. Поэтому основное замечание этого раздела заключается в том, что при написании собственных экспортируемых процедур/функций формы нужно не забывать указывать для них директиву компиляции &НаКлиенте. Если никакая директива указана не будет, платформа будет считать, что используется директива &НаСервере, и, значит, вызвать процедуру/функцию на клиенте вы не сможете.
Клиентские и серверные обработчики событий формы Помимо описания переменных и основной программы, модуль формы может содержать описание процедур-обработчиков событий, связанных с формой. В первую очередь это событие, возникающее при создании формы на сервере. Последовательность событий, вызывающихся при создании формы уже существующего объекта информационной базы, а также открытии и закрытии окна формы, представлена на рис. 3.12.
Подробнее
Раздел «Последовательность событий при открытии формы объекта», стр. 299. Раздел «Последовательность событий при записи объекта из формы», стр. 301. Синтакс-помощник: Интерфейс (управляемый) – Управляемая форма – УправляемаяФорма – События.
Форма полностью подготавливается к открытию на сервере и затем открывается на клиенте. При открытии формы на стороне сервера вызываются два события – ПриЧтенииНаСервере и ПриСозданииНаСервере. Первое событие формы ПриЧтенииНаСервере вызывается только для существующих в информационной базе объектов. Причем поставляется это событие не самой формой, а ее расширением, определяемым типом основного реквизита формы. В обработчике этого события, в параметре ТекущийОбъект разработчику доступен прикладной объект, содержащийся в форме, со всей его функциональностью. То есть здесь можно вызвать экспортируемые методы этого объекта или получить значения его реквизитов, не конвертируя данные формы в объект. Таким образом, в обработчике этого события разработчик может подготовить данные формы, зависящие от данных объекта, к открытию. Второе событие формы ПриСозданииНаСервере вызывается всегда при открытии форм и новых, и существующих объектов. Здесь уже недоступен прикладной объект, отображаемый в форме. В обработчике этого события разработчик может полностью подготовить форму, ее внешнее представление, к открытию, в зависимости от различных условий настроить ее интерфейсные свойства. В обработчике этого события разработчик имеет возможность отказаться как от открытия формы (Отказ = Истина), так и от выполнения стандартных действий при открытии формы (СтандартнаяОбработка = Ложь), если, например, не выполнены требуемые условия. Набор стандартных действий различен для разных форм и определяется расширением формы, соответствующим основному реквизиту формы. Например, для формы списка стандартная обработка заключается в передаче параметров, указанных при открытии формы, в динамический список, а при открытии формы отчета при выполнении стандартной обработки в форму загружается вариант и пользовательские настройки отчета.
Рис. 3.12. Последовательность вызова событий модуля формы
56
После этого уже полностью подготовленная к изображению форма передается на клиента, и вызывается клиентское событие формы ПриОткрытии. Это событие возникает при открытии формы до показа ее окна пользователю. Здесь также можно отказаться от открытия формы, если по каким-то причинам она не должна быть открыта. Если форма наверняка будет открыта, то разработчик может в обработчике этого события выполнить некоторые интерактивные действия, которые невозможны на сервере: выдать предупреждение пользователю или открыть связанную форму, данные которой зависят от основной открываемой формы. Профессиональная разработка в системе «1С:Предприятие 8»
Модули конфигурации При закрытии формы на стороне клиента происходят два события – ПередЗакрытием и ПриЗакрытии (здесь не рассматриваются события, возникающие при записи объекта из формы при ее закрытии). Событие ПередЗакрытием возникает при закрытии формы до закрытия окна формы. В обработчике этого события разработчик имеет возможность отказаться как от закрытия формы (Отказ = Истина), так и от выполнения стандартных действий при закрытии формы (СтандартнаяОбработка = Ложь), если, например, не выполнены требуемые условия. Набор стандартных действий, выполняемых после события ПередЗакрытием, также различен для разных форм и определяется расширением формы, соответствующим основному реквизиту формы. Например, если элемент справочника был модифицирован, одним из стандартных действий будет запрос сохранения изменений перед закрытием формы. Событие ПриЗакрытии возникает при закрытии формы после закрытия окна формы. В обработчике этого события можно описывать алгоритмы, которые должны быть выполнены только в случае, когда форма будет наверняка закрыта. Например, если нужно закрыть вспомогательную форму, существующую только в случае, если открыта основная форма.
Контекст клиентских процедур модуля команды (рис. 3.13) образуется: ■■ свойствами и методами глобального контекста, которые доступны в управляемых клиентах (тонкий клиент, веб-клиент, толстый клиент в режиме управляемого приложения); ■■ экспортируемыми функциями и процедурами клиентских общих модулей, у которых установлено свойство Клиент (управляемое приложение), и неглобальных серверных общих модулей, для которых установлено свойство Вызов сервера; ■■ экспортируемыми переменными, процедурами и функциями модуля управляемого приложения; ■■ локальным контекстом самого модуля команды. Контекст серверных процедур модуля команды (рис. 3.13) образуется: ■■ свойствами и методами глобального контекста; ■■ экспортируемыми функциями и процедурами общих модулей, скомпилированных на сервере (для этих модулей установлено свойство Сервер); ■■ серверными методами модуля команды.
Модуль команды Для прикладных объектов конфигурации существуют подчиненные объекты Команды. Существуют также общие объекты конфигурации – объекты Общая команда. У каждой команды существует модуль команды, в котором можно написать предопределенную процедуру ОбработкаКоманды(), в которой на встроенном языке описываются действия, которые должна выполнить система при вызове этой команды. Модуль команды, так же как и модуль управляемой формы, существует и на сервере, и на клиенте. В модуле команды могут быть использованы следующие директивы компиляции: ■■
&НаКлиенте
■■ ■■
&НаСервере
клиенте;
– процедура/функция исполняется в управляемом
– процедура/функция исполняется на сервере; – процедура/функция может исполняться и в управляемом клиенте, и на сервере. Процедура ОбработкаКоманды() обязательно должна предваряться директивой компиляции &НаКлиенте, так как выполнение команды происходит в клиентском приложении. &НаКлиентеНаСервере
Из клиентских процедур модуля команды можно вызывать серверные, после их выполнения исполнение кода возвращается на клиента. Но при этом из серверных процедур/функций вызывать клиентские процедуры нельзя. Том 1
Рис. 3.13. Контекст модуля команды
Модуль команды должен содержать только описание и функций и не может иметь переменных и тела модуля.
процедур
57
Глава 3. Использование встроенного языка Хотя в модуле команды можно описывать методы с ключевым словом Экспорт, из встроенного языка невозможно получить доступ к командам и, следовательно, к их контексту тоже.
Работа встроенного языка на сервере
Организация выполнения кода на сервере или на клиенте Используя возможность управления компиляцией модулей, исполнение кода передается с клиента на сервер. После выполнения вызванной процедуры или функции система продолжит исполнение кода на клиенте. Архитектура системы ориентирована на максимальный перенос выполнения всей функциональности на сервер и максимальное «облегчение» клиента. На сервере выполняется вся работа прикладных объектов, выполняется подготовка к отображению форм (чтение объектов из информационной базы и заполнение данных формы, расположение элементов, запись данных формы после изменения) и командного интерфейса, формируются отчеты. На клиенте выполняется только отображение информации, подготовленной на сервере, выполняется взаимодействие с пользователем и вызовы серверных методов для выполнения необходимых действий. После запуска прикладного решения выполнение кода всегда осуществляется на клиенте. Передача выполнения с клиента на сервер может быть выполнена путем вызова серверных процедур, описанных с директивой компиляции &НаСервере, &НаСервереБезКонтекста из клиентских процедур модуля формы или команды, а также путем вызова процедуры общего модуля, исполняющегося на сервере. После того как вызываемая процедура завершит свою работу, выполнение будет передано обратно на клиента.
(с директивой компиляции &НаКлиенте) можно вызывать серверные (с директивой компиляции &НаСервере, &НаСервереБезКонтекста), тем самым передавая выполнение с клиента на сервер. После выполнения серверных процедур исполнение кода возвращается на клиента. Принудительно передать исполнение кода в обратную сторону, с сервера на клиента, невозможно, то есть нельзя из серверных процедур модуля формы/команды вызывать клиентские. Рассмотрим пример. Пусть в форме накладной при изменении товара нужно подставлять цену товара из регистра сведений. Работа с прикладными объектами, в частности с регистром сведений, на клиенте невозможна. В этом случае на клиенте, в обработчике события при изменении товара, можно вызвать серверную (лучше внеконтекстную) процедуру, которая возвращает актуальную цену выбранного товара на указанную дату (листинги 3.9, 3.10). Листинг 3.9. Процедура «ТоварыТоварПриИзменении()»
&НаКлиенте Процедура ТоварыТоварПриИзменении(Элемент) // … ЦенаТовара = РозничнаяЦена(Товар, Дата); КонецПроцедуры Листинг 3.10. Функция «РозничнаяЦена()»
&НаСервереБезКонтекста Функция РозничнаяЦена(ВыбранныйТовар, АктуальнаяДата) // … Возврат Цена; КонецФункции
Взаимодействие клиентского и серверного контекста исполнения в модуле формы показано на рис. 3.14.
Клиентские и серверные процедуры в модуле формы, команды Простейшим примером передачи выполнения кода на сервер может служить вызов серверных процедур, описанных с директивой компиляции &НаСервере, &НаСервереБезКонтекста из клиентских процедур модуля формы или команды. Как уже говорилось выше, модуль формы и модуль команды существуют одновременно как на клиенте, так и на сервере. Таким образом, процедуры, содержащиеся в этих модулях, исполняются или в контексте клиента, или в контексте сервера. В целом исполнение модуля формы/команды на клиенте и на сервере характеризуется тем, что из клиентских процедур модуля формы/команды
58
Рис. 3.14. Передача исполнения кода на сервер в модуле формы
Если процедура часто используется, имеет смысл поместить ее в общем серверном модуле и вызывать ее из серверной процедуры модуля формы. Профессиональная разработка в системе «1С:Предприятие 8»
Работа встроенного языка на сервере Для реализации нужной функциональности форм разработчик может использовать клиентские и серверные процедуры в модуле формы. В целях оптимизации клиент-серверного взаимодействия нужно соблюдать следующие рекомендации: ■■ основной объем кода должен содержаться в серверных процедурах (с директивой компиляции &НаСервере, &НаСервереБезКонтекста). Клиентские процедуры (&НаКлиенте) должны содержать небольшой и несложный для исполнения код; ■■ нужно стремиться к минимизации серверных вызовов, то есть ситуаций, когда из клиентских процедур вызываются серверные; ■■ везде, где возможно, нужно использовать внеконтекстные серверные вызовы (&НаСервереБезКонтекста) вместо вызовов сервера с контекстом формы (&НаСервере). Это быстрее и эффективнее. Подробнее
Раздел «Оптимизация клиент-серверного взаимодействия в формах», стр. 391.
Листинг 3.11. Передача исполнения кода на сервер путем вызова процедуры серверного общего модуля
&НаКлиенте Процедура ВыполнитьНаСервере(Команда) Серверный.ВыполнитьНаСервере(); КонецПроцедуры
После того как выполнение передано на сервер, все остальные вызовы процедур и функций будут выполняться также на стороне сервера (рис. 3.16). Например, общий модуль Расчеты, который компилируется как на стороне сервера, так и на стороне клиента, содержит экспортируемую процедуру Пересчитать(). Как видно из рисунка, сначала на клиенте в модуле формы отчета вызывается экспортируемая процедура общего серверного модуля Серверный, и управление передается на сервер. Затем из этой процедуры вызывается процедура Пересчитать(). При этом выполнение кода продолжится на сервере, и процедура Пересчитать() будет вызвана из серверного экземпляра модуля Расчеты.
Вызов процедур из серверных модулей Передача выполнения кода на сервер может быть осуществлена посредством вызова экспортируемой процедуры общего модуля, у которого установлено свойство Сервер и свойство Вызов сервера. Экземпляр этого модуля будет скомпилирован только на стороне сервера. При вызове в модуле формы отчета этой экспортной процедуры выполнение будет передано на сервер, в экспортируемую процедуру общего модуля. После ее завершения управление вернется на клиента (рис. 3.15).
Рис. 3.16. Исполнение вызовов процедур на сервере
После ее завершения управление вернется на клиента. Затем из модуля формы снова вызывается процедура Пересчитать(). Однако теперь эта процедура будет вызвана из клиентского экземпляра модуля Расчеты. Рис. 3.15. Передача выполнения кода на сервер
Например, можно вызвать процедуру неглобального серверного общего модуля (с установленными свойствами Сервер и Вызов сервера) из клиентского обработчика команды в модуле формы (листинг 3.11).
Том 1
Важно отметить, что разработчик не может «управлять» передачей выполнения с сервера обратно на клиента. Выполнение будет передано только после завершения выполнения вызванной процедуры или функции. Другими словами, если выполнение осуществляется на сервере, и вызываемая процедура не найдена в скомпилированном на стороне сервера коде, то будет выдано сообщение об ошибке даже в том случае, если вызываемая процедура присутствует в экземпляре, скомпилированном на стороне клиента (рис. 3.17).
59
Глава 3. Использование встроенного языка
Привилегированный и безопасный режимы исполнения кода В процессе функционирования прикладного решения могут возникать ситуации, когда некоторые действия нужно выполнить максимально быстро, без проверки прав пользователя на используемые данные, а при выполнении некоторых действий, наоборот, нужно оградить систему от выполнения «ненадежного» кода, представляющего потенциальную угрозу для ее безопасности. Для этого платформа поддерживает привилегированный и безопасный режимы исполнения кода.
Привилегированный режим Рис. 3.17. Исполнение вызовов процедур на сервере
Передача параметров на сервер и возврат значений При передаче выполнения кода на сервер, как правило, выполняется передача некоторых параметров вызываемой процедуры или функции. Также в случае вызова функции будет выполняться передача результата работы функции с сервера на клиента. Важно учитывать, что не все типы значений и объекты, работа с которыми возможна на сервере, могут быть переданы с клиента на сервер и обратно.
В привилегированном режиме код исполняется на сервере без проверки прав. Использование привилегированного режима позволяет, во-первых, ускорить работу, так как не будут накладываться ограничения на доступ к данным, а во-вторых, позволяет выполнять операции с данными от лица пользователей, которым эти данные недоступны. Для поддержки привилегированного режима в платформе существует несколько возможностей. Для документов прямо в свойствах конфигурации можно задать использование привилегированного режима при проведении и при отмене проведения документа. Эти свойства стандартно устанавливаются платформой для новых документов (рис. 3.18).
Точная информация о возможности использования типов значений и объектов на сервере и передаче их между клиентом и сервером находится в документации, в описании конкретных объектов. В синтакс-помощнике при описании объектов, которые могут передаваться между клиентом и сервером, содержится фраза «Возможен обмен с сервером». Поскольку на клиенте невозможна работа с объектными данными, то на сервер можно передавать ссылку на объект, а в серверной процедуре получать по этой ссылке объект и работать с ним. Обмен с сервером возможен некоторым набором типов, для которых такой обмен поддерживается, а для обмена «специфическими» данными (например, файлами, картинками, табличными частями документа) предназначено временное хранилище. Методом ПоместитьВоВременноеХранилище() сериализуемое значение сохраняется во временном хранилище, а затем методом ПолучитьИзВременногоХранилища() значение извлекается из временного хранилища по указанному адресу. Например, временное хранилище может быть использовано для передачи данных между формами, минуя клиента, что особенно эффективно в случае больших объемов передаваемых данных.
60
Рис. 3.18. Установка привилегированного режима при проведении и отмене проведения документа
Профессиональная разработка в системе «1С:Предприятие 8»
Работа встроенного языка на сервере Для бизнес-процессов также прямо в свойствах конфигурации можно задать использование привилегированного режима при создании задач. Эти свойства стандартно устанавливаются платформой для новых бизнес-процессов (рис. 3.19).
Безопасный режим Безопасный режим работы предназначен для защиты системы от выполнения на сервере «ненадежного» программного кода. Потенциальную опасность представляют внешние обработки или программный код, вводимый пользователем для использования в методах Выполнить() и Вычислить(). Безопасный режим рекомендуется включать при выполнении на сервере программного кода, надежность которого разработчик гарантировать не может. Для этого в глобальном контексте существует процедура УстановитьБезопасныйРежим(), а также функция БезопасныйРежим(), которая позволяет определить, включен безопасный режим или нет. А также при создании и подключении внешних обработок и отчетов платформа стандартно устанавливает параметр БезопасныйРежим в значение Истина. В безопасном режиме накладываются следующие ограничения:
Рис. 3.19. Установка привилегированного режима при создании задач
Привилегированный режим исполнения кода можно включить/выключить средствами встроенного языка. Для этого в глобальном контексте существует процедура УстановитьПривилегированныйРежим(), а также функция ПривилегированныйРежим(), которая позволяет определить, включен привилегированный режим или нет. Привилегированный режим рекомендуется использовать тогда, когда работа с данными от лица некоторого пользователя не нарушает установленные для этого пользователя права доступа. Например, кладовщик имеет доступ к документу, регистрирующему продажи, но не имеет доступа к самому регистру продаж, в котором содержатся движения документа, возникающие при его проведении. В этом случае использование привилегированного режима при проведении документа не делает данные регистра продаж доступными кладовщику, но позволяет проводить документ и сохранять в регистре движения документа. Можно также поместить код, не требующий проверки прав, в привилегированные общие модули, у которых установлено свойство Привилегированный. В такие модули могут быть перенесены операции, использующие данные, на которые у текущего пользователя нет прав. Подробнее
Документация «1С:Предприятие 8.2. Руководство разработчика», раздел 5.5.4.2.
Том 1
■■ ■■ ■■ ■■ ■■ ■■
привилегированный режим отменяется, если он был установлен; попытки перехода в привилегированный режим игнорируются; запрещены операции с COM-объектами; запрещена загрузка и подключение внешних компонентов; запрещен доступ к файловой системе (кроме временных файлов); запрещен доступ к Интернету.
Подробнее
Документация «1С:Предприятие 8.2. Руководство разработчика», раздел 5.5.4.3.
Работа с метаданными Встроенный язык «1С:Предприятия» позволяет работать с метаданными. Одним из концептуальных моментов этой работы является то, что доступ к метаданным предоставляется только на чтение. Таким образом, средствами встроенного языка разработчик не может модифицировать метаданные. Изменение структуры метаданных возможно только средствами визуального конструирования в режиме Конфигуратор. Для доступа к метаданным из встроенного языка используется объект ОбъектМетаданныхКонфигурация, который доступен через свойство глобального контекста Метаданные. Этот объект предоставляет доступ как к свойствам самой конфигурации, так и к отдельным коллекциям объектов метаданных, которые описывают различные виды прикладных
61
Глава 3. Использование встроенного языка объектов, определенных в прикладном решении. Например, для доступа к коллекции объектов метаданных, описывающих документы, можно использовать следующий код (листинг 3.12). Листинг 3.12. Доступ к коллекции метаданных
МетаданныеДокументов = Метаданные.Документы;
А для того, чтобы получить доступ к объектам конфигурации, описывающим справочники, можно использовать такой вызов (листинг 3.13). Листинг 3.13. Доступ к коллекции метаданных
МетаданныеСправочников = Метаданные.Справочники;
Элементами таких коллекций являются объекты метаданных, которые позволяют получить доступ как к специфическим свойствам объектов, так и к свойствам, общим для различных объектов метаданных. Например, можно получить описание реквизитов объекта, табличных частей объекта и их реквизитов, описания форм, макетов объекта и т. д. (листинг 3.14). Листинг 3.14. Получение описаний реквизитов объектов метаданных
// Для объекта метаданных "Документ.АккредитивПереданный" можно получить: // описание реквизита "ВалютаДокумента" Объект = Метаданные.Документы.АккредитивПереданный.Реквизиты.ВалютаДокумента; // описание табличной части "РасшифровкаПлатежа" Объект = Метаданные.Документы.АккредитивПереданный.ТабличныеЧасти.РасшифровкаПлатежа; // описание реквизита табличной части "ДоговорКонтрагента" Объект = Метаданные.Документы.АккредитивПереданный. ТабличныеЧасти.РасшифровкаПлатежа.Реквизиты.ДоговорКонтрагента;
Реквизиты, табличные части объекта метаданных также представляют собой коллекцию объектов метаданных, состоящих из объектов метаданных, описывающих отдельный реквизит или отдельную табличную часть. В качестве примера на следующей схеме представлена связь объектов, описывающих реквизиты и табличные части объекта метаданных Документ.АккредитивПереданный (рис. 3.20). Таким образом, в большинстве случаев значение некоторого свойства объекта метаданных может быть получено по следующей цепочке программных объектов (рис. 3.21).
Рис. 3.20. Описание реквизитов и табличных частей документа
62
Профессиональная разработка в системе «1С:Предприятие 8»
Работа с метаданными Листинг 3.15. Пример использования метода «Содержит()»
// В качестве примера выбирается первая запись из первого набора записей, // содержащегося в движениях документа. Сообщение = Новый СообщениеПользователю; Движения = Документы.АвансовыйОтчет.НайтиПоНомеру("ТК000009", '20110101000000'). ПолучитьОбъект().Движения[0]; Движения.Прочитать(); ОбъектМетаданных = Метаданные.НайтиПоТипу(ТипЗнч(Движения[0])); Если Метаданные.РегистрыНакопления.Содержит(ОбъектМетаданных) Тогда Сообщение.Текст = "Это движения по регистру накопления"; Сообщение.Сообщить(); Рис. 3.21. Цепочка объектов описания метаданных
Такой подход позволяет упростить и унифицировать работу с метаданными. Объекты метаданных имеют различный набор свойств, перечень которых можно узнать при помощи команды Конфигурация Отчет по конфигурации… Кроме этого, все коллекции объектов метаданных допускают обращение к элементам коллекции по имени или индексу. Также показанные на схеме объекты имеют набор следующих методов (рис. 3.22).
ИначеЕсли Метаданные.РегистрыСведений.Содержит(ОбъектМетаданных) Тогда Сообщение.Текст = "Это движения по регистру сведений"; Сообщение.Сообщить(); ИначеЕсли Метаданные.РегистрыБухгалтерии.Содержит(ОбъектМетаданных) Тогда Сообщение.Текст = "Это движения по регистру бухгалтерии"; Сообщение.Сообщить(); ИначеЕсли Метаданные.РегистрыРасчета.Содержит(ОбъектМетаданных) Тогда Сообщение.Текст = "Это движения по регистру расчета"; Сообщение.Сообщить(); КонецЕсли;
Поскольку метаданные имеют иерархическую структуру, объект, полученный методом НайтиПоТипу(), не всегда может находиться в первом уровне иерархии нужной коллекции объектов метаданных. В этом случае можно использовать метод Родитель() объекта метаданных для того, чтобы получить объект, находящийся на нужном уровне иерархии. Например, если некоторая универсальная процедура обрабатывает табличные части справочников по одному алгоритму, а табличные части документов – по другому, то проанализировать принадлежность табличной части определенному виду метаданных можно следующим образом (листинг 3.16). Рис. 3.22. Методы объектов описания метаданных
Объект ОбъектМетаданныхКонфигурация содержит два метода, которые позволяют найти объект метаданных, описывающий некоторое значение или тип. Полученное таким образом значение может быть использовано для того, чтобы найти его в некоторой коллекции объектов метаданных (метод Содержит() объекта КоллекцияОбъектовМетаданных) или сравнить с конкретным объектом метаданных. Например, в процессе перебора движений документа требуется определить, к какому именно виду регистров относится данная запись регистра. В этом случае для записи можно найти соответствующий объект метаданных и затем определить, в какую из коллекций объектов метаданных, описывающих регистры, входит полученный объект метаданных (листинг 3.15). Том 1
Листинг 3.16. Пример использования метода «Родитель()»
// В качестве примера получается табличная часть "Товары" // документа "АвансовыйОтчет". Сообщение = Новый СообщениеПользователю; ТабличнаяЧасть = Документы.АвансовыйОтчет.НайтиПоНомеру("ТК000009", '20110101000000'). ПолучитьОбъект().Товары; ОбъектМетаданных = Метаданные.НайтиПоТипу(ТипЗнч(ТабличнаяЧасть)).Родитель(); Если Метаданные.Справочники.Содержит(ОбъектМетаданных) Тогда Сообщение.Текст = "Это табличная часть справочника"; Сообщение.Сообщить(); ИначеЕсли Метаданные.Документы.Содержит(ОбъектМетаданных) Тогда Сообщение.Текст = "Это табличная часть документа"; Сообщение.Сообщить(); КонецЕсли;
63
Глава 3. Использование встроенного языка Как уже говорилось выше, коллекция объектов метаданных позволяет обращаться к объектам по имени или индексу. Кроме этого, коллекция поддерживает итератор Для Каждого…, с помощью которого, например, может быть организован перебор всех элементов справочников, содержащихся в конфигурации (листинг 3.17).
64
Листинг 3.17. Использование итератора «Для Каждого»
Сообщение = Новый СообщениеПользователю; Для Каждого Справочник из Метаданные.Справочники Цикл Сообщение.Текст = Символы.ПС + Справочник.ПолноеИмя(); Сообщение.Сообщить(); МенеджерСправочника = Справочники[Справочник.Имя]; Выборка = МенеджерСправочника.Выбрать(); Пока Выборка.Следующий() Цикл Сообщение.Текст = Выборка.Наименование; Сообщение.Сообщить(); КонецЦикла; КонецЦикла;
Профессиональная разработка в системе «1С:Предприятие 8»
Объектные и необъектные данные
Глава 4. Работа с данными Объектные и необъектные данные
Объектные данные
Все данные, которые хранятся в базе данных «1С:Предприятия», можно разделить на две категории: объектные и необъектные. Поскольку природа этих данных различна, различаются и способы работы с ними.
Модель хранения данных
К объектным данным относятся данные справочников, документов, планов видов характеристик, планов счетов, планов видов расчета, бизнеспроцессов, задач, планов обмена. К необъектным данным относятся данные регистров сведений, регистров накопления, регистров расчета, перерасчетов, регистров бухгалтерии и последовательностей. Также к необъектным данным относятся константы. С точки зрения системы объектные данные состоят из отдельных объектов. Каждый из этих объектов обладает внутренним уникальным идентификатором, благодаря наличию которого к некоторой совокупности значений, хранящихся в базе данных, можно обращаться как к единому целому – объекту. Например, объектом является элемент справочника или документ. Каждый объект, помимо того что он является совокупностью значений некоторых полей, имеет также определенную значимость сам по себе. Например, элемент справочника ФизическиеЛица – это некое физическое лицо, которое имеет набор характеризующих его значений: имя, фамилия, отчество, паспортные данные и т. д. У него может поменяться, например, фамилия или паспортные данные, но при этом с точки зрения системы он останется тем же самым физическим лицом – объектом. Удаление какоголибо объекта из системы приводит к тому, что состояние базы данных с точки зрения прикладного решения изменяется. Даже создав новый элемент справочника ФизическиеЛица с теми же самыми значениями реквизитов, мы получим уже другое состояние базы данных, поскольку это будет уже другой объект с другим уникальным идентификатором.
К объектным данным в «1С:Предприятии» относятся данные следующих объектов конфигурации: ■■ ■■ ■■ ■■ ■■ ■■ ■■ ■■
Справочник, Документ, План видов характеристик, План счетов, План видов расчета, План обмена, Бизнес-процесс, Задача.
Для каждой объектной сущности конфигурации система создает набор связанных между собой таблиц, в которых и будут храниться данные этого объекта. Количество и состав таблиц различны для каждого объекта метаданных. Структура хранения объектных данных всегда состоит из основной таблицы и, возможно, нескольких других таблиц (по одной таблице на каждую табличную часть объекта). Например, для документа Доверенность, который имеет некоторый набор реквизитов и табличную часть Товары (рис. 4.1), в базе данных будут созданы две таблицы.
В отличие от объектных данных, необъектные данные не имеют собственной ценности и полностью описываются значениями своих полей. Необъектные данные представляют собой записи, которые хранятся в базе данных. Для записей не поддерживаются внутренние уникальные идентификаторы. Удалив некоторую запись и создав новую с точно такими же значениями полей, мы получим то же самое состояние базы данных, которое было до удаления записи. Рассмотрим работу с объектными и необъектными данными более подробно. Том 1
Рис. 4.1. Документ «Доверенность»
65
Глава 4. Работа с данными Таблица документа будет содержать поля для каждого реквизита документа, а для табличной части будет создана отдельная таблица, содержащая поля для всех реквизитов табличной части документа (рис. 4.2).
Ссылка Значение ссылочного типа (СправочникСсылка.<имя>, ДокументСсылка.<имя> и т. д.) используется везде, где требуется однозначно идентифицировать объект базы данных. Фактически такое значение представляет собой внутренний идентификатор, который хранится в поле Ссылка таблиц базы данных. Например, справочник Валюты хранится в базе данных в таблице, которая, помимо служебных колонок (стандартных реквизитов), содержит отдельные колонки для каждого реквизита справочника, заданного в конфигураторе. Поле Ссылка – это одно из служебных полей. Значение этого поля позволяет однозначно отличить один элемент справочника от другого (проще говоря, одну валюту от другой), рис. 4.3.
Рис. 4.2. Таблицы документа «Доверенность»
Отличительной особенностью этих таблиц является то, что каждая из них содержит поле Ссылка, в котором хранится внутренний идентификатор, соответствующий каждому из документов. Таким образом, объект документа представляет собой совокупность записи основной таблицы и строк табличных частей, относящихся к этому документу. Основная таблица объектных данных также содержит обязательное поле, в котором хранится текущая версия объекта. Значение этого поля изменяется при каждой записи данных объекта в базу данных. Благодаря использованию этого поля обеспечивается оптимистическая блокировка объектных данных. Подробнее
Раздел «Оптимистическая блокировка», стр. 74.
Для работы с объектными данными во встроенном языке существуют два основных типа: ссылка и объект. Рассмотрим каждый из них более подробно.
66
Рис. 4.3. Поле «Ссылка» справочника «Валюты»
Значение ссылки может, например, выбираться в полях ввода, храниться в полях других таблиц базы данных и т. д. Например, поля Организация и ФизЛицо документа Доверенность будут хранить ссылки на элементы справочников Организации и ФизическиеЛица (рис. 4.4). Значения ссылочного типа можно сравнивать между собой. Важным моментом является то, что для каждого объекта конфигурации во встроенном языке создается свой тип ссылки. Таким образом, например, ссылка на справочник Организации никогда не будет равна ссылке на справочник ФизическиеЛица, поскольку это значения разных типов. Однако две ссылки на справочник Организации могут быть равны между собой, и это будет выполняться только в том случае, если это ссылки на один и тот же объект базы данных (рис. 4.5).
Профессиональная разработка в системе «1С:Предприятие 8»
Объектные и необъектные данные Листинг 4.1. Сравнение объектов «Ссылка»
Ссылка1 = Справочники.Валюты.НайтиПоКоду("000000810"); ВыборкаВалют = Справочники.Валюты.Выбрать(); Пока ВыборкаВалют.Следующий() Цикл Если Ссылка1 = ВыборкаВалют.Ссылка Тогда Сообщение = Новый СообщениеПользователю; Сообщение.Текст = " " + ВыборкаВалют.Код + " " + ВыборкаВалют.Наименование; Сообщение.Сообщить(); КонецЕсли; КонецЦикла;
Типы ссылок имеют значение по умолчанию – так называемую пустую ссылку. Пустая ссылка – это значение ссылки, которому не соответствует ни один объект в базе данных. Фактически такой внутренний идентификатор выглядит следующим образом: 00000000-0000-0000-0000-000000000000 Рис. 4.4. Хранение ссылок в полях базы данных
Так как тип ссылки создается для каждого объекта конфигурации, то, например, пустые ссылки на разные справочники никогда не будут равны между собой (листинг 4.2). Листинг 4.2. Сравнение пустых ссылок
ПустаяСсылкаНоменклатура = Справочники.Номенклатура.ПустаяСсылка(); ПустаяСсылкаКонтрагенты = Справочники.Контрагенты.ПустаяСсылка(); Если ПустаяСсылкаНоменклатура <> ПустаяСсылкаКонтрагенты Тогда Сообщение = Новый СообщениеПользователю; Сообщение.Текст = "Ссылки не равны"; Сообщение.Сообщить(); КонецЕсли;
Ссылка позволяет обращаться к свойствам объекта базы данных, а также получать сам объект. При этом выполняется чтение информации из базы данных, поскольку сама ссылка не содержит этих данных. Подробнее
Раздел «Объект», стр. 69.
Представление ссылочных значений Рис. 4.5. Сравнение объектов «Ссылка»
Ссылки, указывающие на один и тот же объект базы данных, будут равны между собой независимо от того, каким образом они получены. Например, ссылка на валюту с кодом 810 (рубли), полученная через менеджера справочника Валюты, будет равна ссылке на эту валюту, полученной из выборки справочника Валюты (листинг 4.1). Том 1
Поскольку ссылочные значения могут выбираться в поле ввода и использоваться в других элементах интерфейса системы, существует механизм формирования представлений ссылочных значений. Благодаря этому механизму, пользователь может оперировать не безличными внутренними идентификаторами, которые содержит ссылка, а вполне определенными и понятными ему данными, идентифицирующими объекты базы данных. При добавлении объектов конфигурации система самостоятельно определяет правила формирования представлений ссылочных значений,
67
Глава 4. Работа с данными и от разработчика не требуется никаких специальных действий. Однако при необходимости он может внести изменения в правила формирования представлений для ссылок на некоторые типы объектов базы данных. Например, для элементов справочников, видов характеристик, счетов, видов расчетов и узлов планов обмена представление ссылок может быть задано либо в виде кода, либо в виде наименования (рис. 4.6).
А для документов и бизнес-процессов система предоставляет только единственное неизменяемое представление ссылочных значений в виде совокупности синонима документа или бизнес-процесса, его номера и даты. Например: «Приходная накладная 000000003 от 03.05.2011 15:35:27».
Контроль ссылочной целостности «1С:Предприятие» предоставляет разработчику возможность контролировать ссылочную целостность базы данных, однако использование этой возможности не является обязательным. С точки зрения платформы в базе данных вполне могут содержаться неразрешимые ссылки (т. е. ссылки на объекты, которых не существует в базе данных), и это не является ошибкой. Необходимость поддержания ссылочной целостности базы данных определяется логикой прикладного решения, и ситуация, когда база данных содержит ссылки на несуществующие объекты, может быть вполне допустимой для данного прикладного решения. Вопрос о необходимости контроля ссылочной целостности возникает при удалении данных из базы данных. Система позволяет гибко использовать возможности контроля ссылочной целостности как при интерактивном, так и при программном удалении объектов. Интерактивное удаление объектов может быть выполнено двумя способами.
Рис. 4.6. Задание представления справочника
Для задач разработчик может выбрать между представлением ссылок в виде номера или наименования (рис. 4.7).
Во-первых, объект может быть удален непосредственно из базы данных. В этом случае не будет выполняться никаких проверок ссылочной целостности и последующее восстановление объекта будет невозможно. Возможность непосредственного интерактивного удаления регулируется правом Интерактивное удаление. Во-вторых, интерактивное удаление может быть выполнено с использованием механизма контроля ссылочной целостности. В этом случае удаление выполняется в два этапа: сначала пользователь устанавливает пометку удаления для тех объектов, которые он собирается удалить, а затем выполняет процедуру удаления помеченных объектов. При этом сначала будет выполнен поиск ссылок на удаляемые объекты в других данных, а затем для объектов, ссылки на которые отсутствуют, будет выполнено удаление.
Рис. 4.7. Задание представления задачи
68
При удалении объектов средствами встроенного языка также существует возможность использовать или не использовать контроль ссылочной целостности. Непосредственное удаление объектов может быть выполнено методом объекта Удалить(), в то время как пометка на удаление может быть установлена с помощью метода объекта УстановитьПометкуУдаления(). Последующий поиск помеченных на удаление объектов может быть выполнен при помощи функции глобального контекста НайтиПомеченныеНаУдаление(), а их удаление – глобальной процедурой УдалитьОбъекты(), которая позволяет удалять объекты как с контролем Профессиональная разработка в системе «1С:Предприятие 8»
Объектные и необъектные данные ссылочной целостности, так и без. При этом следует учитывать, что удаление с контролем ссылочной целостности выполняется в монопольном режиме. При необходимости может быть выполнен отдельно только поиск ссылок на удаляемые объекты – для этого используется функция глобального контекста НайтиПоСсылкам(), которая возвращает список найденных ссылок на переданные ей объекты.
Особенности использования пометки удаления Для того чтобы отличить объекты, помеченные на удаление, от других объектов базы данных, таблицы, хранящие данные этих объектов, содержат специальное поле ПометкаУдаления. Значение этого поля может быть установлено двумя способами.
Рис. 4.8. Документ «ЗаказПоставщику»
Объект документа (ДокументОбъект.ЗаказПоставщику) будет представлять собой совокупность значений полей основной таблицы документа и полей каждой из таблиц, в которых хранятся данные его табличных частей (рис. 4.9).
Во-первых, может использоваться интерактивная установка пометки удаления или программное выполнение метода объекта УстановитьПометкуУдаления(). В этом случае кроме собственно установки значения этого поля будет выполнен ряд дополнительных действий, состав которых зависит от типа помечаемого объекта. Например, для справочника будет установлена пометка удаления для всех подчиненных элементов этого справочника и подчиненных справочников, для документа будет выполнена отмена проведения и т. д. Также будет вызвано событие объекта ПередЗаписью(), поскольку будет выполняться сохранение измененного свойства ПометкаУдаления этого объекта. Во-вторых, значение поля ПометкаУдаления может быть установлено путем непосредственной установки свойства ПометкаУдаления объекта и последующей его записи. В этом случае никаких дополнительных действий выполняться не будет, однако следует учитывать особенности работы некоторых объектов. Например, документ не может быть одновременно проведен и помечен на удаление, поэтому, если требуется пометить на удаление проведенный документ, предварительно следует установить его свойство Проведен в значение Ложь или выполнить отмену проведения документа (Записать(РежимЗаписиДокумента.ОтменаПроведения)).
Объект Тип объекта служит, прежде всего, для модификации (чтения и изменения) данных, содержащихся в объекте базы данных. Остальные объекты встроенного языка позволяют только читать информацию базы данных. Как уже говорилось ранее, объект представляет собой совокупность записи основной таблицы и строк табличных частей, относящихся к этому объекту. Например, рассмотрим документ ЗаказПоставщику, имеющий три табличные части (рис. 4.8). Том 1
Рис. 4.9. Данные объекта документа
Тип объекта используется при создании новых объектов для редактирования и удаления существующих объектов. Кроме этого, тип объекта используется для отображения и редактирования всех данных объекта в форме объекта.
69
Глава 4. Работа с данными Значения этого типа, так же как и значения ссылок, можно сравнивать между собой. Однако, в отличие от ссылок, значения этого типа будут равны между собой только тогда, когда они являются одним и тем же экземпляром программного объекта. Например, если в следующем примере (листинг 4.3) в переменную Объект1 получить экземпляр программного объекта, соответствующий элементу справочника Номенклатура и затем значение этой переменной присвоить переменной Объект2, то значения этих переменных будут равны.
Во-вторых, значение этого типа может быть получено из ссылки путем выполнения метода ПолучитьОбъект(). В этом случае будет создан экземпляр программного объекта и выполнено чтение данных из базы данных (или из кеша). При этом считываются значения всех реквизитов объекта и значения всех реквизитов всех его табличных частей (рис. 4.11).
Листинг 4.3. Сравнение объектов
Объект1 = Справочники.Номенклатура.НайтиПоКоду("000000001").ПолучитьОбъект(); Объект2 = Объект1; Сообщение = Новый СообщениеПользователю; Сообщение.Текст = "Объект1 = Объект2"; Сообщение.Сообщить();
Если же в переменные Объект1 и Объект2 получить экземпляры объекта, соответствующие одному и тому же элементу справочника Номенклатура, то значения этих переменных не будут равны, несмотря на то, что в них считан один и тот же объект базы данных и совпадают все данные этого объекта (листинг 4.4). Листинг 4.4. Сравнение объектов
Объект1 = Справочники.Номенклатура.НайтиПоКоду("000000001").ПолучитьОбъект(); Объект2 = Справочники.Номенклатура.НайтиПоКоду("000000001").ПолучитьОбъект(); Сообщение = Новый СообщениеПользователю; Сообщение.Текст = "Объект1 <> Объект2"; Сообщение.Сообщить();
Значение типа
Объект
Рис. 4.11. Получение объекта
В-третьих, значение этого типа может быть получено из выборки путем выполнения метода с аналогичным названием – ПолучитьОбъект(). В этом случае также будет создан экземпляр программного объекта, однако чтение из базы данных выполняться не будет, т. к. выборка считывает из базы данных все данные объектов, и данные созданного экземпляра объекта будут заполнены непосредственно из программного объекта выборки (рис. 4.12).
может быть получено несколькими способами.
Во-первых, значение этого типа может быть получено через менеджер объекта, с использованием соответствующего метода (например, для справочников это метод СоздатьЭлемент(), для документов – СоздатьДокумент() и т. д.). При этом будет создан новый экземпляр программного объекта, которому не соответствует ни один объект в базе данных. В дальнейшем, когда будет выполнена запись этого объекта, появится и новый объект в базе данных (рис. 4.10).
Рис. 4.12. Получение объекта
В связи с тем, что тип объекта позволяет модифицировать данные, он имеет (помимо свойств и методов) целый ряд событий, позволяющих разработчику определять собственный алгоритм обработки выполняемых действий. Среди основных событий, поддерживаемых этим типом, можно перечислить следующие. – это событие возникает перед записью объекта в базу данных, после начала транзакции записи, но до начала непосредственной записи данных. В обработчике этого события можно проанализировать необходимость (или возможность) выполнения записи данных и отказаться от нее, если какие-либо условия не выполняются. ПередЗаписью
– это событие возникает после того, как данные записаны в базу данных, но до того, как окончится транзакция записи. В обработчике этого события можно выполнять те действия, которые обязательно ПриЗаписи
Рис. 4.10. Создание нового объекта
70
Профессиональная разработка в системе «1С:Предприятие 8»
Объектные и необъектные данные должны быть выполнены только в том случае, если объект записан. Здесь также разработчик может отказаться от записи данных, если, например, в результате записи этих данных в базу нарушаются какие-либо условия. – это событие возникает у нового объекта данных в том случае, если он создается путем копирования (интерактивного или программного) существующего объекта данных. ПриКопировании
– это событие также возникает у нового объекта данных при интерактивном создании нового объекта, при вводе объекта на основании (интерактивного или программного), а также при выполнении метода объекта Заполнить(). В обработчике этого события предусматривается некоторый алгоритм, позволяющий выполнять начальное заполнение реквизитов нового объекта в зависимости от типа объекта-основания. ОбработкаЗаполнения
– это событие вызывается перед записью данных объекта, до начала транзакции записи. В обработчике этого события разработчик может реализовать собственные алгоритмы проверки заполнения реквизитов объекта, добавить в массив проверяемых реквизитов дополнительные реквизиты, чтобы платформа выполнила их проверку, или очистить массив проверяемых реквизитов, отказавшись от их стандартной проверки. Разработчик также может отказаться от записи объекта, если, например, какие-то условия проверки не были выполнены. ОбработкаПроверкиЗаполнения
– это событие возникает в транзакции удаления перед непосредственным удалением объекта из базы данных. В обработчике этого события можно предусмотреть выполнение каких-либо действий перед удалением объекта, а также при необходимости отменить удаление объекта, если не выполняются какие-либо условия. ПередУдалением
Кеширование представлений и объектов При работе с объектными данными (как программно, так и интерактивно), система выполняет кеширование считываемых данных в оперативной памяти. Для этого используется кеш объектов. При любых интерактивных действиях и при программном доступе к объектным данным с использованием объектной модели прежде всего система будет выполнять обращение к кешу объектов для того, чтобы получить запрашиваемые данные. Кеш объектов состоит из двух частей: транзакционного кеша и обычного кеша. В зависимости от того, происходит ли чтение в рамках транзакции или нет, будет выполняться обращение к той или иной части кеша (рис. 4.13). В кеш объектов считываются два «вида» данных: либо все данные объекта целиком, либо значения полей, необходимые для формирования представления ссылки на данный объект. Том 1
Рис. 4.13. Обращение к кешу объектов
Значения полей, необходимые для получения представления ссылки, считываются тогда, когда возникает необходимость отобразить ссылку на объект в каком-либо элементе интерфейса, а также при явном или неявном преобразовании ссылочной переменной к типу Строка. В остальных случаях выполняется полное чтение всех данных объекта, в том числе и тогда, когда выполняется обращение к какому-либо реквизиту объекта через точку от ссылки. Эту особенность нужно учитывать при проектировании структуры объектов конфигурации. Так, например, если предполагается хранение в информационной базе картинок, образов файлов или больших текстовых данных, то рекомендуется создавать для этого отдельные структуры хранения (например, справочники или регистры сведений), а не включать эту информацию в состав реквизитов или табличных частей объектов, которым эта информация соответствует. Это позволит избежать считывания и записи больших объемов данных при работе с этими объектами. Обычный кеш
Если при обращении к обычному кешу требуемых данных в нем нет, то выполняется чтение данных объекта из базы данных и сохранение их в кеше. Уникальным идентификатором для кеша в данном случае будет являться ссылка на объект базы данных. Поэтому данные каждого считанного объекта могут существовать в кеше в одном из двух видов: либо все данные объекта, либо представление объекта. Таким образом, если мы обратимся к кешу для получения представления объекта и в кеше есть информация для нашей ссылки, данные будут взяты из кеша (если в кеше весь объект, нужное представление будет получено из данных объекта). Если в кеше нет информации для нашей ссылки, из базы данных в кеш будут считаны только поля, необходимые для формирования представления объекта.
71
Глава 4. Работа с данными Если мы обратимся к кешу для получения реквизита объекта (через точку от ссылки) и в кеше есть информация для нашей ссылки, дальнейшие действия будут зависеть от того, какие именно данные находятся в кеше. Если в кеше весь объект, значение реквизита будет получено из кеша. Если в кеше представление объекта, оно будет удалено из кеша и в кеш будут считаны все данные объекта. Если же при получении реквизита объекта в кеше нет информации для нашей ссылки, из базы данных будут считаны все поля объекта. Считанные данные будут находиться в кеше до тех пор, пока не наступит одно из четырех событий: ■■ считанные данные будут вытеснены из кеша другими считанными данными других объектов (переполнение кеша); ■■ при очередном обращении к кешу окажется, что считанные данные были изменены в базе данных; ■■ закончится интервал времени в 20 минут; ■■ данные будут изменены в базе данных. Все считанные данные помещаются в последовательную очередь, и, поскольку объем кеша ограничен, наиболее старые данные будут вытесняться из кеша последними считанными данными. При повторном обращении к кешу за данными уже считанного объекта будет анализироваться интервал времени, прошедший с момента появления данных в кеше. Если обращение происходит в пределах 20 секунд после поступления данных в кеш, данные считаются верными (валидными). Если интервал превысил 20 секунд, будет выполняться проверка на то, что версия данных, хранящихся в кеше, соответствует версии данных, находящихся в базе данных. Если окажется, что версии данных не совпадают (т. е. произошло изменение данных в базе данных), данные, находящиеся в кеше, будут удалены из него и выполнено повторное считывание данных из базы данных. Начиная с этого момента, начнется отсчет следующего 20-секундного интервала валидности этих данных. Кроме всех вышеперечисленных событий, считанные данные будут удалены из кеша по истечении 20 минут после их последнего считывания из базы данных.
На выполнение второго оператора будет тратиться гораздо меньше времени, поскольку в первом случае (с большой долей вероятности) будет выполняться обращение к базе данных и чтение всех данных объекта, а во втором – чтение из оперативной памяти (кеша объектов). Транзакционный кеш
Если обращение к данным происходит в рамках транзакции, то оно переадресуется транзакционному кешу. Транзакционный кеш по сути представляет собой ту же последовательную очередь, что и обычный кеш, за исключением того, что все данные, находящиеся в транзакционном кеше, являются валидными (гарантированно актуальными). При считывании данных в транзакционный кеш устанавливается блокировка на данные в базе данных, поэтому они гарантированно не могут быть изменены до окончания транзакции. Транзакционный кеш хранит считанные данные до тех пор, пока они не будут вытеснены более поздними считанными данными или пока не закончится транзакция. По окончании транзакции транзакционный кеш очищается, однако действия, выполняемые при этом, зависят от состояния завершения транзакции. Если транзакция завершена успешно (Commit), данные всех объектов, содержащиеся в транзакционном кеше, переносятся в обычный кеш, а транзакционный кеш очищается (рис. 4.14).
Рис. 4.14. Успешное завершение транзакции
Если был выполнен отказ от изменений (Rollback), то просто очищается транзакционный кеш (рис. 4.15).
Рассмотрим последовательное выполнение двух операторов (листинг 4.5), где Номенклатура – это ссылка на объект справочника, а Наименование и ВидНоменклатуры – реквизиты справочника Номенклатура. Листинг 4.5. Последовательное обращение к реквизитам объекта
А = Номенклатура.Наименование; В = Номенклатура.ВидНоменклатуры; Рис. 4.15. Откат транзакции
72
Профессиональная разработка в системе «1С:Предприятие 8»
Объектные и необъектные данные
Оптимизированная запись объектов При записи объектов базы данных (программной или интерактивной) выполняется оптимизация записи изменений в базу данных. Так, например, если не менялись значения реквизитов самого объекта, то будет записана только минимальная информация об изменении (версия объекта).
Неопределено,
если новый элемент создается интерактивной командой из панели действий. Поэтому в алгоритме начального заполнения нового объекта полезно проанализировать этот параметр и в зависимости от его значения выполнить определенные действия. Следует учитывать, что при копировании (как интерактивном, так и средствами встроенного языка) событие ОбработкаЗаполнения не вызывается.
Если не менялись строки табличной части, то табличная часть записываться не будет.
Блокировки
Если менялись только отдельные строки табличной части или добавлялись новые строки, то будут записаны только измененные и добавленные строки. Однако если менялся порядок строк или строки удалялись, то будут записаны все строки табличной части.
При работе с объектными данными система обеспечивает два вида блокировок – пессимистическую и оптимистическую, которые позволяют выполнять целостные изменения объектов при одновременной работе нескольких пользователей.
Создание новых объектов
Пессимистическая блокировка
Зачастую при разработке или модификации прикладных решений требуется выполнять некоторые действия, сопровождающие создание тех или иных новых объектов базы данных. Например, при создании новой приходной накладной может потребоваться автоматически заполнять поле Склад, если известно, что все поступающие товары должны приходоваться только на один определенный склад. Также может потребоваться установка каких-либо других реквизитов документа по умолчанию.
Механизм пессимистической блокировки запрещает изменение данных объекта другими сессиями или данной сессией до тех пор, пока блокировка не будет снята этим объектом встроенного языка (рис. 4.16).
Прежде всего, при заполнении нового объекта данными можно во многих случаях обойтись вообще без написания какого-либо кода. Для этого у реквизитов объектов конфигурации есть свойства Значение заполнения и Заполнять из данных заполнения. Эти свойства позволяют визуально (в конфигураторе) задать правила, по которым реквизит будет заполняться данными при создании нового объекта.
Механизм пессимистической блокировки используется системой «1С:Предприятие» для блокировки объектов, редактируемых в форме. В то же время разработчик также имеет возможность задействовать этот механизм, используя средства встроенного языка.
Если этих возможностей недостаточно, то нужно использовать возможности встроенного языка. Действия с данными объекта нужно выполнять в модуле объекта, в обработчике события ОбработкаЗаполнения. Это событие возникает при интерактивном создании нового объекта, при вводе объекта на основании (интерактивном или программном), а также при выполнении метода объекта Заполнить(). В обработчике этого события предусматривается некоторый алгоритм, позволяющий выполнять начальное заполнение реквизитов нового объекта в зависимости от типа объекта-основания. При этом в параметр ДанныеЗаполнения этого обработчика могут быть переданы различные значения в зависимости от того, каким образом создается новый элемент. Например, он может иметь тип ссылки, если новый объект вводится на основании. Или он может иметь тип Структура, если новый объект создается интерактивной командой из списка, в котором установлен отбор. В этом случае структура будет содержать значения элементов отбора этого списка. Также этот параметр может иметь тип Том 1
Рис. 4.16. Пессимистическая блокировка
Если говорить о системе, то механизмом пессимистической блокировки управляют расширения форм прикладных объектов. В тот момент, когда пользователь начинает модификацию объекта в форме, расширение формы устанавливает пессимистическую блокировку. Если после этого другой пользователь, например, попытается выполнить редактирование того же объекта, ему будет выдано сообщение о том, что не удалось заблокировать объект. Когда пользователь, редактировавший объект, закроет форму объекта, расширение формы снимет пессимистическую блокировку. Поэтому пессимистическую блокировку можно рассматривать как блокировку данных для редактирования, связанную с идентификатором конкретной формы, в которой редактируется объект.
73
Глава 4. Работа с данными Расширения стандартных форм объектов устанавливают пессимистическую блокировку автоматически, но разработчик, находясь в модуле формы, может с помощью метода формы ЗаблокироватьДанныеФормыДляРедактирования() обеспечить поведение любой другой формы, аналогичное стандартному. Для снятия блокировки используется метод формы РазблокироватьДанныеФормыДляРедактирования(). При использовании этих методов блокировка будет привязана к идентификатору той формы, из которой она установлена. Кроме того, чтобы задействовать пессимистическую блокировку, разработчик может использовать методы глобального контекста ЗаблокироватьДанныеДляРедактирования() и РазблокироватьДанныеДляРедактирования(). В эти методы обязательно нужно передать ссылку на объект информационной базы или ключ записи регистра сведений, данные которого требуется заблокировать. Если блокировка устанавливается с привязкой к конкретной форме, то в метод ЗаблокироватьДанныеДляРедактирования() нужно передать также идентификатор этой формы. В этом случае для снятия блокировки методом РазблокироватьДанныеДляРедактирования() указывается этот же идентификатор.
Исключение // Нельзя модифицировать данные объекта. Сообщение = Новый СообщениеПользователю; Сообщение.Текст = "Данные объекта уже заблокированы"; Сообщение.Сообщить(); Возврат Ложь; КонецПопытки; КонецФункции
Следует помнить, что попытки установить блокировку одного и того же объекта с указанием идентификатора формы и без указания идентификатора несовместимы друг с другом. Оптимистическая блокировка
Оптимистическая блокировка запрещает запись объекта в базу данных, если после считывания объекта он был изменен в базе данных (рис. 4.17).
Можно не использовать в методах глобального контекста идентификатор формы. В этом случае устанавливаемая пессимистическая блокировка не будет привязана к конкретной форме. Например, это может понадобиться в обработке, выполняющей программную модификацию данных параллельно работе других пользователей. Перед модификацией данных нужно попытаться их заблокировать. Если попытка удалась, данные можно модифицировать. Если объект уже заблокирован, то будет вызвано исключение, которое может быть обработано конструкцией Попытка … Исключение … КонецПопытки (листинг 4.6). Листинг 4.6. Пример проверки пессимистической блокировки
&НаСервере Функция ПримерМодификации() ТоварСсылка = Справочники.Товары.НайтиПоКоду("000000001"); Попытка ЗаблокироватьДанныеДляРедактирования(ТоварСсылка); // Можно выполнять модификацию данных объекта. // ... ТоварОбъект = ТоварСсылка.ПолучитьОбъект(); ТоварОбъект.Наименование = "Новое наименование"; ТоварОбъект.Записать(); Возврат Истина;
74
Рис. 4.17. Оптимистическая блокировка
Строго говоря, оптимистическая блокировка представляет собой проверку, которая выполняется перед записью объекта в базу данных. Когда программный объект считывает данные из базы данных, в числе прочего считывается и версия объекта, хранящегося в базе данных. Предположим, что до начала редактирования данных (до установки пессимистической блокировки) данные объекта в базе данных были изменены (например, другим пользователем). В этом случае номер версии объекта, хранящийся в базе данных, также изменится. При попытке первого пользователя записать или заблокировать этот объект будет выполнена проверка соответствия версии объекта, находящегося в памяти, и версии объекта, хранящейся в базе данных. Так как версии отличаются, будет выдано сообщение об ошибке, т. е. сработает оптимистическая блокировка. Оптимистическая блокировка гарантирует, что если пользователь изменяет объект, то его изменения не «затрут» изменения, сделанные другими сессиями или другими программными объектами в этой же сессии. Профессиональная разработка в системе «1С:Предприятие 8»
Объектные и необъектные данные Пессимистические блокировки и транзакции
Важным моментом является то, что пессимистическая и оптимистическая блокировки обеспечиваются не средствами базы данных, а средствами собственного менеджера блокировок, который работает «над уровнем» базы данных. По этой причине объектные блокировки абсолютно прозрачны для транзакций. Единственная особенность заключается в том, что если пессимистическая блокировка была установлена в транзакции и в результате был выполнен откат этой транзакции (rollback), то блокировка будет автоматически снята. Подробнее
стей выделяются только константы: для каждой константы в базе данных хранится одно значение. Поэтому в дальнейшем мы их рассматривать не будем; работа с ними не вызывает сложностей.
Подчинение регистратору Важным свойством всех записей является их подчинение регистратору. Регистратор – это некоторый документ, с которым связаны записи необъектных данных. Не может существовать записей, не относящихся к какому-либо регистратору. Исключение составляет лишь регистр сведений, когда для него выбран независимый режим записи (без подчинения регистратору). Поэтому любая запись всегда содержит обязательное поле Регистратор (рис. 4.18).
Раздел «Транзакции», стр. 104.
Необъектные данные Модель хранения данных К необъектным данным в «1С:Предприятии» относятся данные следующих объектов конфигурации: ■■ ■■ ■■ ■■ ■■ ■■ ■■
регистр сведений, регистр накопления, регистр бухгалтерии, регистр расчета, перерасчет, последовательность, константа.
Необъектные данные с точки зрения «1С:Предприятия» представляют собой некоторый набор записей, которые хранятся в таблице. Каждая из этих записей полностью описывается значениями своих полей. Для системы эти записи не обладают какой-либо значимостью, кроме того, что в их полях содержатся некоторые значения. Запись можно удалить, а затем создать новую, с такими же значениями полей. Состояние базы данных при этом не изменится (с точки зрения логики прикладного решения). Это принципиально отличает необъектные данные от объектных: объект нельзя создать дважды, он ценен сам по себе, самим фактом своего существования. Второе важное отличие заключается в том, что, изменив значения полей записи, мы получаем другую запись, в то время как изменение значений полей объекта не влечет за собой появление нового объекта. Большинство необъектных сущностей конфигурации имеют общий порядок работы с данными. Из всей совокупности необъектных сущноТом 1
Рис. 4.18. Поле «Регистратор»
Записи, относящиеся к одному регистратору, называются движениями этого регистратора. Движения не являются частью владеющего ими документа, при записи и чтении документа они не записываются и не считываются. Однако они тесно связаны с ним. Движения могут создаваться при проведении документов, при записи документов, могут формироваться интерактивно или в виде набора записей регистра (с отбором по регистратору). Движения не могут существовать отдельно от своих регистраторов. Поэтому при удалении документов или отмене проведения (если свойство Удаление движений установлено в значение, отличное от Не удалять) система производит поиск движений этого документа в таблицах всех регистров, для которых данный документ может быть регистратором, и удаляет их. Кроме этого, при удалении документа его движения всегда удаляются. Таким образом, время жизни записей определяется их регистратором: если регистратора нет, то и нет смысла в существовании его движений. Даже в том случае, когда записи создаются без непосредственного участия регистратора, они все равно обязательно должны быть подчинены какомулибо документу; запись нельзя записать, если в ней не указана ссылка на регистратор.
75
Глава 4. Работа с данными Наличие или отсутствие движений не связано с проведенностью документа-регистратора или с пометкой его на удаление: непроведенный документ может иметь движения, проведенный документ может не иметь движений, помеченный на удаление документ также может иметь движения. Такой подход позволяет реализовывать в системе «1С:Предприятие» различные способы регистрации изменений в учетных механизмах (регистрах). Например, движения документа могут редактироваться непосредственно в самом документе, и в этом случае понятие проведения документа просто не имеет смысла. Такой прием используется при автоматизации бухгалтерских задач, для ручного ввода проводок. Также дата движений документа не связана жестко с датой регистратора. Например, один и тот же документ может иметь движения разными датами. Эта возможность используется, например, при автоматизации задач планирования, для ввода тех или иных планируемых в будущем значений. Наиболее простой моделью использования регистров является создание движений в обработчике проведения регистратора. В этом случае вся остальная логика работы будет поддерживаться системой автоматически. Другие варианты взаимодействия движений и регистратора следует разрабатывать и описывать самостоятельно, в зависимости от конкретной прикладной задачи.
Уникальность записей Для каждого объекта метаданных в системе определен ключ записи. Данные объекта конфигурации не могут содержать записи с одинаковыми значениями ключа записи. Ключ записи формируется, как правило, из значений нескольких полей объекта конфигурации. Для разных объектов конфигурации состав ключа записи отличается, кроме этого он может быть различным для одного и того же объекта конфигурации, в зависимости от его свойств. Для всех необъектных сущностей, подчиненных регистратору, ключ записи включает ссылку на регистратор и номер строки. Номер строки, собственно, и используется для обеспечения уникальности записей, а также для упорядочивания записей в пределах регистратора. Кроме этого, в состав ключа записи могут входить и другие поля, например, период, измерения регистра – для необъектных сущностей, не подчиненных регистратору. Наличие уникального ключа требуется системе для решения различных задач. Например, это позволяет позиционироваться в табличном поле на некоторую запись.
76
Набор записей По аналогии с объектными данными, изменение которых возможно только при помощи типов объектов, наборы записей используются для модификации необъектных данных: они позволяют читать, модифицировать и удалять необъектные данные. По своей сути набор записей представляет собой коллекцию отдельных записей, принадлежащих некоторому объекту конфигурации. В зависимости от объекта конфигурации набор записей может содержать только некоторые или же все записи, принадлежащие этому объекту конфигурации. Для указания того, какие именно записи должны входить в набор записей, используется его свойство Отбор. Элементы отбора в наборе записей для того или иного объекта конфигурации создаются платформой; разработчик не имеет возможности добавлять собственные элементы отбора, но может использовать существующие, устанавливая для них условия равенства нужному значению. В таблице 4.1 представлен состав отбора в наборе записей для различных объектов конфигурации. Таблица 4.1. Поля, по которым устанавливается отбор Объект конфигурации
Поля, по которым устанавливается отбор
Регистр сведений (подчиненный регистратору) Регистр сведений (непериодический, независимый) Регистр сведений (периодический, независимый) Регистр накопления Регистр бухгалтерии Регистр расчета Перерасчет
Регистратор Набор измерений Период и набор измерений Регистратор Регистратор Регистратор и набор измерений Объект перерасчета (регистратор регистра расчета) и набор измерений перерасчета Регистратор
Последовательность
Существует следующая особенность работы системы с наборами записей: если среди элементов отбора существует отбор по регистратору, то он должен обязательно быть установлен, иначе при записи такого набора будет выдано сообщение об ошибке. Отсюда следует, что для большинства объектов конфигурации, которые хранят необъектные данные, допускается модификация этих данных только частями, «гранулами» – наборами записей, относящихся к определенному регистратору (или более мелкими, если есть возможность установки других отборов). Наряду с этим для независимых регистров сведений допускается модификация сразу всех данных, хранящихся в регистре (если ни одно из условий отбора не задано). Например, для независимого регистра сведений Комплектующие номенклатуры набор записей может включать в себя как все записи регистра (если отбор не установлен), так и лишь некоторые его записи (рис. 4.19). Профессиональная разработка в системе «1С:Предприятие 8»
Объектные и необъектные данные
Рис. 4.19. Примеры наборов записей
В то же время для регистра расчета Основные начисления, у которого обязательно должен быть установлен отбор по регистратору, набор записей может включать в себя максимум все записи, принадлежащие одному регистратору, или некоторое их подмножество (рис. 4.20).
Рис. 4.20. Примеры наборов записей
Отличительной особенностью наборов записей является то, что для них не существует понятия удаления. Набор записей можно только записать, причем запись может быть выполнена либо с замещением существующих записей, удовлетворяющих отбору, либо с добавлением новых записей к существующим. При записи с добавлением новые записи будут добавлены к существующим (рис. 4.21).
Том 1
77
Глава 4. Работа с данными не используется. Основное назначение этого типа – предоставить доступ к значениям полей записи.
Рис. 4.22. Запись с замещением
Рис. 4.21. Запись с добавлением
При записи с замещением существующие записи будут заменены новыми (рис. 4.22). Таким образом, для удаления записей необъектных данных необходимо просто записать с замещением пустой набор записей (т. е. набор записей, не содержащий ни одной записи). Набор записей представляет собой коллекцию объектов, имеющих тип записи. Перебрать все записи, входящие в набор записей, можно с помощью конструкции Для Каждого Из … Цикл. Тип записи используется только в наборах записей. Отдельно от наборов записей этот тип
78
Интерактивное редактирование наборов записей Для необъектных данных не существует механизма, аналогичного объектным блокировкам (оптимистической и пессимистической). Поэтому при использовании набора записей для интерактивного редактирования следует учитывать, что в период после считывания данных из базы данных и перед записью их обратно в базу данных они могут быть изменены в базе данных другой сессией или другим набором записей в этой же сессии. Таким образом, может возникнуть ситуация, когда изменения, внесенные одним пользователем, могут быть потеряны в результате того, что второй пользователь перезапишет их старыми данными. Профессиональная разработка в системе «1С:Предприятие 8»
Система типов
Система типов
Типы значений и типы данных Прикладное решение «1С:Предприятия» оперирует различными величинами: числами, символами, объектами. Каждая величина имеет тип. Тип величины определяет возможные значения и набор определенных для них операций. Существуют типы, определенные на уровне системы, и типы, создаваемые в конкретном прикладном решении. Например, на уровне системы определены примитивные типы, такие как Строка, Число, Булево и т. д. Также на уровне системы определены и другие типы, которые могут быть использованы в прикладном решении, например, универсальные коллекции значений (Массив, Структура, СписокЗначений), общие типы (ТекстовыйДокумент, ТабличныйДокумент, ПостроительОтчета, АнализДанных) и др. Полный перечень типов значений, которые может использовать система «1С:Предприятие», приведен в описании встроенного языка и в синтакс-помощнике. Переменные встроенного языка «1С:Предприятия» не типизированы. Это значит, что тип переменной определяется типом того значения, которое хранится в переменной в данный момент. Таким образом, в произвольные моменты работы прикладного решения переменная может иметь различные типы значения. Подробнее
Раздел «Типы значений», стр. 80.
В то же время данные «1С:Предприятия» существуют не только в оперативной памяти компьютера, где они содержатся в объектах встроенного языка, но и в базе данных, где осуществляется долговременное хранение этих данных. База данных представляет собой совокупность некоторого количества таблиц, создаваемых в соответствии со структурой объектов конфигурации прикладного решения. Таблицы базы данных состоят из полей, и для каждого поля обязательно должен быть указан тип значений, которые могут храниться в этом поле. По этой причине все объекты конфигурации, которые «отвечают» за создание тех или иных полей в базе
Том 1
данных, должны иметь совершенно определенный тип. Такими объектами являются, например, реквизиты, измерения, ресурсы и т. д. Для того чтобы указать тип объекта конфигурации, «отвечающего» за создание того или иного поля базы данных, в системе «1С:Предприятие» используются не типы значений, а более сложное понятие – тип данных. Такой подход позволяет, с одной стороны, изолировать разработчика от конкретного хранилища данных, а с другой стороны – сделать работу с данными значительно более гибкой. Отличие типа данных от типа значения заключается в том, что тип данных является характеристикой, которая может содержать описание как одного, так и нескольких типов значений. В результате у разработчика появляются две важные возможности: ■■ уточнение некоторых примитивных типов значений. Например, можно указать, что реквизит Количество будет содержать не просто числовые значения, а неотрицательные числовые значения с количеством разрядов не более 15 и дробной частью из 3 разрядов; ■■ указание одновременно нескольких возможных типов значений. Например, можно указать, что реквизит Сделка может содержать ссылку как на счет, выставленный покупателю, так и на счет, выставленный поставщику. В результате в реквизите Сделка смогут одновременно храниться как значения одного, так и другого типа. При этом тип данных этого реквизита будет всегда одним и тем же, но тип значения этого реквизита в каждый конкретный момент времени будет определяться типом значения, которое в нем хранится. Типы данных используются в системе «1С:Предприятие» не только в части, связанной с базой данных, но и в интерфейсной части. Так, например, типы данных должны быть определены для всех реквизитов форм и для всех элементов управления, расположенных в форме. Кроме этого, некоторые объекты встроенного языка в силу специфики своего использования также могут потребовать указания типа данных, которые в них хранятся. Например, указание типа данных может использоваться для списка значений, для колонок таблицы значений и дерева значений. Подробнее
Раздел «Типы данных», стр. 99.
79
Глава 4. Работа с данными
Типы значений Примитивные типы Число Числовой тип предназначен для представления десятичных чисел. Максимально допустимая разрядность числа, которая может быть сохранена в базе данных, составляет 32 знака, включая десятичную точку. Для числовых значений, хранящихся в памяти (являющихся, например, значением некоторой переменной), разрядность неограниченна.
Такое поведение таблицы позволяет создать список, который легко читается и не содержит лишней информации. Однако если есть необходимость указывать для нулевых значений определенное представление, то это можно выполнить, используя свойства Формат и ФорматРедактирования соответствующей колонки таблицы (в приведенном примере – колонки ТЗЗначение), рис. 4.24.
Литерал значения типа «Число»
Конкретные значения числового типа во встроенном языке и языке запросов могут быть заданы литералом, который представляет собой набор цифр, написанных непосредственно в тексте модуля. Этот набор цифр может начинаться с символов «+» или «-», обозначающих знак числа. В качестве разделителя целой и дробной части числа используется символ «.» (точка), табл. 4.2. Таблица 4.2. Примеры литералов типа «Число» Число
Литерал
3874 -1475,25
3874 -1475.25
Значение типа «Число» по умолчанию
Для числового типа значением по умолчанию является значение 0. По умолчанию, если не задан специальный формат, это значение будет представляться как 0.
Рис. 4.24. Установка формата колонки таблицы
Для колонки таблицы форматная строка поддерживает параметр ЧН, который задает представление нулевого значения. В результате приведенная выше таблица будет выглядеть, например, следующим образом (рис. 4.25).
Однако некоторые элементы управления, используемые в интерфейсе системы, имеют другое представление нулевого значения, что сделано для более удобного представления информации пользователю. Например, в ячейке таблицы значение по умолчанию числового типа отображается как пустое место (рис. 4.23).
Рис. 4.25. Представление нулевого значения в колонке таблицы
Аналогичного результата можно добиться средствами встроенного языка (листинг 4.7). Листинг 4.7. Установка формата колонки таблицы Рис. 4.23. Представление значения типа «Число» по умолчанию в колонке таблицы
80
Элементы.ТЗЗначение.Формат = "ЧН='---'"; Элементы.ТЗЗначение.ФорматРедактирования = "ЧН="---'";
Профессиональная разработка в системе «1С:Предприятие 8»
Система типов При задании представления нулевого значения для колонки таблицы следует иметь в виду, что концевые пробелы при выводе заданного представления нулевого значения в ячейке таблицы будут обрезаны. В поле ввода значение по умолчанию числового типа отображается в зависимости от разрядности дробной части, заданной при указании числового типа данных этого поля ввода. Подробнее
Раздел «Числовые типы данных», стр. 99.
Если количество разрядов дробной части равно нулю, то числовое значение будет отображаться как 0. Если количество разрядов дробной части отлично от нуля, то числовое значение будет отображено как 0,000 (количество нулей после запятой будет соответствовать количеству разрядов дробной части), рис. 4.26.
Таблица 4.4. Логические операции для типа «Число» Операция
Операнды
Результат
Больше или равно
Число >= Число
Равно
Число = Число
Истина, если первый операнд больше либо равен второму. В противном случае Ложь
Не равно
Число <> Число
Меньше
Число < Число
Больше
Число > Число
Меньше или равно Число <= Число
Истина, если первый операнд больше второго. В противном случае Ложь
Истина, если первый операнд равен второму. В противном случае Ложь
Истина, если первый операнд не равен второму. В противном случае Ложь Истина, если первый операнд меньше второго. В противном случае Ложь
Истина, если первый операнд меньше либо равен второму. В противном случае Ложь
Преобразование значений типа «Число» Неявное преобразование
Рассмотрим пример, когда переменная, указанная в качестве значения логического выражения в операторе цикла, по каким-либо причинам имеет тип Число (листинг 4.8). Листинг 4.8. Неявное преобразование значения типа «Число»
Рис. 4.26. Представление значения типа «Число» по умолчанию в поле ввода
В отличие от колонки таблицы, для поля ввода нельзя задать собственное представление нулевого значения. Операции со значениями типа «Число»
Для значений типа (табл. 4.3).
Число
определены арифметические операции
Операнды
Сложение Вычитание Умножение Деление
Число + Число Число - Число Число * Число Число / Число
Остаток от деления Унарный минус
Результат
Сумма операндов Разность операндов Произведение операндов Частное операндов. Если второй операнд имеет значение 0, будет вызвана ошибка исполнения Число % Число Остаток от деления первого операнда на второй. Если второй операнд имеет значение 0, будет вызвана ошибка исполнения - Число Изменение знака числа
Для значений типа Число определены логические операции (табл. 4.4). Том 1
В этом случае будет выполняться неявное преобразование значения типа Число к нужному типу. Такое преобразование в ряде случаев может быть выполнено системой. Если же такое преобразование невозможно, будет вызвана ошибка исполнения. Неявное преобразование к типу «Строка»
Таблица 4.3. Арифметические операции для типа «Число» Операция
Условие = 22; … Если Условие Тогда … КонецЕсли;
Любое значение типа Число может быть преобразовано к типу Строка. Это позволяет всегда иметь возможность получить представление такого значения (листинг 4.9). Листинг 4.9. Неявное преобразование значения типа «Число» к значению типа «Строка»
Переменная = 156935.785; Сообщить(Переменная);
Результатом выполнения этих операторов будет представление числа: 156935,785. Преобразование будет выполняться в соответствии с текущими региональными настройками информационной базы, например, как в данном случае, группы разрядов будут отделены друг от друга символом «пробел».
81
Глава 4. Работа с данными Неявное преобразование к типу «Булево»
При выполнении булевых операций или при вычислении логических выражений любое значение, отличное от 0, приводится к значению Истина. Значение 0 приводится к значению Ложь (листинг 4.10). Листинг 4.10. Неявное преобразование значения типа «Число» к значению типа «Булево»
Условие = 22; Сообщение = Новый СообщениеПользователю; Если Условие Тогда Сообщение.Текст = "Условие истинно"; Иначе Сообщение.Текст = "Условие ложно"; КонецЕсли; Сообщение.Сообщить();
В приведенном примере будет получено сообщение об истинности условия, поскольку при вычислении логического выражения значение переменной Условие будет преобразовано к типу Булево, результатом чего будет значение Истина. Также, например, при выполнении булевой операции НЕ в следующем примере сначала значение переменной Условие будет преобразовано к типу Булево (значение Истина), а затем уже выполнена операция НЕ. В результате в окно сообщений будет выведено Нет (листинг 4.11). Листинг 4.11. Неявное преобразование значения типа «Число» к значению типа «Булево»
Условие = 22; Сообщить(НЕ Условие);
Значения логического типа Истина/Ложь будут представлены в соответствии с языком интерфейса платформы, выбранным в параметрах конфигуратора или заданным в параметре /L командной строки при запуске «1С:Предприятия». Если «1С:Предприятие» запущено с русским языком интерфейса, логические значения будут представлены как «Да»/«Нет», с английским – «Yes»/«No», с турецким – «Evet»/«Hayır» и т. д. Например, в приведенном примере для русского языка интерфейса будет выведено Нет, а если платформа будет запущена с литовским интерфейсом, то Ne. Неявное преобразование в операциях сравнения
Порядок неявного преобразования типов в операциях сравнения несколько отличается от описанного выше. Если в операции сравнения один из операндов имеет тип Число, а другой – Булево, то значение типа Булево будет приводиться к типу Число, а затем будет выполнено сравнение.
82
Например, в результате выполнения следующего кода (листинг 4.12) будет получено сообщение о ложности условия, поскольку булев операнд будет приведен к типу Число (значение 1), а затем уже будет выполнено сравнение. Листинг 4.12. Неявное преобразование в операции сравнения
Условие = 22; Сообщение = Новый СообщениеПользователю; Если Истина = Условие Тогда Сообщение.Текст = "Условие истинно"; Иначе Сообщение.Текст = "Условие ложно"; КонецЕсли; Сообщение.Сообщить();
Явное преобразование Преобразование к типу «Булево»
Встроенный язык позволяет выполнить явное преобразование значения типа Число к типу Булево. Для этого используется встроенная функция Булево(), в качестве параметра которой передается преобразуемое число. Значение 0 преобразуется в Ложь, все остальные значения преобразуются в значение Истина. Например, в результате выполнения оператора (листинг 4.13) будет получено сообщение Да. Листинг 4.13. Явное преобразование к типу «Булево»
Сообщить(Булево(34.456));
А в результате выполнения следующего оператора (листинг 4.14) будет получено сообщение Нет. Листинг 4.14. Явное преобразование к типу «Булево»
Сообщить(Булево(0));
Преобразование к типу «Строка»
Любое числовое значение может быть преобразовано к типу Строка при помощи встроенной функции Строка(). Результатом такого преобразования будет строковое представление числа, полученное в соответствии с текущими региональными установками информационной базы. Например, результатом выполнения оператора (листинг 4.15) будет сообщение 26475834,456, в котором используются в данном случае разделители групп разрядов (символ «пробел») и десятичный разделитель (символ «запятая»).
Профессиональная разработка в системе «1С:Предприятие 8»
Система типов Листинг 4.15. Явное преобразование к типу «Строка»
Сообщение = Новый СообщениеПользователю; Сообщение.Текст = Строка(26475834.456); Сообщение.Сообщить();
Вторым способом указания многострочных литералов является использование символа «|». В этом случае кавычки используются только в начале и конце литерала, а символ «|» размещается в начале каждой новой строки (листинг 4.17).
Строка
Листинг 4.17. Пример литерала типа «Строка»
Строковый тип предназначен для представления строк в формате Unicode произвольной длины.
Сообщение = Новый СообщениеПользователю; Сообщение.Текст = "Внимание! |В документе не могут присутствовать строки |с нулевым количеством!"; Сообщение.Сообщить();
Литерал значения типа «Строка»
Для того чтобы задать конкретные значения строкового типа, во встроенном языке и языке запросов используются литералы строкового типа. Они представляют собой набор символов, заключенных в кавычки (табл. 4.5).
Результатом как первого, так и второго оператора будет следующее сообщение: Внимание! В документе не могут присутствовать строки с нулевым
Таблица 4.5. Примеры литералов типа «Строка»
Для строкового типа значением по умолчанию является пустая строка (литерал ""). Это значение не имеет представления, иначе говоря, оно не отображается. В некоторых случаях, например, при вычислении значений в отладчике, для наглядности в качестве представления этого значения может использоваться его литерал (").
Строка
Литерал
книга проверка работы
"книга" "проверка работы"
Если в строке необходимо задать символ кавычка ("), то записываются две кавычки подряд (табл. 4.6). Таблица 4.6. Пример литерала типа «Строка» Строка
Литерал
фирма "Ваш сад"
"фирма ""Ваш сад"""
Наряду с однострочными литералами во встроенном языке могут быть использованы строковые литералы, состоящие из нескольких строк. Для обозначения таких литералов используются два различных способа записи. Во-первых, отдельные строки могут быть заключены в кавычки. В этом случае между ними не должно находиться никаких символов, кроме пробелов, переводов строки и комментариев. Например, строка Внимание! В документе не могут присутствовать строки с нулевым количеством! может быть записана следующим образом (листинг 4.16). Листинг 4.16. Пример литерала типа «Строка»
Сообщение = Новый СообщениеПользователю; Сообщение.Текст = "Внимание!" "В документе не могут присутствовать строки" "с нулевым количеством!"; Сообщение.Сообщить();
Том 1
количеством!
Значение типа «Строка» по умолчанию
Операции со значениями типа «Строка»
Для значений типа Строка определена операция конкатенации (табл. 4.7). Таблица 4.7. Операция конкатенации Операция
Операнды
Результат
Конкатенация Строка + Строка Строка, являющаяся соединением первой и второй строки. Длина результирующей строки равна сумме длин соединяемых строк
Для значений типа Строка определены логические операции (табл. 4.8). Таблица 4.8. Логические операции Операция
Больше
Больше или равно Меньше Меньше или равно Равно Не равно
Операнды
Строка > Строка
Результат
Истина, если первая строка больше второй. В противном случае Ложь Строка >= Строка Истина, если первая строка больше либо равна второй. В противном случае Ложь Строка < Строка Истина, если первая строка меньше второй. В противном случае Ложь Строка <= Строка Истина, если первая строка меньше либо равна второй. В противном случае Ложь Строка = Строка Истина, если первая строка равна второй. В противном случае Ложь Строка <> Строка Истина, если первая строка не равна второй. В противном случае Ложь
83
Глава 4. Работа с данными При выполнении логических операций больше, больше или равно, меньше, меньше или равно существует особенность, связанная с тем, что система «1С:Предприятие» позволяет создавать прикладные решения на различных языках. Внутри платформы «1С:Предприятие» работа со строками ведется только в Unicode, и строковые данные в базах данных также сохраняются в Unicode. Стандартом определен некоторый генеральный порядок сортировки для Unicode. Но он подходит не для всех языков. Поэтому для некоторых языков в этот генеральный порядок внесены минимальные изменения для обеспечения соответствия конкретному языку. Порядок сортировки строковых значений, принятый в конкретном регионе, определяет параметр Язык/Страна, выбранный в диалоге Региональные установки информационной базы. В результате этого, например, для русских и латышских региональных установок будет различный порядок следования строк при сортировке их по возрастанию (табл. 4.9). Таблица 4.9. Порядок следования строк для различных региональных установок Русский (Россия)
Латышский (Латвия)
Ača Acb
Acb Ača
Такой порядок соответствует принятому в России и Латвии алфавиту. Поскольку сортировка строковых значений выполняется на основе сравнения их друг с другом, то один и тот же оператор (листинг 4.18) при установке параметра Язык/Страна в диалоге Региональные установки информационной базы в значение Россия будет давать результат Истина, представленный в соответствии с русским языком интерфейса как Да, а если Язык/Страна установлен в значение Латвия, то – Ложь, представленный как Нет. Если запустить «1С:Предприятие» из командной строки с латышским языком интерфейса ("C:\Program Files\1Cv82\8.2.15.310\bin\1cv8.exe" /L lv), то будет выведено Nē, что значит Нет.
Преобразование значений типа «Строка» Неявное преобразование
При выполнении различных операторов могут возникать ситуации, когда значения типа Строка не подходят для выполнения данных операций. Например, если при выполнении следующего оператора переменная Строка будет иметь значение 25 (листинг 4.19), будет выполняться неявное преобразование значения типа Строка к нужному типу. Листинг 4.19. Неявное преобразование значения типа «Строка»
Строка = "25"; Результат = 35 + Строка; Сообщить(Результат);
Такое преобразование в ряде случаев может быть выполнено системой. Если же такое преобразование невозможно, будет вызвана ошибка исполнения. Неявное преобразование к типу «Число»
Если выполнить приведенный выше пример, то строка 25 будет преобразована к типу Число и в окно сообщений будет выведено 60. Однако следует заметить, что преобразование значения типа Строка к типу Число будет выполняться только тогда, когда подобное преобразование осмысленно. Например, если значение переменной Строка будет равно а25, то преобразование уже выполнено не будет и будет вызвано исключение. Неявное преобразование к типу «Булево»
Неявное преобразование значений строкового типа к типу Булево также выполняется лишь тогда, когда такое преобразование имеет смысл. К значениям типа Булево будут преобразованы строки, соответствующие литералам булевых значений, т. е. Истина, Ложь, True и False. Например, рассмотрим (листинг 4.20).
выполнение
следующего
Листинг 4.18. Сравнение строк
Листинг 4.20. Неявное преобразование к типу «Булево»
Результат = "acb" > "ača"; Сообщить(Результат);
Сообщение = Новый СообщениеПользователю; Если "истина" тогда Сообщение.Текст = "Истина"; Иначе Сообщение.Текст = "Ложь"; КонецЕсли; Сообщение.Сообщить(); Если "false" тогда Сообщение.Текст = "Истина";
Таким образом, результат выполнения логических операций над строковыми значениями будет зависеть не только от самих операндов, участвующих в выражении, но и от региональных установок информационной базы, в которой выполняется эта операция.
84
фрагмента
кода
Профессиональная разработка в системе «1С:Предприятие 8»
Система типов Иначе Сообщение.Текст = "Ложь"; КонецЕсли; Сообщение.Сообщить();
В результате в окно сообщений будет выведен текст: Истина Ложь
Однако кроме этого к булевым значениям будут преобразовываться также строковые значения, соответствующие представлению булевых значений для языка, выбранного в языке интерфейса платформы. Например, если запустить «1С:Предприятие» из командной строки с литовским языком интерфейса ("C:\Program Files\1Cv82\8.2.15.310\bin\1cv8.exe" /L lt), то тогда следующий код (листинг 4.21) будет выполнен без ошибок и в окно состояния будет выведено Ложь. Листинг 4.21. Неявное преобразование к типу «Булево»
Сообщение = Новый СообщениеПользователю; Если "Ne" тогда Сообщение.Текст = "Истина"; Иначе Сообщение.Текст = "Ложь"; КонецЕсли; Сообщение.Сообщить();
Если этот же код попытаться выполнить с языком интерфейса de (Немецкий), то будет вызвано исключение, в результате того что значение ne не может быть преобразовано к типу Булево. Если же в этой ситуации строку ne заменить на Nein, что значит Нет по-немецки, то пример (листинг 4.22) отработает без ошибок и в окно сообщений будет выведено Ложь. Листинг 4.22. Неявное преобразование к типу «Булево»
Сообщение = Новый СообщениеПользователю; Если "Nein" тогда Сообщение.Текст = "Истина"; Иначе Сообщение.Текст = "Ложь"; КонецЕсли; Сообщение.Сообщить();
Явное преобразование Преобразование к типу «Число»
Встроенный язык позволяет выполнить явное преобразование значения типа Строка к типу Число при помощи встроенной функции Число(). При этом будут преобразованы только те строки, которые представляют собой правильное строковое представление литерала численного типа. Том 1
Например, может быть выполнено преобразование строки 1125.78 к числу 1125.78 (листинг 4.23). Листинг 4.23. Явное преобразование к типу «Число»
Сообщить(Число("1125.78"));
Следует заметить, что если в строке в качестве разделителя целой и дробной части будет использоваться не точка, а запятая, преобразование также будет выполнено (листинг 4.24). Листинг 4.24. Явное преобразование к типу «Число»
Сообщить(Число("1125,78"));
Преобразование к типу «Дата»
Строковое значение может быть преобразовано к типу Дата. Для этого используется встроенная функция Дата(). Она позволяет преобразовать строку, которая представляет собой части даты, записанные в определенном порядке: год, месяц, день, час, минута и секунда. Например, для того, чтобы получить дату 15 апреля 2011 года 17 часов 45 минут 34 секунды, преобразуемая строка должна иметь вид 20110415174534 (листинг 4.25). Листинг 4.25. Преобразование к типу «Дата»
Сообщить(Дата("20110415174534"));
В результате выполнения приведенного кода будет получена нужная дата: 15.04.2011 17:45:34.
Дата Тип Дата предназначен для представления значения даты и времени с точностью до секунды. Минимальным значением типа Дата является дата 01 января 0001 года 00 часов 00 минут 00 секунд. Литерал значения типа «Дата»
Конкретные значения типа Дата могут быть заданы литералом, который представляет собой последовательность цифр, заключенных в одинарные кавычки. Последовательность цифр представляет собой части даты в следующем порядке: год, месяц, день, час, минута и секунда. Части даты могут быть отделены друг от друга различными разделителями; час, минута и секунда могут быть не указаны – в этом случае предполагается, что они равны нулю (табл. 4.10).
85
Глава 4. Работа с данными Таблица 4.10. Примеры литералов типа «Дата» Дата
Литерал
15.04.2011 22:45:33 15.04.2011 0:00:00 15.04.2011 22:45:33 15.04.2011 22:45:33
'20110415224533' '20110415' '2011-04-15 22:45:33' '2011/04/15-22/45/33'
Задать собственное представление даты по умолчанию можно с помощью свойства ФорматРедактирования поля ввода (рис. 4.28).
В языке запросов для указания литералов типа Дата используется ключевое слово ДАТАВРЕМЯ, после которого в скобках последовательно указываются год, месяц, день, час, минута и секунда. Последние три указывать не обязательно (табл. 4.11). Таблица 4.11. Примеры литералов типа «Дата» Дата
Литерал
15.04.2011 22:45:33 15.04.2011 0:00:00
ДАТАВРЕМЯ(2011, 04, 15, 22, 45, 33) ДАТАВРЕМЯ(2011, 04, 15)
Значение типа «Дата» по умолчанию
Для типа Дата значением по умолчанию является 01 января 0001 года 00 часов 00 минут 00 секунд.
Рис. 4.28. Установка формата в поле ввода
В поле ввода форматная строка поддерживает параметр ДП, который задает представление значения даты по умолчанию. В результате приведенный выше пример будет выглядеть следующим образом (рис. 4.29).
При выводе значения даты по умолчанию она отображается в соответствии с используемыми региональными установками сеанса (например, 01.01.0001 0:00:00). Однако при выводе значения даты по умолчанию в некоторые элементы управления она будет представляться иначе, что обусловлено удобством ввода или отображения. Например, значение даты по умолчанию в поле ввода будет отображено в виде символов-разделителей даты, используемых при заданных региональных установках. Состав разделителей будет определяться составом даты (Дата и время, Дата, Время), указанным при описании типа данных, с которыми работает данное поле ввода (рис. 4.27).
Рис. 4.29. Отображение пустой даты в поле ввода
Аналогичного результата можно добиться, используя средства встроенного языка (листинг 4.26). Листинг 4.26. Установка формата в поле ввода
Элементы.ПолеВводаДатаИВремя.ФорматРедактирования = "ДП='01.01.2011 00:00:00'"; Элементы.ПолеВводаДата.ФорматРедактирования = "ДП='01.01.2011'"; Элементы.ПолеВводаВремя.ФорматРедактирования = "ДП='00:00:00'";
Рис. 4.27. Пустая дата в поле ввода
При выводе значения даты по умолчанию в колонку таблицы она будет отображаться как пустое место, вне зависимости от того, какой состав даты установлен при описании типа данных (рис. 4.30).
Подробнее
Раздел «Типы данных, описывающие значения типа «Дата»», стр. 101.
86
Профессиональная разработка в системе «1С:Предприятие 8»
Система типов Аналогичного результата можно добиться средствами встроенного языка (листинг 4.27). Листинг 4.27. Установка формата колонки таблицы
Элементы.ТЗЗначение.Формат = "ДП='01.01.2011 00:00:00'"; Элементы.ТЗЗначение.ФорматРедактирования = "ДП='01.01.2011 00:00:00'"; Рис. 4.30. Пустая дата в колонке таблицы
Если необходимо указывать для значений даты по умолчанию определенное представление, то это можно выполнить с помощью свойств Формат и ФорматРедактирования колонки таблицы (в приведенном примере – колонки ТЗЗначение), рис. 4.31.
Операции со значениями типа «Дата» Для значений (табл. 4.12).
типа
Дата
определены
арифметические
операции
Таблица 4.12. Арифметические операции Операция
Операнды
Результат
Сложение Вычитание
Дата + Число Дата - Дата
Вычитание
Дата - Число
Дата, увеличенная на количество секунд Число, соответствующее разнице между двумя датами, измеренной в секундах Дата, уменьшенная на количество секунд
Для значений типа Дата определены логические операции (табл. 4.13). Таблица 4.13. Логические операции Операция
Больше
Операнды
Дата > Дата
Больше или равно Дата >= Дата
Рис. 4.31. Установка формата для колонки таблицы
Для колонки таблицы форматная строка поддерживает параметр ДП, который задает представление пустой даты. В результате приведенная выше таблица будет выглядеть, например, следующим образом (рис. 4.32).
Равно
Дата = Дата
Не равно
Дата <> Дата
Меньше
Дата < Дата
Меньше или равно Дата <= Дата
Результат
Истина, если первый операнд больше второго. В противном случае Ложь Истина, если первый операнд больше либо равен второму. В противном случае Ложь Истина, если первый операнд равен второму. В противном случае Ложь
Истина, если первый операнд не равен второму. В противном случае Ложь Истина, если первый операнд меньше второго. В противном случае Ложь Истина, если первый операнд меньше либо равен второму. В противном случае Ложь
Преобразование значений типа «Дата» Неявное преобразование
При выполнении различных операторов могут возникнуть ситуации, когда значения типа Дата не подходят для выполнения данных операций. Например, при выводе значений типа Дата может быть выполнено преобразование к строке (листинг 4.28). Листинг 4.28. Неявное преобразование значения типа «Дата» Рис. 4.32. Представление пустой даты в колонке таблицы
Том 1
ПеременнаяДата = '20110514234512'; Сообщить(ПеременнаяДата);
87
Глава 4. Работа с данными Явное преобразование
Явным образом значение типа Дата может быть преобразовано только к строке. Для этого используется встроенная функция Строка(), в качестве параметра которой передается преобразуемая дата. Результатом такого преобразования будет строковое представление даты, полученное в соответствии с региональными установками сеанса. Например, результатом выполнения оператора (листинг 4.29) будет сообщение 27.04.2011 12:36:58. Листинг 4.29. Явное преобразование типа «Дата»
Сообщение = Новый СообщениеПользователю; Сообщение.Текст = Строка('20110427123658'); Сообщение.Сообщить();
А для сеанса, запущенного с параметром командной строки /VL, равным el_GR (Греция), результатом выполнения этого же оператора будет другое сообщение – 27/4/2011 12:36:58 μμ.
Таблица 4.15. Операции сравнения Операция
Операнды
Больше Больше или равно Равно Не равно Меньше Меньше или равно
Булево > Булево Булево >= Булево Булево = Булево Булево <> Булево Булево < Булево Булево <= Булево
Для значений типа Булево определены булевы операции (табл. 4.16). Таблица 4.16. Булевы операции Операция
Операнды
Результат
И
Булево И Булево
Истина, если оба операнда имеют значение Истина. В остальных случаях Ложь
ИЛИ
Булево ИЛИ Булево
Ложь, если оба операнда имеют значение Ложь. В остальных случаях Истина
НЕ
НЕ Булево
Истина, если значение операнда Ложь. В противном случае Ложь
Булево Тип Булево предназначен для представления логических величин. Он имеет только два значения: Истина и Ложь.
Преобразование значений типа «Булево»
Литерал значения типа «Булево»
Конкретные значения типа Булево во встроенном языке и языке запросов задаются литералами (табл. 4.14).
При выполнении различных операторов могут возникать ситуации, когда значения типа Булево не подходят для выполнения данных операций (листинг 4.30).
Таблица 4.14. Литералы типа «Булево»
Листинг 4.30. Неявное преобразование значений типа «Булево»
Значение
Литерал
Истина Ложь
Истина или True Ложь или False
Значение типа «Булево» по умолчанию
Значением типа Булево по умолчанию является значение Ложь.
Неявное преобразование
Число = 10; Булево = Истина; Сообщить(Число + Булево);
В этом случае может быть выполнено неявное преобразование значения типа Булево к нужному типу. Если такое преобразование не может быть выполнено, будет вызвана ошибка исполнения.
Операции со значениями типа «Булево»
Неявное преобразование к типу «Число»
Для значений типа Булево определены операции сравнения. При сравнении булевых значений считается, что значение Истина больше, чем значение Ложь (табл. 4.15).
Если логика исполнения требует преобразования значения типа Булево к типу Число, то это преобразование выполняется по следующим правилам: значение Истина преобразуется к значению 1, а значение Ложь – к значению 0. Таким образом, результатом выполнения предыдущего примера (листинг 4.30) будет строка «11».
88
Профессиональная разработка в системе «1С:Предприятие 8»
Система типов Неявное преобразование к типу «Строка»
Неявное преобразование к типу Строка будет выполняться, например, в следующем примере (листинг 4.31). Листинг 4.31. Неявное преобразование к типу «Строка»
Булево = Истина; Сообщить(Булево);
В результате будет получено представление значения в соответствии с языком интерфейса платформы. Например, для русского интерфейса это будет значение Да, а для литовского – Taip. Явное преобразование Преобразование к типу «Число»
Встроенный язык позволяет выполнить явное преобразование значения типа Булево к типу Число. Для этого используется встроенная функция Число(), которой в качестве параметра передается булево значение. При этом значение Истина преобразуется в 1, а значение Ложь – в 0 (листинг 4.32). Листинг 4.32. Преобразование к типу «Число»
Результат = Число(Истина); Сообщить(Результат);
Преобразование к типу «Строка»
Встроенный язык позволяет также преобразовывать значение типа Булево к типу Строка. Для этого используется встроенная функция Строка, которая возвращает представление булева значения в соответствии с языком интерфейса платформы (листинг 4.33). Листинг 4.33. Преобразование к типу «Строка»
Сообщение = Новый СообщениеПользователю; Сообщение.Текст = Строка(Истина); Сообщение.Сообщить();
В результате выполнения этого кода в окно сообщений будет выведено Да (для русского языка интерфейса).
Значение «Неопределено» Значение типа Неопределено применяется тогда, когда необходимо использовать «пустое значение», не принадлежащее ни к одному другому типу данных, определенных в прикладном решении. Тип Неопределено имеет одно-единственное значение – Неопределено. Это значение используется, например, как значение составного типа по умолчанию. По этой причине составной тип всегда содержит тип Неопределено. Том 1
Подробнее
Раздел «Составной тип данных», стр. 101.
Представлением значения Неопределено является пустая строка. Литерал значения типа «Неопределено»
Значение типа Неопределено во встроенном языке и языке запросов задается литералом Неопределено. Операции со значением «Неопределено»
Для значения Неопределено определены операции сравнения на равенство и неравенство со значениями других типов. Таким образом, для любой переменной всегда может быть выполнено сравнение на равенство (или неравенство) ее значения значению Неопределено (листинг 4.34). Листинг 4.34. Сравнение со значением «Неопределено»
Сообщение = Новый СообщениеПользователю; Если РеквизитФормыСоставной = Неопределено Тогда Сообщение.Текст = "Истина"; Иначе Сообщение.Текст = "Ложь"; КонецЕсли; Сообщение.Сообщить();
Преобразование значений типа «Неопределено»
Значение Неопределено может быть преобразовано только в значение типа Строка. Такое преобразование может выполняться системой неявно, например, при выводе значения Неопределено, или явно, с использованием встроенной функции Строка(). Результатом преобразования является пустая строка.
Null Тип Null, так же как и тип Неопределено, имеет единственное значение – Null. Это значение используется системой для обозначения отсутствующего значения при работе с базой данных. Такая ситуация может возникнуть, например, при соединении нескольких таблиц в запросах, когда для одной из соединяемых таблиц нет записей в другой таблице, удовлетворяющих указанным условиям. Кроме приведенного примера, значение Null может быть получено и в других случаях. Например, когда выполняется обращение к реквизитам объекта, которые не используются. Допустим, у иерархического справочника Номенклатура существует реквизит Артикул, для которого свойство Использование установлено в значение ДляЭлемента. В этом случае поле
89
Глава 4. Работа с данными Артикул будет доступно для редактирования только у элементов спра-
вочника. У групп справочника это поле не будет содержать никакой информации.
Поэтому при обращении к реквизиту Артикул у группы справочника Номенклатура система будет возвращать значение Null (листинг 4.35). Листинг 4.35. Значение типа Null
Сообщение = Новый СообщениеПользователю; Выборка = Справочники.Номенклатура.Выбрать(); Пока Выборка.Следующий() Цикл Если Выборка.ЭтоГруппа Тогда Префикс = "Группа: "; Иначе Префикс = "Элемент: "; КонецЕсли; Сообщение.Текст = Префикс + СокрЛП(Выборка.Наименование) + ", тип артикула: " + ТипЗнч(Выборка.Артикул); Сообщение.Сообщить(); КонецЦикла;
В приведенном примере выбираются все элементы справочника Номенклатура, и затем выводится информация о типе значения реквизита Артикул для каждого элемента выборки. Литерал значения типа Null
Значение Null во встроенном языке и языке запросов задается литералом Null, а представлением значения Null является пустая строка. Операции со значениями типа Null
Для значения Null определены операции сравнения на равенство и неравенство со значениями других типов. В результате этого для любой переменной всегда может быть выполнено сравнение на равенство (или неравенство) ее значения значению Null (листинг 4.36). Листинг 4.36. Сравнение со значением типа Null
Сообщение = Новый СообщениеПользователю; Выборка = Справочники.Номенклатура.Выбрать(); Пока Выборка.Следующий() Цикл Суффикс = ?(Выборка.Артикул = Null, "не используется", Выборка.Артикул); Сообщение.Текст = СокрЛП(Выборка.Наименование) + ", артикул: " + Суффикс; Сообщение.Сообщить(); КонецЦикла;
90
В приведенном примере выбираются все элементы справочника Номенклатура. Затем для каждого элемента проверяется равенство его артикула значению Null, и в зависимости от этого формируется строка для вывода сообщения. Преобразование значений типа Null
Значение Null может быть преобразовано только в значение типа Строка. Такое преобразование может выполняться системой неявно, например, при выводе значения Null, или явно, с использованием встроенной функции Строка(). Результатом преобразования является пустая строка.
Тип Значения типа Тип используются для идентификации различных типов значений и их сравнения. Значения этого типа возвращаются двумя системными функциями: Тип() и ТипЗнч(). Также значения этого типа могут быть получены из объекта ОписаниеТипов в виде массива значений (метод Типы()). Функция Тип() позволяет получить значение этого типа, соответствующее переданному в качестве параметра имени некоторого типа (листинг 4.37). Листинг 4.37. Использование функции «Тип()»
ТипСтрока = Тип("Строка"); ТипЧисло = Тип("Число"); ТипСсылкаНаСправочникНоменклатура = Тип("СправочникСсылка.Номенклатура");
Функция ТипЗнч() также позволяет получить значение типа Тип, однако в качестве параметра ей передается не имя типа, а само значение какоголибо типа (листинг 4.38). Листинг 4.38. Использование функции «ТипЗнч()»
ТипСтрока = ТипЗнч("произвольная строка"); ТипЧисло = ТипЗнч(387.67); ТипСсылкаНаСправочникНоменклатура = ТипЗнч(Справочники.Номенклатура.НайтиПоКоду("000000001"));
Операции со значениями типа «Тип»
Для значений типа Тип определены операции сравнения на равенство и неравенство. Это позволяет выполнять проверку принадлежности произвольного значения некоторому типу (листинг 4.39). Листинг 4.39. Проверка принадлежности значения типу
Сообщение = Новый СообщениеПользователю; Если ТипЗнч(ПроверяемаяПеременная) = Тип("Строка") Тогда Сообщение.Текст = "Тип проверяемой переменной – строка"; Сообщение.Сообщить(); КонецЕсли;
Профессиональная разработка в системе «1С:Предприятие 8»
Система типов объекта>Выборка.<имя>), имеют схожую функциональность, схожее поведение и одинаковые приемы работы с ними.
Преобразование значений типа «Тип»
<вид
Значения этого типа могут быть преобразованы только к значениям типа Строка. Такое преобразование может быть выполнено системой неявно, при выводе значения, например, или явно, с использованием встроенной функции Строка(). Результатом такого преобразования будет представление описываемого типа, полученное в соответствии с используемым языком интерфейса платформы (табл. 4.17).
Такая организация системы прикладных типов существенно облегчает разработку прикладных решений, поскольку если разработчик освоил работу с выборкой справочника, то он уже без труда, по аналогии, сможет работать и с выборкой регистра сведений, и, например, с выборкой бизнеспроцесса (табл. 4.18). Таблица 4.18. Основные типы для работы с данными объектов конфигурации
Таблица 4.17. Преобразование к типу «Строка» Значение
Язык интерфейса Представление платформы
Тип("Строка") Тип("Строка") Тип("Строка") Тип("СправочникСсылка.Номенклатура") Тип("СправочникСсылка.Номенклатура") Тип("СправочникСсылка.Номенклатура")
Русский Украинский Латышский Русский Казахский Грузинский
Строка Рядок Rinda Справочник ссылка: Номенклатура Анықтама сілтеме: Номенклатура ცნობარი მინიშნება: Номенклатура
Типы, образуемые в прикладном решении В отличие от примитивных типов, которые определены на уровне технологической платформы и поддерживаются в любом прикладном решении, прикладные типы создаются в конкретных прикладных решениях в результате добавления в конфигурацию какого-либо объекта метаданных. Прикладные типы создаются платформой автоматически и позволяют работать с данными, хранящимися в тех структурах, которые описываются данным объектом конфигурации. В зависимости от объекта конфигурации будут добавляться различные типы данных. Например, при добавлении справочника Номенклатура будут созданы такие типы данных, как: СправочникМенеджер.Номенклатура, СправочникСсылка.Номенклатура, СправочникОбъект.Номенклатура, СправочникВыборка.Номенклатура. Если же в конфигурацию добавить, например, регистр сведений КурсыВалют, то станут доступны следующие типы: РегистрСведенийМенеджер.КурсыВалют; РегистрСведенийВыборка.КурсыВалют; РегистрСведенийМенеджерЗаписи.КурсыВалют; РегистрСведенийНаборЗаписей.КурсыВалют; РегистрСведенийЗапись.КурсыВалют; РегистрСведенийКлючЗаписи.КурсыВалют. Как можно заметить из названий, некоторые типы «похожи» (например, СправочникВыборка.Номенклатура и РегистрСведенийВыборка.КурсыВалют), а некоторые нет (например, СправочникОбъект.Номенклатура и РегистрСведенийНаборЗаписей.КурсыВалют). Это действительно так: типы, создаваемые для различных объектов конфигурации и принадлежащие к одной группе прикладных типов (например, Том 1
Объект конфигурации
Константа
Менеджер Выборка Ссылка Объект Набор Запись записей
Ключ записи
+ + + + + + + + + + + + + + + + + + +
+ + + +
+
Критерий отбора Журнал документов Перечисление Справочник Документ План видов характеристик План счетов План видов расчета Бизнес-процесс Задача План обмена Отчет Обработка Последовательность Перерасчет Регистр сведений Регистр накопления Регистр бухгалтерии Регистр расчета
+ + + + + + + + +
+ + + +
+ + + + + + + + +
+ + + + + + + + + +
+ + + + + +
+ + + + + +
Для некоторых объектов конфигурации создаются дополнительные типы, реализующие специальную функциональность, присущую только данным объектам конфигурации (табл. 4.19). Таблица 4.19. Дополнительные типы для работы с данными объектов конфигурации Объект конфигурации
Константа
План счетов План видов расчета
Регистр сведений Регистр бухгалтерии
Типы КонстантаМенеджерЗначения.<имя> КонстантыНабор ПланСчетовВидыСубконто.<имя> ПланСчетовВидыСубконтоСтрока.<имя> ВедущиеВидыРасчета.<имя> ВедущиеВидыРасчетаСтрока.<имя> ВытесняющиеВидыРасчета.<имя> ВытесняющиеВидыРасчетаСтрока.<имя> БазовыеВидыРасчета.<имя> БазовыеВидыРасчетаСтрока.<имя> РегистрСведенийМенеджерЗаписи.<имя> РегистрБухгалтерииСубконто.<имя>
91
Глава 4. Работа с данными
Менеджер объектов
Листинг 4.41. Использование менеджера для проверки принадлежности к типам ссылок
Для каждого вида объектов конфигурации (справочники, документы и т. д.) в системе определен тип менеджера этих объектов (СправочникиМенеджер, ДокументыМенеджер и т. д.). Эти типы существуют всегда, вне зависимости от того, есть ли в конкретном прикладном решении хоть один такой объект или нет.
СсылкиНаВсеСправочники = Справочники.ТипВсеСсылки();
Каждый из этих типов имеет единственное значение в конкретном прикладном решении. Это можно проиллюстрировать на следующем примере (листинг 4.40). Листинг 4.40. Сравнение экземпляров объектов менеджеров
МенеджерСправочников1 = Справочники; МенеджерСправочников2 = Справочники; Если МенеджерСправочников1 = МенеджерСправочников2 Тогда Сообщение = Новый СообщениеПользователю; Сообщение.Текст = "Объекты равны"; Сообщение.Сообщить(); КонецЕсли;
Менеджеры объектов доступны через соответствующие свойства глобального контекста (например, Справочники или Документы). Главная задача этого типа – предоставить доступ к менеджерам конкретных объектов конфигурации (СправочникМенеджер.<имя>, ДокументМенеджер.<имя> и т. д.), рис. 4.33.
Сообщение = Новый СообщениеПользователю; Если СсылкиНаВсеСправочники.СодержитТип(ТипЗнч(АнализируемоеЗначение)) Тогда Сообщение.Текст = "Это ссылка на справочник"; Иначе Сообщение.Текст = "Значение не является ссылкой на справочник"; КонецЕсли; Сообщение.Сообщить();
В приведенном примере используется метод ТипВсеСсылки() менеджера справочников для того, чтобы в переменной СсылкиНаВсеСправочники получить объект ОписаниеТипов, содержащий типы ссылок на все справочники прикладного решения. Затем, используя его метод СодержитТип(), проверяется, входит ли тип анализируемого значения в состав этого описания типов или нет. Менеджеры конкретных объектов конфигурации доступны двумя путями. Во-первых, они доступны как свойства менеджера объектов (листинг 4.42). Листинг 4.42. Обращение к менеджеру объекта конфигурации
МенеджерСправочников = Справочники; МенеджерСправочникаКонтрагенты = МенеджерСправочников.Контрагенты;
Кроме этого, менеджеры объектов можно получить перебором коллекции значений, которой является менеджер объектов. Элементами этой коллекции как раз и являются менеджеры отдельных объектов (листинг 4.43). Листинг 4.43. Обход коллекции менеджеров объектов
Сообщение = Новый СообщениеПользователю; МенеджерСправочников = Справочники; Для Каждого МенеджерСправочника Из МенеджерСправочников Цикл Сообщение.Текст = ТипЗнч(МенеджерСправочника); Сообщение.Сообщить(); КонецЦикла;
Менеджер Рис. 4.33. Структура типов
Кроме этого, менеджер объектов позволяет проверить, является ли тип какого-либо значения типом ссылки на объект этого типа (листинг 4.41).
Менеджер прикладного объекта можно назвать «точкой входа» в конкретный объект конфигурации в объектной модели встроенного языка. Объекты этого типа предоставляют доступ к общим действиям, относящимся к конкретному объекту конфигурации (например, к справочнику Контрагенты или к документу Авансовый отчет). В основном это: ■■ получение выборок из данных этого объекта конфигурации; ■■ создание и поиск элементов данных;
92
Профессиональная разработка в системе «1С:Предприятие 8»
Система типов ■■ доступ к предопределенным элементам данных; ■■ выполнение общих действий, поддерживаемых данным объектом конфигурации; ■■ получение макетов.
Набор записей
В конкретном прикладном решении всегда существует только один экземпляр каждого менеджера, в чем можно убедиться на следующем примере (листинг 4.44).
Так же как и объект для объектных данных, набор записей является единственным объектом, с помощью которого в конечном счете выполняется модификация необъектных данных.
Листинг 4.44. Сравнение экземпляров объектов менеджеров объекта конфигурации
Подробнее
МенеджерСправочникаКонтрагенты1 = Справочники.Контрагенты; МенеджерСправочникаКонтрагенты2 = Справочники.Контрагенты; Если МенеджерСправочникаКонтрагенты1 = МенеджерСправочникаКонтрагенты2 Тогда Сообщение = Новый СообщениеПользователю; Сообщение.Текст = "Объекты равны"; Сообщение.Сообщить(); КонецЕсли;
Объект Тип объекта, так же как и ссылка, создается не для всех объектов конфигурации, а только для тех, которые хранят в базе данных объектные данные (справочники, документы, планы счетов и пр.). Только с помощью объекта может быть выполнена модификация данных, хранящихся в базе данных. Другие типы объектных данных позволяют выполнять только чтение данных из базы данных. Подробнее
Раздел «Объект», стр. 69.
Ссылка Тип ссылки создается не для всех объектов конфигурации, а только для тех, которые хранят данные объектного типа (справочники, документы, планы счетов и пр.). Тип ссылки служит прежде всего для однозначной идентификации объекта данных (как совокупности логически связанных данных) в базе данных. Значением ссылки является фактически уникальный внутренний идентификатор, который хранится в поле Ссылка таблиц, создаваемых системой для объекта конфигурации.
Тип набора записей, в отличие от ссылок и объектов, предназначен для работы с необъектными данными, такими как, например, наборы записей различных регистров.
Раздел «Необъектные данные», стр. 75.
Динамический список Объект ДинамическийСписок предназначен для динамического просмотра данных объекта конфигурации в элементе формы Таблица. Динамический список осуществляет считывание данных из базы данных порциями, в процессе навигации пользователя по списку или в процессе обращения к ним из встроенного языка. С помощью динамического списка построены все формы списка объектов конфигурации, которые содержат основной реквизит типа ДинамическийСписок. Динамический список формируется путем запроса к основной таблице, указанной в соответствующем свойстве реквизита, или путем произвольного запроса к базе данных. Кроме того, объект ДинамическийСписок может быть доступен из встроенного языка. Динамический список использует систему компоновки данных и позволяет задать группировку, отбор, порядок и условное оформление списка путем установки соответствующих свойств реквизита типа ДинамическийСписок (как интерактивно, так и программно) или путем настройки списка в режиме 1С:Предприятие. Для примера рассмотрим форму списка документов Расходная накладная, сформированную конструктором форм. В качестве основного реквизита формы платформа добавила реквизит Список типа ДинамическийСписок и заполнила по умолчанию его свойства ОсновнаяТаблица и ДинамическоеСчитываниеДанных (рис. 4.34).
Ссылка позволяет обращаться к свойствам объекта базы данных, а также получать сам объект. Подробнее
Раздел «Ссылка», стр. 66.
Том 1
93
Глава 4. Работа с данными Обычно далеко не все поля динамического списка используются для отображения в форме. Хотя в списке полей присутствуют все реквизиты документа РасходнаяНакладная, платформа стандартно отображает в форме списка документов только поля Дата и Номер. При необходимости разработчик может перетащить любое поле динамического списка в дерево элементов формы и тем самым отобразить его в форме списка. Особенность использования динамического списка в том, что запросом из базы данных считываются значения только тех реквизитов, которые отображаются в форме. Это сделано для того, чтобы не передавать на клиента лишнюю информацию и не замедлять работу прикладного решения со списками данных.
Рис. 4.34. Свойства основного реквизита типа «Динамический список»
Если указана основная таблица, то платформа автоматически будет формировать запрос к этой таблице для получения данных динамического списка. С помощью свойства ДинамическоеСчитываниеДанных динамическому списку указывается на необходимость считывания данных небольшими порциями только при необходимости их отображения на экране. Раскрыв реквизит Список, можно увидеть поля динамического списка (стандартные и созданные разработчиком реквизиты документа РасходнаяНакладная), а также его свойства: Отбор, Порядок, УсловноеОформление, Группировка и Параметры, доступные для настройки списка как интерактивно, так и программно (рис. 4.35).
Однако если есть необходимость всегда считывать запросом и передавать на клиента значение какого-то поля, то можно включить для него свойство Использовать всегда (см. рис. 4.35) или установить программно признак обязательного использования (Список.УстановитьОбязательноеИспользование("Ссылка", Истина)). В этом случае указанное поле будет считываться из базы данных и передаваться на клиента, даже если оно не отображается в форме. Если у динамического списка установить свойство ПроизвольныйЗапрос, то станет доступным ручное формирование запроса для получения данных из информационной базы. Открыв окно Настройка списка, можно с помощью конструктора запроса либо вручную создать произвольный запрос к базе данных, выбирающий данные из нескольких таблиц, использующий параметры, вычисляемые поля и т. д. (рис. 4.36).
Рис. 4.36. Создание произвольного запроса для динамического списка
Произвольный запрос для динамического списка можно создать и программным образом. Например, требуется открыть список приходных накладных с отбором по номенклатуре (листинг 4.45). Рис. 4.35. Поля основного реквизита типа «Динамический список»
94
Профессиональная разработка в системе «1С:Предприятие 8»
Система типов Листинг 4.45. Создание произвольного запроса для динамического списка
&НаСервере Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка) Если Параметры.Свойство("Номенклатура") Тогда Список.ПроизвольныйЗапрос = Истина; Список.ТекстЗапроса = "ВЫБРАТЬ | ДокументРасходнаяНакладная.Номер, | ДокументРасходнаяНакладная.Дата, | ДокументРасходнаяНакладная.Контрагент, | ДокументРасходнаяНакладная.Склад |ИЗ | Документ.РасходнаяНакладная КАК ДокументРасходнаяНакладная |ГДЕ | ДокументРасходнаяНакладная.Товары.Номенклатура = &Номенклатура"; Список.ОсновнаяТаблица = "Документ.РасходнаяНакладная"; Список.Параметры.УстановитьЗначениеПараметра("Номенклатура", Параметры.Номенклатура) КонецЕсли; КонецПроцедуры
В обработчике ПриСозданииНаСервере формы списка документов РасходнаяНакладная задается произвольный запрос, показанный на рис. 4.36. Его текст помещается в свойство ТекстЗапроса реквизита Список, содержащего динамический список расходных накладных. Также задается основная таблица списка и устанавливается значение параметра запроса методом УстановитьЗначениеПараметра() коллекции параметров динамического списка (Список.Параметры). Причем произвольный запрос с отбором по номенклатуре выполняется только в том случае, если форма списка расходных накладных открывается с параметром Номенклатура, например, при выполнении параметризированной команды из списка номенклатуры (листинг 4.46). Листинг 4.46. Обработчик параметризированной команды
&НаКлиенте Процедура ОбработкаКоманды(ПараметрКоманды, ПараметрыВыполненияКоманды) ПараметрыФормы = Новый Структура("Номенклатура", ПараметрКоманды); ОткрытьФорму("Документ.РасходнаяНакладная.ФормаСписка", ПараметрыФормы); КонецПроцедуры
Если форма списка открывается без параметров, например, при открытии списка расходных накладных из панели навигации, то свойства динамического списка останутся без изменения (см. рис. 4.34) и платформой будет автоматически сгенерирован запрос к основной таблице динамического списка, выбирающий данные всей таблицы расходных накладных. Платформа предоставляет разнообразные и гибкие возможности по настройке динамического списка. Разработчик может настроить группировку, отбор, порядок и условное оформление списка в конфигураторе в окне Настройка списка, нажав в палитре свойств гиперссылку Открыть (рис. 4.37). Том 1
Рис. 4.37. Создание произвольного запроса для динамического списка
На приведенном рисунке установлено, что в списке расходных накладных поле Номер документов, содержащих в табличной части в поле Количество значение больше 3, будет выделено пурпурным цветом фона. Аналогичного результата можно добиться программным образом (листинг 4.47). Листинг 4.47. Условное оформление списка
&НаКлиенте Процедура УсловноеОформление(Команда) УО = Список.УсловноеОформление.Элементы; ЭлементУО = УО.Добавить(); // Оформление – цвет фона. ЭлементУО.Оформление.УстановитьЗначениеПараметра("ЦветФона", WebЦвета.Пурпурный); // Условие – поле "Количество" больше трех. ЭлементУсловия = ЭлементУО.Отбор.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"); ЭлементУсловия.ЛевоеЗначение = Новый ПолеКомпоновкиДанных("Товары.Количество"); ЭлементУсловия.ВидСравнения = ВидСравненияКомпоновкиДанных.Больше; ЭлементУсловия.ПравоеЗначение = 3;
// Оформляемое поле – "Номер". ОформляемоеПоле = ЭлементУО.Поля.Элементы.Добавить(); ОформляемоеПоле.Поле = Новый ПолеКомпоновкиДанных("Номер");
КонецПроцедуры
Пользователь также может настроить группировку, отбор, порядок и условное оформление динамического списка в режиме 1С:Предприятие, выполнив команду Все действия Настроить список… Диалог настройки списка в пользовательском режиме очень похож на диалог для интерактивной настройки списка в конфигураторе. При этом если разработчик интерактивно или программно уже задал настройки списка, то пользователь увидит эти настройки и сможет их изменить, отключить или удалить.
95
Глава 4. Работа с данными
Выборка Выборка предназначена для динамического обхода элементов данных, хранимых в структуре объекта конфигурации. Выборка не считывает данные целиком в память, а получает их блоками, по мере обхода выборки методом Следующий(), листинг 4.48. Листинг 4.48. Пример обхода выборки
Сообщение = Новый СообщениеПользователю; ВыборкаВалют = Справочники.Валюты.Выбрать(); Пока ВыборкаВалют.Следующий() Цикл Сообщение.Текст = ВыборкаВалют.Наименование; Сообщение.Сообщить(); КонецЦикла;
Благодаря тому, что считывание данных осуществляется порциями, выборку можно использовать для обработки очень больших объемов информации. Каждый блок считываемых данных содержит 25 записей. Для объектных таблиц каждая такая запись содержит все данные объекта, включая все его поля и табличные части. Поэтому, например, при обращении к реквизитам выборки или при получении объекта из выборки не происходит повторного обращения к базе данных. Выборка осуществляет считывание данных в определенном порядке. Этот порядок может задаваться, например, путем указания параметров Отбор и Порядок метода Выбрать(). Отбор может быть выполнен только по одному полю, причем это может быть только то поле, для которого построен индекс. Кроме полей, которые индексируются системой по умолчанию, это может быть также поле, для которого в конфигураторе установлен признак индексирования в значение Индексировать или Индексировать с дополнительным упорядочиванием. Отбор по таким полям позволяет выполнять выборку быстро и эффективно. Например, приведенный ниже пример (листинг 4.49) позволяет выбрать из справочника Номенклатура только те элементы, для которых не задан артикул.
Отбор задается структурой, содержащей единственный элемент, у которого ключ соответствует имени поля, а значение – значению отбора. Порядок отбираемых записей также может быть задан с использованием полей, которые либо индексируются по умолчанию, либо имеют примитивный тип и для них построение индекса указано в явном виде в конфигураторе. Например, следующий пример (листинг 4.50) позволяет выбрать элементы справочника Договоры контрагентов в порядке убывания даты договора. Листинг 4.50. Пример использования порядка
ВыборкаДоговоров = Справочники.ДоговорыКонтрагентов.Выбрать( , , , "Дата Убыв"); Сообщение = Новый СообщениеПользователю; Пока ВыборкаДоговоров.Следующий() Цикл Сообщение.Текст = ВыборкаДоговоров.Наименование; Сообщение.Сообщить(); КонецЦикла;
Для иерархических данных (например, справочников, планов видов характеристик, планов счетов) существует также иерархическая выборка, получаемая методом ВыбратьИерархически(). Такая выборка отличается от обычной тем, что выдает данные путем обхода записей в соответствии с их иерархией. То есть после выдачи элемента выдается подчиненный ему элемент, если такой существует. Если подчиненных не существует, то выдается следующий элемент. Причем каждое считывание подчиненных элементов реализовано как считывание отдельного блока данных. Кроме отбора и порядка, выборка позволяет задать также родителя и владельца считываемых данных. При указании конкретного родителя выборка, получаемая методом Выбрать(), будет содержать те элементы, родитель которых равен указанному (рис. 4.38).
Листинг 4.49. Пример использования отбора
СтруктураОтбора = Новый Структура; СтруктураОтбора.Вставить("Артикул", "); Сообщение = Новый СообщениеПользователю; ВыборкаНоменклатуры = Справочники.Номенклатура.Выбрать( , , СтруктураОтбора); Пока ВыборкаНоменклатуры.Следующий() Цикл Сообщение.Текст = ВыборкаНоменклатуры.Наименование; Сообщение.Сообщить(); КонецЦикла;
96
Рис. 4.38. Указание родителя в выборке
В то же время выборка, получаемая методом ВыбратьИерархически(), будет содержать все элементы, находящиеся в иерархии указанного родителя, т. е. в первом, втором и последующих уровнях иерархии (рис. 4.39). Профессиональная разработка в системе «1С:Предприятие 8»
Система типов
Рис. 4.39. Иерархическая выборка
Если в методе Выбрать() в качестве родителя указать пустую ссылку, то будут выбраны все элементы первого уровня (рис. 4.40).
Рис. 4.41. Считывание данных блоками
Особенностью такой схемы работы механизма выборки является то, что разработчик не имеет контроля над актуальностью получаемой информации, даже если выборка инициирована в транзакции. При получении очередной записи нет возможности определить, считывается ли эта запись из уже полученного ранее блока, или же она была только что считана в составе нового блока записей. Рис. 4.40. Выборка элементов верхнего уровня
При указании в параметрах выборки конкретного владельца будут отбираться записи подчиненного справочника, владелец которых равен указанному. Например, в следующем примере (листинг 4.51) будут выбраны все договоры контрагента с кодом Ю0004. Листинг 4.51. Выборка подчиненных элементов
Владелец = Справочники.Контрагенты.НайтиПоКоду("Ю00000004"); ВыборкаДоговоров = Справочники.ДоговорыКонтрагентов.ВыбратьИерархически( , Владелец); Сообщение = Новый СообщениеПользователю; Пока ВыборкаДоговоров.Следующий() Цикл Сообщение.Текст = ВыборкаДоговоров.Наименование; Сообщение.Сообщить(); КонецЦикла;
Эта особенность работы механизма выборки может приводить к тому, что в выборку могут попасть данные удаленного объекта, некоторые записи могут попасть дважды или не попасть в выборку вообще. Получение данных удаленного объекта
Допустим, после получения записей очередного блока одна из записей, относящихся к этому блоку, была удалена из базы данных. В этом случае к моменту окончания обхода выборки физически эта запись будет отсутствовать в базе данных, хотя в то же время она будет присутствовать в полученной выборке (рис. 4.42).
Особенности использования выборки
Как было показано выше, выборка считывает данные в определенной последовательности сортировки. При обходе выборки методом Следующий() выполняется получение очередных блоков данных в соответствии с порядком сортировки и выдачей записей ранее считанного блока. Другими словами, очередной блок считывается как множество записей, которые следуют в указанном порядке после последней полученной записи предыдущего блока (рис. 4.41). Том 1
Рис. 4.42. Получение данных удаленного объекта
97
Глава 4. Работа с данными Множественное попадание записи в выборку
Например, в процессе получения выборки справочника в порядке наименования элемент справочника Женские сапоги был переименован в Сапоги женские. В этом случае порядок следования данной записи изменится, и может возникнуть ситуация, когда переименованный элемент справочника в порядке следования окажется среди записей еще не считанного блока. При получении данного блока эта запись будет считана повторно (рис. 4.43).
Рис. 4.45. Удаление родителя
Таким образом, при использовании обычной выборки может возникнуть ситуация, когда в результате удаления элемента могут быть удалены также и элементы, уже считанные в текущем блоке (рис. 4.46).
Рис. 4.43. Множественное попадание записи в выборку
Непопадание записи в выборку
Ситуация, когда запись может вообще не попасть в выборку, прямо противоположна предыдущей. Например, в процессе выборки справочника в порядке наименования элемент справочника Сапоги женские, находящийся в порядке следования среди записей еще не считанного блока, был переименован в Женские сапоги и в соответствии с порядком следования оказался среди записей уже считанного ранее блока (рис. 4.44).
Рис. 4.46. Удаление родителя в процессе выборки
В этом случае при попытке выполнения каких-либо действий с полученным из выборки объектом (на рисунке – Подчиненный1) будет выдаваться ошибка, т. к. в базе данных этот объект уже не существует. По этой причине для удаления иерархических данных следует использовать иерархическую выборку. В этом случае все подчиненные элементы будут располагаться в порядке следования в одном или нескольких блоках за родительским элементом, и после удаления родителя (и, соответственно, его подчиненных элементов) просто будет выполнено чтение следующего за ними по порядку блока записей (рис. 4.47).
Рис. 4.44. Непопадание записи в выборку
Удаление иерархических данных
Особенность использования выборки для обхода и удаления иерархических данных связана с тем, что при удалении элемента (родителя) удаляются и все его подчиненные элементы (рис. 4.45).
98
Рис. 4.47. Удаление родителя в процессе иерархической выборки
Профессиональная разработка в системе «1С:Предприятие 8»
Система типов Обобщая все перечисленные особенности использования выборок, можно сказать, что следует внимательно относиться к изменению объектов в процессе обхода динамической выборки, так как это может повлиять на порядок их включения в выборку. Наряду с этим рекомендуется использовать динамические выборки либо для задач, не требующих ответственного чтения данных, либо для регламентных задач, которые могут выполняться в монопольном режиме. Также использование динамических выборок можно рекомендовать в тех случаях, когда объем данных, выбираемых из базы данных, очень велик, и получение выборки такого объема другими способами (например, запросом) неэффективно.
При редактировании объектов конфигурации (например, при указании типа данных реквизита формы) числовой тип данных описывается средствами визуального конструирования (рис. 4.48).
Типы данных Тип данных в системе «1С:Предприятие» представляет собой перечень возможных типов значений, которые могут быть использованы тем или иным элементом системы. Типы данных используются при описании таких элементов системы, как: ■■ объекты конфигурации (реквизиты, измерения, ресурсы и др.); ■■ реквизиты формы; ■■ элементы управления, расположенные в форме и в табличном документе; ■■ некоторые объекты встроенного языка (список значений, колонки таблицы значений и дерева значений и др.). Тип данных позволяет перечислить типы значений, которые используются, а также для некоторых примитивных типов значений позволяет задать квалификаторы, описывающие допустимые значения примитивных типов. При визуальном конструировании тип данных может быть описан с помощью палитры свойств или в специальном диалоге редактирования типа данных. Во встроенном языке для описания типа данных используется объект встроенного языка ОписаниеТипов.
Числовые типы данных При описании допустимых значений типа Число существует возможность указать: ■■ допустимый знак числа (он может быть любым или неотрицательным); ■■ общую разрядность числа; ■■ разрядность дробной части. Эта возможность часто используется при организации интерфейса системы. Том 1
Рис. 4.48. Редактирование типа данных «Число»
Кроме этого, числовой тип данных может быть указан и средствами встроенного языка (например, при создании таблицы значений, которая в дальнейшем будет использована для ввода данных), листинг 4.52. Для этого используется объект КвалификаторыЧисла. Листинг 4.52. Использование квалификаторов числа
КвалификаторЧисла = Новый КвалификаторыЧисла(5, 2, ДопустимыйЗнак.Неотрицательный); ОписаниеТипа = Новый ОписаниеТипов("Число", КвалификаторЧисла); ТаблицаСкидок.Колонки.Добавить("Товар", Новый ОписаниеТипов( "СправочникСсылка.Номенклатура")); ТаблицаСкидок.Колонки.Добавить("Скидка", ОписаниеТипа);
В
этом
примере сначала создается новый объект Квалификаустанавливающий общее количество разрядов – 5, количество разрядов дробной части – 2 и допустимый знак числа – неотрицательный. Затем на основании этого объекта создается новый объект ОписаниеТипов, содержащий описание типа Число с указанными ограничениями. Далее при добавлении колонки Скидка в таблицу значений ТаблицаСкидок этот объект указывается в качестве описания типа данной колонки. Таким образом, в колонке Скидка таблицы значений ТаблицаСкидок сможет находиться неотрицательное число, содержащее пять разрядов, из которых два отведены под дробную часть числа. торыЧисла,
Строковые типы данных При описании допустимых значений типа ность указать:
Строка
существует возмож-
■■ какой вариант ограничения длины будет использоваться для строкового значения (фиксированная длина или переменная длина); ■■ длину строкового значения (в случае фиксированной длины).
99
Глава 4. Работа с данными В зависимости от длины строки различают строки ограниченной и неограниченной длины. Если длина строки равна нулю, то такая строка имеет неограниченную длину. В противном случае строка будет иметь ограниченную длину. Отличие строк ограниченной и неограниченной длины можно проиллюстрировать следующим примером. Пусть есть два реквизита: строка длиной 10 (СтрокаОграниченная10) и строка неограниченной длины (СтрокаНеограниченная). Тогда при присвоении этим реквизитам строкового значения, имеющего длину 14 символов, в первом случае оно будет обрезаться до 10 символов, а во втором случае – нет (листинг 4.53).
Результатом выполнения приведенного примера будут следующие сообщения: Строка фиксированной длины (10): "новое Строка переменной длины (10): "новое"
"
При редактировании объектов конфигурации (например, при указании типа данных реквизита формы) строковый тип данных описывается средствами визуального конструирования (рис. 4.49).
Листинг 4.53. Использование строк ограниченной и неограниченной длины
Сообщение = Новый СообщениеПользователю; СтрокаОграниченная10 = "новое значение"; Сообщение.Текст = "Строка ограниченной длины (10): " + """" + СтрокаОграниченная10 + """"; Сообщение.Сообщить(); СтрокаНеограниченная = "новое значение"; Сообщение.Текст = "Строка неограниченной длины: " + """" + СтрокаНеограниченная + """"; Сообщение.Сообщить();
Результатом выполнения приведенного примера будут следующие сообщения: Строка ограниченной длины (10): "новое знач" Строка неограниченной длины: "новое значение"
Строки ограниченной длины могут быть двух видов: фиксированной и переменной длины. Их отличие также лучше всего продемонстрировать на примере. Пусть есть два реквизита: строка фиксированной длины 10 символов (СтрокаФиксированная10) и строка переменной длины 10 символов (СтрокаПеременная10). Тогда при присвоении этим реквизитам строкового значения, имеющего длину 5 символов, в первом случае оно будет дополняться пробелами справа до указанной длины, а во втором случае – нет (листинг 4.54). Листинг 4.54. Использование строк фиксированной и переменной длины
Сообщение = Новый СообщениеПользователю; СтрокаФиксированная10 = "новое"; Сообщение.Текст = "Строка фиксированной длины (10): " + """" + СтрокаФиксированная10 + """"; Сообщение.Сообщить();
Рис. 4.49. Редактирование типа данных «Строка»
Кроме этого, строковый тип данных может быть указан и средствами встроенного языка. Например, при создании таблицы значений, которая в дальнейшем будет использована для ввода данных (листинг 4.55). Для этого используется объект КвалификаторыСтроки. Листинг 4.55. Использование квалификаторов строки
КвалификаторСтроки = Новый КвалификаторыСтроки(5, ДопустимаяДлина.Переменная); ОписаниеТипа = Новый ОписаниеТипов("Строка", КвалификаторСтроки); ТаблицаСкидок.Колонки.Добавить("Товар", Новый ОписаниеТипов("СправочникСсылка.Номенклатура")); ТаблицаСкидок.Колонки.Добавить("Артикул", ОписаниеТипа);
В этом примере сначала создается новый объект КвалификаторыСтроки, устанавливающий переменную длину строки в пять символов, затем на основании этого объекта создается новый объект ОписаниеТипов, содержащий описание типа Строка с указанными ограничениями. Далее при добавлении колонки Артикул в таблицу значений ТаблицаСкидок этот объект указывается в качестве описания типа данной колонки. Таким образом, в колонке Артикул таблицы значений ТаблицаСкидок сможет находиться строка переменной длины, содержащая максимум пять разрядов.
СтрокаПеременная10 = "новое"; Сообщение.Текст = "Строка переменной длины (10): "+ """" + СтрокаПеременная10 + """"; Сообщение.Сообщить();
100
Профессиональная разработка в системе «1С:Предприятие 8»
Система типов
Типы данных, описывающие значения типа «Дата»
Составной тип данных
При описании допустимых значений типа Дата существует возможность указать части даты, которые будут использованы:
До сих пор мы рассматривали типы данных, содержащие описание только одного типа значений. Однако в общем случае тип данных может содержать перечень нескольких типов значений. Такой тип данных называется составным.
■■ дата и время, ■■ дата, ■■ время. При редактировании объектов конфигурации (например, при указании типа данных реквизита формы) используются средства визуального конструирования (рис. 4.50).
Благодаря наличию составного типа в базе данных могут храниться реквизиты, значения которых имеют разный тип в разные моменты времени, однако в один момент времени может храниться значение только одного из перечисленных типов. Например, документ Внутренний заказ может иметь реквизит Заказчик, имеющий составной тип данных: СправочникСсылка.Подразделения, СправочникСсылка.Склады (рис. 4.51). Это значит, что в этом реквизите могут храниться как значения ссылок на справочник Подразделения, так и значения ссылок на справочник Склады.
Рис. 4.50. Редактирование типа данных «Дата»
Кроме этого, тип данных, описывающий значения типа Дата, может быть указан и средствами встроенного языка. Например, при создании таблицы значений, которая в дальнейшем будет использована для ввода данных (листинг 4.56). Для этого используется объект КвалификаторыДаты.
Тип значения такого реквизита в каждый момент времени может быть различным и определяется значением, которое в данный момент хранится в реквизите. Другими словами, если реквизиту присвоить значение ссылки на справочник Подразделения, то тип значения реквизита будет СправочникСсылка.Подразделения; если присвоить ссылку на справочник Склады, то тип значения будет СправочникСсылка.Склады.
Листинг 4.56. Использование квалификаторов даты
КвалификаторДаты = Новый КвалификаторыДаты(ЧастиДаты.Дата); ОписаниеТипаДата = Новый ОписаниеТипов("Дата", КвалификаторДаты); КвалификаторЧисла = Новый КвалификаторыЧисла(15, 2); ОписаниеТипаЧисло = Новый ОписаниеТипов("Число", КвалификаторЧисла); ТаблицаКурсВалют.Колонки.Добавить("Дата", ОписаниеТипаДата); ТаблицаКурсВалют.Колонки.Добавить("Курс", ОписаниеТипаЧисло);
В этом примере сначала создается новый объект КвалификаторыДаты, который устанавливает использование части даты – Дата. Затем на основании этого объекта создается новый объект ОписаниеТипов, содержащий описание типа Дата с указанными ограничениями. Далее при добавлении колонки Дата в таблицу значений ТаблицаКурсВалют этот объект указывается в качестве описания типа создаваемой колонки. Таким образом, в колонке Дата смогут находиться значения типа Дата, для которых возможно изменение только непосредственно самой даты. Время у этих значений всегда будет равно 00 часов 00 минут 00 секунд. Том 1
Рис. 4.51. Реквизит составного типа
Описание значений составного типа Описание составного типа данных может быть выполнено как средствами визуального конструирования, так и средствами встроенного языка. В процессе визуального описания объектов конфигурации для этого используется окно редактирования типа данных (рис. 4.52). Разработчик может перечислить типы значений и наборы типов, которые должны входить в составной тип данных, а также, при необходимости, задать квалификаторы для числовых, строковых значений и значений типа Дата.
101
Глава 4. Работа с данными
Значение реквизита составного типа по умолчанию Для реквизита составного типа значением по умолчанию является значение Неопределено. По этой причине тип Неопределено всегда входит в составной тип данных наряду с прочими типами. Представлением значения Неопределено является пустая строка. Подробнее
Раздел «Значение «Неопределено»», стр. 89.
Если значение реквизита составного типа данных по умолчанию отображается в поле ввода, то при нажатии кнопки выбора в этом поле ввода открывается окно для выбора одного из возможных типов значений. После этого можно будет ввести конкретное значение выбранного типа (рис. 4.53).
Рис. 4.52. Окно редактирования типа данных
Описывать составной тип данных можно также средствами встроенного языка. Например, у формы можно создать реквизит РеквизитСоставногоТипа и задать его составной тип данных следующим образом (листинг 4.57).
Рис. 4.53. Отображение значения по умолчанию реквизита составного типа
Листинг 4.57. Описание составного типа
МассивТипов = Новый Массив; МассивТипов.Добавить(Тип("Строка")); МассивТипов.Добавить(Тип("Число")); МассивТипов.Добавить(Тип("СправочникСсылка.Номенклатура")); ОписаниеСоставногоТипа = Новый ОписаниеТипов(МассивТипов); НовыйРеквизит = Новый РеквизитФормы("РеквизитСоставногоТипа", ОписаниеСоставногоТипа); МассивРеквизитов = Новый Массив; МассивРеквизитов.Добавить(НовыйРеквизит); ИзменитьРеквизиты(МассивРеквизитов);
Преобразование значений, хранящихся в реквизитах составного типа
В этом примере сначала создается массив, содержащий все нужные типы значений, а затем на его основании создается новый объект ОписаниеТипов, который описывает составной тип данных. Затем на основе описания этого типа описывается новый реквизит формы РеквизитСоставногоТипа. После этого формируется массив добавляемых реквизитов, и методом управляемой формы ИзменитьРеквизиты() новый реквизит добавляется в форму.
Если составной тип данных содержит тип присваиваемого значения, то реквизиту будет установлен новый тип значения и новое значение.
102
Неявное преобразование
При присвоении значений реквизитам, имеющим составной тип данных, могут возникнуть ситуации, когда присваиваемое значение не соответствует текущему типу значения реквизита. В этом случае система будет выполнять неявное преобразование типа присваиваемого значения к одному из доступных типов значений.
Например, пусть для реквизита СоставнойРеквизит задан составной тип данных (рис. 4.54) и текущее значение реквизита равно Истина. После выполнения оператора, приведенного в листинге 4.58, значение реквизита станет равным «новая строка». Профессиональная разработка в системе «1С:Предприятие 8»
Система типов В результате выполнения этого кода будет выведено следующее сообщение: Номенклатура: Сигареты Рис. 4.54. Состав типов
Если несколько видоизменить код и в качестве приводимого значения получить не ссылку на справочник Номенклатура, а объект справочника, то результат будет уже другим:
Листинг 4.58. Присвоение нового значения реквизиту составного типа
Строка: Сигареты
СоставнойРеквизит = "новая строка";
Так происходит потому, что тип СправочникОбъект.Номенклатура не входит в составной тип данных и система приводит его к одному из типов, входящих в составной тип, в данном случае к типу Строка.
Если тип присваиваемого значения не соответствует ни одному из типов, входящих в составной тип данных, тогда система попытается привести тип присваиваемого значения к одному из типов составного типа данных. Например, после выполнения оператора (листинг 4.59) значение реквизита СоставнойРеквизит станет равным строке 10, т. е. система приведет значение типа Число к значению типа Строка, который входит в составной тип данных. Листинг 4.59. Присвоение значения реквизиту составного типа
СоставнойРеквизит = 10;
В случае, если система не сможет выполнить приведение присваиваемого значения ни к одному типу, входящему в составной тип данных, реквизиту будет присвоено значение по умолчанию – Неопределено. Явное преобразование
Явное преобразование к значению реквизита составного типа данных может быть выполнено с использованием объекта встроенного языка ОписаниеТипов. Этот объект имеет метод ПривестиЗначение(), который позволяет привести значение произвольного типа к значению, соответствующему составному типу данных (листинг 4.60). Листинг 4.60. Приведение значения
МассивТипов = Новый Массив; МассивТипов.Добавить(Тип("Строка")); МассивТипов.Добавить(Тип("Число")); МассивТипов.Добавить(Тип("СправочникСсылка.Номенклатура")); ОписаниеСоставногоТипа = Новый ОписаниеТипов(МассивТипов); ПриводимоеЗначение = Справочники.Номенклатура.НайтиПоКоду("000000001"); Результат = ОписаниеСоставногоТипа.ПривестиЗначение(ПриводимоеЗначение); Сообщение = Новый СообщениеПользователю; Сообщение.Текст = "" + ТипЗнч(Результат) + ": " + Результат; Сообщение.Сообщить();
Том 1
Наборы типов При выборе типа данных реквизита система, помимо выбора типов, определенных в конкретном прикладном решении, предоставляет разработчику возможность выбирать наборы типов. Наборами типов, например, являются ЛюбаяСсылка, СправочникСсылка, Характеристика.<имя> и др. Наборы типов, так же как и составной тип данных, содержат некий перечень типов, определенных в данном прикладном решении, однако, в отличие от составного типа, этот перечень формируется системой автоматически, в результате анализа объектов конфигурации. Проведем сравнение на примере ссылок на справочники. Допустим, в прикладном решении имеются справочники Номенклатура и Контрагенты. Тогда мы можем определить реквизит составного типа данных, в который входят типы СправочникСсылка.Номенклатура и СправочникСсылка.Контрагенты. Наряду с этим мы можем определить реквизит, содержащий набор типов СправочникСсылка. И в том и в другом случае мы будем иметь возможность хранить в реквизите ссылки как на справочник Номенклатура, так и на справочник Контрагенты. Теперь добавим в конфигурацию новый справочник Цены. В реквизите составного типа мы по-прежнему сможем хранить только ссылки на справочники Номенклатура и Контрагенты, а в реквизите, описанном как набор типов, мы сможем хранить ссылку на любой из справочников, доступных в данной конфигурации, в том числе и на справочник Цены. При запуске прикладного решения набор типов преобразуется системой, как правило, в составной тип, содержащий все типы, которые должны входить в этот набор. Поэтому во втором случае в набор типов попадет и новый справочник Цены. Однако набор типов не всегда преобразуется системой в составной тип данных. Если оказывается, что в набор типов входит единственный тип значений, то набор типов будет преобразован в этот самый тип значений. Такая ситуация возможна, например, когда план видов характеристик
103
Глава 4. Работа с данными (назовем его Свойства) имеет единственный тип значений в свойстве ТипЗначенияХарактеристик. Тогда набор типов Характеристика.Свойства будет преобразован системой не в составной тип данных, содержащий один тип значений, а в тот единственный тип значений, который указан для плана видов характеристик.
а часть – нет. С точки зрения системы такая ситуация недопустима и нарушает целостность базы данных, т. к. результатом интерактивной пометки на удаление должна быть установка пометки на удаление самого элемента и всех его подчиненных элементов. То есть должны быть выполнены либо все перечисленные операции, либо ни одна из них.
Эта особенность может быть важна, когда, например, выполняется проверка реквизита, тип которого описан как Характеристика.Свойства, на заполненность. В случае, когда Характеристика.Свойства преобразуется системой в составной тип данных, проверять нужно на значение Неопределено, а если Характеристика.Свойства преобразуется в определенный тип значения, то проверять нужно на значение по умолчанию данного типа.
Для того чтобы обеспечить именно такое поведение, установка пометки на удаление выполняется системой в транзакции. Если в процессе выполнения этой последовательности операций произойдет ошибка (например, один из подчиненных элементов будет заблокирован другим пользователем), будет выполнен откат транзакции, и изменения, которые к этому моменту произошли в базе данных, будут отменены (рис. 4.55).
Транзакции Независимо от выбранного варианта работы (файловый или клиент-серверный) система «1С:Предприятие» обеспечивает работу с информацией, хранящейся в базе данных, с использованием механизма транзакций. Транзакция – это неделимая с точки зрения воздействия на базу данных последовательность операций манипулирования данными, выполняющаяся по принципу «все или ничего» и переводящая базу данных из одного целостного состояния в другое целостное состояние. Если по каким-либо причинам одно из действий транзакции невыполнимо или произошло какое-либо нарушение работы системы, база данных возвращается в то состояние, которое было до начала транзакции (происходит откат транзакции). Одним из главных свойств транзакции является ее атомарность, то есть неделимость. Рассмотрим простой пример: интерактивная пометка на удаление группы справочника. Фактически это означает, что нужно выполнить целую последовательность операций: 1. Для группы справочника установить значение поля ПометкаУдаления. 2. Записать группу справочника. 3. Выбрать все элементы справочника, находящиеся в иерархии помечаемой группы. 4. Для каждого из них установить значение поля ПометкаУдаления. 5. Выполнить запись каждого из выбранных элементов. В общем случае нет гарантии, что каждая из перечисленных операций будет успешно выполнена. Например, один из подчиненных элементов справочника может редактироваться другим пользователем, и система в этом случае не сможет изменить данные этого элемента справочника. В результате часть элементов справочника окажется помеченной на удаление,
104
Рис. 4.55. Отказ от изменений, выполненных в транзакции
Таким образом, перечисленная последовательность операций становится неделимой с точки зрения базы данных: изменения будут зафиксированы в базе данных только в том случае, если транзакция успешно завершена, т. е. выполнены все перечисленные операции (рис. 4.56).
Рис. 4.56. Принятие изменений, выполненных в транзакции
Транзакции могут использоваться как самой системой, так и разработчиком при написании модулей. Система осуществляет неявный вызов транзакций при выполнении любых действий, связанных с модификацией информации, хранящейся в базе данных. Например, все обработчики событий, расположенные в модулях объектов и наборов записей, связанные с модификацией данных базы данных, вызываются в транзакции. Наряду с этим разработчик может использовать работу с транзакциями в явном виде. Для этого используются процедуры глобального контекста НачатьТранзакцию(), ЗафиксироватьТранзакцию() и ОтменитьТранзакцию(). Профессиональная разработка в системе «1С:Предприятие 8»
Транзакции
Использование явного вызова транзакций Процедура НачатьТранзакцию() позволяет открыть транзакцию. После этого все изменения информации базы данных, выполняемые последующими операторами, могут быть либо целиком приняты, либо целиком отвергнуты. Для принятия всех выполненных изменений используется процедура ЗафиксироватьТранзакцию().
Рис. 4.58. Принятие изменений
Для того чтобы отменить все изменения, выполнявшиеся в открытой транзакции, используется процедура ОтменитьТранзакцию().
Обработка ошибок базы данных в транзакции
Например, может использоваться следующая схема работы с транзакцией (листинг 4.61). Листинг 4.61. Пример использования транзакции
НачатьТранзакцию(); // Последовательность выполняемых операторов. … // Проверка возможности выполнения операции. Если не <условие> Тогда ОтменитьТранзакцию(); КонецЕсли;
Далеко не во всех случаях разработчик заранее может предусмотреть все возможные проверки. По большому счету это и не нужно. Встроенный язык предоставляет разработчику возможность перехватывать и обрабатывать ошибочные ситуации, возникающие в процессе выполнения модуля с помощью конструкции Попытка … Исключение … КонецПопытки. В конструкцию Попытка … КонецПопытки заключаются операторы, при выполнении которых может произойти исключительная ситуация, а после оператора Исключение описывается последовательность действий, которая должна выполняться, если возникает исключительная ситуация (ошибка). Таким образом, схема работы с транзакцией в более общем виде может выглядеть следующим образом (листинг 4.62).
// Последовательность выполняемых операторов. …
Листинг 4.62. Обработка исключительных ситуаций
ЗафиксироватьТранзакцию();
НачатьТранзакцию();
Суть этой схемы заключается в том, что в процессе выполнения связанной последовательности изменений данных базы данных проверяется возможность выполнения некоторых операций. Если операцию выполнить невозможно, осуществляется откат всех произведенных изменений к состоянию, которое существовало перед выполнением оператора НачатьТранзакцию(), рис. 4.57.
// Последовательность операторов. … Попытка
// Последовательность выполняемых операторов. …
Исключение ОтменитьТранзакцию(); КонецПопытки; // Последовательность выполняемых операторов. … ЗафиксироватьТранзакцию();
Рис. 4.57. Отмена изменений
Если все операции выполнены успешно, то после выполнения оператора ЗафиксироватьТранзакцию() все произведенные изменения будут зафиксированы в базе данных (рис. 4.58). Том 1
При использовании такой схемы следует помнить о том, что не все ошибки, возникающие при работе с базой данных, обрабатываются системой одинаково.
105
Глава 4. Работа с данными В общем случае все ошибки базы данных можно разделить на две категории:
В зависимости от характера произошедшей ошибки возможны различные сценарии обработки этой ситуации.
■■ невосстановимые, ■■ восстановимые.
Если произошедшая ошибка не связана с базой данных, то возможно продолжение транзакции и дальнейшей работы модуля. Если разработчик считает это необходимым, он может отменить транзакцию или, наоборот, продолжить выполнение транзакции, если произошедшая ошибка не нарушает атомарность транзакции.
Невосстановимые ошибки – это ошибки, при возникновении которых нормальное функционирование «1С:Предприятия» может быть нарушено, например, могут быть испорчены данные. При возникновении невосстановимой ошибки выполнение «1С:Предприятия» прекращается в любом случае. Если невосстановимая ошибка произошла в процессе выполнения транзакции, то все изменения, сделанные в рамках этой транзакции, отменяются системой (рис. 4.59).
Если же исключительная ситуация была вызвана ошибкой базы данных, то система фиксирует факт возникновения ошибки в этой транзакции и дальнейшее продолжение транзакции или ее фиксация становятся невозможны. Единственная операция с базой данных, которую разработчик может произвести в данной ситуации, – это отмена транзакции. После этого он может осуществить попытку выполнения этой транзакции еще раз. Например, фрагмент кода, реализующий этот подход при записи некоторых данных в базу данных, может выглядеть следующим образом (листинг 4.63). Листинг 4.63. Обработка исключительных ситуаций
// Признак окончания попыток выполнения записи. Записано = Ложь; Рис. 4.59. Невосстановимая ошибка
Восстановимые ошибки – это ошибки, не вызывающие серьезных нарушений в работе «1С:Предприятия». В случае возникновения восстановимой ошибки дальнейшая работа системы может быть продолжена. При этом, естественно, сама операция, вызвавшая ошибку, прекращается, и вызывается исключение, которое может быть перехвачено и обработано конструкцией Попытка … Исключение … КонецПопытки. Если восстановимая ошибка произошла в процессе выполнения транзакции, то система автоматически не выполняет отмену транзакции, предоставляя разработчику возможность самостоятельно обработать сложившуюся ситуацию (рис. 4.60).
// Попытки записи выполняются в цикле. Пока не Записано Цикл Попытка НачатьТранзакцию(); Данные.Записать(); ЗафиксироватьТранзакцию();
// В случае фиксации транзакциии прекратить попытки записи. Записано = Истина;
Исключение // В случае неудачи отменить текущую транзакцию и следующую // попытку начать с новой транзакции. ОтменитьТранзакцию(); КонецПопытки; КонецЦикла;
Рис. 4.60. Восстановимая ошибка
106
Профессиональная разработка в системе «1С:Предприятие 8»
Транзакции
Вложенный вызов транзакций В рамках уже выполняемой транзакции можно обращаться к процедурам НачатьТранзакцию(), ЗафиксироватьТранзакцию() и ОтменитьТранзакцию(). Например, может использоваться следующая схема вызовов (листинг 4.64). Листинг 4.64. Вложенный вызов транзакций
НачатьТранзакцию(); … // Вложенный вызов транзакции. НачатьТранзакцию(); … ЗафиксироватьТранзакцию(); … // Вложенный вызов транзакции. НачатьТранзакцию(); … ЗафиксироватьТранзакцию(); … ЗафиксироватьТранзакцию();
Рис. 4.62. Обработка вложенных вызовов транзакций в «1С:Предприятии»
Рассмотрим подробнее механику вложенных вызовов транзакций, реализуемую «1С:Предприятием». Когда в рамках выполняемой транзакции происходит вызов процедуры НачатьТранзакцию(), фактически выполняется всего лишь увеличение на единицу внутреннего счетчика транзакций. Процедура НачатьТранзакцию() действительно начинает новую транзакцию, только если значение внутреннего счетчика транзакций равно нулю (рис. 4.63).
Однако подобное обращение не означает начала новой транзакции в рамках уже выполняющейся. «1С:Предприятие» не поддерживает вложенных транзакций. Это означает, что всегда действует только транзакция самого верхнего уровня. Все транзакции, вызванные внутри уже открытой транзакции, фактически относятся к той же транзакции, а не образуют вложенную транзакцию. Таким образом, отмена изменений, выполняемая во вложенной транзакции, будет приводить в конечном счете не к отмене изменений самой вложенной транзакции (рис. 4.61), а к отмене всех изменений транзакции верхнего уровня (рис. 4.62).
Рис. 4.63. Работа метода «НачатьТранзакцию()»
Обращение к методу ЗафиксироватьТранзакцию() приводит к фиксации результата транзакции только в том случае, если значение внутреннего счетчика транзакций равно единице (рис. 4.64). Рис. 4.61. Механика вложенных транзакций
Том 1
107
Глава 4. Работа с данными щение к методам ЗафиксироватьТранзакцию() и действительно завершает транзакцию.
ОтменитьТранзакцию()
По этой причине во многих случаях при возникновении ошибки при выполнении транзакции разумнее выдать сообщение и предоставить пользователю решать: повторить попытку выполнения операции еще раз или перед повторением попытки предпринять какие-то действия по устранению ситуации, приведшей к ошибке.
Влияние транзакций на работу программных объектов
Рис. 4.64. Работа метода «ЗафиксироватьТранзакцию()»
Обращение к методу ОтменитьТранзакцию() при значении счетчика транзакций больше единицы приведет не только к уменьшению значения счетчика, но и к установке признака, не позволяющего зафиксировать результаты выполнения всей транзакции в целом. Последующее обращение к процедуре ЗафиксироватьТранзакцию() при значении счетчика, равном единице, приведет фактически к отмене всей транзакции верхнего уровня (рис. 4.65).
Как уже отмечалось выше, механизм транзакций обеспечивает атомарность и согласованность изменений, выполняемых в базе данных. Работа с данными базы данных осуществляется в системе «1С:Предприятие» посредством различных программных объектов, которые используются системой непосредственно, а также доступны во встроенном языке. Результат такого опосредованного взаимодействия не всегда является очевидным и иногда может вызвать непонимание. В общем случае программные объекты, используемые системой «1С:Предприятие», абсолютно прозрачны для транзакций базы данных. Иначе говоря, транзакции базы данных могут вызываться при выполнении различных методов программных объектов, однако, например, действия, выполняемые базой данных при откате транзакции, в общем случае никак не влияют на соответствующие программные объекты. В качестве примера рассмотрим изменение наименования элемента справочника, выполняемое в транзакции, которая затем отменяется. При выполнении метода ПолучитьОбъект() данные объекта будут считаны из базы данных в свойства экземпляра программного объекта СправочникОбъект.Номенклатура (листинг 4.65). Листинг 4.65. Получение объекта справочника
Товар = Справочники.Номенклатура.НайтиПоКоду("000000001").ПолучитьОбъект();
Таким образом, и в базе данных, и в свойстве программного объекта будет находиться одно и то же значение наименования – Старое наименование (рис. 4.66). После этого вызывается транзакция и изменяется значение свойства Наименование программного объекта на Новое наименование (листинг 4.66). Листинг 4.66. Изменение наименования элемента справочника в транзакции Рис. 4.65. Работа метода «ОтменитьТранзакцию()»
Товар = Справочники.Номенклатура.НайтиПоКоду("000000001").ПолучитьОбъект();
Таким образом, не всегда можно быть уверенным, что обращение к методу НачатьТранзакцию() действительно начинает новую транзакцию, а обра-
НачатьТранзакцию(); Товар.Наименование = "Новое наименование";
108
Профессиональная разработка в системе «1С:Предприятие 8»
Транзакции
Рис. 4.66. Получение объекта справочника
Теперь наименования в базе данных и в свойстве программного объекта отличаются (рис. 4.67).
Рис. 4.68. Успешная запись объекта справочника Листинг 4.68. Отмена транзакции
Товар = Справочники.Номенклатура.НайтиПоКоду("000000001").ПолучитьОбъект(); НачатьТранзакцию(); Товар.Наименование = "Новое наименование"; Товар.Записать(); ОтменитьТранзакцию();
В результате того, что изменения, выполненные в базе данных в транзакции, не принимаются, состояние базы данных возвращается в исходное, т. е. то, которое было до начала транзакции. Это значит, что наименование элемента справочника снова принимает значение Старое наименование.
Рис. 4.67. Изменение наименования элемента справочника в транзакции
Однако эти изменения никоим образом не касаются программного объекта: значение свойства Наименование остается равным Новое наименование (рис. 4.69).
После этого выполняется запись программного объекта (листинг 4.67). Листинг 4.67. Запись объекта справочника
Товар = Справочники.Номенклатура.НайтиПоКоду("000000001").ПолучитьОбъект(); НачатьТранзакцию(); Товар.Наименование = "Новое наименование"; Товар.Записать();
После успешной записи данных программного объекта в базу данных наименование элемента справочника и в памяти, и в базе данных будет одинаковым: Новое наименование (рис. 4.68). Затем выполняется отмена транзакции (листинг 4.68).
Рис. 4.69. Отмена транзакции
Для того чтобы сравнить наименования в базе данных и программном объекте, можно выполнить запрос к базе данных (листинг 4.69). Том 1
109
Глава 4. Работа с данными Листинг 4.69. Сравнение наименования элемента справочника в базе данных и программном объекте
Товар = Справочники.Номенклатура.НайтиПоКоду("000000001").ПолучитьОбъект(); НачатьТранзакцию(); Товар.Наименование = "Новое наименование"; Товар.Записать(); ОтменитьТранзакцию(); Запрос = Новый Запрос(“ВЫБРАТЬ | Номенклатура.Наименование |ИЗ | Справочник.Номенклатура КАК Номенклатура |ГДЕ | Номенклатура.Код = ""000000001"""); Выборка = Запрос.Выполнить().Выбрать(); Выборка.Следующий(); НаименованиеВБазе = Выборка.Наименование; НаименованиеВПамяти = Товар.Наименование;
Из приведенного примера следует важный вывод: при отмене транзакций базы данных разработчик (если в этом есть необходимость) должен самостоятельно обеспечивать адекватное изменение данных соответствующих программных объектов. Это можно выполнять путем перечитывания всех данных объекта или путем изменения некоторых реквизитов программного объекта (если, например, это необходимо для отображения в интерфейсе). Однако, как в любом правиле, здесь тоже есть исключения. В силу значительной прикладной специфики программных объектов «1С:Предприятия» в некоторых случаях откат изменений, выполненных в базе данных, все же может влиять на значения свойств соответствующих программных объектов.
Восстановление признака проведенности документа
Сообщение = Новый СообщениеПользователю; Сообщение.Текст = НаименованиеВПамяти; Сообщение.Сообщить(); Сообщение.Текст = НаименованиеВБазе; Сообщение.Сообщить();
При отмене транзакции признак проведенности документа восстанавливает значение, которое было до начала транзакции (листинг 4.71).
Если теперь заново прочитать данные объекта из базы данных в программный объект, то значение наименования в программном объекте станет таким же, как и в базе данных (листинг 4.70).
НачатьТранзакцию(); Накладная = Документы.ПриходнаяНакладная.СоздатьДокумент(); Накладная.Дата = ТекущаяДата(); Накладная.Записать(РежимЗаписиДокумента.Проведение); Проведен = Накладная.Проведен; ОтменитьТранзакцию();
Листинг 4.70. Перечитывание данных объекта
Товар = Справочники.Номенклатура.НайтиПоКоду("000000001").ПолучитьОбъект(); НачатьТранзакцию(); Товар.Наименование = "Новое наименование"; Товар.Записать(); ОтменитьТранзакцию(); Запрос = Новый Запрос("ВЫБРАТЬ | Номенклатура.Наименование |ИЗ | Справочник.Номенклатура КАК Номенклатура |ГДЕ | Номенклатура.Код = ""000000001"""); Выборка = Запрос.Выполнить().Выбрать(); Выборка.Следующий(); НаименованиеВБазе = Выборка.Наименование; НаименованиеВПамяти = Товар.Наименование; Сообщение = Новый СообщениеПользователю; Сообщение.Текст = НаименованиеВПамяти; Сообщение.Сообщить(); Сообщение.Текст = НаименованиеВБазе; Сообщение.Сообщить(); Товар.Прочитать(); Сообщение.Текст = Товар.Наименование; Сообщение.Сообщить();
110
Листинг 4.71. Восстановление признака проведенности документа
Сообщение = Новый СообщениеПользователю; Сообщение.Текст = Строка(Накладная.Проведен); Сообщение.Сообщить(); // Нет Сообщение.Текст = Строка(Проведен); Сообщение.Сообщить(); // Да
Очистка ссылки Если объект был создан в транзакции, то при ее откате очищается значение ссылки (листинг 4.72). Листинг 4.72. Очистка ссылки
НачатьТранзакцию(); Товар = Справочники.Номенклатура.СоздатьЭлемент(); Товар.Записать(); Ссылка = Товар.Ссылка; ОтменитьТранзакцию(); Сообщение = Новый СообщениеПользователю; Сообщение.Текст = ?(Товар.Ссылка = Справочники.Номенклатура.ПустаяСсылка(), "Истина", "Ложь"); Сообщение.Сообщить(); // истина Сообщение.Текст = Строка(Ссылка); Сообщение.Сообщить(); // <Объект не найден> (1:9e4b00055d4c7bcf11d934028f79e857)
Профессиональная разработка в системе «1С:Предприятие 8»
Механизм управляемых блокировок
Очистка кода/номера объекта Если объект создавался вне транзакции и при записи его в транзакции использовался код/номер, сгенерированный автоматически, то при отмене транзакции код/номер очищается (листинг 4.73). Листинг 4.73. Очистка кода
Товар = Справочники.Номенклатура.СоздатьЭлемент(); НачатьТранзакцию(); Товар.Записать(); Код = Товар.Код; ОтменитьТранзакцию();
которая записала свои изменения последней, поскольку эти изменения заменят собой все изменения, внесенные до этого. Рассмотрим следующий пример. Допустим, Транзакция № 1 обратилась к элементу справочника Номенклатура и решила изменить значение реквизита товара ЦенаПродажи с 420 на 450. Одновременно Транзакция № 2 решила у этого же товара изменить значение реквизита ЕдиницаИзмерения со Штука на Коробка. Распределение по времени описанных действий показано на рис. 4.70. Таким образом, в элементе справочника остались только те изменения, которые сделала Транзакция № 2. Из примера следует вывод: нельзя одновременно изменять одни и те же данные.
Сообщение = Новый СообщениеПользователю; Сообщение.Текст = Товар.Код; Сообщение.Сообщить(); // "" Сообщение.Текст = Код; Сообщение.Сообщить(); // "000000008"
Проблема «грязного» чтения (англ. The Uncommitted Dependency Problem) возникает в случае, если одна транзакция начинает считывать некоторые данные, не дождавшись окончания внесения изменений, вносимых в эти данные другой транзакцией. При этом достаточно вероятен случай, когда прочитанные данные будут содержать неверную информацию.
Механизм управляемых блокировок
Вернемся к примеру, рассмотренному выше. Допустим, Транзакция № 1 обратилась к элементу справочника Номенклатура и изменила значение реквизита товара ЦенаПродажи с 420 на 450. Не дождавшись фиксации изменений, Транзакция № 2 использовала значение реквизита этого товара для определения суммы продажи. Однако первая транзакция решила не сохранять внесенные изменения (откат транзакции) и восстановила старые данные. Графическое представление действий транзакций показано на рис. 4.71. Таким образом, Транзакция № 2 в своих расчетах использовала данные, не существующие в системе.
Возможные проблемы при многопользовательском доступе к одним и тем же данным Работа в многопользовательской среде требует соблюдения определенного компромисса между требованиями предсказуемости, целостности и непротиворечивости данных информационной базы и требованиями параллельности работы. Как известно, при одновременном чтении и изменении одних и тех же данных конкурирующими транзакциями могут возникнуть следующие проблемы одновременного доступа: ■■ ■■ ■■ ■■
проблема потерянного изменения, проблема «грязного» чтения, проблема неповторяемого чтения, проблема чтения фантомов.
Рассмотрим проблем.
подробнее
каждую
из
этих
Проблема потерянного изменения (англ. The Lost Update Problem) возникает в случае, если две транзакции изменяют одни и те же данные, взяв в качестве первоисточника начальное значение этих данных. При этом в системе останутся изменения, внесенные той транзакцией, Том 1
Рис. 4.70. Иллюстрация проблемы потерянного изменения
111
Глава 4. Работа с данными Допустим, в нашем примере Транзакция № 1 два раза подряд обращается к элементу справочника Номенклатура и каждый раз считывает значение реквизита ЦенаПродажи. Если в промежуток между первым и вторым чтением вклинится Транзакция № 2 и изменит значение этого реквизита, то в результате получится, что первая транзакция работает с данными, которые с ее точки зрения самопроизвольно изменяются. Графическое представление данной проблемы показано на рис. 4.72. Из примера следует вывод: нельзя повторно читать измененные и записанные данные, если эти же самые данные уже были прочитаны до внесения в них изменений.
Рис. 4.71. Иллюстрация проблемы «грязного» чтения
Проблема чтения фантомов (англ. The Phantom Read Problem) возникает в случае, если первая транзакция считывает данные и потом на их основе осуществляет определенные действия, а вторая транзакция в этот момент добавляет в эти данные новую информацию. При этом, как и в предыдущем случае, это может привести к некорректному результату. Рассмотрим следующий пример. Допустим, компания занимается продажей товаров и состоит из нескольких отделов. Если объем продаж сотрудников одного отдела превышает 1 000 рублей, то каждый сотрудник отдела получает премию 20 % от суммы своих продаж. В противном случае размер премии составляет 10 %. Очевидно, что процесс начисления премии сотрудникам каждого отдела будет состоять из нескольких операций:
Из примера следует вывод: нельзя читать уже измененные, но еще не записанные данные.
■■ получения общей суммы продаж по отделу в целом путем суммирования отдельных продаж по каждому из сотрудников; ■■ определения на основании полученных данных процента премии; ■■ расчета суммы премии для каждого из сотрудников отдела.
Проблема неповторяемого чтения (англ. The Inconsistent Analysis Problem) возникает в случае, если одна транзакция несколько раз считывает одни и те же данные, а вторая вносит изменения в эти данные между циклами чтения данных первой транзакции. При этом при повторном считывании первая транзакция может получить другой набор данных.
Предположим, что данные о продажах вводит Транзакция № 2, а размер премии рассчитывает Транзакция № 1. Тогда при одновременной работе транзакций может возникнуть ситуация, показанная на рис. 4.73. Таким образом, Транзакция № 1 в двух одинаковых выборках строк получила разные результаты.
Рис. 4.72. Иллюстрация проблемы неповторяемого чтения
112
Профессиональная разработка в системе «1С:Предприятие 8»
Механизм управляемых блокировок ■■ READ COMMITED – обеспечивает запрет «грязного» чтения. Если одна транзакция начала изменять данные, то конкурирующая транзакция не может не только изменить, но даже прочитать их до завершения изменений, вносимых первой транзакцией. После того как эти изменения закончены, конкурирующие транзакции могут читать данные, не дожидаясь окончания первой транзакции в целом. Таким образом, существует проблема неповторяемого чтения; ■■ REPEATABLE READ – обеспечивает повторяемость чтения данных. Если первая транзакция начинает читать данные, то другая транзакция не может их изменить до окончания первой транзакции; ■■ SERIALIZABLE – последовательное выполнение. Этот уровень изоляции является максимальным и обеспечивает полную изоляцию транзакций друг от друга. Решаются все рассмотренные выше проблемы, включая проблему фантомов.
Рис. 4.73. Иллюстрация проблемы чтения фантомов
Из примера следует вывод: нельзя вводить новые данные (удалять имеющиеся), если они могут попасть в уже один раз прочитанные данные при повторном чтении. Строго говоря, список вышеперечисленных проблем не является окончательным.
Уровни изоляции транзакций Итак, ради увеличения производительности системы необходимо разрешить параллельное выполнение транзакций. При этом также нужно обеспечить необходимую степень целостности данных (то есть ограничить параллельность транзакций при работе с одними ресурсами). Строгость этих ограничений может быть различной, в зависимости от решаемой задачи. Поэтому платформе необходим механизм гибкой настройки этих ограничений. В современных СУБД такая возможность реализуется путем применения уровней изоляции транзакций. СУБД, с которыми может взаимодействовать «1С:Предприятие», позволяют использовать следующие уровни изоляции транзакции: ■■ READ UNCOMMITED – незавершенное чтение. Низший уровень изоляции, обеспечивает максимальную параллельность выполнения транзакций. Данный уровень защищает данные, изменяемые одной транзакцией, от изменений, которые могут внести конкурирующие транзакции. Если другой транзакции необходимо изменить те же самые данные, то она должна ожидать завершения изменения данных первой транзакцией. Однако чтение данных разрешено. Таким образом, этот уровень изоляции допускает чтение незавершенных изменений данных; Том 1
В зависимости от используемого уровня изоляции СУБД накладывает различные типы блокировок на различные объекты базы данных на различное время.
Режим управляемых блокировок Система «1С:Предприятие» стандартно поддерживает управляемый режим блокировок данных в транзакции. При работе в этом режиме используется достаточно низкий уровень изоляции транзакций в СУБД, позволяющий достичь высокой параллельности работы пользователей (табл. 4.20). Таблица 4.20. Блокировки СУБД, используемые в режиме управляемых блокировок в транзакции СУБД
Вид блокировок Уровень изоляции транзакций
Файловая база данных
MS SQL Server
Таблиц Serializable
Записей Записей Записей Read Committed Read Committed Read Committed
IBM DB2
PostgreSQL
Однако этот уровень изоляции транзакций СУБД уже не может сам по себе обеспечить целостность и непротиворечивость данных во всех случаях. Поэтому при модификации данных методами встроенного языка (например, методом Записать() у объектных данных) платформа устанавливает собственные управляемые блокировки в транзакции, которые
113
Глава 4. Работа с данными обрабатываются собственным менеджером транзакционных блокировок (рис. 4.74).
Установка управляемых блокировок Средствами встроенного языка установка управляемых блокировок внутри явной или скрытой (неявной) транзакции происходит с помощью специального объекта БлокировкаДанных, описание доступных свойств и методов которого можно посмотреть в синтакс-помощнике, в ветви Общие объекты (рис. 4.75).
Рис. 4.74. Управляемые блокировки в транзакции «1С:Предприятия»
Эти блокировки также могут быть установлены и разработчиком самостоятельно в тех местах кода, где требуется обеспечить неизменность считываемых в транзакции данных (разделяемая блокировка) или запретить чтение данных другими транзакциями (исключительная блокировка). Управляемые блокировки «1С:Предприятия» учитывают логическую структуру прикладного решения, поэтому позволяют максимально точно блокировать необходимые области данных. Таким образом, менеджер управляемых блокировок позволяет максимально избежать возникновения «плохих» (избыточных) блокировок. Блокируются только действительно необходимые области данных. В результате любой запрос к данным прежде всего обрабатывается собственным менеджером транзакционных блокировок «1С:Предприятия» (см. рис. 4.74). Если на уровне «1С:Предприятия» конфликт управляемых блокировок не обнаруживается, то запрос передается далее, на исполнение СУБД. СУБД также использует собственный механизм блокировок для определения конфликтующих транзакций, с низким уровнем изоляции транзакций, указанным в таблице 4.20.
Установка режима управления блокировкой данных в конфигурации Режим блокировок в конфигурации устанавливается с помощью свойства Режим управления блокировкой данных. Это свойство имеет как конфигурация в целом, так и каждый прикладной объект конфигурации. Для платформы «1С:Предприятие» стандартным является режим управляемых блокировок. Поэтому свойство конфигурации Режим управления блокировкой данных для новых конфигураций устанавливается в значение Управляемый.
114
Рис. 4.75. Набор свойств и методов объекта «БлокировкаДанных», доступных в синтакс-помощнике
Новый экземпляр данного объекта может быть создан с помощью одноименного конструктора и представляет собой коллекцию элементов блокировки данных. Изначально эта коллекция пуста, и задача разработчика состоит в добавлении в эту коллекцию некоторого количества элементов блокировки. При добавлении нового элемента блокировки для него необходимо указать пространство блокировок, которое будет блокировать данный элемент. Пространства блокировок определены в платформе «1С:Предприятие» Профессиональная разработка в системе «1С:Предприятие 8»
Механизм управляемых блокировок и соответствуют структуре прикладных объектов конфигурации. Допустимы следующие имена пространств блокировок и имена полей пространств блокировок (табл. 4.21). Таблица 4.21. Имена пространств блокировок и имена полей пространств блокировок Имя пространства блокировки
Имя поля пространства блокировки
Справочник.<имя> Документ.<имя> ПланОбмена.<имя> ПланСчетов.<имя> БизнеcПроцесс.<имя> Задача.<имя> ПланВидовРасчета.<имя> ПланВидовХарактеристик.<имя> РегистрСведений.<имя>.НаборЗаписей – только для регистра сведений, подчиненного регистратору РегистрСведений.<имя> РегистрНакопления.<имя>.НаборЗаписей РегистрНакопления.<имя> РегистрБухгалтерии.<имя>.НаборЗаписей РегистрБухгалтерии.<имя>
Ссылка Ссылка Ссылка Ссылка Ссылка Ссылка Ссылка Ссылка Регистратор
РегистрРасчета.<имя>.НаборЗаписей РегистрРасчета.<имя> Перерасчет.<имя>.НаборЗаписей Последовательность.<имя>.НаборЗаписей Последовательность.<имя>
Период – если есть; <имя измерения> Регистратор Период; <имя измерения> Регистратор Период; <имя измерения>; <вид движения> – значение системного перечисления ВидДвиженияБухгалтерии; Счет; Субконто; <вид субконто> Регистратор ПериодРегистрации; ПериодДействия; <имя измерения> ОбъектПерерасчета Регистратор <имя измерения>
Константа.<имя>
Как видно из таблицы, для объектных данных (справочник, документ и др.) определено единственное пространство блокировки – сам объект данных. Для необъектных данных (например, регистры) определено по два пространства блокировок, которые имеют разный логический смысл. Пространство блокировок с суффиксом НаборЗаписей используется в тех случаях, когда необходимо заблокировать сами записи данного объекта (например, при добавлении новых записей). Пространство блокировок без суффикса используется, когда анализируются некоторые данные этого объекта (например, остатки регистра) или когда выполняются какие-либо операции, приводящие к изменению существующих данных объекта (например, восстановление границы последовательности). Том 1
После того как элемент блокировки, соответствующий некоторому пространству блокировок, добавлен, следует установить для этого элемента режим блокировки (разделяемая или исключительная) и определить значения полей блокировки, чтобы указать, какие же именно «записи» будут заблокированы (для каждого пространства блокировок в платформе определены имена полей, значения которых могут задаваться при установке тех или иных блокировок). Следует понимать, что в данном случае речь не идет о реальных записях базы данных. Несмотря на то, что управляемые блокировки описываются в терминах объектов метаданных и их полей, эти блокировки никак не связаны с реальной структурой хранения данных «1С:Предприятия» в СУБД. Это всего лишь записи о том, что заблокировано «нечто». Иногда можно провести аналогию между управляемыми блокировками и реальными записями СУБД. Например, для объектных данных блокировка объекта с указанной ссылкой будет «соответствовать» блокировке всех записей, содержащих указанную ссылку, во всех таблицах этого объекта конфигурации (в основной таблице и в таблицах его табличных частей). Однако в других случаях провести такую аналогию достаточно затруднительно, да и не нужно. Например, блокировка регистра бухгалтерии с указанием значения вида субконто. Достаточно понимать, что, накладывая такую блокировку, мы запрещаем другим транзакциям каким-либо образом изменять «записи» регистра бухгалтерии, у которых значение вида субконто равно указанному нами. Как при этом данное условие «проецируется» на реальную структуру данных регистра бухгалтерии – для нас совершенно не важно. При установке новых блокировок менеджер анализирует имеющиеся блокировки. Если оказывается, что «нечто», что мы пытаемся заблокировать, уже заблокировано ранее, сравниваются режимы существующей и новой блокировок. Если режимы совместимы, новая блокировка устанавливается. Если режимы не совместимы, новая блокировка ожидает снятия существующей блокировки. Условия необходимо ставить именно на те поля, имена которых приведены в списке имен пространств блокировок. Для каждого пространства блокировок количество устанавливаемых условий неограниченно. Условия могут быть заданы или на равенство значения поля какому-либо значению, или на вхождение значения поля в указанный диапазон. Существует два способа задать условия на поля пространств блокировки: ■■ с помощью явного задания имени поля и его значения; ■■ с помощью указания источника данных, содержащего необходимые значения. При явном задании имени поля и его значения необходимо использовать метод УстановитьЗначение() объекта ЭлементБлокировкиДанных.
115
Глава 4. Работа с данными В этом случае имя и значение указывают в качестве параметров метода, например так, как показано в листинге 4.74. Листинг 4.74. Пример установки условия блокировки записей с помощью явного указания имени поля и его значения
// Создать объект блокировка данных. БлокировкаДанных = Новый БлокировкаДанных; // Добавить новый элемент блокировки, блокирующий "нечто" в данных регистра // накопления Остатки номенклатуры. ЭлементБлокировки = БлокировкаДанных.Добавить("РегистрНакопления.ОстаткиНоменклатуры"); // Установить режим блокировки – исключительный. Другие транзакции, устанавливающие // управляемые блокировки, не смогут даже начать чтение этих данных. ЭлементБлокировки.Режим = РежимБлокировкиДанных.Исключительный; // Указать, что именно мы блокируем в данных регистра Остатки номенклатуры – все // "записи", у которых значение измерения Склад равно значению, содержащемуся в // переменной Склад. ЭлементБлокировки.УстановитьЗначение("Склад", Склад);
Для значений типа Дата или Число в качестве значения может быть задан некоторый диапазон значений. Диапазон значений передается методу с помощью объекта встроенного языка Диапазон. Данный объект позволяет задать верхнюю и нижнюю границы диапазона, причем в диапазон включаются и границы диапазона (листинг 4.75). Листинг 4.75. Пример установки условия блокировки записей с помощью задания диапазона
// Создать объект блокировка данных. БлокировкаДанных = Новый БлокировкаДанных; // Добавить новый элемент блокировки, блокирующий "нечто" в данных регистра // накопления Продажи. ЭлементБлокировки = БлокировкаДанных.Добавить("РегистрНакопления.Продажи"); // Установить режим блокировки – разделяемый. Эти данные гарантированно не будут // изменены другими транзакциями до окончания существующей транзакции. ЭлементБлокировки.Режим = РежимБлокировкиДанных. Разделяемый; // Указать, что именно мы блокируем в данных регистра Продажи – все "записи", у // которых значение измерения Контрагент равно значению, содержащемуся в переменной // Контрагент. ЭлементБлокировки.УстановитьЗначение("Контрагент", Контрагент); // Создать объект Диапазон, описывающий интервал от начала месяца, к которому // принадлежит указанная дата, до указанной даты. Диапазон = Новый Диапазон(НачалоМесяца(Дата), Дата);
При указании источника данных сначала необходимо задать свойство ИсточникДанных объекта ЭлементБлокировкиДанных, после чего, используя метод ИспользоватьИзИсточникаДанных(), настроить соответствие полей области блокировки данных полям источника данных (листинг 4.76). Листинг 4.76. Пример установки условия блокировки записей с помощью источника данных
// Создать объект блокировка данных. БлокировкаДанных = Новый БлокировкаДанных; // Добавить новый элемент блокировки, блокирующий "нечто" в данных регистра // накопления Остатки номенклатуры. ЭлементБлокировки = БлокировкаДанных.Добавить("РегистрНакопления.ОстаткиНоменклатуры"); // Установить режим блокировки – исключительный. Другие транзакции, устанавливающие // управляемые блокировки, не смогут даже начать чтение этих данных. ЭлементБлокировки.Режим = РежимБлокировкиДанных.Исключительный; // Указать, что именно мы блокируем в данных регистра Остатки номенклатуры – все // "записи", у которых значение измерения Склад равно значению, содержащемуся в // переменной Склад. ЭлементБлокировки.УстановитьЗначение("Склад", Склад); // Указать источник данных, который содержит данные для установки ограничений на // другие поля этого элемента блокировки – в данном случае таблица значений // СписокНоменклатуры. ЭлементБлокировки.ИсточникДанных = СписокНоменклатуры; // Указать, что именно мы блокируем в данных регистра Остатки номенклатуры – все // "записи", у которых значение измерения Склад равно значению, содержащемуся в // переменной Склад и у которых значение измерения Номенклатура равно какому-либо // значению, содержащемуся в колонке Номенклатура указанного источника данных. ЭлементБлокировки.ИспользоватьИзИсточникаДанных("Номенклатура", "Номенклатура");
В качестве источника данных можно указывать результат запроса, табличную часть, набор записей или таблицу значений. При установке соответствия полей именами полей источника будут являться имена колонок результата запроса, имена реквизитов табличной части, имена измерений или имена колонок таблицы значений соответственно. Заметим, что объект Диапазон также может являться значением поля источника данных. Для установки всех созданных нами блокировок используется метод объекта БлокировкаДанных – Заблокировать(). На рисунке 4.76 показано действие данного метода в случае использования его внутри транзакции и вне нее.
// Указать, что именно мы блокируем в данных регистра Продажи – все "записи", у // которых значение измерения Контрагент равно значению, содержащемуся в переменной // Контрагент, и значение поля Период содержится в указанном диапазоне. ЭлементБлокировки.УстановитьЗначение("Период", Диапазон);
116
Профессиональная разработка в системе «1С:Предприятие 8»
Механизм управляемых блокировок Как следует из рисунка, если этот метод выполняется внутри транзакции (явной или неявной), то блокировки устанавливаются в момент вызова метода. При окончании транзакции они будут сняты автоматически. Если же метод Заблокировать() выполняется вне транзакции, то блокировки установлены не будут.
Рис. 4.76. Схема вызова метода «Заблокировать()» объекта «БлокировкаДанных»
Том 1
117
Глава 4. Работа с данными
118
Профессиональная разработка в системе «1С:Предприятие 8»
Общие сведения
Глава 5. Клиент-серверный вариант работы Общие сведения Клиент-серверный вариант работы системы «1С:Предприятие» предполагает использование трехуровневой архитектуры: клиент – кластер серверов «1С:Предприятия» – сервер баз данных. В этом варианте работы клиентское приложение, работающее у пользователя (толстый клиент, тонкий клиент или веб-клиент), взаимодействует с кластером серверов «1С:Предприятия», а кластер, при необходимости, обращается к серверу баз данных (Microsoft SQL Server, PostgreSQL, IBM DB2 или Oracle Database), рис. 5.1.
Трехуровневая архитектура «1С:Предприятия» разработана таким образом, что пользователю не требуется доступ ни к каким файловым ресурсам, связанным с «1С:Предприятием». Пользователю клиентского приложения «1С:Предприятия» также не требуется доступ к базе данных сервера баз данных. Для доступа к информационной базе клиентское приложение взаимодействует с кластером серверов «1С:Предприятия», который образует промежуточный программный слой между клиентским приложением и сервером баз данных. При этом физически кластер серверов «1С:Предприятия» и сервер баз данных могут располагаться как на одном компьютере, так и на разных. Это позволяет администратору при необходимости распределять нагрузку между разными компьютерами. Наиболее желательным является размещение всех приложений на разных компьютерах.
Программные компоненты клиент-серверной архитектуры «1С:Предприятия» В общем случае под клиент-серверным вариантом работы «1С:Предприятия» понимается архитектура, включающая следующие программные уровни (рис. 5.2): ■■ клиентское приложение (толстый клиент, тонкий клиент или веб-клиент); ■■ кластер серверов «1С:Предприятия»; ■■ веб-сервер (для веб-клиента и тонкого клиента, подключенного через веб-сервер); ■■ сервер баз данных. Толстый клиент – это одно из клиентских приложений системы «1С:Предприятие». Исполняемый файл этого приложения – 1cv8.exe. «Толстым» клиент называется потому, что может исполнять практически всю функциональность, предоставляемую встроенным языком, в том числе умеет работать с прикладными типами данных, такими как СправочникОбъект.<имя>, ДокументОбъект.<имя> и т. д.
Рис. 5.1. Схема работы в клиент-серверном варианте
Том 1
Но по этой же причине он требует значительного количества аппаратных ресурсов на компьютере пользователя и может «общаться» с базой данных или с сервером «1С:Предприятия» только посредством файлового доступа или по локальной сети.
119
Глава 5. Клиент-серверный вариант работы Веб-клиент – это одно из клиентских приложений системы «1С:Предприятие». У веб-клиента нет исполняемого файла. Для начала работы ему не нужно иметь никаких файлов на компьютере пользователя. Веб-клиент, в отличие от толстого и тонкого клиентов, исполняется не в среде операционной системы компьютера, а в среде интернетбраузера (Windows Internet Explorer, Mozilla Firefox, Google Chrome или Safari). Поэтому любому пользователю достаточно всего лишь запустить свой браузер, ввести адрес веб-сервера, на котором опубликована информационная база, и веб-клиент сам «приедет» к нему на компьютер и начнет исполняться. Веб-клиент использует технологии DHTML и HTTPRequest. При работе веб-клиента клиентские модули, разработанные в конфигурации, компилируются автоматически из встроенного языка «1С:Предприятия 8» и непосредственно исполняются на стороне веб-клиента. Рис. 5.2. Общая схема работы в клиент-серверном варианте
Веб-клиент может работать с информационными базами через Интернет только через веб-сервер.
Помимо работы в пользовательском режиме 1С:Предприятие, толстый клиент может работать в режиме Конфигуратор, в котором выполняется администрирование информационных баз и разработка прикладных решений.
Кластер серверов «1С:Предприятия» обеспечивает взаимодействие между клиентскими приложениями и системой управления базами данных. Кластер серверов «1С:Предприятия» представляет собой множество рабочих процессов, агентов сервера и менеджеров кластера, обслуживающих один и тот же набор информационных баз.
Толстый клиент поддерживает работу приложения в обычном режиме. Поэтому его можно использовать для работы с прикладными решениями, созданными в старых версиях платформы – 8.0 и 8.1, которые не использовали управляемый интерфейс и управляемые формы. Тонкий клиент – это одно из клиентских приложений системы «1С:Предприятие». Исполняемый файл этого приложения – 1cv8c.exe.
Рабочие процессы кластера серверов «1С:Предприятия» могут функционировать как на одном компьютере (в простейшем виде), так и на нескольких компьютерах, работающих под управлением различных операционных систем как Windows, так и Linux.
Тонким клиент называется потому, что умеет исполнять ограниченный набор функциональности встроенного языка. В частности, на тонком клиенте недоступны все прикладные типы данных. Вместо этого тонкий клиент оперирует ограниченным набором типов встроенного языка, предназначенным лишь для отображения и изменения данных в памяти. Вся работа с базой данных, объектными данными, исполнение запросов выполняются на стороне сервера. Тонкий клиент только получает готовые данные, подготовленные для отображения.
Архитектура системы ориентирована на максимальный перенос выполнения всей функциональности на кластер серверов и максимальное «облегчение» клиента. В кластере серверов выполняется вся работа прикладных объектов, выполняется подготовка к отображению форм (чтение объектов из информационной базы и заполнение данных формы, расположение элементов, запись данных формы после изменения) и командного интерфейса, формируются отчеты. На клиенте выполняется только отображение информации, подготовленной в кластере серверов, выполняется взаимодействие с пользователем и вызовы серверных методов для выполнения необходимых действий.
Тонкий клиент гораздо «легче» толстого, поэтому он поддерживает работу приложения только в управляемом режиме (управляемый интерфейс и управляемые формы), реализованном в версии 8.2 и выше.
Наличие кластера позволяет обеспечить бесперебойную, отказоустойчивую, конкурентную работу большого количества пользователей с крупными информационными базами.
Тонкий клиент может работать с информационными базами через Интернет и по локальной сети, и через веб-сервер. Тонкий клиент обеспечивает работу только в пользовательском режиме 1С:Предприятие. Режим работы Конфигуратор тонким клиентом не поддерживается.
Веб-сервер необходим для работы веб-клиента и одного из вариантов работы тонкого клиента. Фактически в случае работы через веб-сервер с кластером серверов взаимодействует именно веб-сервер, а уже веб-сервер взаимодействует с тонким и веб-клиентами.
120
Профессиональная разработка в системе «1С:Предприятие 8»
Общие сведения Сервер баз данных обеспечивает хранение данных информационных баз «1С:Предприятия». В качестве сервера баз данных в «1С:Предприятии» могут использоваться различные СУБД: ■■ ■■ ■■ ■■
Microsoft SQL Server, PostgreSQL, IBM DB2, Oracle Database.
При умеренной нагрузке на прикладное решение и при небольших объемах вычислений, производимых на сервере «1С:Предприятия», возможно размещение сервера баз данных и кластера серверов «1С:Предприятия» на одном компьютере (рис. 5.4).
Варианты использования При использовании клиент-серверного варианта работы допускаются различные варианты взаимного расположения сервера баз данных, кластера серверов «1С:Предприятия» и клиентского приложения на компьютерах. Наиболее желательным является размещение всех приложений на разных компьютерах (рис. 5.3).
Рис. 5.4. Размещение сервера баз данных и кластера серверов «1С:Предприятия» на одном компьютере
Такой вариант является более дешевым, однако менее эффективным с точки зрения производительности. Работа серверов на одном компьютере предъявляет, в частности, повышенные требования к объему оперативной памяти, которая активно используется как одним, так и другим приложением. Также возможны и другие варианты взаимного размещения приложений, например, на одном и том же компьютере (рис. 5.5).
Рис. 5.3. Размещение приложений на разных компьютерах
В этом случае как сервер баз данных, так и кластер серверов «1С:Предприятия» смогут полноценно использовать аппаратные ресурсы и работать максимально производительно. Также этот вариант использования предоставляет лучшие возможности для масштабирования системы, поскольку модификацию аппаратных средств можно производить независимо, исходя из реальной загрузки того или иного сервера. Том 1
Рис. 5.5. Размещение сервера баз данных и кластера серверов «1С:Предприятия» на рабочей станции
121
Глава 5. Клиент-серверный вариант работы Этот вариант вряд ли имеет смысл использовать для реальной многопользовательской работы, однако он может часто применяться, например, при разработке прикладных решений одним разработчиком.
Работа под управлением различных операционных систем
В общем случае архитектура «1С:Предприятия» позволяет смешивать в одной системе элементы, работающие под управлением различных операционных систем, например, в одной системе могут работать тонкий клиент под управлением операционной системы Windows, веб-клиент под управлением Linux в интернет-браузере Mozilla Firefox, веб-клиент под управлением Windows в браузере Internet Explorer и веб-клиент под управлением Mac OS X в браузере Safari (рис. 5.7).
Все основные компоненты платформы могут функционировать как под управлением операционной системы Windows, так и под управлением операционной системы Linux (рис. 5.6): ■■ тонкий и толстый клиенты системы «1С:Предприятие» могут работать только на компьютерах под управлением ОС Windows; ■■ веб-клиент может работать в любой операционной системе, где могут работать поддерживаемые веб-браузеры; ■■ веб-серверы, через которые веб-клиент и тонкий клиент общаются с кластером серверов, могут работать как под управлением ОС Windows, так и под управлением ОС Linux; ■■ рабочие серверы, входящие в кластер серверов, могут работать как под управлением ОС Windows, так и под управлением ОС Linux. Все процессы кластера серверов поддерживают работу в этих операционных системах; ■■ если используется СУБД Microsoft SQL Server, то сервер баз данных может работать только под управлением операционной системы Windows. Если же используются другие СУБД (кроме Microsoft SQL Server), то сервер баз данных может работать как под управлением ОС Windows, так и под управлением ОС Linux.
Рис. 5.7. Элементы системы «1С:Предприятия», работающие под управлением различных операционных систем
Кластер серверов
Состав кластера
Рис. 5.6. Многоплатформенность системы «1С:Предприятие»
122
Кластер серверов «1С:Предприятия» является логическим понятием и представляет собой совокупность одного или нескольких рабочих процессов, агентов сервера и менеджеров кластера, функционирующих на одном или нескольких компьютерах, и списка информационных баз, с которыми работают данные процессы. Профессиональная разработка в системе «1С:Предприятие 8»
Кластер серверов В простейшем виде кластер серверов «1С:Предприятия» может функционировать на одном компьютере (рис. 5.8).
Процесс rmngr называется менеджером кластера. Этот процесс управляет функционированием всего кластера. Рабочий сервер, на котором функционирует менеджер кластера и располагается реестр кластера, называется центральным сервером кластера. По умолчанию кластер серверов содержит один менеджер кластера, который называется главным менеджером кластера. Для повышения масштабируемости администратор кластера имеет возможность определить в составе кластера один или несколько дополнительных менеджеров кластера. Дополнительные менеджеры кластеров могут запускаться на рабочих серверах. При этом функциональность кластера может быть распределена между главным и дополнительными менеджерами кластера. Одной из функций главного менеджера кластера является ведение реестра кластера, который содержит следующую информацию: ■■ ■■ ■■ ■■ ■■
список информационных баз, зарегистрированных в данном кластере; список рабочих серверов, входящих в кластер; список рабочих процессов, входящих в кластер; список дополнительных менеджеров кластера; соответствие сервиса кластера и дополнительного менеджера кластера; ■■ список администраторов кластера.
Рис. 5.8. Состав простого кластера
В работе кластера серверов используются следующие элементы: ■■ процессы кластера серверов: ragent, rmngr, rphost; ■■ хранилища данных: список кластеров, реестр кластера. Процесс ragent, который называется агентом сервера, обеспечивает функционирование компьютера в составе кластера. Соответственно, компьютер, на котором запущен агент сервера, называется рабочим сервером. Одной из функций агента сервера является ведение списка кластеров, расположенных на данном рабочем сервере. Агент сервера и список кластеров не входят в состав кластера серверов, а лишь обеспечивают работу сервера и кластеров, которые расположены на нем. Непосредственно кластер серверов включает в себя следующие элементы: ■■ один или несколько процессов rmngr, ■■ реестр кластера, ■■ один или несколько процессов rphost. Том 1
Процесс rphost называется рабочим процессом. Рабочий процесс обслуживает непосредственно клиентские приложения, взаимодействует с сервером баз данных, и в нем, в частности, могут исполняться процедуры серверных модулей конфигурации. Подробнее
Документация «1С:Предприятие 8.2. Клиент-серверный вариант. Руководство администратора», раздел 2.1.
Сеансы и соединения В процессе взаимодействия пользователя с информационной базой посредством кластера серверов используются такие понятия, как сеанс и соединение. Это не одно и то же. Сеанс определяет активного пользователя информационной базы. Соединение обеспечивает доступ сеансов к кластеру серверов «1С:Предприятия» и не отождествляется с активным пользователем. Для обращения клиента к кластеру сеанс назначается соединению. Все время, пока клиент не выполняет обращений к кластеру, сеанс может быть не назначен никакому соединению. Если удаляется сеанс, назначенный соединению, то происходит разрыв этого соединения.
123
Глава 5. Клиент-серверный вариант работы
Виды соединений Можно выделить два вида соединений: соединения с информационной базой и служебные соединения с рабочими процессами кластера.
Соединения с информационной базой Возможны следующие виды соединений с информационной базой: ■■ ■■ ■■ ■■ ■■ ■■ ■■
Толстый клиент, Тонкий клиент, Конфигуратор, Модуль расширения веб-сервера, COM-соединение, WS-соединение, Фоновое задание.
Соединение Толстый клиент представляет собой соединение толстого клиента с информационной базой. Это соединение предназначено для модификации данных информационной базы и выполнения другой функциональности, предоставляемой конфигурацией информационной базы. Соединение создается в результате интерактивного запуска толстого клиента в режиме 1С:Предприятие или в результате подключения к информационной базе с использованием технологии Automation Client/Server, например (листинг 5.1): Листинг 5.1. Установка соединения «Толстый клиент»
// Создать Automation сервер 1С:Предприятия. AutomationCервер = Новый COMОбъект("V82.Application"); // Установить соединение с информационной базой // TestBase в кластере 1541 центрального сервера TestSrv. AutomationCервер.Connect("Srvr="TestSrv";Ref="TestBase");
Соединение Тонкий клиент представляет собой соединение тонкого клиента с информационной базой. Это соединение предназначено для модификации данных информационной базы и выполнения другой функциональности, предоставляемой конфигурацией информационной базы. Соединение создается в результате интерактивного запуска тонкого клиента или в результате подключения к информационной базе с использованием технологии Automation Client/Server, например (листинг 5.2): Листинг 5.2. Установка соединения «Тонкий клиент»
// Создать Automation сервер 1С:Предприятия. AutomationCервер = Новый COMОбъект("V82c.Application"); // Установить соединение с информационной базой // TestBase в кластере 1541 центрального сервера TestSrv. AutomationCервер.Connect("Srvr="TestSrv";Ref="TestBase");
124
Соединение Конфигуратор представляет собой соединение конфигуратора с информационной базой. Это соединение предназначено для создания и модификации конфигурации информационной базы и для выполнения административных и регламентных действий. Соединение Модуль расширения веб-сервера представляет собой соединение веб-сервера с рабочим процессом сервера. Это соединение предназначено для работы веб-клиента, Web-сервисов, а также тонкого клиента (по протоколу http). Соединение создается в момент обращения к Web-сервису или при обращении веб-клиента или тонкого клиента (по протоколу http) к серверу «1С:Предприятия». Соединение существует до перезапуска веб-сервера или до тех пор, пока соединение находится в пуле соединений модулей расширений веб-сервера. Соединение COM-соединение представляет собой соединение процесса, использующего функциональность внешнего соединения «1С:Предприятия», с информационной базой. Это соединение предназначено для модификации данных информационной базы и выполнения другой функциональности, предоставляемой конфигурацией информационной базы. COM-соединение создается в результате подключения к информационной базе с использованием технологии COM, например (листинг 5.3): Листинг 5.3. Установка внешнего соединения
// Создать Automation сервер 1С:Предприятия. COMСоединитель = Новый COMОбъект("V82.COMConnector"); // Установить соединение с информационной базой // TestBase в кластере 1541 центрального сервера TestSrv. СоединениеСИнформационнойБазой = COMСоединитель.Connect("Srvr="TestSrv";Ref="TestBase");
Соединение WS-соединение представляет собой соединение веб-сервера с информационной базой. Это соединение предназначено для выполнения кода модуля Web-сервиса «1C:Предприятия». WS-соединение возникает в процессе обращения к Web-сервису, опубликованному на веб-сервере. Соединение существует до тех пор, пока соединение находится в пуле WS-соединений (пока не закончится время жизни соединения в пуле или пока данное соединение не будет вытеснено из пула другими соединениями). Подробнее
Том 2, глава 18, раздел «Web-сервисы».
Соединение Фоновое задание представляет собой соединение рабочего процесса кластера с информационной базой. Это соединение предназначено для выполнения кода процедуры фонового задания. Профессиональная разработка в системе «1С:Предприятие 8»
Кластер серверов Соединение фонового задания создается в результате запуска фонового задания на выполнение. Такой запуск может выполняться системой «1С:Предприятие» в результате автоматического запуска регламентного задания (регламентное задание порождает соответствующее фоновое задание) или разработчиком средствами встроенного языка, например (листинг 5.4): Листинг 5.4. Установка соединения «Фоновое задание»
// Выполнить фоновое задание, описанное в процедуре // ОбновлениеИндексаПолнотекстовогоПоиска // общего модуля РегламентныеПроцедуры. ФоновоеЗадание = ФоновыеЗадания.Выполнить( "РегламентныеПроцедуры.ОбновлениеИндексаПолнотекстовогоПоиска");
Соединение фонового задания существует до тех пор, пока существует контекст исполняемой процедуры фонового задания. После того как процедура выполнена, соединение фонового задания закрывается. Подробнее
Документация «1С:Предприятие 8.2. Руководство разработчика».
Служебные соединения Возможны следующие виды служебных соединений: ■■ ■■ ■■ ■■
Планировщик заданий, Отладчик, Консоль кластера, COM-администратор.
Соединение Планировщик заданий представляет собой соединение планировщика заданий с рабочим процессом. Это соединение предназначено для управления работой фоновых заданий, в том числе для запуска регламентных заданий по расписанию. Соединение Отладчик представляет собой соединение отладчика с рабочим процессом кластера, находящимся в режиме отладки. Это соединение предназначено для управления ходом отладки и поиском предметов отладки, имеющихся в настоящий момент. Соединение создается при подключении предмета отладки или при поиске предметов отладки и существует до тех пор, пока предмет отладки не будет отключен или не завершит свою работу. Соединение Консоль кластера представляет собой соединение утилиты администрирования клиент-серверного варианта с рабочим процессом. Это соединение предназначено для администрирования информационных баз кластера серверов. Соединение консоли кластера создается в момент обращения к данным рабочего процесса (например, при получении параметров информационной Том 1
базы, при получении подробного списка соединений информационной базы и пр.). Соединение COM-администратор представляет собой соединение с рабочим процессом сервера с использованием технологии COM. Это соединение предназначено для администрирования информационных баз кластера серверов. Соединение COM-администратора создается при подключении к выбранному рабочему процессу с использованием технологии COM, например (листинг 5.5): Листинг 5.5. Установка соединения «COM-администратор»
// Создать COMСоединитель 1С:Предприятия. COMСоединитель = Новый COMОбъект("V82.COMConnector"); // Установить соединение с рабочим процессом 1562 // в кластере 1541 центрального сервера TestSrv. СоединениеСРабочимПроцессом = COMСоединитель.ConnectWorkingProcess("tcp://TestSrv:1562");
Виды сеансов Возможны следующие виды сеансов: ■■ Толстый клиент, Тонкий клиент, Веб-клиент – создаются при обращении, соответственно, толстого, тонкого и веб-клиента к информационной базе; ■■ Конфигуратор – создается при обращении конфигуратора к информационной базе; ■■ COM-соединение – создается при обращении к информационной базе через внешнее соединение; ■■ WS-соединение – создается при обращении веб-сервера к информационной базе в результате обращения к Web-сервису, опубликованному на веб-сервере; ■■ Фоновое задание – создается при обращении рабочего процесса кластера к информационной базе. Предназначен для выполнения кода процедуры фонового задания; ■■ Консоль кластера – создается при обращении утилиты администрирования клиент-серверного варианта к рабочему процессу; ■■ COM-администратор – создается при обращении к рабочему процессу через внешнее соединение. Подробнее
Документация «1С:Предприятие 8.2. Клиент-серверный вариант. Руководство администратора», раздел 2.1.5.
125
Глава 5. Клиент-серверный вариант работы
Масштабируемость и отказоустойчивость
Масштабируемость кластера Масштабируемость кластера серверов выражается в перераспределении нагрузки между несколькими менеджерами и рабочими процессами кластера и может осуществляться за счет: ■■ увеличения количества менеджеров кластера и распределения между ними сервисов; ■■ увеличения количества рабочих процессов, функционирующих на конкретном рабочем сервере; ■■ увеличения количества рабочих серверов, входящих в состав кластера.
Перераспределение сервисов между менеджерами кластера В платформе «1С:Предприятие» определен состав независимых сервисов кластера серверов, которые заключают в себе всю функциональность менеджера кластера. Три сервиса могут использоваться только на главном менеджере кластера: ■■ сервис конфигурации кластера – хранит все настройки кластера; ■■ сервис блокировок кластера – хранит блокировки информационных баз, сведения об активных процессах и другую динамическую информацию о работе кластера; ■■ сервис управления предметами отладки – управляет подсоединением отладчика к серверным предметам отладки. Другие сервисы могут быть назначены на дополнительные менеджеры кластера: ■■ сервис журналов регистрации – поддерживает доступ к журналу регистрации; ■■ сервис полнотекстового поиска – выполняет полнотекстовый поиск и осуществляет индексирование; ■■ сервис заданий – управляет запуском и отслеживанием времени жизни фоновых и регламентных заданий; ■■ сервис нумерации – обеспечивает генерацию уникальных номеров и кодов объектов; ■■ сервис времени – поддерживает получение оперативной отметки времени и некоторые вспомогательные функции; ■■ сервис пользовательских настроек – обеспечивает доступ к файлам, в которых размещаются некоторые пользовательские настройки;
126
■■ сервис блокировок объектов – хранит пессимистические (нетранзакционные) блокировки объектов; ■■ сервис транзакционных блокировок – содержит транзакционные блокировки управляемого режима; ■■ сервис сеансовых данных – обеспечивает хранение и кеширование сеансовой информации, например информация форм управляемого приложения. Обеспечивает получение клиентских лицензий. В целях повышения масштабируемости кластера серверов наиболее ресурсоемкие сервисы могут быть назначены различным менеджерам кластера, что позволяет распределить всю нагрузку между несколькими процессами. Подробнее
Документация «1С:Предприятие 8.2. Клиент-серверный вариант. Руководство администратора», раздел 2.1.3.
Использование нескольких рабочих процессов Использование нескольких рабочих процессов, с одной стороны, позволяет снизить нагрузку на каждый конкретный рабочий процесс. С другой стороны, запуск нескольких рабочих процессов позволяет более эффективно использовать аппаратные ресурсы рабочего сервера. Кроме этого, запуск нескольких рабочих процессов позволяет повысить надежность сервера, изолировав группы клиентов, работающих с разными информационными базами. В кластере, в котором возможен запуск нескольких рабочих процессов, рабочий процесс может быть автоматически перезапущен по истечении времени, установленного администратором кластера. Подробнее
Документация «1С:Предприятие 8.2. Клиент-серверный вариант. Руководство администратора», раздел 2.1.10.1.
Использование нескольких рабочих серверов Кластер серверов может функционировать как на одном, так и на нескольких рабочих серверах. Разделение кластера серверов по нескольким компьютерам позволяет повысить производительность кластера в целом посредством распределения нагрузки между компьютерами. Подробнее
Документация «1С:Предприятие 8.2. Клиент-серверный вариант. Руководство администратора», раздел 2.1.10.2.
Профессиональная разработка в системе «1С:Предприятие 8»
Масштабируемость и отказоустойчивость
Устойчивость клиентских приложений Рассмотрим общие схемы построения системы «1С:Предприятие» в клиент-серверном и в файловом варианте работы с точки зрения устойчивости клиентских соединений. В клиент-серверном варианте работы, кроме собственно компонентов «1С:Предприятия», принимают участие программные продукты других производителей. Это веб-сервер и сервер СУБД (рис. 5.9).
Рис. 5.10. Общая схема файлового варианта работы
Таким образом, если говорить о системе в целом, то можно сказать, что тонкий клиент и веб-клиент практически нечувствительны к потере соединения.
Использование протокола HTTP В «1С:Предприятии» в качестве транспортного протокола используется TCP/IP. Он используется и в файловом варианте работы через веб-сервер, и в клиент-серверном. Он используется при взаимодействии клиентского и серверного приложений. Этот же протокол используется при взаимодействии элементов кластера между собой (рис. 5.11).
Рис. 5.9. Общая схема клиент-серверного варианта работы
На этой схеме стрелками показано направление вызовов. Прерывистыми линиями показаны те соединения, которые могут обрываться «безболезненно» для пользователя. То есть в случае физического обрыва и последующего его восстановления пользователь в большинстве случаев ничего не заметит. Клиентское приложение само восстановит соединение и продолжит работу «с того места», на котором она была прервана, без повторного запуска клиентского приложения и подключения к информационной базе. Исключение составляет лишь толстый клиент, работающий в режиме обычного приложения. Он далеко не всегда умеет восстанавливать соединение так, как это делают тонкий клиент и веб-клиент. В ряде случаев после разрыва соединения потребуется перезапуск клиентского приложения и повторное соединение с информационной базой. В файловом варианте работы разнообразия меньше. Однако и в этом случае могут присутствовать программные компоненты других производителей – веб-серверы Apache или IIS (рис. 5.10). Том 1
Рис. 5.11. Транспортные протоколы в «1С:Предприятии»
127
Глава 5. Клиент-серверный вариант работы В качестве прикладного протокола при взаимодействии с веб-сервером используется HTTP (рис. 5.12).
Последняя стандартная возможность HTTP, о которой следует сказать, это кеширование запросов. Оно существенно снижает трафик и повышает производительность, особенно на тонких каналах. «1С:Предприятие» использует все стандартные возможности кеширования, предоставляемые HTTP.
Отказоустойчивость кластера Отказоустойчивость кластера серверов выражается в обеспечении бесперебойной работы пользователей при программных и аппаратных сбоях в кластере серверов и достигается за счет: ■■ резервирования самого кластера, ■■ резервирования рабочих процессов кластера, ■■ устойчивости к обрыву канала связи.
Резервирование кластера
Рис. 5.12. Прикладные протоколы в «1С:Предприятии»
Несколько кластеров могут быть объединены в группу резервирования. Кластеры, перечисленные в списке резервирования и имеющие одинаковые списки резервирования, образуют группу резервирования (рис. 5.13).
Протокол HTTP был выбран для унификации взаимодействия клиентов с веб-сервером потому, что он достаточно хорошо проработан и развит. Это открытый протокол, без каких-либо специальных доработок. К тому же данный протокол стандартно поддерживается браузерами, что значительно облегчило реализацию веб-клиента. Протокол HTTP предоставляет достаточно много стандартных возможностей, которые используются в «1С:Предприятии». Например, для того, чтобы клиент сообщил серверу, какой тип данных нужно получить, в каком формате, используются стандартные заголовки HTTP. В этих же стандартных заголовках передается информация о языке содержания и о том, поддерживает ли клиент сжатие данных при передаче. Если поддерживает, то сервер возвращает ему содержимое ответов в сжатом виде. Другая стандартная возможность – механизм Cookie. Он используется как в браузерах, так и в тонком/толстом клиентах. Правда используется он несколько ограниченным образом. В частности, в Cookie хранится идентификатор сеанса, по которому клиента узнают на сервере при каждом сообщении. Также посредством Cookie клиент оповещается, что для него есть некоторое сообщение. Клиент обращается по определенному адресу на сервер и получает те сообщения, которые предназначены ему.
128
Рис. 5.13. Группа резервирования кластеров
Профессиональная разработка в системе «1С:Предприятие 8»
Масштабируемость и отказоустойчивость Кластеры, находящиеся в одной группе резервирования, синхронизируются автоматически. Пользователей обслуживает только один кластер из группы. Он считается активным. Остальные кластеры группы считаются резервными и обеспечивают синхронизацию наиболее важных данных в актуальном состоянии. При выходе из строя активного кластера активным становится следующий работоспособный кластер группы. При восстановлении работоспособности кластера, который находится в группе раньше активного, активность передается ему после автоматической синхронизации данных. Подробнее
Документация «1С:Предприятие 8.2. Клиент-серверный вариант. Руководство администратора», раздел 2.1.7.1.
Резервирование рабочих процессов Каждому рабочему процессу можно указать вариант его использования: Использовать, Использовать как резервный или Не использовать (рис. 5.14). Агент центрального сервера запускает все рабочие процессы (свойство Использование = Использовать). Если запуск процесса закончился с ошибкой, то кластер запускает вместо него один из неактивных процессов, помеченных как резервный, при этом попытки запуска используемого процесса продолжаются до тех пор, когда процесс запуска не увенчается успехом. Тогда самый старый процесс, помеченный как резервный, но используемый системой, выключается и будет остановлен после отключения всех соединений или через заданное администратором время.
Если у кластера нет резервных рабочих процессов (нет вовсе или все резервные процессы уже используются) и перезапуск неактивного рабочего процесса окончился неудачей, то система попытается перераспределить нагрузку по оставшимся рабочим процессам. Подробнее
Документация «1С:Предприятие 8.2. Клиент-серверный вариант. Руководство администратора», раздел 2.1.7.2.
Устойчивость к обрыву канала связи Устойчивость к обрыву канала связи реализуется за счет того, что кластер «запоминает» подключившихся пользователей и состояние выполняемых ими действий благодаря тому, что для каждого пользователя создается собственный сеанс. Сеанс является отражением активного пользователя в кластере серверов. Не следует путать сеансы с соединениями. В процессе работы пользователя соединения могут устанавливаться, могут разрываться, но сеанс продолжает существовать (рис. 5.15).
Рис. 5.15. Сеансы в кластере серверов
Сеанс начинается с момента начала работы конечного пользователя и заканчивается в момент завершения им работы (пользователь закрывает клиентское приложение, или администратор принудительно завершает работу этого сеанса).
Рис. 5.14. Варианты использования рабочего процесса
Том 1
Данные сеансов сохраняет менеджер кластера. Для этого предусмотрен сервис сеансовых данных. При перезапуске кластера серверов данные сеансов сохраняются. Если активный пользователь не выполнил ни одного обращения к кластеру за 20 минут и сеанс не назначен соединению, то сеанс удаляется вместе с данными сеанса. Для поддержания сеанса тонкий клиент и веб-клиент обеспечивают обращение к кластеру не реже 1 раза в 10 минут.
129
Глава 5. Клиент-серверный вариант работы В случае потери физического соединения кластер будет ожидать восстановления соединения с этим пользователем. В подавляющем большинстве случаев после восстановления соединения пользователь сможет продолжить работу с того «места», на котором она была прекращена. При этом не потребуется повторное подключение к информационной базе.
В случае, если текущий рабочий процесс выключен или в кластере серверов появился рабочий процесс с не менее чем в два раза большей доступной производительностью, чем у данного рабочего процесса, происходит переключение клиента на более производительный рабочий процесс. Причем выполняется это совершенно незаметно для пользователя.
Подробнее
Таким образом, в кластере серверов автоматически происходит динамическая балансировка нагрузки, что способствует более надежной и эффективной работе системы.
Документация «1С:Предприятие 8.2. Клиент-серверный вариант. Руководство администратора», раздел 2.1.5.
Динамическое перераспределение нагрузки В процессе работы «1С:Предприятия» платформа автоматически анализирует загруженность рабочих процессов кластера серверов. При этом оценивается значение свойства Доступная производительность, которое имеет каждый рабочий процесс. Доступная производительность показывает, насколько быстро данный процесс способен выполнить вызов сервера по сравнению с другими рабочими процессами (рис. 5.16).
Подробнее
Документация «1С:Предприятие 8.2. Клиент-серверный вариант. Руководство администратора», раздел 2.1.8.
Безопасность Платформа «1С:Предприятие» обеспечивает довольно высокий уровень безопасности работы с данными и защиты их от внешних воздействий. При этом используются два механизма: многоуровневая аутентификация и шифрование передаваемых данных.
Многоуровневая аутентификация Многоуровневая аутентификация используется при подключении к базе данных через веб-сервер, то есть при работе «1С:Предприятия» в режиме веб-клиента и в режиме тонкого клиента, подключенного через веб-сервер (рис. 5.17). Первый уровень аутентификации обеспечивается на веб-сервере средствами самого веб-сервера в момент соединения с веб-сервером. При этом пользователь должен пройти процедуру аутентификации.
Рис. 5.16. Свойства рабочего процесса
Клиенты распределяются между рабочими процессами так, чтобы сделать доступную производительность всех рабочих процессов примерно одинаковой. При установке нового соединения с сервером «1С:Предприятия» выбирается процесс с наибольшей доступной производительностью. При изменении соотношения между доступной производительностью рабочих процессов клиенты динамически перераспределяются между рабочими процессами.
130
Рис. 5.17. Многоуровневая аутентификация
Профессиональная разработка в системе «1С:Предприятие 8»
Безопасность При подключении к веб-серверу с помощью веб-клиента можно использовать любые виды аутентификации, поддерживаемые браузером пользователя. При подключении с помощью тонкого клиента можно использовать два вида аутентификации: Basic аутентификацию и аутентификацию с помощью пакета Negotiate. Если выполняется Basic аутентификация, то пользователь просто вводит свое имя и пароль. Если выполняется аутентификация с помощью пакета Negotiate, то подключающийся клиент сопоставляется одному из доменных пользователей. При этом если пользователь находится в том же домене, что и веб-сервер, то аутентификация будет выполнена автоматически, незаметно для пользователя. Если же подключающийся пользователь хочет аутентифицироваться на веб-сервере не как текущий пользователь операционной системы, а как пользователь того домена, в котором находится веб-сервер, то нужно, чтобы вместо аутентификации текущего пользователя в операционной системе тонкий клиент использовал диалог для ввода имени и пароля пользователя вручную. Для этого можно использовать настройки информационной базы (рис. 5.18) или параметр WSA- при запуске «1С:Предприятия» из командной строки.
Платформа поддерживает два вида аутентификации: аутентификация «1С:Предприятия» и аутентификация операционной системы. В случае аутентификации средствами «1С:Предприятия» пользователь при начале работы с прикладным решением должен указать имя пользователя и соответствующий этому имени пароль. В случае аутентификации средствами операционной системы аутентификация будет «прозрачна» для пользователя. Система анализирует, от имени какого пользователя операционной системы выполняется подключение к прикладному решению, и на основании этого определяет соответствующего пользователя «1С:Предприятия». При этом диалог аутентификации «1С:Предприятия» не отображается, если не указан специальный параметр командной строки.
Шифрование передаваемых данных Шифрование передаваемых данных служит для защиты передаваемой информации от несанкционированного доступа к ней извне. В процессе клиент-серверного взаимодействия можно выделить различные области передачи данных, нуждающиеся в защите (рис. 5.19).
Рис. 5.18. Установка способа аутентификации в настройках информационной базы
Подробнее
Информацию о параметрах запуска из командной строки можно посмотреть во встроенной справке – Справка Содержание справки
1С:Предприятие Запуск 1С:Предприятия 8 и параметры запуска Общие параметры запуска.
Второй уровень аутентификации выполняется средствами самого «1С:Предприятия» при установке соединения с информационной базой. Том 1
Рис. 5.19. Общая схема безопасности
131
Глава 5. Клиент-серверный вариант работы Безопасность этих участков передачи данных обеспечивается путем применения различных алгоритмов шифрования данных. Для защиты канала передачи данных между веб-клиентом и веб-сервером или между тонким клиентом и веб-сервером используются криптографические протоколы SSL или TLS. Поддержку этих протоколов обеспечивает HTTPS-соединение с веб-сервером. Для этого на сервере должен находиться действительный серверный сертификат, который гарантирует клиенту подлинность открытого ключа сервера, используемого для шифрования данных. При подключении по HTTPS с помощью веб-клиента можно использовать любые возможности этого протокола, поддерживаемые веб-браузером. Например, можно использовать клиентские сертификаты, гарантирующие серверу подлинность клиента. При подключении по HTTPS с помощью тонкого клиента набор возможностей несколько ограничен: ■■ использование клиентских сертификатов не поддерживается; ■■ соединение с веб-сервером может быть установлено только в том случае, если сертификат службы сертификации, подписавшей серверный сертификат, присутствует в списке доверенных служб сертификации тонкого клиента. Если его нет в этом списке, тонкий клиент завершит свою работу, в отличие от браузера, который в этой ситуации предложит пользователю самостоятельно принять или отклонить сертификат, полученный от сервера. Для защиты каналов передачи данных между кластером серверов и клиентами, между кластером серверов и веб-сервером и для защиты каналов внутри самого кластера используются алгоритмы шифрования данных, реализуемые системой «1С:Предприятие»: RSA и Triple DES. При этом может быть выбран один из трех уровней безопасности: Постоянно, Установка соединения или Выключено. Использование уровня безопасности Постоянно позволяет полностью защитить весь поток данных (как пароли, так и непосредственно данные), но при этом возможно значительное снижение производительности системы. Использование уровня безопасности Установка соединения позволяет частично защитить весь поток данных (только пароли). Этот уровень безопасности является компромиссом между безопасностью и производительностью. Уровень безопасности Выключено является самым низким и самым производительным. Практически все данные передаются без использования шифрования. Рассмотрим схему взаимодействия клиента и кластера серверов при использовании уровня безопасности Постоянно (рис. 5.20).
132
Рис. 5.20. Уровень безопасности «Постоянно»
Протокол взаимодействия одинаков как для менеджера кластера (rmngr), так и для рабочего процесса (rphost): после установки соединения первый обмен данными выполняется с использованием шифрования по алгоритму RSA, дальнейший обмен данными выполняется с использованием шифрования по алгоритму Triple DES. Уровень безопасности задается при создании информационной базы. Эта информация сохраняется как на клиенте (в списке информационных баз), так и в кластере серверов (в реестре сервера). После создания информационной базы ее параметры, сохраненные в кластере серверов, изменить уже нельзя. Однако можно изменить уровень безопасности, указанный для этой информационной базы на клиенте. Поэтому после установки соединения клиент генерирует приватный и публичный ключи для шифрования RSA и передает в кластер серверов публичный ключ и уровень безопасности, который указан для данной информационной базы на клиенте. Это желаемый уровень безопасности. Кластер серверов выбирает максимальный уровень безопасности из переданного клиентом и указанного для этой информационной базы в реестре кластера. Это фактический уровень безопасности. Кроме этого, кластер серверов генерирует сеансовый ключ для шифрования Triple DES и вместе с фактическим уровнем безопасности передает его клиенту, предварительно зашифровав эти данные с помощью публичного ключа клиента. Профессиональная разработка в системе «1С:Предприятие 8»
Безопасность Дальнейший обмен данными выполняется в соответствии с фактическим уровнем безопасности, при этом как клиент, так и сервер шифруют передаваемые данные с использованием сеансового ключа по алгоритму Triple DES. Особенностью защиты передачи данных между кластером и веб-сервером является то, что соединение между кластером и веб-сервером защищается только кластером на основании свойств информационной базы, к которой выполняется подключение.
Том 1
Защита канала передачи данных между кластером серверов и СУБД осуществляется средствами той СУБД, которая используется. Все поддерживаемые СУБД позволяют настроить свои клиентские компоненты, находящиеся в кластере, так, чтобы трафик между ними и самой СУБД был зашифрован. Все поддерживаемые СУБД могут использовать протокол SSL. Подробнее
Документация «1С:Предприятие 8.2. Клиент-серверный вариант. Руководство администратора», раздел 2.1.12.
133
Глава 5. Клиент-серверный вариант работы
134
Профессиональная разработка в системе «1С:Предприятие 8»
Несколько дистрибутивов
Глава 6. Установка и администрирование системы Несколько дистрибутивов Для установки системы «1С:Предприятие» существуют два дистрибутива: «1С:Предприятие 8» и «1С:Предприятие 8. Тонкий клиент». Дистрибутив «1С:Предприятие 8» – это полный дистрибутив платформы, который позволяет использовать все ее возможности. Дистрибутив «1С:Предприятие 8. Тонкий клиент» – это только клиентское приложение. Основной сценарий его использования – это работа с клиент-серверной базой по локальной сети или по протоколу HTTP. Возможность работы с файловой информационной базой непосредственно по сети у него отсутствует. Не у тонкого клиента вообще, а у тонкого клиента, установленного из этого дистрибутива. Подробнее
Раздел «Программные компоненты клиент-серверной архитектуры «1С:Предприятия»», стр. 119.
Появление второго дистрибутива обусловлено тем, что «1С:Предприятие» предоставляет возможность для работы через Интернет по протоколу HTTP. Поэтому к информационной базе могут подключаться клиенты, расположенные в разных странах и разных частях света.
низация не хочет «выставлять наружу» веб-сервер, а предпочитает работать с удаленными клиентами через VPN. В этом случае использование веб-клиента также будет невозможным, поскольку он умеет работать с информационной базой только через веб-сервер. Как раз для таких случаев и предназначен дистрибутив «1С:Предприятие 8. Тонкий клиент». Он имеет небольшой размер, что удобно для удаленных пользователей. Он реализует полную функциональность управляемого приложения и предназначен для таких пользователей, у которых есть необходимость лишь в подключении к существующим информационным базам.
Установка, обновление и запуск
Запуск На одном компьютере могут существовать произвольное количество одновременно установленных версий «1С:Предприятия». Структура каталогов «1С:Предприятия» выглядит следующим образом (рис. 6.1).
В общем случае у таких клиентов существуют две возможности: либо использовать веб-клиента, либо использовать тонкого клиента. Для использования веб-клиента не требуется никакая предварительная установка программного обеспечения на компьютер пользователя. И это очень удобно. Однако использование веб-клиента может оказаться возможным не всегда. Например, в силу особенностей самого прикладного решения. Потому что веб-клиент умеет не все то, что умеет тонкий клиент. Количество таких отличий невелико, и большинство прикладных решений общего назначения создаются так, чтобы они одинаково работали и в тонком клиенте, и в веб-клиенте. Однако специализированные прикладные решения могут использовать функциональность, доступную в веб-клиенте частично или недоступную совсем. Например, работа с файловой системой, XML, электронной почтой и др. Также невозможность использования веб-клиента может быть связана с требованиями информационной безопасности. Например, оргаТом 1
Рис. 6.1. Структура файлов «1С:Предприятия»
135
Глава 6. Установка и администрирование системы В корневом каталоге 1С:Предприятия 8.2 (С:\Program Files\1cv82) находится некоторое количество каталогов установленных версий платформы. Каждая из этих версий содержит свои версии клиентских приложений (толстый и тонкий клиенты) и свою версию интерактивной программы запуска (1cv8s.exe). Кроме этого, в корневом каталоге «1С:Предприятия 8.2» находится каталог common, в котором – программа запуска 1CEStart.exe.
Запуск с локального компьютера Если система запускается с локального компьютера, то стандартный сценарий запуска такой: ■■ пользователь запускает программу запуска 1CEStart.exe (1). Ссылка на эту программу всегда есть в меню Старт операционной системы. При установке новых версий платформы существующая программа запуска перезаписывается файлом из новой версии; ■■ программа запуска запускает интерактивную программу запуска 1cv8s.exe от последней версии (2). Она предлагает выбрать одну из имеющихся информационных баз и запускает для этой базы нужное клиентское приложение нужной версии платформы (3). Интерактивная программа запуска показывает общий список баз для версий 8.0, 8.1 и 8.2. При первом запуске она может автоматически импортировать списки информационных баз для версий 8.0 и 8.1. Подробнее
Том 2, глава 21, раздел «Шаблоны конфигураций».
Для каждой информационной базы может быть указана версия платформы, которой нужно запускать эту информационную базу. На основе этой информации интерактивная программа запуска выбирает подходящую версию платформы. Если никакая версия для информационной базы не указана, запускается клиентское приложение последней версии «1С:Предприятия» или версии, указанной по умолчанию.
Рис. 6.2. Запуск системы «1С:Предприятие» по сети
■■ программа запуска анализирует состав установленных у пользователя версий платформы и автоматически устанавливает последнюю версию платформы, если ее нет на компьютере пользователя (v. 8.2.9.216); ■■ после этого, как и в ранее описанном сценарии, запускается интерактивная программа запуска последней версии платформы на компьютере пользователя (2), а затем клиентское приложение, соответствующее выбранной информационной базе (3).
Запуск по сети
В сетевом каталоге также обычно размещается и список общих информационных баз. Таким образом, администратор может полностью управлять и составом информационных баз, доступных пользователям, и информацией о том, какие базы, какими версиями платформы и какими клиентскими приложениями должны запускаться.
Если пользователи работают в сети, то стандартный сценарий запуска будет немного другим (рис. 6.2).
Различные сценарии установки и запуска
■■ администратор «1С:Предприятия» создает сетевой каталог, в котором размещает программу запуска 1CEStart.exe и структуру каталогов, содержащих дистрибутивы версий платформы; ■■ пользователи запускают программу запуска не со своего локального компьютера, а из сетевого каталога (1). Программа запуска не требует компонентов «1С:Предприятия», поэтому ее можно скопировать в произвольный каталог;
136
Нужно сказать, что описанный стандартный сценарий запуска по сети не является обязательным. Механизм установки и запуска обладает большой гибкостью и настраиваемостью. Он позволяет реализовывать различные сценарии в зависимости от потребностей конкретного внедрения. Во-первых, и программа запуска, и интерактивная программа запуска имеют свои конфигурационные файлы (1CEStart.cfg и 1CESCmn.cfg). Профессиональная разработка в системе «1С:Предприятие 8»
Установка, обновление и запуск С помощью этих файлов можно настроить расположение дистрибутивов, перечень компонентов системы, которые должны устанавливаться, версию платформы, которая должна запускаться по умолчанию и т. д. Подробнее
Документация «1С:Предприятие 8.2. Руководство администратора», Приложения 3.4 и 3.5 – «Описание и расположение служебных файлов».
Во-вторых, и клиентские приложения, и кластер при запуске ищут общие конфигурационные файлы платформы, которые описывают особенности ее функционирования:
При необходимости администратор может использовать другие способы работы с конфигурационными файлами. Например: ■■ задать различные конфигурационные файлы для одной или нескольких версий платформы. Такие конфигурационные файлы должны располагаться в каталогах конкретных версий. Они будут найдены первым способом; ■■ задать другие конфигурационные файлы для одного из компонентов платформы (любой версии), работающей от имени некоторого пользователя (например, для кластера). Такие конфигурационные файлы должны располагаться только в каталоге соответствующего пользователя. Они будут найдены вторым способом.
■■ logcfg.xml – конфигурационный файл технологического журнала; ■■ nethasp.ini – конфигурационный файл системы защиты; ■■ adminstall.cfg – конфигурационный файл установки с использованием средств администрирования Windows; ■■ inetcfg.xml – конфигурационный файл прокси по умолчанию; ■■ debugcfg.xml – настройка дополнительного диапазона портов, используемого при отладке; ■■ comcntrcfg.xml – настройка запуска внешнего соединения в отладочном режиме.
Конечно, возможны и различные сочетания перечисленных способов.
Для каждой версии «1С:Предприятия» существует свой каталог установки. И теоретически различных вариантов использования этих файлов может быть много: все версии используют одни и те же настройки, разные версии используют разные настройки и т. д.
В то же время интерактивная программа запуска может самостоятельно установить новую версию платформы на компьютер пользователя.
Поэтому клиентские приложения и сервер «1С:Предприятия» при запуске ищут конфигурационные файлы по определенному алгоритму. Подробнее
Документация «1С:Предприятие 8.2. Руководство администратора», Приложение 1.3 «Структура каталога установки и назначение каталогов и файлов – Конфигурационные файлы расположение и поиск».
При стандартной установке системы используется следующий способ поиска конфигурационных файлов: сами файлы записываются в каталог конфигурационных файлов C:\Program Files\1Cv82\conf, и данный путь записывается в файл conf.cfg устанавливаемой версии. Таким образом, в каталогах конкретных версий платформы конфигурационных файлов нет. В профилях пользователей их тоже нет. А в каждом файле conf.cfg указано, что все они находятся в одном и том же месте. Таким образом, стандартно используются единые конфигурационные файлы для всех версий и компонентов «1С:Предприятия», установленных на данном компьютере. Том 1
Ключи командной строки Обе программы запуска (как и клиентские приложения) поддерживают одни и те же ключи командной строки. В результате, например, программа запуска (кроме стандартного сценария установки новой версии платформы и запуска интерактивной программы запуска) может самостоятельно запустить указанную информационную базу нужным клиентским приложением.
Более того, клиентские приложения могут самостоятельно определять версию платформы, необходимой для работы с конкретной информационной базой, и при необходимости устанавливать ее из сетевого каталога дистрибутивов на компьютер пользователя. Поэтому кроме стандартного сценария администратор может создавать собственные сценарии запуска и обновления клиентских приложений. Например, без использования программы запуска, расположенной в сети, и даже без использования интерактивной программы запуска.
Установка В результате установки платформы создается структура файлов, показанная ранее на рисунке 6.1. В меню Старт появляется программа и подменю Дополнительно (рис. 6.3).
запуска
(1С:Предприятие)
Таким образом, пользователю при запуске «1С:Предприятия» не нужно выбирать из нескольких пунктов меню. Есть одна команда – 1С Предприятие, ее и нужно нажимать.
137
Глава 6. Установка и администрирование системы ■■ поскольку все пользователи запускают программу запуска, расположенную в сетевом каталоге, то при очередном ее запуске на компьютере пользователя автоматически будет установлена новая версия платформы из дистрибутива, расположенного в сетевом каталоге. Как уже говорилось, такой сценарий не является единственным. Кроме автоматической установки средствами «1С:Предприятия», администратор может использовать и средства операционной системы: ■■ установка с помощью групповых политик Windows, ■■ установка с помощью logon-скрипта. В этих случаях он может полностью управлять всеми деталями и особенностями установки для различных пользователей. Рис. 6.3. Программа запуска в меню «Старт»
Обновление
Подменю Дополнительно позволяет перейти ко всем версиям платформы «1С:Предприятия», установленным на компьютере (рис. 6.4).
Изменение установленной версии В некоторых случаях может возникнуть необходимость самостоятельного изменения уже установленной версии, без участия администратора. Например, могут понадобиться какие-то компоненты платформы, которые не были установлены с самого начала. В этом случае нужно использовать компонент Установка и обновление программ панели управления Windows. Он позволяет изменить уже установленную версию платформы, добавить или удалить компоненты платформы. Если просто запускать файл setup.exe из дистрибутива платформы, будут обновлены только те компоненты платформы, которые уже установлены. Выбор состава компонентов предлагаться не будет.
Рис. 6.4. Интерактивная программа запуска в меню «Старт»
Для каждой версии верхняя команда (1С:Предприятие) запускает интерактивную программу запуска этой версии. Также здесь сразу можно запустить толстого или тонкого клиента. Если администратор устанавливает платформу в организации, то предполагается следующий стандартный сценарий. ■■ прежде всего, администратор устанавливает платформу локально на один любой компьютер и проверяет работоспособность имеющихся конфигураций на новой платформе; ■■ после этого он копирует с этого компьютера в сетевой каталог новую версию программы запуска (1CEStart.exe), а также размещает в этом сетевом каталоге дистрибутив новой версии платформы;
138
Удаление Для удаления старых версий платформы нужно использовать компонент Установка и удаление программ панели управления Windows. Однако не нужно спешить удалять старые дистрибутивы из сетевого каталога. Если для работы с какой-либо информационной базой пользователю понадобится старая версия платформы, она будет автоматически установлена из дистрибутива, находящегося в сетевом каталоге. Подробнее
Документация «1С:Предприятие 8.2. Руководство администратора».
Профессиональная разработка в системе «1С:Предприятие 8»
Управление кластером серверов
Управление кластером серверов Утилита администрирования кластера серверов позволяет управлять кластером серверов и выполнять такие действия, как: ■■ создание, изменение и удаление кластеров серверов; ■■ модификация существующих кластеров: создание, изменение параметров и удаление рабочих серверов, рабочих процессов кластера, информационных баз, входящих в состав кластера; ■■ управление списками администраторов центральных серверов кластеров и списками администраторов кластеров; ■■ мониторинг соединений пользователей с информационными базами и служебных соединений; ■■ отключение пользователей от информационной базы; ■■ мониторинг объектных блокировок «1С:Предприятия» и блокировок клиентского соединения; ■■ оперативный анализ транзакционных блокировок системы управления базами данных; ■■ управление блокировкой установки соединений пользователей с информационной базой; ■■ управление блокировкой выполнения регламентных заданий. Утилита представляет собой подключаемый модуль MMC (Microsoft Management Console) и может быть использована на компьютерах, на которых установлено соответствующее программное обеспечение (для операционных систем Windows 2000/XP/Server 2003 это программное обеспечение является стандартным).
Рис. 6.5. Список администраторов кластера серверов
Работа со списком кластеров центрального сервера Утилита администрирования предоставляет возможность создать список кластеров центрального сервера (рис. 6.6).
Работа со списком резервирования кластеров и рабочих процессов описана в разделе «Отказоустойчивость кластера», стр. 128. Рассмотрим некоторые другие функции по администрированию кластера серверов.
Работа со списком администраторов центрального сервера Утилита администрирования предоставляет возможность создать список администраторов центрального сервера для того, чтобы ряд административных действий (например, добавление нового кластера, просмотр списка администраторов центрального сервера) могли выполнять только аутентифицированные пользователи (рис. 6.5). Также можно просмотреть и изменить свойства администраторов центрального сервера или удалить какого-либо администратора. Рис. 6.6. Список кластеров
Том 1
139
Глава 6. Установка и администрирование системы Также можно просмотреть и изменить свойства кластеров центрального сервера или удалить какой-либо кластер (в том случае, если он не содержит ни одного активного соединения, ни одного рабочего процесса, ни одного сервера и ни одной зарегистрированной информационной базы).
Работа со списком менеджеров кластера Утилита администрирования предоставляет возможность для просмотра и изменения списка менеджеров кластера. По умолчанию существует один менеджер кластера, который является основным и который невозможно удалить. Такой менеджер определен в любом кластере. Имеется возможность добавлять новые менеджеры кластера, переназначать сервисы с менеджера на менеджера, удалять менеджеры кластера. В окне свойств отображается компьютер, на котором работает менеджер кластера, его описание, идентификатор (в терминах операционной системы) процесса rmngr, порт менеджера кластера и номер служебного сетевого порта менеджера кластера (рис. 6.7).
Рис. 6.8. Добавить назначение сервиса на другой менеджер кластера
Работа со списком администраторов кластера Утилита администрирования предоставляет возможность создать отдельный список администраторов для каждого кластера, зарегистрированного на центральном сервере, для того, чтобы административные действия с кластером могли выполнять только аутентифицированные пользователи (рис. 6.9).
Рис. 6.7. Менеджеры кластера
Сервис сеансовых данных можно назначать одновременно нескольким менеджерам кластера (рис. 6.8). Рис. 6.9. Список администраторов кластера
Также можно просмотреть и изменить свойства администраторов кластера или удалить какого-либо администратора. Таким образом, с целью ограничения круга пользователей, которые могут выполнять административные действия, создаются отдельно списки адми-
140
Профессиональная разработка в системе «1С:Предприятие 8»
Управление кластером серверов нистраторов центрального сервера и списки администраторов каждого из кластеров, расположенных на данном сервере. Области действий, на которые распространяются права администраторов центрального сервера и администраторов кластеров, не пересекаются. Аутентификация администратора центрального сервера позволяет пользователю выполнять административные действия с центральным сервером, но для того, чтобы выполнить какие-либо административные действия с конкретным кластером, требуется аутентификация администратора кластера. В то же время для выполнения административных действий с кластером пользователь должен аутентифицироваться как администратор кластера, но дополнительная аутентификация в качестве администратора сервера для этого не требуется.
Работа со списком рабочих процессов Утилита администрирования позволяет отобразить список рабочих процессов для всего кластера в целом или для отдельного сервера кластера. Выбрав конкретный сервер кластера, можно добавить рабочий процесс (рис. 6.11).
Механизм аутентификации администраторов центрального сервера/ кластера включается системой автоматически, как только в списке администраторов центрального сервера/кластера создается хотя бы один администратор. В этом случае при попытке выполнения действия, требующего аутентификации, системой автоматически будет запрошена аутентификация администратора центрального сервера/кластера.
Работа со списком рабочих серверов кластера Утилита администрирования предоставляет возможность добавить рабочий сервер в кластер (рис. 6.10). Рис. 6.11. Список рабочих процессов конкретного рабочего сервера
Выбрав конкретный рабочий процесс, можно просмотреть его свойства и изменить некоторые из них (рис. 6.12).
Рис. 6.10. Список рабочих серверов
Также можно просмотреть и изменить свойства серверов кластера или удалить какой-либо рабочий сервер (в том случае, если он не содержит ни одного активного соединения, ни одного рабочего процесса). Том 1
Рис. 6.12. Свойства рабочего процесса
141
Глава 6. Установка и администрирование системы Также можно отключить какой-либо рабочий процесс, установив его свойство Использование в значение Не использовать. Рабочий процесс будет остановлен после того, как завершится последнее клиентское соединение, обслуживаемое данным рабочим процессом. При повторных запусках кластера серверов неиспользуемые рабочие процессы запускаться не будут. Для запуска неиспользуемого рабочего процесса нужно установить его свойство Использование в значение Использовать. Через некоторое время рабочий процесс будет запущен менеджером кластера.
Параметры информационной базы эквивалентны параметрам новой информационной базы, создаваемой с помощью окна запуска «1С:Предприятия». Подробнее
Описание этих параметров можно посмотреть в документации «1С:Предприятие 8.2. Руководство администратора».
Также можно удалить какой-либо рабочий процесс (в том случае, если он не обслуживает ни одного соединения).
Можно также удалить какую-либо информационную базу в различных вариантах: либо удалить базу целиком с сервера, либо только очистить базу данных и удалить ее регистрацию из кластера серверов, либо только удалить регистрацию информационной базы из кластера серверов.
Работа со списком информационных баз
Работа со списком сеансов
Регистрация новой информационной базы в кластере серверов может быть выполнена двумя способами: из клиентского приложения или непосредственно в кластере серверов.
Утилита администрирования позволяет отобразить список сеансов для всего кластера в целом или для отдельной информационной базы. Выбрав конкретный сеанс, можно просмотреть (без возможности редактирования) его свойства (рис. 6.14).
При добавлении новой информационной базы в клиентском приложении ее регистрация в кластере серверов выполняется системой автоматически. Утилита администрирования позволяет зарегистрировать новую информационную базу в кластере серверов, просмотреть и изменить ее свойства (рис. 6.13).
Рис. 6.14. Свойства сеанса
Администратор кластера серверов может также удалить сеанс, но в случае активно работающего пользователя с информационной базой это может привести к потере данных.
Рис. 6.13. Свойства информационной базы
142
Профессиональная разработка в системе «1С:Предприятие 8»
Управление кластером серверов
Работа со списком соединений Утилита администрирования позволяет отобразить список соединений для всего кластера в целом, для отдельного рабочего процесса кластера, для отдельной информационной базы или для отдельного рабочего процесса сервера кластера. Выбрав конкретное соединение, можно просмотреть (без возможности редактирования) его свойства (рис. 6.15).
Соединение с агентом сервера позволяет выполнять следующие действия: ■■ аутентификация, добавление, удаление, получение списка администраторов центрального сервера и администраторов кластера; ■■ создание, удаление, получение списка кластеров; ■■ создание, удаление, получение списка серверов; ■■ создание, удаление, получение списка рабочих процессов кластера; ■■ получение списка сервисов кластера; ■■ получение списка сеансов информационной базы; ■■ получение списка соединений кластера; ■■ получение списка соединений информационной базы; ■■ получение списка информационных баз, зарегистрированных в кластере; ■■ получение списка блокировок кластера; ■■ получение списка резервирования; ■■ получение другой информации. Соединение с рабочим процессом может быть получено при помощи метода ConnectWorkingProcess() объекта Менеджер COM-соединений (листинг 6.2). Листинг 6.2. Установка соединения с рабочим процессом
Рис. 6.15. Свойства соединения
Администратор кластера серверов может также разорвать соединение, но в случае активно работающего пользователя с информационной базой это может привести к потере данных.
// Создать COMСоединитель 1С:Предприятия. COMСоединитель = Новый COMОбъект("V82.COMConnector"); СоединениеСРабочимПроцессом = COMСоединитель.ConnectWorkingProcess("TestSrv:1562");
Соединение с рабочим процессом позволяет выполнять следующие действия:
Соединение с агентом сервера может быть получено при помощи метода ConnectAgent() объекта Менеджер COM-соединений (листинг 6.1):
■■ аутентификация пользователей информационных баз; ■■ создание, удаление, получение списка информационных баз, зарегистрированных в кластере; ■■ получение списка соединений информационной базы; ■■ разрыв соединения информационной базы; ■■ соединение с информационной базой (COM-соединение); ■■ получение другой информации.
Листинг 6.1. Установка соединения с агентом сервера
Подробнее
Программные средства администрирования кластера серверов Для администрирования кластера серверов используются два объекта: Соединение с агентом сервера и Соединение с рабочим процессом.
// Создать COMСоединитель 1С:Предприятия. COMСоединитель = Новый COMОбъект("V82.COMConnector"); СоединениеСАгентомСервера = COMСоединитель.ConnectAgent("TestSrv");
Том 1
Синтакс-помощник:
Средства интеграции и администрирования Менеджер COM-соединений – Администрирование кластера серверов.
–
143
Глава 6. Установка и администрирование системы
144
Профессиональная разработка в системе «1С:Предприятие 8»
Пользователь, интерфейс, команда
Глава 7. Командный интерфейс прикладных решений Пользователь, интерфейс, команда
Пользователь – лицо (или организация), которое использует действующую систему для выполнения конкретной функции.
навигация между блоками системы; дизайн экранов программы; отображаемая информация и форматы отображения; устройства и технологии ввода данных; диалоги, взаимодействие и транзакции между пользователем и компьютером; ■■ обратная связь с пользователем.
Пользователь автоматизированной системы – лицо, участвующее в функционировании автоматизированной системы или использующее результаты ее функционирования.
Составной частью пользовательского интерфейса является командный интерфейс, обеспечивающий доступ пользователей к функциональности компьютерной программы.
ПРИМЕЧАНИЕ
ПРИМЕЧАНИЕ
В книге часто будут встречаться термины «пользователь», «пользовательский интерфейс», «команда» и «командный интерфейс». Давайте определим, что подразумевают под собой эти термины и как они связаны.
Определения взяты из свободной интернет-энциклопедии «Википедия»: http://ru.wikipedia.org/wiki/Пользователь.
Автоматизированная система создает рабочую среду, взаимодействуя с которой, пользователь решает стоящие перед ним задачи. Для обеспечения удобной и безопасной работы создаются пользовательские интерфейсы. Пользовательский интерфейс – совокупность средств, при помощи которых пользователь общается с различным сложным инструментарием (системой). ПРИМЕЧАНИЕ
Определение взято из свободной интернет-энциклопедии «Википедия»: http://ru.wikipedia.org/wiki/Интерфейс_пользователя.
К сложному инструментарию с полным правом можно отнести и компьютерные программы. Однако пользовательский интерфейс компьютерной программы часто понимают только как ее внешний вид. В действительности пользовательский интерфейс объединяет в себе все элементы и компоненты программы, которые влияют на взаимодействие пользователя с программным обеспечением. Основными элементами пользовательского интерфейса являются: ■■ набор задач пользователя, которые он решает при помощи системы; ■■ элементы управления системой; Том 1
■■ ■■ ■■ ■■ ■■
В дальнейшем мы будем оперировать в основном понятием «командный интерфейс». Однако для режима управляемого приложения «1С:Предприятия» принципы формирования командного интерфейса во многом аналогичны принципам формирования прочих составных частей пользовательского интерфейса, в частности, форм.
В общем случае команда – это указание некоему интерфейсу (командный интерфейс пользователя), побуждающее исполнителя (компьютерная программа) выполнить действия для решения задачи. ПРИМЕЧАНИЕ
Определение взято из свободной интернет-энциклопедии «Википедия»: http://ru.wikipedia.org/wiki/Команда_(программирование).
При этом команда: ■■ может быть отдана только пользователем, имеющим на это право; ■■ не включает в себя подробные разъяснения, как будет происходить исполнение, а предполагает, что исполнитель (программа) знает, что и как необходимо исполнить. Командный интерфейс – совокупность команд, доступных пользователю, при помощи которых он отдает приказание системе на выполнение действий.
145
Глава 7. Командный интерфейс прикладных решений Применительно к компьютерной программе совокупность команд определяет, какие действия она может выполнить, а командный интерфейс определяет, какие команды может отдать конкретный пользователь и как он получит доступ к этим командам. Набор команд интерактивной компьютерной включает в себя несколько категорий команд:
программы
обычно
■■ команды, которые позволяют перемещаться между функциональными блоками программы, – например, функции настройки программы, функции просмотра данных, функции модификации данных, функции импорта/экспорта данных; ■■ команды, которые позволяют вызывать формы и перемещаться между ними, – например, вызов формы просмотра перечня товаров, вызов формы ввода нового документа; ■■ команды, которые позволяют выполнять те или иные действия с обрабатываемыми данными, – например, изменение элемента справочника, построение отчета. В связи с тем, что различные пользователи выполняют различные задачи, права на использование обрабатываемой системой информации и состав доступных команд для них будут различаться. Для разграничения прав и состава команд в компьютерных программах обычно реализуется система учетных записей. Каждая учетная запись (возможно, защищенная паролем) определяет совокупность ресурсов, доступных пользователю. На основании учетной записи осуществляется идентификация и аутентификация пользователя и предоставление разрешения на работу с ресурсами. Таким образом, при разработке командного интерфейса необходимо решить две основные задачи: ■■ из множества команд, исполняемых программой, выделить подмножество команд, доступных конкретному пользователю; ■■ предоставить возможность пользователю вызывать доступные команды.
Командный интерфейс системы В данном разделе мы узнаем о командах системы «1С:Предприятие» и их источниках. Также мы разберемся, как из этих команд формируется глобальный командный интерфейс. В качестве примера мы будем использовать демонстрационную базу «Командный интерфейс прикладных решений, пример 1».
146
Команды «1С:Предприятия» Для начала давайте поговорим о том, какие команды бывают. Все команды «1С:Предприятия» можно разделить по источникам и по области видимости (рис. 7.1).
Рис. 7.1. Команды «1С:Предприятия»
ПРИМЕЧАНИЕ
Приведенная классификация не является исчерпывающей. Те же самые команды могут быть классифицированы и по другим критериям. Например, «что команды делают» – изменяют состав отображаемых данных или изменяют сами данные; «необходимость в параметре» – одни команды не требуют для своего исполнения параметров, а другим необходимо передавать параметры.
По источникам команды можно разделить на три группы: ■■ системные команды, ■■ стандартные команды объектов и расширений форм, ■■ произвольные команды. Системные команды предопределены на уровне технологической платформы и предоставляются автоматически. Их состав и выполняемые действия одинаковы для любого прикладного решения и не могут быть изменены разработчиком. Стандартные команды предопределены на уровне объекта конфигурации (или расширения формы) и предоставляются автоматически. Состав стандартных команд зависит от того, какие объекты присутствуют в конфигурации и какие значения заданы для свойств этих объектов. Выполняемые действия также предопределены, но разработчик может в какой-то мере повлиять на них. Для этого используется механизм событий. Произвольные команды полностью создаются разработчиком. Для этого предназначен объект конфигурации Команда. Для реализации универсального (в рамках прикладного решения) функционала используются Профессиональная разработка в системе «1С:Предприятие 8»
Командный интерфейс системы общие команды. Для реализации функционала, специфического для того или иного объекта, используются команды, подчиненные этому объекту. По области видимости команды делятся: ■■ на глобальные, ■■ локальные команды формы. Глобальные команды предназначены для выбора пользователем той или иной функциональности в рамках приложения в целом. В состав глобальных команд входят системные команды, стандартные команды объектов конфигурации, а также общие и подчиненные произвольные команды. Локальные команды формы предназначены для выполнения действий в форме. В состав локальных входят стандартные команды формы, расширений формы, расширений элементов формы Таблица, а также произвольные команды формы. Эти команды доступны только в контексте той или иной формы.
Структура командного интерфейса При запуске прикладного решения для пользователя формируется индивидуальный глобальный командный интерфейс. Его структура, то есть размещение команд, однозначно определяется иерархией подсистем конфигурации и свойствами самих команд. Состав же команд, включенных в командный интерфейс, определяется правами пользователя, значениями функциональных опций и видимостью команд по ролям. Кроме того, если в предыдущих сеансах пользователь выполнял настройку командного интерфейса под себя, эти настройки также будут влиять на размещение и состав команд командного интерфейса этого пользователя. В командном интерфейсе можно выделить несколько структурных элементов, в каждом из которых размещаются определенные команды (рис. 7.2).
Глобальные команды формируют глобальный командный интерфейс прикладного решения. Локальные команды формы и, возможно, часть глобальных команд формируют командный интерфейс форм. ПРИМЕЧАНИЕ
В дальнейшем изложении, до раздела «Командуем формами» (стр. 210), мы будем рассматривать глобальный командный интерфейс. При этом зачастую прилагательное «глобальный» использовать не будем.
А теперь, зная откуда берутся команды, сравним количество объектов конфигурации и форм в демонстрационной базе и количество команд, отображаемых в командном интерфейсе, например, для пользователя Продавец. Из сравнения можно сделать вывод: в командном интерфейсе мы видим не все команды, предоставляемые прикладным решением. Для каждого пользователя предоставлены только те команды, которые ему необходимы для решения своих конкретных задач. Как же «ужимается» командный интерфейс? Чтобы ответить на этот вопрос, давайте разберемся с тем, как система формирует командный интерфейс пользователя. ПРИМЕЧАНИЕ
На данном этапе будем считать, что для построения командного интерфейса пользователя система использует все глобальные команды. Управление составом команд, используемых для построения командного интерфейса пользователя, описано в разделе «Настраиваем состав команд» (стр. 154).
Том 1
Рис. 7.2. Структура глобального командного интерфейса
Подробнее
Раздел «Управляемый интерфейс», стр. 15.
Все системные команды размещаются в области системных команд основного или вспомогательного окна приложения. Стандартные и произвольные глобальные команды размещаются в панели разделов, панели навигации и панели действий основного окна приложения. ПРИМЕЧАНИЕ
Глобальные команды также могут быть размещены в панели навигации вспомогательного окна приложения и в командной панели формы.
147
Глава 7. Командный интерфейс прикладных решений
Влияние подсистем Почему же иерархия подсистем однозначно определяет структуру командного интерфейса? Да потому, что это логично. Обычно с помощью подсистем описываются различные виды деятельности, автоматизируемые прикладным решением, то есть с их помощью формируется функциональная структура прикладного решения. В одной подсистеме имеет смысл «собирать» объекты конфигурации, реализующие тесно связанную функциональность. При этом состав подсистем верхнего уровня иерархии отражает наиболее общее разделение функциональности прикладного решения. Например, разработчик может определить подсистему Запасы и собрать в ней функции управления складскими запасами, а в подсистеме Взаиморасчеты объединить функции управления взаиморасчетами с контрагентами и т. д. Для использования же той или иной функциональности предназначены команды. Соответственно, структурирование командного интерфейса по подсистемам представляется наиболее естественным. Для того чтобы командный интерфейс был удобным, не перегруженным и не содержал «лишних» команд, разработку прикладного решения рекомендуется начинать с определения его функциональной структуры. Это значит, что перед реализацией функциональности (создание объектов конфигурации, написания программного кода на встроенном языке) разработчик должен эту функциональность описать иерархией элементов. Корень иерархии будет соответствовать создаваемому прикладному решению (корневому элементу конфигурации), а элементы – объектам конфигурации Подсистема. При этом платформа не накладывает никаких ограничений по количеству и уровням вложенности элементов иерархии. Это обеспечивает необходимую гибкость при описании функциональной структуры прикладного решения. Для пользователей подсистемы верхнего уровня иерархии представляются как разделы глобального командного интерфейса. Команды выбора разделов размещаются в панели разделов основного окна приложения (рис. 7.3). Выбранный раздел определяет состав команд, размещаемых в панели навигации и панели действий, – отображаются команды тех объектов конфигурации, которые принадлежат соответствующей подсистеме верхнего уровня. У подсистемы, для которой был сформирован раздел, могут существовать подчиненные подсистемы. В этом случае для каждой из подчиненных подсистем будет сформирован подраздел, отображаемый группой в панели навигации. В подразделах отображаются команды объектов, включенных в соответствующую подчиненную подсистему.
148
Рис. 7.3. Соответствие подсистем конфигурации и разделов командного интерфейса
Например, для раздела Товарные запасы (соответствует подсистеме Товарные запасы) в командном интерфейсе созданы подразделы Характеристики и Цены (соответствуют подчиненным подсистемам), см. рис. 7.3. В панели действий для команд, принадлежащих различным подчиненным подсистемам, подразделы не создаются. В этой панели команды «собираются» в группы, формируемые в соответствии с назначением команд (например, команды создания объектов, команды формирования отчетов, сервисные команды и др.). Отдельно стоит обратить внимание на командный интерфейс раздела Рабочий стол. Этот раздел предназначен для отображения наиболее важной для пользователя информации и наиболее часто используемых команд. Именно рабочий стол открывается по умолчанию при запуске прикладного решения. В связи с тем, что для разных пользователей состав важной информации различен, рабочий стол не связан с какой-либо из подсистем. По той же причине состав отображаемой информации и доступных команд формируется вручную разработчиком. Для наполнения рабочего стола командами используется редактор командного интерфейса рабочего стола. Подробнее
Раздел «Система настройки командного интерфейса», стр. 174.
Профессиональная разработка в системе «1С:Предприятие 8»
Командный интерфейс системы
Формирование состава командного интерфейса Разобравшись со структурированием командного интерфейса, перейдем к рассмотрению того, как платформа наполняет его командами. Основной целью, достигаемой при формировании состава команд, является «превращение» полного командного интерфейса в командный интерфейс конкретного пользователя, запустившего прикладное решение. При этом идеология системы «1С:Предприятие» обуславливает выполнение действий по «превращению» на сервере приложений. ВНИМАНИЕ!
В «1С:Предприятии» реализована идеология «командный интерфейс формирует сервер». Клиент же показывает то, что ему передал сервер.
В соответствии с задачами, решаемыми системой при формировании командного интерфейса, процесс его построения можно условно разбить на несколько этапов. ■■ Обеспечение доступности только тех команд, которые пользователь имеет право выполнять. Для решения этой задачи используется механизм прав доступа – состав команд, доступных конкретному пользователю, автоматически формируется системой на основании прав, устанавливаемых для ролей этого пользователя. ■■ Оптимизация командного интерфейса в соответствии с задачами, решаемыми конкретным пользователем. Для решения этой задачи выполняется настройка пользовательской видимости команд по ролям – для доступных пользователю команд система определяет их видимость по умолчанию. Эта видимость задается разработчиком. При этом платформа обеспечивает возможность задания видимости в разрезе ролей. ■■ Исключение команд, относящихся к отключенным функциональным возможностям. Для решения этой задачи выполняется настройка доступности команд по функциональным опциям – система автоматически ограничивает состав доступных команд только теми функциональными возможностями прикладного решения, которые используются в конкретном случае. ■■ Предоставление пользователю возможности собственной настройки видимости команд. Для решения этой задачи выполняется настройка видимости команд в разрезе пользователей прикладного решения. Давайте кратко рассмотрим каждый из перечисленных этапов. Том 1
ВНИМАНИЕ!
В этом разделе речь идет о стандартных командах объектов конфигурации. Настройка доступности команд, созданных разработчиком, описана в разделе «Создаем произвольные команды», стр. 193.
Обеспечение доступности команд При формировании командного интерфейса для конкретного пользователя в первую очередь анализируются права этого пользователя на доступ к данным. Это позволяет автоматически согласовать набор команд, предоставляемых пользователю, с набором предоставленных ему прав. Подробнее
О системе определения прав рассказано в разделе «Система прав доступа», стр. 161.
Доступ пользователя к разделу можно ограничить на уровне функциональной структуры прикладного решения. Для такого ограничения используется право Просмотр объекта конфигурации Подсистема. Из командного интерфейса пользователя исключаются все разделы, соответствующие подсистемам, для которых у роли пользователя право «Просмотр» не установлено. ПРИМЕЧАНИЕ
Как мы увидим в дальнейшем (см. раздел «Состав разделов», стр. 155), на доступность раздела также влияет свойство подсистемы Включать в командный интерфейс. Это свойство влияет на всех пользователей.
Например, у роли Администратор для подсистемы Закупки право Просмотр установлено. В командном интерфейсе доступна команда выбора соответствующего раздела и доступны команды этого раздела (рис. 7.4).
Рис. 7.4. Право на просмотр подсистемы установлено
149
Глава 7. Командный интерфейс прикладных решений У роли Продавец для этой же подсистемы право не установлено. В командном интерфейсе команда перехода к разделу Закупки недоступна, и невозможно использовать команды этого раздела (рис. 7.5).
Рис. 7.5. Право на просмотр подсистемы не установлено
Если необходимо ограничить доступ пользователя только к командам, связанным с определенным объектом конфигурации, это можно реализовать установкой прав на объект конфигурации, предоставляющий эти команды.
Рис. 7.6. Права на объект конфигурации установлены – команды доступны
Из командного интерфейса пользователя исключаются стандартные команды тех объектов конфигурации, доступ к которым пользователю запрещен. ПРИМЕЧАНИЕ
Как мы увидим в дальнейшем (см. раздел «Стандартные команды», стр. 157), на доступность команд объекта также влияет его свойство Использовать стандартные команды. Это свойство влияет на всех пользователей.
Например, у роли Администратор для справочника Контрагенты установлены все права. В командном интерфейсе доступны команды перехода к списку контрагентов и создания нового контрагента (рис. 7.6). У роли Продавец для этого же справочника ни одно право не установлено. В командном интерфейсе команд перехода к списку контрагентов и создания нового контрагента нет (рис. 7.7). Если для пользователя определен ограниченный доступ к объекту конфигурации, то из командного интерфейса исключаются только те команды объекта, которые выполняют недоступные пользователю операции. Например, у роли Администратор для справочника Товары установлены все права. В глобальном командном интерфейсе доступны команды перехода к списку товаров и создания нового товара (рис. 7.8).
150
Рис. 7.7. Права на объект конфигурации сброшены – команды недоступны
У роли Продавец для этого же справочника установлены только права, позволяющие просматривать товары. В глобальном командном интерфейсе команда перехода к списку товаров доступна, а команда создания нового товара отсутствует (рис. 7.9). Профессиональная разработка в системе «1С:Предприятие 8»
Командный интерфейс системы
Оптимизация командного интерфейса Кроме доступности команд в зависимости от прав, система выполняет настройку видимости доступных команд для конкретных ролей пользователей. Связано это с тем, что одна и та же доступная команда в одном разделе пользователю нужна, а в другом она только мешает. ВНИМАНИЕ!
Необходимо различать механизм ограничения доступности на основании прав и механизм видимости по ролям. Первый жестко ограничивает пользователя в его возможностях выполнить те или иные действия. Второй позволяет оптимизировать состав видимых команд в соответствии с теми действиями, которые пользователь выполняет наиболее интенсивно.
Настройка видимости позволяет предоставить пользователю ту часть функциональности, которая ему требуется при решении тех или иных конкретных задач.
Рис. 7.8. Права на объект конфигурации установлены – команды доступны
При этом для пользователя оставлена возможность самостоятельно донастроить видимость доступных команд – как удобно ему, а не как думает разработчик. ВНИМАНИЕ!
Настройка видимости выполняется только для тех команд, которые оказались доступны пользователю в соответствии с его правами (ролью). Установка видимости для недоступных команд не приведет к их появлению в командном интерфейсе. Подробнее
Правила пользовательской видимости команд, автоматически устанавливаемые платформой, приведены в документации «1С:Предприятие 8.2. Руководство разработчика», раздел 6.2.7.
Для изменения пользовательской видимости команд по умолчанию необходимо использовать редактор командного интерфейса. Подробнее
Раздел «Система настройки командного интерфейса», стр. 174.
Рис. 7.9. Права на объект конфигурации установлены частично – команды доступны частично
Например, для команды Товар: создать видимость установлена, и эта команда отображается в группе Создать панели действий (рис. 7.10). Для команды же Товар: создать группу видимость сброшена, и эта команда в интерфейсе не отображается. Видимость можно настраивать как общую для всех ролей – колонка Видимость, так и для каждой роли отдельно – колонка Видимость по ролям.
Том 1
151
Глава 7. Командный интерфейс прикладных решений Например, в демонстрационной базе реализован функционал учета по складам. Но часть компаний, использующих прикладное решение, не ведут учет в разрезе складов. Для этих компаний из интерфейса необходимо исключить элементы, связанные с функционалом учета по складам. Значение функциональной опции, управляющей учетом по складам, хранится в константе Учет по складам. Функциональная опция связана со справочником Склады. ПРИМЕЧАНИЕ
В общем случае в качестве хранилища значений функциональных опций кроме констант могут выступать элементы справочников и записи регистра сведений.
Если константа имеет значение Истина, то команды для работы со справочником включены в командный интерфейс (рис. 7.11).
Рис. 7.10. Пользовательская видимость команд по умолчанию
Например, команда Регистр товарных запасов будет отображаться в командном интерфейсе для всех пользователей, за исключением пользователей с ролью Продавец (см. рис. 7.10).
Доступность команд по функциональным опциям Установка доступности команд в зависимости от значений функциональных опций не зависит от роли пользователя, то есть выполняется одинаково для всех ролей. Механизм функциональных опций позволяет определить в прикладном решении ту функциональность, которая может использоваться или не использоваться в зависимости от потребностей конкретной организации. Различным элементам командного интерфейса могут быть назначены функциональные опции. При эксплуатации прикладного решения можно устанавливать значение для функциональных опций. В зависимости от установленного значения система будет автоматически включать/выключать отображение всех элементов командного интерфейса, которым эта функциональная опция назначена.
Рис. 7.11. Команды доступны при включенной функциональной опции
Если же значение константы Ложь, то эти команды из командного интерфейса исключены (рис. 7.12). Таким образом, при отсутствии учета в разрезе складов мы имеем возможность убрать из прикладного решения «лишнюю» функциональность, в том числе и команды из командного интерфейса.
Подробнее
Раздел «Механизм функциональных опций», стр. 183.
152
Профессиональная разработка в системе «1С:Предприятие 8»
Командный интерфейс системы Пользователь изменил состав отображаемых разделов (рис. 7.14) – из списка выбранных удалены разделы Закупки и Предприятие.
Рис. 7.12. Команды недоступны при отключенной функциональной опции
Рис. 7.14. Отключены разделы
Пользовательская настройка командного интерфейса
Затем пользователь изменил состав команд, отображаемых в панели навигации (рис. 7.15), – из списка выбранных удалены команды Корректировка остатков, Регистр товарных запасов, Характеристики товаров, Цены товаров.
При формировании видимой части командного интерфейса система осуществляет установку видимости команд в зависимости от персональных настроек пользователя. Этот механизм позволяет пользователям настраивать командный интерфейс в соответствии со своими предпочтениями. Подробнее
Раздел «Пользовательская настройка интерфейса», стр. 187.
Например, при первом запуске демонстрационной базы от имени пользователя Администратор состав видимых команд соответствует настройкам, выполненным разработчиком (рис. 7.13).
Рис. 7.15. Отключены команды в панели навигации
Также изменен состав отображаемых команд в панели действий (рис. 7.16) – из списка выбранных удалена команда Корректировка остатка. После применения всех настроек (и при последующих запусках) состав видимых команд соответствует настройкам пользователя Администратор (рис. 7.17) – все скрытые пользователем команды не отображаются. Рис. 7.13. Командный интерфейс при первом запуске
Том 1
Важно помнить, что отключенные команды остались доступны – пользователь вновь может включить их отображение.
153
Глава 7. Командный интерфейс прикладных решений ПРИМЕЧАНИЕ
На рис. 7.18 величина прямоугольника, представляющего создаваемый глобальный командный интерфейс, отражает его «насыщенность» командами.
В общем случае формирование глобального командного интерфейса выполняется в зависимости:
Рис. 7.16. Отключены команды в панели действий
■■ от структуры подсистем и их свойств Включать в командный интерфейс – определяют структуру командного интерфейса; ■■ состава объектов конфигурации и их свойств Использовать стандартные команды – определяют состав команд прикладного решения; ■■ прав пользователя, определяющих состав доступных команд; ■■ настройки пользовательской видимости команд по умолчанию (возможно, в разрезе ролей); ■■ установленных значений функциональных опций; ■■ настроек самого пользователя.
Настраиваем состав команд
Рис. 7.17. Командный интерфейс при последующих запусках
Краткие итоги В заключение рассмотрения процесса построения глобального командного интерфейса можно представить изложенный материал в виде схемы (рис. 7.18).
В дальнейшем изложении для демонстрации механизмов конструирования командного интерфейса мы будем использовать демонстрационную базу «Командный интерфейс прикладных решений, пример 1». В качестве демонстрационного примера мы будем решать практическую задачу по адаптации этой конфигурации. Результат решения этой задачи содержится в демонстрационной базе «Командный интерфейс прикладных решений, пример 2».
Постановка задачи На предприятии процесс ценообразования выделен в отдельный функциональный блок, и управлением ценами занимаются специально выделенные сотрудники. В демонстрационной базе операции управления ценами совмещены с операциями управления товарными запасами в подсистеме Товарные запасы. Необходимо выделить функционал управления ценами в отдельную подсистему и создать командный интерфейс для сотрудников, работающих с этой подсистемой. ПРИМЕЧАНИЕ
Рис. 7.18. Построение глобального командного интерфейса
154
В данном разделе мы будем рассматривать системные и стандартные команды. Произвольные команды рассматриваются в разделе «Создаем произвольные команды», стр. 193.
Профессиональная разработка в системе «1С:Предприятие 8»
Настраиваем состав команд
Системные команды Начнем мы с самого простого – с главного меню приложения. Главное меню формируется из системных команд, предоставляемых технологической платформой. С точки зрения управления это самая простая группа команд. Системные команды присутствуют в любом прикладном решении, и разработчик прикладного решения не может изменить их состав. Для всех пользователей, вне зависимости от роли, в командном интерфейсе доступен один и тот же набор системных команд.
ПРИМЕЧАНИЕ
Для простых конфигураций возможна работа без подсистем. В этом случае все команды располагаются на рабочем столе. Раздел «Рабочий стол» формируется всегда. Однако в зависимости от настроек он может быть пустым.
Формирование раздела командного интерфейса для подсистемы верхнего уровня иерархии управляется свойством подсистемы Включать в командный интерфейс (рис. 7.20).
Все системные команды доступны через главное меню прикладного решения. Часть команд, доступных из главного меню, представлены в области системных команд (рис. 7.19).
Рис. 7.20. Управление формированием раздела для подсистемы
Рис. 7.19. Системные команды
Вызов главного меню осуществляется кнопкой Главное меню, расположенной в области системных команд основного или вспомогательного окна приложения. Подробнее
Об основном и вспомогательном окне приложения рассказано в разделе «Управляемый интерфейс», стр. 15. О пользовательской настройке видимости системных команд рассказано в разделе «Настройка области системных команд», стр. 187.
Состав разделов Как уже было сказано, состав команд панели разделов определяется составом объектов конфигурации Подсистема верхнего уровня иерархии. Однако создание в дереве конфигурации подсистемы верхнего уровня еще не гарантирует, что для нее при построении командного интерфейса будет создан раздел. Том 1
Данное свойство оказывает влияние на формирование раздела командного интерфейса для всех пользователей прикладного решения, независимо от назначенных им ролей. Доступность же раздела для того или иного пользователя определяется назначенной ему ролью (см. раздел «Обеспечение доступности команд», стр. 149). Если для подсистемы верхнего уровня свойство Включать в командный интерфейс установлено, то для нее будет сформирован отдельный раздел. Стандартные команды объектов конфигурации, включенных в подсистему, будут учитываться при формировании командного интерфейса пользователя. Например, для подсистемы Финансы свойство Включать в командный интерфейс установлено (рис. 7.21). Для этой подсистемы сформирован раздел, и команды включены в командный интерфейс. Если же для подсистемы свойство Включать в командный интерфейс сброшено, то стандартные команды объектов, принадлежащих этой подсистеме, не будут учитываться при формировании командного интерфейса пользователя. Например, для подсистемы Финансы свойство Включать в командный интерфейс сброшено (рис. 7.22). Для этой подсистемы раздел не сформирован, и, следовательно, команды недоступны.
155
Глава 7. Командный интерфейс прикладных решений ВНИМАНИЕ!
Для новых подсистем свойство Включать в командный интерфейс устанавливается по умолчанию, то есть предполагается, что подсистемы в первую очередь предназначены для формирования командного интерфейса. Если же выполняется конвертация конфигурации, разработанной для версии 8.1, то у всех подсистем свойство будет сброшено.
Теперь мы можем начать решать поставленную задачу. Прежде всего, создадим новую подсистему верхнего уровня иерархии. Для добавления подсистемы используем команду Добавить контекстного меню узла Подсистемы дерева конфигурации (рис. 7.23).
Рис. 7.21. В командном интерфейсе раздел формируется для подсистем с установленным свойством «Включать в командный интерфейс»
Рис. 7.23. Добавление подсистемы
В результате будет добавлен объект конфигурации и откроется окно свойств этого объекта (рис. 7.24).
Рис. 7.24. Новая подсистема «Ценообразование» и ее свойства
В группе свойств Основные представлены свойства:
Рис. 7.22. Свойство «Включать в командный интерфейс» сброшено
156
■■ Имя – определяет идентификатор объекта для доступа из встроенного языка; зададим имя «Ценообразование»; ■■ Синоним – определяет представление объекта в интерфейсе; оставим автоматически сформированный синоним. Профессиональная разработка в системе «1С:Предприятие 8»
Настраиваем состав команд ВНИМАНИЕ!
Для свойства Синоним необходимо подбирать значение, которое максимально полно отражает назначение объекта. Особенно это важно для подсистем. У них, в отличие от прикладных объектов, нет других свойств, позволяющих задать представление объекта в интерфейсе, – пользователь увидит именно тот текст, который задан для свойства Синоним.
Свойство Включать в командный интерфейс оставим установленным – нам необходимо формировать раздел в командном интерфейсе. Теперь необходимо вспомнить, что доступность раздела для пользователя определяется значением права Просмотр, установленным у роли пользователя для соответствующей подсистемы. Проконтролируем значение этого права для роли Администратор (рис. 7.25) – право должно быть установлено.
Стандартные команды Для начала разберемся, какими же командами может быть наполнен раздел командного интерфейса. В раздел командного интерфейса включаются стандартные команды тех объектов конфигурации, которые принадлежат соответствующей подсистеме верхнего уровня (и подсистемам иерархически ей подчиненным). Что же мы подразумеваем под стандартной командой? Каждый объект конфигурации имеет стандартный набор свойств, определяющий его поведение по умолчанию. Для доступа к функциональности объекта платформа предоставляет некоторый набор команд. Вот эти команды и являются стандартными. ВНИМАНИЕ!
Для стандартных команд выполняемые действия определены на уровне технологической платформы и не могут быть изменены разработчиком. ПРИМЕЧАНИЕ
Непосредственно сами стандартные команды не имеют событий, для которых разработчик мог бы описать собственные алгоритмы. Но в результате выполнения многих стандартных команд вызываются события, связанные с данными, формами или элементами форм. Поэтому разработчик, используя механизм событий, может в некоторой степени влиять на действия, выполняемые стандартными командами.
Рис. 7.25. Для роли «Администратор» установлено право «Просмотр» на подсистему «Ценообразование»
ПРИМЕЧАНИЕ
Контроль значения права осуществляем в редакторе прав. О работе с этим редактором рассказано в разделе «Система прав доступа», стр. 161.
Следующей операцией по созданию раздела является его наполнение командами. ВНИМАНИЕ!
Например, в демонстрационной базе справочник Товары включен в подсистемы Предприятие, Закупки, Продажи и Товарные запасы (рис. 7.26). Стандартные команды этого объекта доступны в разделах командного интерфейса, сформированных для соответствующих подсистем. А от чего зависит состав стандартных команд? Конечно же, от класса объектов, которому принадлежит объект конфигурации. И это логично, так как различные классы объектов конфигурации предназначены для решения различных прикладных задач. Например, объект-справочник Товары предоставляет команды открытия списка элементов – Товары, создания нового элемента – Товар и создания новой группы – Товар: создать группу, а объект-отчет Остатки товаров только команду открытия формы отчета – Остатки товаров (рис. 7.27).
Если в подсистему не включено ни одного объекта конфигурации, раздел в командном интерфейсе не будет сформирован.
Том 1
157
Глава 7. Командный интерфейс прикладных решений
Рис. 7.26. Справочник «Товары» принадлежит нескольким подсистемам – стандартные команды объекта доступны в соответствующих разделах
Подробнее
Рис. 7.27. Состав стандартных команд зависит от прототипа объекта конфигурации
Полный список командообразующих объектов конфигурации и предоставляемые ими стандартные команды приведены в документации «1С:Предприятие 8.2. Руководство разработчика», раздел 6.1.2.1. Состав предоставляемых стандартных команд мы видим в окне редактора командного интерфейса. О работе с этим редактором рассказано в разделе «Система настройки командного интерфейса», стр. 174.
Кроме прототипа, на состав команд объекта конфигурации влияют и значения свойств этого объекта. Например, объект-справочник Товары предоставляет стандартные команды, как для создания элемента, так и для создания группы, а объект-справочник Склады – только команду создания нового элемента (рис. 7.28).
Рис. 7.28. Состав стандартных команд зависит от настройки свойств объекта конфигурации
158
Профессиональная разработка в системе «1С:Предприятие 8»
Настраиваем состав команд А причина заключается в том, что у справочника Товары установлено свойство Иерархический с иерархией групп и элементов, а у справочника Склады свойство Иерархический сброшено. Таким образом, справочник Склады не может содержать записей-групп, и, следовательно, команда создания группы для этого объекта конфигурации не имеет смысла. Так же как и с подсистемами, наличие объекта в дереве конфигурации еще не гарантирует наличие его команд в командном интерфейсе. Возможность использовать стандартные команды объекта конфигурации при построении командного интерфейса определяется значением свойства Использовать стандартные команды этого объекта. При установленном свойстве команды объекта доступны для включения в командный интерфейс. Например, свойство Использовать стандартные команды для справочника Товары установлено (рис. 7.29). В командном интерфейсе присутствует навигационная команда Товары, которая позволяет открыть форму списка справочника, и команда действия Товар, которая позволяет создать новый элемент справочника.
Рис. 7.30. Свойство «Использовать стандартные команды» сброшено
ПРИМЕЧАНИЕ
Значение свойства Использовать стандартные команды объекта конфигурации не влияет на использование произвольных подчиненных команд объекта (см. раздел «Произвольные команды», стр. 193).
Пришло время обеспечить командами подсистему Ценообразование. Для начала определимся, какими прикладными объектами конфигурации реализован функционал управления ценами. В нашей конфигурации их три (рис. 7.31): ■■ справочник Товары – хранит список товаров и услуг, для которых могут назначаться цены; ■■ справочник Виды цен – хранит список видов цен, которые могут быть назначены каждому товару (услуге); ■■ регистр сведений Цены товаров – хранит значения цен, назначенных товарам в разрезе различных видов цен. Рис. 7.29. Свойство «Использовать стандартные команды» установлено
Если же для объекта конфигурации свойство Использовать стандартные команды сброшено, то стандартные команды этого объекта в любом случае не будут использоваться при построении командного интерфейса. Например, при сброшенном свойстве для справочника Товары в командном интерфейсе отсутствуют команды открытия списка справочника и создания нового элемента (рис. 7.30). Для вновь созданного объекта конфигурации свойство Использовать стандартные команды установлено. Том 1
Рис. 7.31. Объекты конфигурации, реализующие функционал ценообразования
159
Глава 7. Командный интерфейс прикладных решений ПРИМЕЧАНИЕ
На рис. 7.31 представлены только те объекты конфигурации, которые включены в подсистему Товарные запасы. Для этого на дерево объектов установлен фильтр по этой подсистеме.
(на примере справочника Товары) у роли Администратор (рис. 7.33) – права должны быть установлены. Контроль прав на справочник Виды цен и регистр сведений Цены товаров выполняем аналогично справочнику Товары.
Включим каждый из указанных объектов в нашу подсистему. Для этого необходимо заполнить свойство Состав подсистемы Ценообразование. Откроем окно свойств нашей подсистемы и через гиперссылку Открыть свойства Состав перейдем к окну Выбор объекта. В этом окне отметим требуемые объекты конфигурации (рис. 7.32).
Рис. 7.33. Для роли «Администратор» установлены все права на справочник «Товары»
Сохраним внесенные изменения, запустим демонстрационную базу в режиме 1С:Предприятие от имени пользователя Администратор и в панели разделов основного окна выберем раздел Ценообразование (рис. 7.34).
Рис. 7.32. Включение объектов конфигурации в подсистему
Для каждого из включенных объектов проверим свойство Использовать стандартные команды – оно должно быть установлено. Как и для подсистемы, доступность для пользователя объектов и их стандартных команд определяется значением прав, установленных у роли пользователя для этих объектов. Проконтролируем значения права
160
Рис. 7.34. Раздел «Ценообразование» с командами
В панели навигации представлены команды открытия списков объектов, принадлежащих подсистеме Ценообразование. Представление стандартных команд объектов сформировано системой на основании значений в свойстве Представление списка. Профессиональная разработка в системе «1С:Предприятие 8»
Настраиваем доступность команд по ролям ПРИМЕЧАНИЕ
Настройкой представления мы займемся в разделе «Настраиваем представление команд», стр. 190.
На данном этапе мы сформировали структуру подсистемы Ценообразование и обеспечили доступ к ней пользователям с ролью Администратор. По условию задачи управлением ценами будут заниматься специально выделенные сотрудники, а никак не администраторы системы. Поэтому нам необходимо для этих сотрудников создать отдельную роль. ПРИМЕЧАНИЕ
Этой настройкой мы займемся в разделе «Настраиваем доступность команд по ролям», стр. 161.
Основные действия для создания командного интерфейса
Система прав доступа Основным механизмом настройки доступности команд в командном интерфейсе является система прав доступа. Операция назначения роли пользователю решает две основные задачи: ■■ во-первых, ограничивает состав пользователей, имеющих доступ к конфиденциальной информации; ■■ во-вторых, предотвращает возможные потери информации путем запрета выполнения пользователем определенных операций (в первую очередь операций удаления и корректировки данных). При проектировании прикладного решения разработчик должен выделить группы пользователей, выполняющих одинаковые и/или логически связанные операции. Для каждой из выделенных групп на основе шаблона Роли создается объект конфигурации (рис. 7.35).
Из приведенных примеров видно, что для построения командного интерфейса необходимо и достаточно выполнить следующие действия: ■■ создать иерархию подсистем; ■■ при необходимости установить свойство подсистемы Включать в командный интерфейс; ■■ установить значение права Просмотр на подсистемы для тех ролей, которым должны отображаться соответствующие разделы командного интерфейса; ■■ определить состав объектов каждой подсистемы; ■■ при необходимости установить свойство Использовать стандартные команды для объектов конфигурации, включенных в подсистемы. На основании этой информации «1С:Предприятие» автоматически построит командный интерфейс пользователя. Пользователю будет отображена функциональная структура прикладного решения (разделы и подразделы) и предоставлен доступ к стандартной функциональности прикладных объектов (стандартные команды).
Настраиваем доступность команд по ролям В данном разделе мы рассмотрим систему прав доступа и ее влияние на командный интерфейс. В качестве отправной точки мы будем использовать демонстрационную базу «Командный интерфейс прикладных решений, пример 1». Результат выполняемых действий можно посмотреть в демонстрационной базе «Командный интерфейс прикладных решений, пример 3». Том 1
Рис. 7.35. Объекты конфигурации с шаблоном «Роли»
Каждая из ролей определяет независимый (от других ролей) набор прав доступа к обрабатываемой в прикладном решении информации и действий, которые пользователь может выполнять с этой информацией. Разработчик имеет возможность создать любое необходимое количество ролей, обеспечивающих предоставление разным пользователям различных полномочий. Используя механизмы управления пользователями, администратор системы регистрирует пользователей прикладного решения. Каждому пользователю назначается роль (или несколько ролей), которая определяет права пользователя на доступ к данным. Настройка прав выполняется в окне редактирования роли. Для доступа к этому окну можно либо выбрать команду Открыть права из контекстного меню, либо воспользоваться гиперссылкой Открыть в окне свойств роли (рис. 7.36).
161
Глава 7. Командный интерфейс прикладных решений
Рис. 7.36. Варианты открытия окна редактирования прав
В результате выполнения команды будет открыто окно редактирования прав для выбранной роли (рис. 7.37).
Рис. 7.38. Установка прав для группы однотипных объектов конфигурации
В этом случае назначаются одинаковые права всем объектам, созданным на основании выбранного шаблона. Права применяются к объектам данных информационной базы, которые описаны объектами конфигурации, созданными на основании выбранного шаблона. Права могут быть установлены и на отдельный объект конфигурации (рис. 7.39).
Рис. 7.37. Окно редактирования прав для роли
Для настройки прав необходимо в дереве конфигурации выбрать объект (левое поле) и в списке прав (правое верхнее поле) установить или снять отметку рядом с настраиваемым правом. Права можно установить на уровне прототипов платформы. Для этого в дереве конфигурации необходимо выбрать узел, представляющий соответствующий шаблон объектов (рис. 7.38).
Рис. 7.39. Установка прав на объект конфигурации
В этом случае права применяются к объектам данных информационной базы, которые описаны выбранным объектом конфигурации. Права также могут быть установлены на объекты, подчиненные выбранному (как в целом для всех подчиненных объектов одного типа, так и индивидуально на каждый из подчиненных объектов) – реквизиты, табличные части и команды (рис. 7.40).
162
Профессиональная разработка в системе «1С:Предприятие 8»
Настраиваем доступность команд по ролям А теперь давайте создадим роль Менеджер по ценам. Эта роль будет назначена пользователям, которые выполняют операции по управлению ценами. Для добавления роли используем команду Добавить контекстного меню узла Роли дерева конфигурации (рис. 7.42).
Рис. 7.40. Установка прав на подчиненный объект конфигурации
В этом случае права применяются только к командам, подчиненным объекту, или к данным, хранящимся в подчиненных информационных структурах. Права, установленные на объект конфигурации, имеют приоритет перед правами, установленными на его подчиненные объекты.
Рис. 7.42. Добавление роли
В результате будет добавлен объект конфигурации и откроется окно свойств и окно редактирования прав (рис. 7.43).
Кроме прав, применяемых для объектов конфигурации, существует набор прав, применяемый к конфигурации в целом. Список этих прав отображается при выборе корневого узла дерева конфигурации (рис. 7.41).
Рис. 7.41. Набор прав конфигурации
Эти права определяют возможность выполнения административных функций, использования внешних отчетов и обработок, доступа к журналу регистрации и др. Том 1
Рис. 7.43. Окно свойств и окно редактирования прав роли
163
Глава 7. Командный интерфейс прикладных решений В группе свойств Основные зададим значения свойств роли: ■■ Имя – «Менеджер по ценам»; ■■ Синоним – оставим автоматически сформированный синоним; ■■ Комментарий – не будем заполнять. По умолчанию для вновь созданной роли все права на все существующие объекты конфигурации сброшены, то есть запрещены любые действия с данными. Давайте настроим права на доступ к объектам, используемым в подсистеме управления ценами. Прежде всего, в правах на конфигурацию установим право Тонкий клиент (рис. 7.44). Установка этого права позволит пользователю запускать тонкий клиент «1С:Предприятия».
Рис. 7.45. Установка права «Просмотр» для подсистемы «Ценообразование» у роли «Менеджер по ценам»
Рис. 7.44. Право на запуск тонкого клиента
Как и для других объектов конфигурации, для подсистем определены права. Доступность раздела в командном интерфейсе настраивается для роли установкой права Просмотр подсистемы, соответствующей разделу. Проверим право Просмотр для подсистемы Ценообразование и при необходимости установим его (рис. 7.45). Установленное право обеспечит доступность раздела Ценообразование в командном интерфейсе пользователя с ролью Менеджер по ценам. Для справочника Товары установим право Просмотр – пользователь должен иметь возможность просматривать и выбирать товары, для которых он будет устанавливать/изменять цены (рис. 7.46). ПРИМЕЧАНИЕ
Рис. 7.46. Установка права «Просмотр» для справочника «Товары» у роли «Менеджер по ценам»
Для справочника Виды цен установим все права – пользователь должен иметь полный доступ к этому справочнику для формирования используемых видов цен (рис. 7.47).
При установке интерактивного права Просмотр автоматически устанавливается основное право Чтение.
164
Профессиональная разработка в системе «1С:Предприятие 8»
Настраиваем доступность команд по ролям ПРИМЕЧАНИЕ
Перед созданием пользователя необходимо обновить конфигурацию базы данных. Это можно сделать, выбрав команду Конфигурация Обновить конфигурацию базы данных.
Система управления пользователями Для регистрации пользователей и назначения для них ролей используется система управления пользователями. Для знакомства с этой системой добавим в наше приложение нового пользователя, который будет осуществлять управление ценами. Командой Администрирование Пользователи откроем список пользователей и воспользуемся командой Добавить контекстного меню этого списка (рис. 7.49). Рис. 7.47. Установка всех прав для справочника «Виды цен» у роли «Менеджер по ценам»
Для регистра сведений Цены товаров также установим все права – пользователь должен иметь полный доступ к этому регистру для управления ценами в разрезе товаров и видов цен (рис. 7.48).
Рис. 7.49. Добавление нового пользователя
В открывшемся окне определим значения свойств учетной записи добавляемого пользователя. На закладке Основные (рис. 7.50) заполним свойства: ■■ Имя – краткое имя пользователя, которое вводится в диалоге аутентификации пользователя (должно быть уникальным среди всех пользователей данного прикладного решения); задаем имя «Менеджер по ценам».
Рис. 7.48. Установка всех прав для регистра сведений «Цены товаров» у роли «Менеджер по ценам»
Мы определили набор прав для пользователей, выполняющих операции по ценообразованию. Теперь нам необходимо создать пользователя и назначить ему вновь созданную роль. Перейдем к решению этой задачи. Том 1
Рис. 7.50. Назначение пользователю имени
165
Глава 7. Командный интерфейс прикладных решений На закладке Прочие (рис. 7.51) заполним свойства: ■■ Доступные роли – указываются те роли, которые есть у пользователя при работе с прикладным решением; помечаем роль «Менеджер по ценам».
Рис. 7.53. Для пользователя «Менеджер по ценам» справочник «Товары» доступен, а справочник «Контрагенты» недоступен Рис. 7.51. Назначение роли пользователю
ПРИМЕЧАНИЕ
Права складываются по правилам логического ИЛИ – если хотя бы в одной из доступных ролей право на выполнение операции установлено, то пользователь может выполнить операцию.
Все дело в том, что для справочника Контрагенты у роли Менеджер по ценам все права сброшены – для вновь создаваемой роли права на существующие объекты по умолчанию не устанавливаются. Чтобы в списке отображался поставщик, достаточно установить у роли основное право Чтение для справочника Контрагенты (рис. 7.54).
Сохраним сведения о пользователе, нажав кнопку OK, и запустим наше приложение от имени созданного пользователя (рис. 7.52).
Рис. 7.52. Запуск приложения от имени пользователя «Менеджер по ценам»
Для менеджера по ценам доступен раздел глобального командного интерфейса Ценообразование и команды этого раздела. Выберем команду Товары для открытия списка товаров – в рабочей области открылась форма списка справочника. Развернем группу товаров Обувь. В колонке Поставщик вместо данных присутствует сообщение Объект не найден… (рис. 7.53). Рис. 7.54. Разрешение пользователю «Менеджер по ценам» читать справочник «Контрагенты»
Теперь при открытии списка товаров в колонке Поставщик отображается наименование поставщика (рис. 7.55).
166
Профессиональная разработка в системе «1С:Предприятие 8»
Настраиваем доступность команд по ролям ВНИМАНИЕ!
При установке прав на объект конфигурации права на его подчиненные команды автоматически не устанавливаются.
Исправим ситуацию установкой права Просмотр для подчиненной команды (рис. 7.57).
Рис. 7.55. Для пользователя «Менеджер по ценам» доступны справочники «Товары» и «Контрагенты»
ПРИМЕЧАНИЕ
Для того чтобы форма просмотра товара открывалась, необходимо установить право Чтение для плана видов характеристик Виды характеристик товаров и регистра сведений Характеристики товаров. Для того чтобы в форме присутствовала картинка с изображением товара, нужно установить право Просмотр на справочник Хранимые файлы.
Пойдем дальше и откроем форму товара. Пользователь, управляющий ценами, должен иметь возможность распечатать штрихкод товара. Однако в открытой форме нет команды, позволяющей выполнить эту операцию (рис. 7.56).
Рис. 7.57. Разрешение пользователю «Менеджер по ценам» использовать подчиненную команду «Печать штрихкода»
Сохраним изменения, запустим демонстрационную базу в режиме 1С:Предприятие от имени пользователя Менеджер по ценам и опять откроем форму товара. Теперь за счет установленного права в ней присутствует команда Печать штрихкода (рис. 7.58).
Рис. 7.56. В форме товара отсутствует команда печати штрихкода
Непосредственно печать штрихкода выполняет команда Печать штрихкода, подчиненная справочнику Товары. А использовать эту команду для роли запрещено – право Просмотр не установлено. Том 1
Рис. 7.58. Данные по контрагентам доступны, данные по файлам недоступны
167
Глава 7. Командный интерфейс прикладных решений Все, мы полностью закончили настройку прав для роли Менеджер по продажам. На текущий момент для управления ценами мы обеспечили формирование отдельного раздела командного интерфейса, формирование набора команд для этого раздела и ролевую настройку прав пользователей, занимающихся ценообразованием.
Редактирование командного интерфейса Одним из условий комфортной работы пользователя с командным интерфейсом является «минимализм» последнего – в идеале пользователь должен иметь удобный доступ только к тем командам, которые необходимы для решения его задач. В разделе «Настраиваем доступность команд по ролям» (стр. 161) мы рассмотрели механизм ролевой настройки доступности команд в командном интерфейсе. Этот механизм позволяет эффективно добиться выполнения условия минимализации командного интерфейса – доступны только те команды, которые необходимы пользователю. С другой стороны, хотелось бы обеспечить пользователю максимально комфортные условия для работы. Ведь среди доступных команд есть такие, к которым пользователи обращаются очень часто, и такие, доступ к которым необходим изредка. Хорошо бы иметь возможность не отображать в командном интерфейсе вторую группу команд, оставив пользователю возможность обращаться к ним при необходимости.
■■ настраивается пользователем – в режиме эксплуатации каждый пользователь настраивает видимость команд, исходя из собственных предпочтений. При этом пользователи с одной и той же ролью могут определить различный состав видимых по умолчанию команд. ПРИМЕЧАНИЕ
Возможности настройки командного интерфейса пользователем будут рассмотрены в разделе «Пользовательская настройка интерфейса», стр. 187. Сейчас же мы рассмотрим первые два уровня.
В качестве отправной точки мы будем использовать демонстрационную базу «Командный интерфейс прикладных решений, пример 3». Результат выполняемых действий можно посмотреть в демонстрационной базе «Командный интерфейс прикладных решений, пример 4».
Автоматическое размещение и видимость команд На данный момент пользователю с ролью Менеджер по ценам в разделе Ценообразование видимы команды открытия форм списков в панели навигации. Панель же действий вообще не содержит видимых команд и не отображается (рис. 7.59).
Для решения этой задачи предназначен механизм настройки размещения и видимости команд по ролям. Он позволяет оптимальным образом настроить командный интерфейс для различных ролей пользователей – показать часто используемые команды и скрыть те, которые используются редко. ВНИМАНИЕ!
Видимость команды вступает в силу только тогда, когда команда доступна. Недоступные для роли команды не попадут в командный интерфейс независимо от настройки видимости.
При редактировании размещения и видимости команд можно выделить три уровня настройки: ■■ не настраивается – система автоматически разместит команды в командном интерфейсе и настроит их видимость; ■■ настраивается разработчиком – в режиме конфигурирования настраивается размещение и видимость команд в разрезе ролей. Эта настройка будет настройкой по умолчанию, используемой для всех пользователей с определенной ролью;
168
Рис. 7.59. Автоматически сформированный набор видимых команд раздела «Ценообразование»
А где же команды создания новых объектов? Эти команды «спрятаны». Мы не вмешивались в процесс размещения и установки видимости команд. Система разместила команды командного интерфейса и установила их видимость автоматически. Подробнее
Правила, которым следует система при размещении команд командного интерфейса, описаны в разделе «Правила размещения глобальных команд», стр. 173.
Профессиональная разработка в системе «1С:Предприятие 8»
Редактирование командного интерфейса Правила автоматической настройки видимости команд приведены в документации «1С:Предприятие 8.2. Руководство разработчика», раздел 6.2.7.
Такая автоматическая видимость команд объясняется достаточно просто. В общем случае просмотр списков требуется многим пользователям, а вот операция создания новых элементов выполняется реже. Поэтому проще настроить видимость команд создания элементов для нескольких пользователей, чем настраивать видимость команд открытия списков для многих пользователей. Как же создавать новые объекты (элементы справочников, документы и т. д.), когда пользователь не видит соответствующих команд? В этом случае можно воспользоваться командами, предоставляемыми формами списков. Например, новый вид цен можно создать из формы списка справочника Виды цен (рис. 7.60).
Кроме видимости, следует обратить внимание и на порядок команд. Сейчас команды в панели навигации расположены не очень удачно. Самой важной для пользователя является команда открытия списка цен на товары, а она расположена в самом низу списка. Хотелось бы, чтобы эта команда отображалась первой. Для решения подобных задач система «1С:Предприятие» предоставляет редакторы, позволяющие настраивать размещение и видимость команд в командном интерфейсе в соответствии с требованиями прикладного решения. ВНИМАНИЕ!
Редактирование командного интерфейса не позволит добавить или исключить команды. Эта операция позволит лишь оптимизировать командный интерфейс – обеспечить удобство работы для различных групп пользователей.
Однако прежде чем заниматься настройкой, давайте познакомимся с автоматическим размещением и видимостью команд.
Категории и группы команд На размещение команд командного интерфейса влияет категория команды. По сути, категория – это еще одна классификация команд. В ней команды разделяются по двум признакам: зависимость команды от дополнительных данных и назначение команды. По зависимости от данных команды делятся: ■■ на независимые, ■■ параметризуемые. Рис. 7.60. Работа с видами цен из формы списка
При таком доступе к команде создания нового объекта пользователь должен выполнить дополнительное действие – открыть форму списка. Для справочника Виды цен это достаточно удобно – состав видов цен изменяется редко, и, соответственно, пользователь редко обращается к команде создания нового элемента. А вот команда назначения цены на товар нужна часто, и выполнение дополнительного действия может быть неудобно. Для обеспечения более комфортного доступа к команде ее необходимо сделать видимой в командном интерфейсе. Еще одной командой, видимость которой стоит настроить, является команда Товары, открывающая список товаров для просмотра.
Том 1
По назначению команды делятся: ■■ на навигационные, ■■ команды действия. Независимые команды не требуют для своего исполнения никаких дополнительных данных. Это значит, что результат выполнения такой команды будет одинаков независимо от того, из какого окна (или формы) вызвана команда, какие данные обрабатываются пользователем в момент вызова команды и т. д. К независимым относятся команды открытия списка справочника, создания нового документа и др. Например, в результате выполнения навигационной команды Товары в рабочей области основного окна приложения открывается форма списка справочника Товары (рис. 7.61). При этом дополнительная информация для открытия списка команде не требуется.
169
Глава 7. Командный интерфейс прикладных решений Различие между независимыми и параметризуемыми командами можно продемонстрировать на следующем примере. Предположим, нам необходимо получить отчет по остаткам товаров на складе Большой. Мы можем выбрать раздел Товарные запасы и воспользоваться независимой командой Остатки товаров (рис. 7.63).
Рис. 7.61. Независимая команда не требует параметра
Параметризуемые команды для своего выполнения требуют дополнительные данные – параметры выполнения, которые определяют результат исполнения команды. К параметризуемым относятся команды открытия списка подчиненного справочника (параметр – ссылка на элемент справочника владельца), создания нового документа на основании (параметр – объект, на основании которого создается документ) и др. ВНИМАНИЕ!
Источником значения для параметра могут служить только данные формы. Поэтому параметризуемые команды должны располагаться в форме. Причем в той, которая содержит данные подходящего для параметра типа.
Например, команда Файлы, вызванная из формы элемента справочника Товары, откроет (в том же окне) форму списка элементов справочника Хранимые файлы (рис. 7.62). В списке будут отображены элементы, подчиненные редактируемому элементу справочника Товары.
Рис. 7.63. Вызов отчета независимой командой «Остатки товаров»
Но в этом случае нам необходимо в настройках отчета выбрать интересующий нас склад. Для исключения этапа выбора склада мы можем вызвать отчет из формы списка складов. Для этого выделяем в списке интересующий нас склад и выбираем параметризуемую команду Остатки по складу (рис. 7.64). В этом случае нет необходимости выбирать склад в настройках отчета – он передан команде как параметр. Навигационные команды предназначены для навигации пользователя по функциональности прикладного решения, то есть для выбора наиболее подходящего контекста для решения текущей задачи. Исполнение навигационной команды обычно приводит к открытию новой формы в окне (основном или вспомогательном), из которого была вызвана команда. Если в рабочей области окна отображалась какая-либо форма, то она замещается на новую. ПРИМЕЧАНИЕ
Рис. 7.62. Параметризуемая команда требует параметр
170
Навигационная команда может привести к открытию нового окна, если при выборе команды левой кнопкой мыши удерживать нажатой клавишу Shift. Еще один способ открыть новое окно – вызвать контекстное меню команды.
Профессиональная разработка в системе «1С:Предприятие 8»
Редактирование командного интерфейса
Рис. 7.65. Навигационная команда
Рис. 7.64. Вызов отчета параметризуемой командой «Остатки по складу»
Навигационными могут быть как независимые, так и параметризуемые глобальные команды. К навигационным относится команда перехода к форме списка справочника – независимая; команда перехода к форме списка подчиненного справочника – параметризуемая. Например, навигационная команда Продажи, вызванная из основного окна приложения, откроет форму списка документов Расход товара в рабочей области этого окна (рис. 7.65). Команды действия предназначены для непосредственного выполнения какой-либо задачи по обработке данных. Вследствие «переключения» пользователя на выполнение очередной операции команды действия открывают формы для работы с данными в отдельном вспомогательном окне приложения. К командам действия относится команда создания нового документа – независимая; команда вызова отчета об остатках по складу – параметризуемая. Например, команда Продажа откроет новое вспомогательное окно для ввода нового документа Расход товара, и пользователь перейдет от навигации по приложению к обработке данных документа (рис. 7.66).
Том 1
Рис. 7.66. Команда действия
Различие между командами навигации и командами действия можно продемонстрировать на следующем примере. Предположим, нам необходимо создать новый вид цен. Мы можем выбрать раздел Товарные запасы и воспользоваться командой действия Вид цен (рис. 7.67).
171
Глава 7. Командный интерфейс прикладных решений Каждая из глобальных команд с точки зрения рассмотренной классификации принадлежит одной из четырех предопределенных категорий: ■■ панель навигации – независимые навигационные команды; ■■ панель действий – независимые команды действий; ■■ панель навигации формы – параметризуемые навигационные команды; ■■ командная панель формы – параметризуемые команды действий. ПРИМЕЧАНИЕ
Рис. 7.67. Команда действия – для обработки данных
ПРИМЕЧАНИЕ
Для команды создания нового вида цен предварительно была выполнена настройка видимости.
Но мы не можем сказать с уверенностью, что создаваемый вид цен еще не существует. Чтобы убедиться, что такого вида цен нет, необходимо просмотреть список видов цен, то есть изменить состав отображаемой в окне информации. Это можно сделать навигационной командой Виды цен. Убедившись в отсутствии требуемого вида цен, для его создания можно воспользоваться командой действия Вид цены или командой формы Создать (рис. 7.68).
Для категорий отсутствуют специальные названия. Именование категорий команд реализовано по «территориальному» признаку – в качестве имени категории выступает название панели, в которой обычно располагаются команды, принадлежащие этой категории.
Команды каждой категории объединены в стандартные группы (табл. 7.1). Таблица 7.1. Стандартные категории и группы команд Категория команд
Группы команд
Панель навигации
Важное, Обычное, См. также Создать, Отчеты, Сервис Важное, Перейти, См. также Важное, Создать на основании
Панель действий Панель навигации формы Командная панель формы
Группа определяет «вес» команды – ее важность для задач, решаемых пользователем. При необходимости для каждой категории разработчик может расширить состав групп. Для определения произвольных групп предназначены общие объекты конфигурации класса Группы команд. Подробнее
Раздел «Произвольные группы», стр. 208.
Рис. 7.68. Навигационная команда – для формирования контекста обработки данных
172
Профессиональная разработка в системе «1С:Предприятие 8»
Редактирование командного интерфейса
Правила размещения глобальных команд Для каждой из категорий предопределено место для автоматического размещения команд, принадлежащих этой категории. Правила размещения команд командного интерфейса представлены в табл. 7.2. Таблица 7.2. Размещение команд командного интерфейса Команды
Независимые
Категория: панель навигации. Навигационные Размещение: панель навигации основного окна Категория: панель действий. Размещение: панель действий Действия основного окна
Параметризуемые
Категория: панель навигации формы. Размещение: панель навигации вспомогательного окна Категория: командная панель формы. Размещение: командная панель формы
Порядок размещения групп соответствует их порядку в табл. 7.1. По умолчанию порядок команд внутри группы определяется их текстовым представлением – команды размещаются в алфавитном порядке. В панели навигации основного окна размещаются независимые навигационные глобальные команды (рис. 7.69).
■■ Обычное – команды перехода к функциональности, имеющей обычный приоритет. Визуально команды группы Важное выделяются жирным начертанием. После всех подразделов выводится третья группа команд См. также. В этой группе обычно размещаются команды перехода к наименее используемой функциональности прикладного решения. Эта группа имеет заголовок и отделена от остальных групп горизонтальной чертой. Особенностью группы См. также является то, что в ней собраны команды как раздела, так и всех его подразделов. Эти команды выводятся единым списком без структурирования по подразделам. Команды также могут быть размещены в произвольных группах. Эти группы образуются объектами конфигурации Группа команд. Произвольные группы не имеют заголовков, а команды, им принадлежащие, размещаются в стандартной группе Обычное и отделены от других команд пустой строкой. В панели действий основного окна глобальные команды действий (рис. 7.70).
размещаются
независимые
Рис. 7.69. Категория команд «Панель навигации» основного окна
Рис. 7.70. Категория команд «Панель действий» основного окна
В выбранном разделе навигационные команды структурируются по подразделам. Каждый из подразделов, образованный подсистемами второго и следующих уровней иерархии, образует отдельный блок команд и выделяется заголовком.
Команды в панели действий могут размещаться в одной из трех стандартных групп:
При размещении команд сначала выводятся команды раздела, а ниже – блоки команд каждого из подразделов. Команды раздела и каждого из подразделов могут размещаться в двух стандартных группах: ■■ Важное – команды перехода к наиболее важной или наиболее часто используемой функциональности; Том 1
■■ Создать – команды открытия окон с формами ввода данных; ■■ Отчеты – команды открытия окон с формами отчетов; ■■ Сервис – команды открытия окон с формами обработок. ПРИМЕЧАНИЕ
В панели действий команды по подразделам не структурируются. В группах объединены команды, принадлежащие как подсистеме верхнего уровня иерархии, так и всем подчиненным подсистемам.
173
Глава 7. Командный интерфейс прикладных решений Как и в панели навигации, команды могут быть размещены и в произвольных группах. Эти группы располагаются после стандартных и представлены синонимом соответствующего объекта конфигурации Группа команд.
ботка данных, отображаемых в форме. Например, команда проведения документа (рис. 7.72).
В панели навигации вспомогательного окна (при наличии этой панели в окне) размещаются параметризуемые навигационные глобальные команды. С использованием этих команд осуществляется навигация по данным, логически связанным с данными, обрабатываемыми в форме. Например, команда перехода к записям регистра, подчиненным редактируемому документу (рис. 7.71).
Рис. 7.72. Категория команд «Командная панель формы» вспомогательного окна
Команды в командной панели формы могут размещаться в одной из двух стандартных групп:
Рис. 7.71. Категория команд «Панель навигации формы» вспомогательного окна
ПРИМЕЧАНИЕ
Для наглядного представления группировки команд состав групп изменен по сравнению с демонстрационной базой.
Команды в панели навигации вспомогательного окна могут размещаться в одной из трех стандартных групп: ■■ Важное – команды перехода к наиболее важным или наиболее часто используемым связанным данным; ■■ Перейти – команды перехода к данным, имеющим обычный приоритет; ■■ См. также – команды перехода к информационным (справочным) данным. Команды также могут быть размещены в произвольных группах. Произвольные группы не имеют заголовков, а команды, им принадлежащие, размещаются в стандартной группе Перейти и ничем не отделяются от команд этой группы. В командной панели формы размещаются параметризуемые глобальные команды действий. С использованием этих команд выполняется обра-
174
■■ Важное – команды, исполняющие наиболее важные или наиболее часто выполняемые действия; ■■ Создать на основании – команды, выполняющие создание новых объектов на основании того объекта, который обрабатывается в форме. Группа Создать на основании в командной панели формы отображается в виде меню. Команды также могут быть размещены в произвольных группах. Произвольные группы отображаются в виде отдельных меню и могут быть представлены текстом, картинкой или картинкой и текстом (в зависимости от значения свойства Отображение объекта конфигурации Группа команд). Разобравшись с автоматическим размещением команд, перейдем к знакомству со средствами настройки размещения и видимости команд.
Система настройки командного интерфейса Для настройки командного интерфейса платформа предоставляет специализированные редакторы и обеспечивает сохранение выполненных настроек. Для хранения настроек командного интерфейса конфигурации используется свойство Командный интерфейс корневого объекта конфигурации (рис. 7.73). Профессиональная разработка в системе «1С:Предприятие 8»
Редактирование командного интерфейса
Рис. 7.73. Свойство конфигурации «Командный интерфейс»
В этом свойстве сохраняются: ■■ настройка порядка следования разделов; ■■ настройка видимости разделов, в том числе в разрезе ролей. Для хранения настроек командного интерфейса раздела используется свойство Командный интерфейс соответствующей подсистемы (рис. 7.74).
Рис. 7.75. Свойство конфигурации «Командный интерфейс рабочего стола»
Для редактирования командного интерфейса система предоставляет специализированные инструменты: ■■ ■■ ■■ ■■
редактор командного интерфейса, редактор командного интерфейса конфигурации, редактор командного интерфейса рабочего стола, редактор «Все подсистемы».
Основные приемы работы во всех редакторах совпадают. Мы их подробно рассмотрим применительно к редактору командного интерфейса.
Редактор командного интерфейса Редактор командного интерфейса предназначен для редактирования командного интерфейса конкретного раздела (подсистемы).
Рис. 7.74. Свойство подсистемы «Командный интерфейс»
Редактор можно открыть либо гиперссылкой Открыть свойства подсистемы Командный интерфейс, либо из контекстного меню выбрать команду Открыть командный интерфейс (рис. 7.76).
В этом свойстве сохраняются: ■■ настройка расположения команд в группах команд; ■■ настройка порядка следования команд; ■■ настройка видимости команд, в том числе в разрезе ролей. Хранение настроек в свойстве подсистемы позволяет независимо настраивать каждый из разделов (подразделов) командного интерфейса. Для раздела Рабочий стол настройки сохраняются в свойстве Командный интерфейс рабочего стола корневого объекта конфигурации (рис. 7.75). При работе со свойством Командный интерфейс необходимо помнить, что оно будет непустым (то есть будет хранить настройки) только в том случае, когда разработчик выполнил настройку размещения и видимости команд, отличающуюся от автоматически используемой системой. Том 1
Рис. 7.76. Доступ к редактору командного интерфейса подсистемы
175
Глава 7. Командный интерфейс прикладных решений В результате выполнения команды откроется окно редактора. В окне редактора отображается дерево команд, доступных в той подсистеме, для которой вызван редактор (рис. 7.77).
Рис. 7.77. Окно редактора командного интерфейса подсистемы
Для настройки размещения команд в глобальном командном интерфейсе редактор предоставляет следующие возможности: ■■ можно изменить порядок следования команд внутри группы; ■■ можно изменить группу, в которой будет отображаться команда.
Группу, в которой будет отображаться команда, можно изменить командой Переместить команду (вызвав ее из контекстного меню или из командной панели) или перетащить команду в нужную группу мышью (рис. 7.79).
Рис. 7.79. Настройка принадлежности команды к группе
ПРИМЕЧАНИЕ
Переместить команду в группу, принадлежащую другой панели (имеющую другую категорию), редактор не позволит.
Порядок следования команды внутри группы можно изменять командами Вверх и Вниз (вызвав их из контекстного меню или из командной панели) или перетаскивая команду на нужную позицию мышью (рис. 7.78).
При установке порядка следования команд, отличающегося от автоматического, рядом с группой будет отображаться текст Ручной порядок (рис. 7.80).
Рис. 7.78. Настройка порядка следования команд
Рис. 7.80. Признак ручного изменения порядка следования команд
176
Профессиональная разработка в системе «1С:Предприятие 8»
Редактирование командного интерфейса Например, перетащили команду Товары в первую позицию группы ПанельНавигации.Обычное (см. рис. 7.80). В результате рядом с этой группой появился текст Ручной порядок. Если необходимо вернуться к автоматическому порядку следования команд внутри группы, то это можно сделать командой Восстановить автоматический порядок команд из контекстного меню группы (рис. 7.81).
Рис. 7.82. Настройка общей видимости команд
Рис. 7.81. Восстановление автоматического размещения команд
Например, для группы ПанельНавигации.Обычное выполнено восстановление автоматического порядка команд (см. рис. 7.81). В результате в этой группе команды упорядочились по алфавиту. Для настройки видимости по умолчанию команд в командном интерфейсе редактор предоставляет следующие возможности: ■■ можно настроить общую видимость команды, ■■ можно настроить видимость команды в разрезе ролей. Общая видимость команды используется для тех ролей, у которых не выполняется индивидуальная настройка видимости этой команды. Для изменения общей видимости команды необходимо установить или снять флажок в колонке Видимость для требуемой команды (рис. 7.82). Для общей видимости может быть задано только два значения: ■■ команда видима – флажок установлен; ■■ команда невидима – флажок сброшен. При необходимости редактор позволяет задать видимость по ролям – отдельно для каждой роли, определенной в конфигурации. Для изменения видимости команды для роли необходимо установить или снять флажок в соответствующей колонке группы Видимость по ролям (рис. 7.83). Том 1
Рис. 7.83. Настройка видимости команд по ролям
Для видимости по ролям может быть задано три значения: ■■ команда видима – белый фон, флажок установлен; ■■ команда невидима – белый фон, флажок сброшен; ■■ использовать общую видимость – серый фон, флажок установлен. Значения устанавливаются щелчком левой клавиши мыши и перебираются последовательно в цикле. В командном интерфейсе пользователя команда будет видима, если хотя бы для одной из ролей, назначенных этому пользователю, видимость для данной команды установлена.
177
Глава 7. Командный интерфейс прикладных решений При необходимости вернуться к автоматическим размещению и видимости команд можно воспользоваться командой контекстного меню Установить свойства по умолчанию или одноименной кнопкой командной панели (рис. 7.84).
Рис. 7.85. Установка фильтра на видимые команды
Рис. 7.84. Установка свойств команды по умолчанию
Редактор командного интерфейса поддерживает групповую настройку размещения с помощью множественного выделения команд в списке. Для выделения диапазона команд необходимо выделить первую команду из диапазона, а затем, удерживая нажатой клавишу Shift, выделить последнюю команду из диапазона. В результате будут выбраны все команды, расположенные между первой и последней (включая граничные). Для выделения нескольких команд, следующих не подряд, необходимо выделить первую команду, а затем, удерживая нажатой клавишу Ctrl, отмечать необходимые команды. В результате будут выделены все отмеченные команды. С группой команд можно выполнять те же операции, что и с отдельной командой. При необходимости разработчик может настроить состав отображаемых команд и колонки списка, в котором команды отображаются. Для того чтобы в списке команд отобразить только видимые по умолчанию команды, следует нажать кнопку командной панели Скрыть невидимые по умолчанию (рис. 7.85). При этом также будут скрыты группы без команд. Для того чтобы в списке команд отобразить только команды, доступные некоторым ролям (возможно, одной), следует задать эти роли в поле Отбор по ролям (рис. 7.86).
178
Рис. 7.86. Установка фильтра на команды, доступные роли
В списке будут отображаться только те команды, которые доступны хотя бы одной из выбранных ролей (рис. 7.87). Если при отборе по ролям установлен отбор только видимых команд, то будут отображены только те команды, которые по умолчанию видимы хотя бы одной роли. Для отключения отбора по ролям в поле отбора нужно выбрать значение Не установлен. Список выбора позволяет быстро включать один из нескольких последних установленных отборов (рис. 7.88). Для настройки колонок списка команд необходимо вызвать команду контекстного меню Настройка списка (рис. 7.89). Профессиональная разработка в системе «1С:Предприятие 8»
Редактирование командного интерфейса
Редактор командного интерфейса конфигурации Редактор командного интерфейса конфигурации предназначен для редактирования порядка следования и видимости разделов в панели разделов. Редактор можно открыть либо гиперссылкой Открыть свойства конфигурации Командный интерфейс, либо из контекстного меню выбрать команду Открыть командный интерфейс (рис. 7.90).
Рис. 7.87. Команды, доступные роли «Менеджер по ценам»
Рис. 7.90. Доступ к редактору командного интерфейса конфигурации
В результате выполнения команды откроется окно редактора (рис. 7.91). В этом окне отображается список разделов командного интерфейса, соответствующих подсистемам первого уровня иерархии с установленным свойством Включать в командный интерфейс. Рис. 7.88. История отбора и отключение отбора команд
Рис. 7.91. Окно редактора командного интерфейса конфигурации
Редактор позволяет: Рис. 7.89. Окно настройки отображения колонок редактора
В открывшемся окне можно настроить состав, размер и положение колонок списка команд. Том 1
■■ упорядочить разделы – в установленном порядке разделы будут показаны в панели разделов; ■■ установить общую видимость раздела и его видимость по ролям.
179
Глава 7. Командный интерфейс прикладных решений Приемы работы при настройке командного интерфейса конфигурации совпадают с приемами работы при настройке командного интерфейса подсистемы.
Редактор командного интерфейса рабочего стола Редактор командного интерфейса рабочего стола предназначен для редактирования порядка следования и видимости команд рабочего стола. Редактор можно открыть либо гиперссылкой Открыть свойства конфигурации Командный интерфейс рабочего стола, либо из контекстного меню выбрать команду Открыть командный интерфейс рабочего стола (рис. 7.92).
При редактировании командного интерфейса рабочего стола в окне редактора отображается дополнительное табличное поле (слева). Это поле содержит иерархический список команд конфигурации, которые могут быть добавлены в командный интерфейс рабочего стола. ПРИМЕЧАНИЕ
Если в конфигурации отсутствуют подсистемы или у всех подсистем свойство Включать в командный интерфейс сброшено, иерархический список команд не отображается.
В список доступных команд включаются: ■■ общие команды без параметров, для которых в свойстве Группа указана панель и группа команд этой панели; ■■ стандартные команды объектов конфигурации, для которых установлено свойство Использовать стандартные команды; ■■ команды объектов конфигурации, определенные в подчиненной группе Команды. Редактирование командного интерфейса выполняется табличном поле редактора. Возможности и приемы вания командного интерфейса рабочего стола полностью возможностям и приемам редактирования командного подсистемы.
в правом редактироаналогичны интерфейса
Рис. 7.92. Доступ к редактору командного интерфейса рабочего стола
Редактор «Все подсистемы»
В результате выполнения команды откроется окно редактора (рис. 7.93).
Редактор «Все подсистемы» предназначен для управления подсистемами конфигурации, в том числе и их командными интерфейсами. Для вызова редактора необходимо спозиционироваться на узле Подсистемы ветки Общие и из контекстного меню выбрать команду Все подсистемы (рис. 7.94).
Рис. 7.93. Окно редактора командного интерфейса рабочего стола
180
Рис. 7.94. Вызов редактора подсистем
Профессиональная разработка в системе «1С:Предприятие 8»
Редактирование командного интерфейса В результате выполнения команды откроется окно редактора (рис. 7.95).
Рис. 7.97. Управление составом подсистемы Рис. 7.95. Окно редактора подсистем
Редактор Все подсистемы визуально отличается от редактора командного интерфейса подсистемы наличием дополнительных табличных полей: Подсистемы и Состав (слева, сверху вниз). В списке подсистем отображается дерево подсистем конфигурации. Используя командную панель этого списка (или контекстное меню), можно управлять подсистемами – добавлять, удалять, редактировать свойства, изменять порядок следования и иерархию (рис. 7.96).
Командный интерфейс подсистемы, выбранной в дереве подсистем, редактируется в табличном поле Командный интерфейс (правое поле). При необходимости, используя команду контекстного меню списка подсистем, из редактора подсистем можно открыть отдельный редактор командного интерфейса подсистемы. Приемы редактирования командного интерфейса одинаковы в обоих редакторах. В редакторе Все подсистемы присутствует возможность перехода от команды к ее источнику в дереве объектов конфигурации. Для этого из контекстного меню списка команд нужно выбрать пункт Найти в дереве (рис. 7.98). В результате в дереве конфигурации окна Конфигурация будет выделен объект, предоставивший команду.
Рис. 7.96. Управление подсистемами
В списке Состав отображаются объекты конфигурации, включенные в подсистему, выбранную в дереве подсистем. Используя командную панель этого списка, можно управлять составом объектов, включенных в подсистему (рис. 7.97). Том 1
Рис. 7.98. Переход к источнику команды
181
Глава 7. Командный интерфейс прикладных решений
Ручное размещение и видимость команд А теперь вернемся к нашей задаче и настроим расположение и видимость команд в разделе Ценообразование.
Для решения этой задачи воспользуемся настройкой видимости в разрезе ролей. Для команды Товары снимем флажок не в колонке Видимость, а в колонке Менеджер по ценам (рис. 7.100).
Первое, что мы сделаем, это отобразим в командном интерфейсе команду назначения цены на товар. Назначение цены – это создание записи в регистре сведений Цены товаров. Откроем редактор командного интерфейса подсистемы. В колонке Видимость для команды Цена на дату: создать установим флажок (рис. 7.99).
Рис. 7.100. Установка ролевой видимости по умолчанию для команды «Товары»
В результате для пользователя Администратор команда Товары включена в командный интерфейс, а для пользователя Менеджер по ценам команда не включена. Рис. 7.99. Установка общей видимости по умолчанию для команды «Цена на дату: создать»
Теперь эта команда включена в командный интерфейс, причем для всех ролей (на рис. 7.99 показаны командные интерфейсы пользователей с ролями Администратор и Менеджер по ценам). Далее необходимо скрыть команду открытия списка товаров для пользователей с ролью Менеджер по ценам. Для остальных ролей команда должна остаться доступной.
182
И последней настройкой мы изменим порядок следования команд в панели навигации. Сейчас все команды панели навигации расположены в группе ПанльНавигации.Обычное в алфавитном порядке. Нас такое расположение не устраивает. Команду Цены товаров переместим в группу ПанельНавигации.Важное (рис. 7.101). В отличие от видимости, порядок размещения команд в разрезе ролей не настраивается. И для пользователя Администратор, и для пользователя Менеджер по ценам команда Цены товаров располагается в одном и том же месте (рис. 7.102).
Профессиональная разработка в системе «1С:Предприятие 8»
Влияние функциональных опций на командный интерфейс ВНИМАНИЕ!
В отличие от настройки доступности команд по ролям, настройка по функциональным опциям является единой для всех ролей.
Механизм функциональных опций Использование функциональных опций предполагает, что в прикладном решении присутствуют возможности, которые могут использоваться или не использоваться в зависимости от конкретных условий. Для каждой из таких возможностей разработчик создает в конфигурации функциональные опции и связывает с ними объекты, реализующие этот функционал.
Рис. 7.101. Изменение группы для команды «Цены товаров»
Влияние же функциональных опций на командный интерфейс выражается в том, что система не включает в него команды тех объектов, которые относятся к выключенным опциям. Для описания функциональных опций используются объекты конфигурации Функциональные опции и Параметры функциональных опций. Эти объекты располагаются в узлах ветки Общие дерева конфигурации (рис. 7.103).
Рис. 7.102. Размещение команды «Цены товаров» в командном интерфейсе для пользователей с ролями «Администратор» и «Менеджер по ценам»
Влияние функциональных опций на командный интерфейс Механизм функциональных опций позволяет на этапе эксплуатации прикладного решения подключать или отключать функциональные возможности конфигурации. Для того чтобы пользователь не видел команд, относящихся к неиспользуемым возможностям, система автоматически формирует состав доступных команд в зависимости от значений функциональных опций. Том 1
Рис. 7.103. Объекты конфигурации «Функциональные опции» и «Параметры функциональных опций»
Каждая функциональная опция в свойстве Состав хранит состав объектов конфигурации, реализующих вариабельные возможности, и в свойстве Хранение содержит объект, являющийся источником значения опции (рис. 7.104). В зависимости от установленного для функциональной опции значения система включает (или исключает) в командный интерфейс команды объектов конфигурации, относящихся к этой опции.
183
Глава 7. Командный интерфейс прикладных решений Если значение функциональной опции хранится в константе, то затруднений в получении этого значения не возникает – система обращается к соответствующей константе. Если же значение функциональной опции хранится в реквизите справочника или ресурсе регистра сведений, системе необходимо «рассказать», из какого элемента справочника или записи регистра сведений получать значения. То есть функциональную опцию необходимо параметризовать. Фактически параметры функциональных опций задают систему координат, в которой хранятся значения функциональных опций.
Рис. 7.104. Свойства объекта «Функциональная опция»
Состав объектов конфигурации, относящихся к функциональной опции, можно указать, воспользовавшись гиперссылкой Открыть свойства Состав. Подробнее
Список объектов, которым можно назначить функциональные опции, приведен в документации «1С:Предприятие 8.2. Руководство разработчика», раздел 5.5.9.4.
В качестве источника значения функциональной опции могут использоваться: ■■ константа, ■■ реквизит справочника, ■■ ресурс регистра сведений. Важно понимать, что значения функциональных опций не изменяют структуру конфигурации. Состав объектов конфигурации и соответствующих им информационных структур в базе данных остается неизменным при любых значениях функциональных опций. В связи с тем, что функциональные опции отвечают на вопрос «Использовать объект конфигурации или нет?», их значения чаще всего имеют тип данных Булево. ПРИМЕЧАНИЕ
В общем случае тип данных хранилища значения функциональной опции системой не ограничивается. Однако для автоматического управления командным интерфейсом используются только функциональные опции с булевым типом значений. Значения функциональных опций с другими типами доступны только для анализа из встроенного языка.
184
Для параметризации функциональных опций используется объект конфигурации Параметр функциональной опции. Каждый из параметров определяет отдельную «координату» хранения значений функциональных опций. При этом один и тот же параметр может одновременно использоваться для параметризации нескольких функциональных опций. Основываясь на значении параметра, система будет выбирать соответствующий элемент справочника или запись регистра сведений для получения значения функциональной опции.
Отключаем неиспользуемые команды А теперь, познакомившись с функциональными опциями, вернемся к нашей задаче. В качестве отправной точки мы будем использовать демонстрационную базу «Командный интерфейс прикладных решений, пример 4». Результат выполняемых действий можно посмотреть в демонстрационной базе «Командный интерфейс прикладных решений, пример 5». Нам требуется предоставить пользователям возможность самостоятельно настроить вариант задания цен на товары – либо в целом на товар, либо на товар в разрезе различных видов цен. Для решения этой задачи в первую очередь создадим хранилище значения функциональной опции, значение которой будет управлять вариантом ценообразования. В качестве хранилища будем использовать константу Ценообразование по видам цен с типом данных Булево. Если значение константы Истина, то в подсистеме ценообразования используются виды цен, иначе виды цен не используются. Используя контекстное меню узла Константы дерева конфигурации, добавим новую константу. В окне свойств установим значения для свойств добавленной константы (рис. 7.105): ■■ Имя – «ЦенообразованиеПоВидамЦен»; ■■ Синоним – оставляем автоматически сформированный «Ценообразование по видам цен»; ■■ Тип – константа имеет тип данных Булево; Профессиональная разработка в системе «1С:Предприятие 8»
Влияние функциональных опций на командный интерфейс ■■ Использовать стандартные команды – нет.
Рис. 7.105. Заполнение свойств константы
Обеспечим возможность редактирования значения константы. Для этого командой контекстного меню Открыть форму откроем форму констант Общие настройки из ветки Общие формы (рис. 7.106).
Рис. 7.107. Добавление новой константы в форму
Рис. 7.108. Обработчик «ПослеЗаписи()» в модуле формы
Подробнее
Раздел «Редактирование формы», стр. 240.
Рис. 7.106. Открытие формы констант для редактирования
Теперь создадим саму функциональную опцию. Для этого откроем контекстное меню узла Функциональные опции и выберем команду Добавить (рис. 7.109).
В дерево элементов формы добавим поле Ценообразование по видам цен, связанное с реквизитом формы Ценообразование по видам цен. Для этого захватим мышью реквизит ЦенообразованиеПоВидамЦен (в правом верхнем списке) и перетащим его в левый верхний список (рис. 7.107). Мы обеспечили возможность хранения и редактирования значения функциональной опции. А теперь давайте представим, что мы изменили значение константы. Что хотелось бы увидеть в командном интерфейсе? Правильно, хочется увидеть обновленный командный интерфейс (панель разделов, панель навигации, рабочий стол и т. д.), построенный с учетом нового значения функциональной опции. Для этого в модуле формы реализован обработчик события ПослеЗаписи(), в котором функцией ОбновитьИнтерфейс() выполняется обновление интерфейса пользователя (рис. 7.108). Том 1
Рис. 7.109. Добавление функциональной опции
185
Глава 7. Командный интерфейс прикладных решений В окне свойств установим значения для свойств добавленной функциональной опции (рис. 7.110): ■■ Имя – «ЦенообразованиеПоВидамЦен»; ■■ Синоним – оставляем автоматически сформированный «Ценообразование по видам цен»; ■■ Хранение – указываем константу «Ценообразование по видам цен», хранящую значение функциональной опции.
Рис. 7.110. Заполнение свойств функциональной опции
Следующим шагом будет выбор объектов конфигурации, зависящих от созданной функциональной опции. Для этого гиперссылкой Открыть свойства Состав открываем окно выбора объектов (рис. 7.111). В дереве объектов устанавливаем пометки рядом со справочником Виды цен и измерением Вид цен регистра сведений Цены товаров. Если ценообразование в разрезе видов цен не используется, то все команды для работы с этим справочником будут «лишними». Поэтому зависимость настраиваем для справочника в целом.
Рис. 7.111. Заполнение состава функциональной опции
Обновим конфигурацию базы данных и запустим демонстрационную базу в режиме 1С:Предприятие от имени пользователя Администратор. В панели разделов основного окна выберем раздел Ценообразование. Команды обращения к списку справочника Виды цен в командном интерфейсе нет. Эта команда отключена вследствие того, что константа Ценообразование по видам цен имеет значение Ложь (рис. 7.112).
С регистром сведений ситуация другая. Нам в любом случае необходимо выполнять ценообразование в разрезе товаров. А вот в разрезе видов цен ценообразование выполняется не всегда. Поэтому зависимость настраиваем не в целом для регистра сведений, а для подчиненного ему объекта измерения. В общем случае одни и те же объекты конфигурации могут входить в состав нескольких функциональных опций. В такой ситуации доступность их команд определятся по правилу логического ИЛИ – если хотя бы одна функциональная опция имеет логическое значение Истина, команды будут доступны. Если же объект конфигурации не входит в состав ни одной из функциональных опций, то и доступность его команд от опций не зависит.
186
Рис. 7.112. При отключенной функциональной опции команда «Виды цен» в командном интерфейсе отсутствует
Профессиональная разработка в системе «1С:Предприятие 8»
Влияние функциональных опций на командный интерфейс Выберем команду Цены товаров, открывающую список регистра сведений Цены товаров (рис. 7.113).
Пользовательская настройка интерфейса Мы уже говорили о том, что пользователь имеет возможность настроить глобальный командный интерфейс под собственные предпочтения. Каждый пользователь прикладного решения может настроить состав команд в области системных команд, команды главного меню и команды в панелях основного окна приложения. Настройки, выполненные пользователем, сохраняются между сеансами его работы с прикладным решением.
Настройка области системных команд Состав команд, отображаемый в области системных команд основного окна приложения, настраивается вызовом подменю Добавить или удалить кнопки системного меню Другие кнопки (рис. 7.115). Рис. 7.113. Список регистра сведений «Цены товаров» при отключенной функциональной опции
В списке отсутствует измерение Вид цен регистра сведений Цены товаров. Теперь у константы Ценообразование по видам цен установим значение Истина и посмотрим, как изменился состав команд панели навигации и вид формы списка регистра сведений (рис. 7.114).
Рис. 7.115. Меню настройки состава командных панелей главного меню
Рис. 7.114. Командный интерфейс и список регистра сведений «Цены товаров» при включенной функциональной опции
В панели навигации появилась команда Виды цен, открывающая форму списка справочника, а в форме списка регистра сведений отображается колонка Вид цен. Таким образом, при отсутствии учета цен в разрезе их видов мы имеем возможность убрать из командного интерфейса «лишние» команды. Том 1
Пользователь отмечает в списке те команды, которые он хочет видеть в области системных команд. Для возврата к настройкам по умолчанию необходимо выбрать в подменю команду Сброс панели (см. рис. 7.115). Аналогично настраивается область системных команд и вспомогательного неблокирующего окна приложения. Для блокирующего вспомогательного окна приложения настройка области системных команд недоступна.
187
Глава 7. Командный интерфейс прикладных решений
Настройка командного интерфейса В основном окне приложения пользователь может настраивать состав отображаемых команд и их расположение в панели разделов, панели навигации и панели действий. Пользовательская настройка командного интерфейса выполняется в диалогах, вызываемых из подменю Сервис Настройка интерфейса главного меню системы (рис. 7.116).
Доступность команд определяется ролью пользователя и функциональными опциями. В диалоге отображаются только те команды, которые связаны с доступными пользователю элементами командного интерфейса, и эти элементы не относятся к отключенным функциональным опциям. В командном интерфейсе отображаются только те команды, которые пользователь поместил в список выбранных. Команды отображаются в тех группах и в том порядке, которые установлены в этом списке. Перемещение выбранной команды между списками выполняется кнопками Добавить >, Добавить все >>, Удалить > и Удалить все >>. Для помещения команды в группу, отличающуюся от стандартной, используются кнопки Добавить в группу… и Переместить в группу… Порядок команд в группах устанавливается кнопками перемещения вверх и вниз (кнопки со стрелками в командной панели списка Выбранные команды). В диалоге настройки поддерживается множественное выделение команд и перетаскивание команд с помощью мыши. Применение выполненной настройки происходит с помощью кнопки OK. При этом сделанные настройки сохраняются в информационной базе и окно настроек закрывается. Для отмены выполненной настройки необходимо выбрать кнопку Отмена.
Рис. 7.116. Команды открытия окон настройки интерфейса
ПРИМЕЧАНИЕ
Диалог настройки также может быть вызван из контекстного меню соответствующей панели.
При последующем отображении командного интерфейса к нему применяются последние сохраненные настройки. Для возврата к стандартным (заданным в конфигурации) настройкам необходимо в меню Все действия выбрать команду Установить стандартные настройки (рис. 7.118).
Диалог настройки любой командной панели содержит два списка – доступные команды и выбранные команды (рис. 7.117).
Рис. 7.118. Восстановление стандартных настроек
Рис. 7.117. Диалог настройки командной панели
188
Для применения стандартных настроек их также необходимо подтвердить кнопкой OK. Профессиональная разработка в системе «1С:Предприятие 8»
Пользовательская настройка интерфейса
Настройка панели разделов В диалоге настройки панели разделов отображаются только доступные пользователю команды выбора раздела. Для панели разделов можно настроить (рис. 7.119): ■■ видимость и порядок команд, ■■ способ отображения команд. Рис. 7.121. Основное окно с неотображаемой панелью разделов
Настройка панели навигации В диалоге настройки панели навигации отображаются доступные пользователю навигационные команды. Для панели навигации настраиваются видимость и расположение этих команд (рис. 7.122).
Рис. 7.119. Настройка панели разделов
Видимость и порядок команд настраиваются аналогично общему порядку, описанному ранее. Для настройки способа отображения команды необходимо в поле выбора Показывать указать один из режимов: ■■ Картинка – каждый раздел показывается только картинкой; ■■ Текст – каждый раздел показывается только текстом (название раздела); ■■ Картинка и текст – каждый раздел показывается картинкой и текстом. После закрытия диалога настройки кнопкой OK панель разделов будет изменена в соответствии с настройками (рис. 7.120).
Рис. 7.122. Настройка панели навигации
В списке Выбранные команды команды отображаются с учетом иерархии подсистем выбранного раздела и иерархии групп. Видимость и порядок команд настраиваются аналогично общему порядку, описанному ранее. Рис. 7.120. Настроенная панель разделов
Если пользователем скрыты все разделы (в диалоге настройки список Выбранные разделы пустой), то панель разделов также скрывается. Если при этом в разделе Рабочий стол есть команды в панели навигации, то в эту панель помещается команда Рабочий стол (рис. 7.121). Том 1
Перемещение команд между подчиненными подсистемами (и подсистемой верхнего уровня иерархии, соответствующей разделу) невозможно. В предопределенную группу См. также можно перемещать любые команды, так как эта группа является общей для всех вложенных подсистем. Однако из нее команду можно переместить только в группу той подсистемы, к которой команда относится.
189
Глава 7. Командный интерфейс прикладных решений
Настройка панели действий В диалоге настройки панели действий отображаются доступные пользователю команды действий. Для панели действий настраиваются видимость и расположение команд (рис. 7.123): ■■ открытия форм новых объектов в стандартной группе Создать, ■■ открытия отчетов в стандартной группе Отчеты, ■■ вызова обработок в стандартной группе Сервис.
Для задания различных представлений у многих объектов реализованы специальные свойства. Состав этих свойств определяется прототипом объекта конфигурации. Свойства отображаются в палитре свойств на закладке (или в группе, в зависимости от способа отображения свойств) Представление (рис. 7.124).
Рис. 7.124. Интерфейсные свойства объектов конфигурации
Рис. 7.123. Настройка панели действий
Видимость и порядок команд настраиваются аналогично общему порядку, описанному ранее. В панели действий вложенные подсистемы не отображаются, так как все группы являются общими. Команды раздела и всех его подразделов отображаются в одном списке.
Настраиваем представление команд Кроме настройки размещения и видимости команд, необходимо обратить внимание и на пользовательское представление команд. Они должны быть представлены в командном интерфейсе говорящими названиями – представление команды должно помочь пользователю быстро вспомнить ее назначение. Если разработчик специально не настраивает представление, то при формировании командного интерфейса система автоматически формирует представление для команд. Подробнее
Правила автоматического формирования представления приведены в документации «1С:Предприятие 8.2. Руководство разработчика, Приложение 3 «Правила формирования текстов стандартных команд и автоматических заголовков форм».
190
Задавая значения свойствам из этой группы, разработчик может формировать представления для заголовков форм объекта, представления для стандартных команд объекта и представления для подсказок к командам. ВНИМАНИЕ!
Заполнение свойств, связанных с представлением, необходимо только в тех случаях, когда синоним не может представить объект требуемым образом или есть необходимость в уточнении информации, отображаемой по умолчанию.
Если не заданы все свойства объекта конфигурации, используемые в формировании представления, то используется его системное текстовое представление – в большинстве случаев это значение его свойства Синоним. Это свойство должно быть заполнено (по умолчанию свойство заполняется исходя из имени объекта), и значение свойства должно осмысленно и максимально лаконично описывать объект конфигурации. ПРИМЕЧАНИЕ
Если синоним не задан, то для представления объекта конфигурации используется значение его свойства Имя.
В качестве отправной точки мы будем использовать демонстрационную базу «Командный интерфейс прикладных решений, пример 5». Результат выполняемых действий можно посмотреть в демонстрационной базе «Командный интерфейс прикладных решений, пример 6». Профессиональная разработка в системе «1С:Предприятие 8»
Настраиваем представление команд Например, в демонстрационной базе для справочника Товары заполнены свойства: ■■ Представление объекта – значение «Товар», представляет объект данных; ■■ Представление списка – значение «Товары», представляет множество (список) объектов данных. Команды открытия списка, создания объекта и создания группы представлены в интерфейсе в соответствии с заданным представлением (рис. 7.125).
ПРИМЕЧАНИЕ
Для всех стандартных команд объекта используется один и тот же текст пояснения.
Для демонстрации влияния свойств, связанных с представлением стандартных команд, на командный интерфейс изменим свойства следующим образом: ■■ Представление объекта – зададим значение «Номенклатурная позиция»; ■■ Представление списка – зададим значение «Номенклатура товаров»; ■■ Пояснение – зададим значение «Номенклатура товаров, продаваемых компанией». ПРИМЕЧАНИЕ
Свойства изменены в демонстрационных целях. В подавляющем большинстве случаев представление Товар для объекта и представление Товары для списка являются вполне приемлемыми.
Представление команд в интерфейсе изменилось в соответствии с новыми значениями (рис. 7.126).
Рис. 7.125. Представление команд справочника «Товары», первый вариант
Нас будут интересовать свойства, влияющие на представление стандартных команд объектов. К этим свойствам относятся: ■■ Представление объекта – определяет представление стандартной команды создания объекта; ■■ Представление списка – определяет представление стандартной команды открытия списка объектов; ■■ Пояснение – определяет подсказку к стандартным командам. Том 1
Рис. 7.126. Представление команд справочника «Товары», второй вариант
191
Глава 7. Командный интерфейс прикладных решений Текст, заданный в «представительских» свойствах, представляет не только команды, но и формы. Например, для справочника в заголовке формы списка используется значение свойства Представление списка (см. рис. 7.126), а в заголовке формы элемента, помимо текстового представления самого объекта, еще и значение свойства Представление объекта (рис. 7.127).
■■ в свойстве Картинка выберем картинку «ПодсистемаЦенообразование».
Рис. 7.127. Представление заголовка формы элемента, второй вариант
Таким образом, при заполнении свойств, связанных с формированием представления объектов и команд в интерфейсе, необходимо выбирать для них такие значения, которые были бы и информативны, и одинаково читались как в представлении команд, так и в заголовках форм. Для подсистем также определены свойства, позволяющие настроить их представление в интерфейсе. Настроим представление созданной нами подсистемы Ценообразование. На данный момент раздел, соответствующий подсистеме, представлен картинкой по умолчанию (желтый диск) и значением свойства Синоним подсистемы (рис. 7.128).
Рис. 7.129. Настройка представления раздела
В результате представление раздела изменилось в соответствии со значениями, заданными для свойств подсистемы.
Модель разработки глобального командного интерфейса
Рис. 7.128. Представление раздела по умолчанию
Хотелось бы назначить разделу собственную картинку и вместо текста Ценообразование выводить текст Управление ценами. Для настройки представления обратимся к свойствам подсистемы Ценообразование и зададим значения для свойств, определяющих представление подсистемы (рис. 7.129): ■■ для свойства Синоним зададим значение «Управление ценами»; ■■ в свойстве Пояснение введем текст «Выполнение задач по назначению и редактированию цен на товары»;
192
Мы видели, как многообразны средства разработки и управления глобальным командным интерфейсом, предоставляемые системой «1С:Предприятие». Это многообразие и сложность требуют вдумчивого и тщательного подхода к разработке командного интерфейса. В общем случае перечень задач, которые необходимо решить при реализации одной итерации цикла разработки, состоит из следующей последовательности: 1. Проектирование состава подсистем – структура подсистем имеет одно из важнейших значений, так как именно по ней система будет строить командный интерфейс пользователя, а пользователь «видеть» прикладное решение. 2. Формирование состава ролей пользователей – для пользователей, решающих разные задачи, командный интерфейс должен предоставлять набор команд, соответствующий этой задаче. Профессиональная разработка в системе «1С:Предприятие 8»
Модель разработки глобального командного интерфейса 3. Проектирование и настройка функциональных опций – начиная разработку, следует продумать, какие части функционала должны быть настраиваемыми при внедрении. 4. Настройка свойств объектов конфигурации – для объектов конфигурации следует задать свойства, определяющие их принадлежность к подсистемам, функциональным опциям, и состав команд объекта; назначить права доступа по ролям. 5. Установка интерактивных свойств конфигурации – для объектов конфигурации следует задать свойства, определяющие их представление в интерфейсе. Уже эти минимальные действия приведут к тому, что система построит командный интерфейс по умолчанию. В разделах глобального командного интерфейса появятся стандартные команды открытия форм списков объектов, создания новых объектов, вызова отчетов и др. Стандартные команды объектов, если это определено в их свойствах, также появятся в формах других объектов – команды ввода на основании, перехода к списку по регистратору, перехода к списку по владельцу и т. д. Если стандартных команд недостаточно для реализации функциональных возможностей прикладного решения, разработчик может расширить состав команд путем создания произвольных команд. Если не устраивает автоматическое расположение и видимость команд, то можно отредактировать фрагменты глобального командного интерфейса и состав команд тех форм, в которых автоматически размещены параметризованные команды объектов (перехода к подчиненному списку и ввода на основании). При редактировании командного интерфейса необходимо обращать внимание на следующее: ■■ Подбор состава команд – следует определить команды, которые будут отображаться по умолчанию; ■■ Настройку размещения команд – следует организовать размещение команд таким образом, чтобы наиболее важные и востребованные команды были всегда под рукой; ■■ Настройку видимости по ролям – следует продумать, для каких ролей откорректировать видимость по умолчанию, чтобы интерфейс системы не оказался перегружен. После завершения итерации разработки выполняется оценка работы интерфейса – полезно посмотреть, как выглядит интерфейс для типичных пользователей, а также посмотреть, как выглядит интерфейс с выключенными функциональными опциями.
Том 1
Создаем произвольные команды В данном разделе мы рассмотрим возможности, предоставляемые разработчику системой «1С:Предприятия» для создания собственных команд – механизм произвольных команд.
Произвольные команды Технологическая платформа «1С:Предприятие» используется для автоматизации решения широкого круга управленческих и учетных задач на самых разных предприятиях. При такой обширной сфере применения, естественно, могут возникать ситуации, когда функциональности стандартных команд недостаточно. Для реализации дополнительной функциональности используется встроенный язык «1С:Предприятия». В основном эта функциональность реализована в обработчиках событий. Однако возникает и необходимость предоставить пользователям возможность интерактивного обращения к части реализованных функций из интерфейса. Для решения этих задач в «1С:Предприятии» существует возможность создавать произвольную команду. В конфигурации произвольные команды представлены новым объектом конфигурации Команда. Объект конфигурации Команда предназначен для реализации в прикладном решении нестандартных функций с возможностью использования стандартных механизмов включения реализованного функционала в командный интерфейс. Технологическая платформа ничем не ограничивает состав произвольных команд и реализуемые ими функции. Все определяется требованиями к конкретному прикладному решению. При создании произвольной команды разработчик должен установить ее свойства, определяющие правила включения команды в интерфейс, и написать программный код, определяющий выполняемые командой действия. Этим произвольные команды отличаются от стандартных. Для последних и свойства, и выполняемые действия определены самой платформой. В конфигурации произвольные команды могут быть реализованы или как независимые объекты – общие команды, или как подчиненные другим объектам. Подробнее
Список объектов, для которых разработчик может создать подчиненные произвольные команды, приведен в документации «1С:Предприятие 8.2. Руководство разработчика», раздел 6.2.2.
193
Глава 7. Командный интерфейс прикладных решений Общие произвольные команды позволяют реализовать нестандартную функциональность, относящуюся в целом к прикладному решению. В этом случае произвольная команда создается как независимый объект конфигурации, принадлежащий классу Общие команды (рис. 7.130).
На торговых предприятиях часто требуется автоматизировать процесс регистрации продаваемого товара. Для этого используются сканеры штрихкода. Однако технологическая платформа ничего «не знает» об этих устройствах и не имеет средств работы с ними. Следовательно, для работы со сканером штрихкода требуется подключать специальную программу – драйвер. В демонстрационной базе для подключения такого драйвера реализована общая произвольная команда Установить сканер штрихкодов. Установив определенные значения свойств этой команды, разработчик обеспечил ее доступность пользователям (рис. 7.132).
Рис. 7.130. Произвольные общие команды
Подчиненные произвольные команды позволяют реализовать нестандартную функциональность какого-либо объекта конфигурации. В этом случае произвольная команда создается как подчиненный объект конфигурации (рис. 7.131).
Рис. 7.132. Произвольная общая команда «Установить сканер штрихкодов»
Функции работы со сканером являются общими для всего прикладного решения, то есть не относятся к какому-то конкретному объекту конфигурации, поэтому произвольная команда реализована как общая. Рис. 7.131. Произвольная подчиненная команда
Чтобы иметь представление о том, какие задачи решаются с использованием произвольных команд, давайте посмотрим на демонстрационную базу «Командный интерфейс прикладных решений, пример 6».
194
Команда выполняет действие – подключает к прикладному решению драйвер для работы со сканером штрихкодов. Поэтому она расположена в панели действий основного окна приложения.
Профессиональная разработка в системе «1С:Предприятие 8»
Создаем произвольные команды Еще одной распространенной задачей является получение печатных копий электронных документов. Состав документов, их структура определяются автоматизируемой прикладной задачей. Естественно, в платформе невозможно предусмотреть все многообразие документов и варианты их печатных форм. Для того чтобы «научить» документ «переносить» себя на бумагу, можно воспользоваться произвольной командой. В демонстрационной базе для получения печатной формы документа РасходТовара создана подчиненная команда ПечатьРасходнойНакладной (рис. 7.133).
Еще одним, достаточно специфическим вариантом использования произвольных команд является расширение или переопределение стандартной функциональности стандартной команды. Такие задачи возникают, например, вследствие требования сократить количество ручных операций или изменить стандартное поведение объектов. Например, в демонстрационной базе реализован объект-обработка Административный сервис. Команду открытия основной формы необходимо было расположить в панели навигации, а саму форму открывать в рабочей области основного окна приложения. Но стандартная функциональность этого объекта отличается от требуемой – команда открытия формы располагается в панели действий, а форма открывается в новом вспомогательном окне. Для обеспечения требуемой функциональности у обработки снято свойство Использовать стандартные команды (рис. 7.134) – стандартные команды нас не устраивают.
Рис. 7.134. Стандартные команды обработки не используются
Рис. 7.133. Произвольная подчиненная команда «Печать расходной накладной»
Значения свойств команды Группа и Тип параметра команды определили расположение команды в командном интерфейсе – меню Печать командной панели формы документа, а процедура на встроенном языке обеспечила формирование печатной формы конкретного документа, ссылка на который передается в параметре команды.
Доступ же к обработке обеспечивает произвольная подчиненная команда Административный сервис, для которой задано расположение в группе Обычное панели навигации основного окна приложения (рис. 7.135). В результате выбора этой команды в рабочей области основного окна отображается форма обработки. Подобных задач в конкретных прикладных решениях возникает великое множество, и для их решения наиболее подходящими являются произвольные команды.
Подробнее
Раздел «Особенности размещения», стр. 196.
Том 1
195
Глава 7. Командный интерфейс прикладных решений Размещение по умолчанию в командном интерфейсе для произвольных команд определяется: ■■ категорией и группой, назначенными команде; ■■ принадлежностью команды к подсистеме конфигурации (для независимых команд); ■■ типом параметра команды (для параметризуемых команд). Категория команды и ее группа устанавливаются в свойстве Группа этой команды (рис. 7.132, 7.133, 7.135). ВНИМАНИЕ!
Свойство команды Группа обязательно должно быть заполнено. В противном случае возникнет ошибка при обновлении конфигурации базы данных, и обновление не выполнится.
При выборе группы для команды следует обращать внимание на необходимость в передаче параметров команде и на действия, выполняемые командой. В качестве общего критерия можно предложить придерживаться тех же правил, которые используются для стандартных команд. подробнее
Раздел «Правила размещения глобальных команд», стр. 173.
Рис. 7.135. Произвольная подчиненная команда «Административный сервис»
Особенности размещения Особенностью произвольных команд, по сравнению со стандартными, является необходимость описания места их размещения по умолчанию (см. раздел «Категории и группы команд», стр. 169) в командном интерфейсе. Место размещения произвольной команды задает разработчик при конфигурировании прикладного решения. ПРИМЕЧАНИЕ
Остальные аспекты управления произвольными командами – доступность по ролям (см. раздел «Система прав доступа», стр. 161), управление видимостью команды (см. раздел «Ручное размещение и видимость команд», стр. 182), настройка зависимости от функциональных опций (см. раздел «Отключаем неиспользуемые команды», стр. 184) и т. д. – аналогичны управлению стандартными командами.
196
■■ Если команда для своего исполнения не требует параметров, то для нее выбирают группу с категорией Панель навигации или с категорией Панели действий. ■■ Если команда для своего исполнения требует передачи параметра, то для нее необходимо выбрать группу с категорией Панель навигации формы или с категорией Командная панель формы. ■■ Для команд, выполнение которых приводит к изменению информации, отображаемой в рабочей области того же окна, следует выбирать категорию Панель навигации для независимых команд или Панель навигации формы для параметризуемых команд. ■■ Для команд, выполнение которых приводит к изменению данных в информационной базе, следует выбирать категорию Панель действий для независимых команд или Командная панель формы для параметризуемых команд. Также эту категорию рекомендуется выбирать для команд, которые приведут к открытию нового окна для отображения форм выбора, форм отчетов, форм обработок. Для включения общей независимой команды в тот или иной раздел командного интерфейса необходимо указать ее принадлежность к соответствующим подсистемам. Включение команды в подсистемы выполняется путем ее отметки в свойстве Состав требуемых подсистем (см. раздел «Стандартные команды», стр. 157). Профессиональная разработка в системе «1С:Предприятие 8»
Создаем произвольные команды Подчиненную же команду непосредственно включить в подсистему невозможно. Поэтому подчиненные независимые команды автоматически включаются в командный интерфейс тех подсистем, в которые включен объект-владелец команды. А вот параметризуемые произвольные команды, как общие, так и подчиненные, включаются в командный интерфейс иначе. Связано это с тем, что фактическое значение своего параметра команда может получить только из данных формы.
Развитие функциональности ценообразования Вернемся к решению нашей задачи по выделению функционала работы с ценами в отдельную подсистему. Кроме назначения цен, нам потребуется и возможность распечатывать ценники на товары. При этом необходимо реализовать два режима: ■■ печать ценников на все товары по всем существующим видам цен, ■■ печать ценников на все товары по одному виду цен.
Именно поэтому параметризуемые команды можно размещать только в панели навигации формы или в командной панели формы.
Стандартные команды объектов конфигурации не могут обеспечить нас этими возможностями. Следовательно, нам необходимо реализовать дополнительную функциональность. Для этого будем использовать произвольные команды.
Причем это значение должно иметь тип данных, допустимый для параметра. Состав допустимых типов параметра устанавливается в свойстве Тип параметра команды (рис. 7.136).
В качестве отправной точки мы будем использовать демонстрационную базу «Командный интерфейс прикладных решений, пример 6». Результат выполняемых действий можно посмотреть в демонстрационной базе «Командный интерфейс прикладных решений, пример 7».
ПРИМЕЧАНИЕ
Общая независимая команда Функционал печати всех ценников на первый взгляд должен расширять возможности справочника Товары. Однако этот объект конфигурации описывает множество объектов данных информационной базы. Если мы реализуем команду как подчиненную справочнику, то мы «научим» каждый из объектов данных печатать ценники на все товары. А это уже лишнее. Объект данных должен быть ответственен только за себя. Поэтому команда будет общей. Для добавления произвольной общей команды используем пункт Добавить контекстного меню узла Общие команды дерева конфигурации (рис. 7.137).
Рис. 7.136. Состав допустимых типов параметров для параметризуемой команды определяется ее свойством «Тип параметра команды»
Сравнивая состав типов, заданных в свойстве команды, с типами реквизитов формы, система принимает решение о включении команды в ту или иную форму. Параметризуемая произвольная команда включается в форму только тогда, когда форма имеет хотя бы один реквизит с типом, входящим в состав допустимых. При проверке учитываются и реквизиты, подчиненные основному реквизиту формы. Состав проверяемых подчиненных реквизитов ограничен первым уровнем подчинения.
Том 1
Рис. 7.137. Добавление произвольной общей команды
197
Глава 7. Командный интерфейс прикладных решений В результате будет добавлена общая команда, и для нее откроется окно свойств и окно редактирования модуля команды (рис. 7.138).
Рис. 7.139. Задание места размещения произвольной общей команды
Созданная нами команда является независимой. Следовательно, необходимо определить, в каких разделах командного интерфейса она будет доступна. Команда должна быть доступна в тех же разделах, в которых можно выполнять действия по управлению ценами. Рис. 7.138. Свойства и модуль общей произвольной команды
В группе свойств Основные зададим значения свойств команды: ■■ Имя – «ПечатьЦенниковТовары»; ■■ Синоним – оставим автоматически сформированный синоним; ■■ Комментарий – заполнять не будем. Следующий шаг – выбор категории команды и группы для ее размещения по умолчанию.
В нашем случае созданная команда должна принадлежать трем подсистемам – Ценообразование, Цены, Предприятие. Таким образом, нам требуется отредактировать свойство Состав трех подсистем. Для сокращения количества выполняемых действий из контекстного меню созданной команды выберем пункт Дополнительно. В результате откроется окно, в котором на закладке Подсистемы можно указать все подсистемы, которым принадлежит команда (рис. 7.140).
Наша команда для своего исполнения не требует параметров – она независимая. Команда выполняет действия по обработке данных, хранимых в информационной базе, с целью получения набора ценников, а не изменяет контекст решения какой-либо задачи. Следовательно, для команды установим категорию Панель действий. А в какой группе она будет отображаться? Логичнее всего поместить ее в группу Сервис. Поэтому для свойства Группа открываем окно со списком групп и выбираем элемент ПанельДействий.Сервис (рис. 7.139). ПРИМЕЧАНИЕ
Обратите внимание на свойства Тип параметра команды, Режим использования параметра и Изменяет данные – они недоступны для заполнения. Свойства предназначены для описания параметризуемой команды и становятся доступны только при выборе группы с категориями Панель навигации формы или Командная панель формы.
198
Рис. 7.140. Включение произвольной общей команды в подсистемы
Профессиональная разработка в системе «1С:Предприятие 8»
Создаем произвольные команды Следующая задача – назначение прав на использование команды. Наша команда доступна пользователям с ролью Администратор за счет установленного свойства роли Устанавливать права для новых объектов. От нас требуется обеспечить ее доступность и для роли Менеджер по ценам. Как и для других объектов конфигурации, для общей команды настройку доступности можно выполнить в окне редактирования роли (см. раздел «Система прав доступа», стр. 161). А можно – в уже открытом окне Дополнительно на закладке Права. В списке Роли выбираем настраиваемую роль и в списке Права устанавливаем право Просмотр для созданной команды (рис. 7.141).
Рис. 7.142. Настройка видимости произвольной общей команды
Рис. 7.141. Настройка доступности команды для роли «Менеджер по ценам»
Настройка видимости команды по ролям для произвольной независимой команды выполняется аналогично настройке для стандартных команд – в редакторе командного интерфейса. Подробнее
Раздел «Система настройки командного интерфейса», стр. 174.
Наша команда по умолчанию должна быть видима пользователю с ролью Менеджер по ценам, а от пользователя с ролью Администратор ее необходимо скрыть. Для этого в редакторе командного интерфейса подсистемы Ценообразование снимем флажок общей видимости в колонке Видимость. Это обеспечит нам невидимость команды для всех ролей, в том числе и вновь создаваемых. А для роли Менеджер по ценам явным образом установим флажок в соответствующей колонке (рис. 7.142). Сохраним конфигурацию, запустим приложение от имени пользователя Менеджер по ценам и выберем раздел Управление ценами. Том 1
В командном интерфейсе (рис. 7.143) команда Печать ценников товары доступна в разделе Управление ценами (за счет указания принадлежности к подсистеме Ценообразование). Команда размещена в группе Сервис панели действий (за счет указания соответствующего значения свойства Группа). Таким образом, для произвольной общей независимой команды: ■■ размещение в командном интерфейсе по умолчанию определяется значением свойства Группа; ■■ включение в раздел командного интерфейса определяется принадлежностью к соответствующей подсистеме; ■■ доступность для пользователя определяется значением права Просмотр. Команду мы создали. А как рассказать пользователю о том, какие действия выполняет произвольная команда? Ответ очевиден – описать назначение команды в документации к прикладному решению. Также назначение команды можно описать во встроенной электронной справке. Для работы со справочной информацией предназначены свойства общей команды из группы Справочная информация (рис. 7.144).
199
Глава 7. Командный интерфейс прикладных решений
Рис. 7.144. Справочная информация по произвольной общей команде
Рис. 7.143. Размещение произвольной общей независимой команды в командном интерфейсе
Однако поиск описания команды в документации или встроенной справке – процесс длительный. Можно помочь пользователю быстро вспомнить назначение команды, выбрав для нее говорящее представление. Произвольная общая команда в командном интерфейсе представляется своим свойством Синоним. Сейчас команда представлена текстом «Печать ценников товары», и это представление достаточно информативно. Но в дальнейшем мы добавим в прикладное решение еще одну команду печати ценников – по виду цен. Поэтому стоит подумать над таким представлением команды, которое подскажет пользователю, какой вариант печати ценников будет выполнен. Скажем, это будет «Печать всех ценников». Еще одним способом напоминания пользователю о назначении команды является использование свойства Подсказка. Текст, заданный в этом свойстве, отображается во всплывающей подсказке при наведении указателя мыши на команду. Для свойства Подсказка зададим текст «Печать ценников на все товары по всем видам цен». В результате изменения значений свойств Синоним и Подсказка представление команды в командном интерфейсе изменилось (рис. 7.145).
200
Рис. 7.145. Измененное представление команды
Профессиональная разработка в системе «1С:Предприятие 8»
Создаем произвольные команды На данный момент мы создали команду, настроили ее расположение, доступность и представление. Нам осталось реализовать функциональность команды, то есть те действия, которые должна выполнять команда. Для определения выполняемых действий разработчику необходимо реализовать процедуру на встроенном языке. Процедура должна размещаться в модуле команды, доступ к которому можно получить через гиперссылку Открыть свойства Модуль команды (рис. 7.146).
Мы не будем реализовывать требуемую функциональность команды. Для нас достаточно просто увидеть реакцию системы на выбор команды. Поэтому в модуле команды просто выведем сообщение. При выборе команды в режиме эксплуатации в окне сообщений будет выведен текст нашего сообщения (рис. 7.147).
Подчиненная параметризуемая команда Теперь реализуем функциональность печати ценников по одному виду цен. Для этого также будем использовать произвольную команду. В отличие от предыдущей, эта команда расширяет функциональные возможности справочника Виды цен – любой из элементов справочника (объектов, хранимых в информационной базе) должен знать, как распечатать «свои» ценники (по виду цены). Поэтому команду реализуем как подчиненный справочнику Виды цен объект Команда. Для добавления произвольной подчиненной команды выберем пункт Добавить контекстного меню узла Команды справочника Виды цен (рис. 7.148).
Рис. 7.146. Процедура, реализующая функциональность произвольной команды
Рис. 7.148. Создание произвольной подчиненной команды
В результате будет добавлен подчиненный справочнику объект Команда, и для него откроется окно свойств и окно редактирования модуля команды (рис. 7.149). Состав свойств подчиненной произвольной команды практически полностью совпадает со свойствами общей. Особенностью является отсутствие у подчиненной команды группы свойств Справочная информация – описание команды включается в справку самого объекта-владельца. Рис. 7.147. Результат исполнения произвольной общей команды
Том 1
201
Глава 7. Командный интерфейс прикладных решений
Рис. 7.150. Принадлежность к подсистеме для произвольной подчиненной команды определяется объектом-владельцем
ПРИМЕЧАНИЕ Рис. 7.149. Свойства и модуль произвольной подчиненной команды
В группе свойств Основные заполним следующие свойства: ■■ Имя – «ПечатьЦенниковВидЦены»; ■■ Синоним – оставим автоматически сформированный синоним; ■■ Комментарий – заполнять не будем.
Обратите внимание, что стали доступны для заполнения свойства Тип параметра команды, Режим использования параметра и Изменяет данные.
В качестве параметра наша команда принимает ссылку на тот вид цен (элемент справочника Виды цен), для которого необходимо распечатать ценники. Поэтому в качестве значения свойства Тип параметра команды зададим тип данных СправочникСсылка.ВидыЦен (рис. 7.151).
Для свойства Группа пока установим значение ПанельДействий.Сервис – этим мы определили произвольную подчиненную независимую команду действия. Подчиненная команда включается в те же разделы интерфейса, что и объект-владелец. Следовательно, созданная команда включена в раздел Предприятие, раздел Управление ценами и подраздел Цены раздела Товарные запасы за счет принадлежности справочника Виды цен соответствующим подсистемам (рис. 7.150). Теперь давайте вспомним, что команда выполняет действия по печати ценников только для выбранного вида цен. Этот вид цены команда принимает как управляющий параметр, то есть команда параметризуемая. Поэтому, ориентируясь на общий критерий выбора категории, изменим у команды значение свойства Группа на Командная панель формы.Важное – команда по умолчанию располагается в группе Важное командной панели формы.
202
Рис. 7.151. Группа и тип параметра определяют расположение произвольной параметризуемой команды
Профессиональная разработка в системе «1С:Предприятие 8»
Создаем произвольные команды ПРИМЕЧАНИЕ
В случае, если параметр может принимать значения разных типов, для свойства Тип параметра команды необходимо выбрать составной тип данных.
Исходя из типа параметра, наша команда будет доступна как минимум в двух формах: ■■ в форме списка справочника Виды цен, где параметром будет ссылка из текущей строки списка; ■■ в форме элемента того же справочника, параметром будет ссылка на редактируемый объект. А если команде потребуется передать не одно значение параметра, а несколько? В этом случае необходимо воспользоваться свойством Режим использования параметра. Это свойство предназначено для определения количества значений, которые будут переданы в качестве параметра (рис. 7.152).
выделения строк табличного поля). Порядок элементов после первого не определен. Если же текущая строка не входит в выделение, то первый элемент в массиве невозможно предсказать однозначно. Массив значений будет передан и в том случае, если в таблице выделена только одна строка. Такой массив будет содержать только одни элемент. Еще одним свойством, которое определено для параметризуемых команд, является свойство Изменяет данные. Если это свойство установлено, то система пытается заблокировать данные формы для редактирования. В случае успеха для формы устанавливается признак модифицированности. Такое поведение позволяет сымитировать интерактивное изменение данных в форме. Как и для команды печати всех ценников, для нашей команды необходимо выполнить назначение прав на ее использование. Команда должна быть доступна пользователям с ролью Менеджер по ценам. Для настройки доступности воспользуемся возможностью «1С:Предприятия» – установкой прав на подчиненные объекты. Подробнее
Раздел «Система прав доступа», стр. 161.
Для этого в контекстном меню подчиненной команды выберем пункт Дополнительно. В открывшемся окне на закладке Права установим право Просмотр для роли Менеджер по ценам (рис. 7.153).
Рис. 7.152. Возможность использования многозначного параметра определяется свойством «Режим использования параметра»
Если свойство установлено в значение Одиночный, то в команду передается одно значение указанного типа. Если свойство установлено в значение Множественный, то в команду всегда передается массив значений указанного типа. Этот режим имеет смысл выбирать тогда, когда источником параметра является таблица с установленным режимом множественного выделения. Если в таблице выделено несколько строк, то первым элементом массива будет выступать текущая строка (вне зависимости от последовательности Том 1
Рис. 7.153. Ролевая доступность произвольной подчиненной команды определяется ее правом «Просмотр»
203
Глава 7. Командный интерфейс прикладных решений Если право Просмотр будет сброшено, система не включит подчиненную команду в командный интерфейс пользователя. Даже в том случае, когда роль обладает полными правами на объект-владелец (установлены все права на этот объект). Настройка видимости параметризуемой команды по ролям для произвольной параметризуемой команды выполняется в редакторе формы. Подробнее
Об этом мы поговорим в разделе «Командуем формами», стр. 210.
В результате выполненных настроек команда печати ценников для вида цены доступна в командных панелях формы списка справочника Виды цен и в форме элемента того же справочника для пользователей с ролью Менеджер по ценам (рис. 7.154).
Рис. 7.155. Размещение произвольной параметризуемой подчиненной команды в командном интерфейсе
Нам осталось настроить представление команды в интерфейсе и реализовать процедуру исполнения команды. Рис. 7.154. Произвольная параметризуемая команда доступна в форме списка и в форме элемента
Таким образом, для произвольной подчиненной параметризуемой команды: ■■ размещение в командном интерфейсе определяется значением свойства Группа; ■■ состав форм, в которых будет доступна команда, определяется значением свойства Тип параметра команды; ■■ доступность для пользователя определяется значением права Просмотр, устанавливаемого для подчиненной команды. Сохраним конфигурацию, запустим приложение от имени пользователя Менеджер по ценам, выберем раздел Управление ценами и откроем форму списка справочника Виды цен. Созданная нами команда действительно расположена в группе Важное командной панели формы (рис. 7.155).
204
Для настройки представления заполним свойство Синоним текстом «Печать ценников для вида цены», свойство Подсказка – текстом «Печать ценников на товары по выбранному виду цены», а для того чтобы видеть реакцию на выбор команды, в модуле команды реализуем вывод сообщения (рис. 7.156). При выборе команды в режиме эксплуатации в окне сообщений будет выведен текст нашего сообщения (рис. 7.157). Помимо свойств Синоним и Подсказка, на представление команды в командном интерфейсе также влияют свойства Картинка и Отображение. ПРИМЕЧАНИЕ
Свойства Картинка и Отображение определены и для общих произвольных команд.
Профессиональная разработка в системе «1С:Предприятие 8»
Создаем произвольные команды фейсе. В качестве пиктограммы может быть выбрана любая стандартная или общая картинка. Давайте для команды зададим стандартную картинку Печать (рис. 7.158).
Рис. 7.156. Настройка представления и функциональности произвольной подчиненной команды Рис. 7.158. Назначение картинки для произвольной подчиненной команды
Свойство Отображение задает способ отображения команды:
Рис. 7.157. Результат исполнения произвольной подчиненной команды
На данный момент свойство Картинка не заполнено, а свойство Отображение имеет значение Авто. В этом случае команда представлена значением своего свойства Синоним (см. рис. 7.157).
■■ Текст – в представлении команды присутствует только текст; ■■ Картинка – в представлении команды присутствует только пиктограмма; ■■ Картинка и текст – в представлении команды присутствует и текст, и пиктограмма; ■■ Авто – решение о представлении команды принимает система (в командных панелях, связанных с интерфейсными элементами, присутствует пиктограмма; в пунктах меню присутствует текст и пиктограмма). Установим для свойства значение Картинка и текст. В результате команда представлена и пиктограммой, и текстом (рис. 7.159).
Свойство Картинка содержит пиктограмму, которая, в зависимости от значения свойства Отображение, может представлять команду в интерТом 1
205
Глава 7. Командный интерфейс прикладных решений
Рис. 7.160. Произвольная подчиненная команда с назначенной клавиатурной комбинацией
Рис. 7.159. Измененное представление произвольной подчиненной команды
ПРИМЕЧАНИЕ
Свойства Картинка и Отображение используются только для команд, размещенных в командной панели формы. При размещении в других панелях (навигации, действий, навигации формы) команды представляются своим синонимом (или именем, если синоним не заполнен).
У произвольных команд есть еще свойство, которое мы не рассмотрели, – Сочетание клавиш. Это свойство позволяет назначить команде клавиатурную комбинацию для ее быстрого вызова. Для назначения клавиатурной комбинации необходимо выбрать свойство Сочетание клавиш и нажать на клавиатуре требуемую комбинацию клавиш. Назначим нашей команде печати ценников по виду цен комбинацию клавиш Ctrl + P (рис. 7.160).
Зависимость от функциональных опций А теперь вспомним о том, что ценообразование в разрезе видов цен является опциональным. Если цены назначаются только в разрезе товаров, то печать ценников в разрезе видов цен не потребуется. Поэтому доступность команды печати ценников по виду цен поставим в зависимость от значения функциональной опции. Для настройки зависимости произвольной команды от функциональной опции необходимо эту команду включить в свойство Состав управляющей функциональной опции. Подробнее
Раздел «Отключаем неиспользуемые команды», стр. 184.
Как и для включения в подсистемы, для включения команды в функциональные опции воспользуемся окном Дополнительно, вызванным из контекстного меню для подчиненной команды (рис. 7.161). ПРИМЕЧАНИЕ
Аналогично можно настроить зависимость от функциональных опций и для общей произвольной команды.
206
Профессиональная разработка в системе «1С:Предприятие 8»
Создаем произвольные команды
Рис. 7.161. Настройка зависимости произвольной команды от функциональной опции
Также для нашей команды в свойстве Отображение установим значение Картинка.
Рис. 7.163. При истинном значении функциональной опции произвольная команда доступна
Сохраним конфигурацию, запустим приложение от имени пользователя Администратор и установим значение константы Ценообразование по видам цен в Истина (рис. 7.162).
Изменим значение константы Ценообразование по видам цен на Ложь, перезапустим приложение от имени пользователя с ролью Менеджер по ценам и откроем форму списка справочника Виды цен. Команда печати недоступна (рис. 7.164).
Рис. 7.162. Установка ценообразования в разрезе видов цен
Рис. 7.164. При ложном значении функциональной опции произвольная команда недоступна
Теперь запустим приложение от имени пользователя Менеджер по ценам и откроем форму списка справочника Виды цен. Команда печати доступна в командной панели формы и отображается только пиктограммой (рис. 7.163).
Том 1
ПРИМЕЧАНИЕ
В случае с отключенной функциональной опцией форма списка справочника Виды цен открыта через пункт Все функции… главного меню.
207
Глава 7. Командный интерфейс прикладных решений
Произвольные группы В разделе «Автоматическое размещение и видимость команд» (стр. 168) мы говорили о том, что команды располагаются в стандартных группах и что при необходимости разработчик может расширить стандартный состав групп. Для этого используются объекты конфигурации Группа команд, расположенные в ветке Общие дерева конфигурации.
Для группы команд Печать установлена категория Командная панель формы. Это значит, что в интерфейсе произвольная группа размещена в командной панели формы (рис. 7.166).
Произвольная группа команд используется для логического объединения команд, выполняющих похожие действия. Например, в демонстрационной базе создана произвольная группа команд Печать (рис. 7.165), предназначенная для объединения команд, которые формируют различные печатные формы.
Рис. 7.165. Произвольная группа команд «Печать»
Как и для других объектов конфигурации, для объекта Группа определены универсальные свойства Имя, Синоним, Комментарий.
команд
Рис. 7.166. Свойство «Категория» определяет размещение произвольной группы
Для определения места размещения группы используется свойство Категория.
Давайте включим произвольную команду печати ценников по виду цен в группу Печать. Для этого в свойстве Группа нашей подчиненной команды установим произвольную группу Командная панель формы.Печать.
ВНИМАНИЕ!
Кроме того, для свойства Отображение установим значение Авто (рис. 7.167).
Свойство группы Категория обязательно должно быть заполнено. Если значение для свойства не выбрано, система установит значение по умолчанию Панель навигации.
Выбранная категория определяет, где будет размещена группа, и, следовательно, команды, принадлежащие этой группе. В качестве значения может быть выбрана только одна из стандартных категорий команд. Подробнее
Теперь в форме списка и форме элемента справочника Виды цен команда печати ценников располагается уже не в группе Важное, а в группе Печать. ПРИМЕЧАНИЕ
В командной панели формы кнопками отображаются команды из группы Важное. Команды остальных групп отображаются в виде подменю.
Раздел «Категории и группы команд», стр. 169.
208
Профессиональная разработка в системе «1С:Предприятие 8»
Создаем произвольные команды В результате наших настроек представление группы команд изменилось (рис. 7.168) – она представлена назначенной картинкой и текстом, заданным в свойстве Синоним.
Рис. 7.167. Включение произвольной команды в произвольную группу
Для формирования представления группы в командном интерфейсе используются свойства Синоним, Отображение, Подсказка и Картинка. Свойство Синоним содержит текст, представляющий произвольную группу в командном интерфейсе. Для синонима зададим значение «Печатные формы». Свойство Отображение содержит вариант отображения группы команд. Для отображения оставим вариант Авто. Свойство Подсказка содержит текст всплывающей подсказки при кратковременной задержке курсора над командой. Для подсказки зададим значение «Получение печатных форм». Свойство Картинка содержит картинку, которая будет представлять группу в интерфейсе. Для картинки зададим (аналогично произвольной команде) значение Печать.
Том 1
Рис. 7.168. Настройка представления произвольной группы команд
Из особенностей объекта Группа команд необходимо отметить, что для него не назначаются права, не определяется принадлежность к подсистемам и зависимость от функциональных опций. Произвольная группа будет представлена в командном интерфейсе пользователя только в том случае, когда в нем доступна хотя бы одна из команд, включенных в группу. В противном случае группа в командный интерфейс не включается. В нашем приложении доступ к справочнику Виды цен разрешен и для роли Менеджер по продажам. Но для этой роли сброшено право Просмотр для произвольной подчиненной команды (рис. 7.169). В результате такой настройки прав произвольная группа команд Печать для менеджера по продажам оказалась пустая, и она не представлена в командной панели формы списка справочника Виды цен.
209
Глава 7. Командный интерфейс прикладных решений Однако наличие команды в форме еще не дает возможности использовать ее функциональность. Аналогично и реквизиты сами по себе не обеспечивают возможности отображения и редактирования данных. Для использования команд, для отображения и редактирования данных, хранимых в реквизитах, служат элементы формы, связанные с соответствующими командами и реквизитами. Не вдаваясь в детали, связь между командами, реквизитами и элементами формы можно представить схемой (рис. 7.170).
Рис. 7.170. Связь между командами, реквизитами и элементами формы
Подробнее
Раздел «Конструирование форм», стр. 233. Рис. 7.169. Ролям со сброшенным свойством «Просмотр» произвольная команда недоступна
«Командуем» формами В предыдущих разделах мы познакомились с глобальным командным интерфейсом «1С:Предприятия», принципами его построения и глобальными командами. В данном разделе мы рассмотрим формирование набора команд, доступных для использования в контексте формы. Здесь же изложены основные сведения о форме, необходимые для понимания этого механизма.
Необходимые сведения о формах Формы, существующие в «1С:Предприятии», предназначены для интерактивной работы пользователя с данными информационной базы. Для обеспечения этой возможности форма «наполняется» необходимой функциональностью. Функциональность формы определяется составом ее реквизитов и команд. Реквизиты формы – это данные, с которыми работает форма. Команды формы – это действия, которые может выполнить форма над данными.
210
Можно отметить следующие ключевые особенности форм. Во-первых, новая форма не прорисовывается детально разработчиком, а строится системой автоматически. Разработчик же в режиме конфигурирования: ■■ определяет состав формы в виде дерева элементов; ■■ описывает поведение формы, задавая значения для ее свойств и/или реализуя процедуры на встроенном языке. При построении интерфейса для того или иного пользователя система использует это декларативное описание для создания формы и размещения ее элементов. Во-вторых, при создании формы используется новая модель управления доступностью и видимостью элементов формы. При этом учитываются: ■■ настройки прав в разрезе ролей пользователей; ■■ зависимость элементов формы от функциональных опций; ■■ настройка формы, выполненная разработчиком на этапе конфигурирования прикладного решения; ■■ настройка формы, выполненная пользователем на этапе эксплуатации прикладного решения.
Профессиональная разработка в системе «1С:Предприятие 8»
«Командуем» формами
Функциональность по умолчанию
Команды формы
В «1С:Предприятии» можно не создавать формы для представления и обработки объектов данных. В этом случае при выполнении команд открытия форм система самостоятельно на лету создаст необходимую форму. Созданная форма будет обладать функциональностью и представлением по умолчанию. Что же определяет представление и функциональность формы?
Для знакомства с командами формы создадим еще одну форму для документа Расход товара. Из контекстного меню узла Формы этого документа выберем пункт Добавить (рис. 7.171).
Стандартное представление и функциональность формы определяют интерфейсный объект «Управляемая форма» (например, способность формы закрываться) и расширение формы (например, способность записывать данные формы в информационную базу). Расширение формы – это дополнительные свойства, методы, параметры и команды, которые появляются у объекта Форма, когда ей назначен основной реквизит. ВНИМАНИЕ!
В качестве основного может быть выбран только один реквизит из состава реквизитов формы.
Важно понимать, что: ■■ дополнительно предоставляемая функциональность включается в объект Управляемая форма, то есть становится ее неотъемлемой частью; ■■ состав дополнительных возможностей определяется типом основного реквизита формы, то есть типом тех данных, для редактирования которых предназначена форма.
Рис. 7.171. Добавление подчиненной формы
В результате откроется окно конструктора форм (рис. 7.172). В окне конструктора выберем тип формы – Форма документа, установим флажок Назначить форму основной и зададим имя ОсновнаяФорма. Нажмем кнопку Готово.
Расширения могут присутствовать и у элементов формы. Как и для самой формы, состав расширения, то есть дополнительные свойства, методы и т. д., элемента формы определяется типом реквизита, с которым элемент связан. При необходимости реализовать нестандартное представление данных или нестандартную функциональность разработчик может самостоятельно создать форму в конфигураторе. Для создания форм используется редактор форм. С помощью этого редактора разработчик создает для формы необходимый набор реквизитов и команд, а также элементы формы, которыми они отображаются. Подробнее
Раздел «Редактирование формы», стр. 240.
В качестве отправной точки мы будем использовать демонстрационную базу «Командный интерфейс прикладных решений, пример 7». Результат выполняемых действий можно посмотреть в демонстрационной базе «Командный интерфейс прикладных решений, пример 8». Том 1
Рис. 7.172. Окно конструктора формы
В результате работы конструктора создана форма документа, эта форма назначена основной, то есть она используется по умолчанию для работы с документом. После завершения работы конструктора для созданной формы откроется окно редактора форм (рис. 7.173).
211
Глава 7. Командный интерфейс прикладных решений Элементы, обеспечивающие доступ к командам, расположены в командных панелях. В нашем случае система сформировала командную панель формы и командную панель таблицы товаров. Выбор любой из доступных команд можно осуществить из меню Все действия соответствующей командной панели. Для ускорения доступа к командам часть из них (наиболее важные или часто используемые) представлена кнопками непосредственно в командных панелях. Чем «руководствуется» система при формировании состава команд формы? Какие команды должны быть в форме? Для ответа на эти вопросы нужно вспомнить основное назначение формы – интерактивная обработка данных. Следовательно, в форме должны присутствовать команды, предоставляющие пользователю возможность обработать данные формы и возможность обратиться к данным, связанным с обрабатываемыми.
Для обработки данных формы – стандартные команды формы Рис. 7.173. Редактор формы с автоматически созданной формой документа
ПРИМЕЧАНИЕ
В редакторе форм основной реквизит формы выделяется жирным шрифтом.
Если открыть документ Расход товара в режиме 1С:Предприятие, мы увидим, что для работы с документом используется созданная нами форма (рис. 7.174).
В форме должны присутствовать команды для обработки данных и для управления формой. Эти возможности обеспечивают стандартные локальные команды формы. В редакторе форм они представлены на закладке Стандартные команды редактора команд (рис. 7.175). Эти команды предоставлены формой и расширением формы. Состав команд, предоставляемых формой, является стандартным и не зависит от данных формы – это команды Справка, Изменить форму…, Закрыть, Сохранить параметры…, Восстановить параметры… Состав команд, предоставляемых расширением, зависит от типа основного реквизита формы. В нашем случае основным реквизитом формы назначен реквизит Объект с типом данных ДокументОбъект.РасходТовара (см. рис. 7.175). Расширение, соответствующее этому типу данных, предоставило команды Провести и закрыть, Записать, Перечитать, Скопировать, Пометить на удаление/Снять пометку, Удалить, Провести и Отмена проведения. ВНИМАНИЕ!
Необходимо различать стандартные команды объекта конфигурации и стандартные команды формы. Первые используются в глобальном командном интерфейсе и предоставляются объектом конфигурации. Вторые же используются в форме и предоставляются самой формой, ее расширением и расширениями элементов формы, имеющих тип Таблица.
Рис. 7.174. Форма редактирования документа «Расход товара»
212
Профессиональная разработка в системе «1С:Предприятие 8»
«Командуем» формами в форме используется элемент Товары, имеющий тип Таблица. В состав стандартных локальных команд формы включены команды обработки табличных данных – узел Товары в редакторе команд (рис. 7.176).
Рис. 7.175. Стандартные команды формы в редакторе и интерфейсе
Для облегчения разработки алгоритмов управления формами в стандартные команды формы включены команды Да, Нет, OK, Отмена, Прервать, Пропустить, Повторить. Если такая команда добавлена в форму, то при ее выборе пользователем выполняются следующие действия: ■■ для формы, открытой в модальном режиме, выполняется закрытие формы, и возвращается соответствующее выбранной команде значение типа КодВозвратаДиалога; ■■ для формы, открытой в немодальном режиме, выполняется только закрытие формы. Если в составе элементов формы присутствуют таблицы, то в состав стандартных локальных команд формы добавляются команды, обеспечивающие обработку данных, отображаемых в этих элементах. У документа Расход товара есть табличная часть, которая в данных формы представлена реквизитом Товары. Для отображения списка товаров Том 1
Рис. 7.176. Стандартные команды таблицы в редакторе и интерфейсе
Для работы со связанными данными – глобальные параметризованные команды При обработке данных формы может возникнуть необходимость просмотреть данные, связанные с обрабатываемыми. Это может быть, например, набор записей в регистре взаиморасчетов с контрагентами, подчиненный обрабатываемому документу, или список цен на продаваемый товар и др. Также может потребоваться выполнить какую-либо обработку связанных данных, например, ввести документ оплаты на основании документа продажи или напечатать штрихкоды продаваемого товара и др.
213
Глава 7. Командный интерфейс прикладных решений Доступ к связанным данным обеспечивают глобальные параметризуемые навигационные команды, а обработку связанных данных – глобальные параметризуемые команды действий. В редакторе форм они представлены на закладке Глобальные команды редактора команд (рис. 7.177).
Если для команды в форме существует несколько источников, то команда представлена как узел дерева, а список источников – как элементы этого узла. В состав команд формы такую команду можно включить с любым из источников (или несколько экземпляров одной команды с разными источниками).
Для работы с функциональностью приложения – глобальные независимые команды При обработке данных формы может возникнуть необходимость воспользоваться функциональностью приложения, не связанной напрямую с обрабатываемыми данными. Например, при обработке данных документа нам необходимо выполнить поиск в данных или ввести новый вид цен. Выполнить эти операции помогут глобальные независимые команды. В редакторе форм они представлены на закладке Глобальные команды редактора команд (рис. 7.178).
Рис. 7.177. Глобальные параметризуемые команды в редакторе и интерфейсе
Эти команды предоставлены глобальным командным интерфейсом прикладного решения. Состав команд, доступный в форме, зависит от типа параметра параметризованной команды (см. раздел «Произвольные команды», стр. 193). В форме доступны те глобальные параметризованные команды, для которых в контексте формы можно получить значения параметра требуемого типа. В редакторе команд источник параметра для команды указывается в скобках после команды. Например, для команды открытия списка регистра продажи параметром выступает ссылка на редактируемый документ.
214
Рис. 7.178. Глобальные независимые команды в редакторе и интерфейсе
Профессиональная разработка в системе «1С:Предприятие 8»
«Командуем» формами Глобальные независимые команды предоставлены глобальным командным интерфейсом. В редакторе команд глобальные независимые команды сгруппированы по разделам глобального командного интерфейса. Команда будет доступна из всех разделов глобального командного интерфейса, в которые она включена.
Способы формирования состава команд формы Познакомившись с источниками команд формы, давайте посмотрим, какие варианты предоставляет нам система для формирования состава команд формы. ПРИМЕЧАНИЕ
Для формы есть еще один источник команд – разработчик, который может создавать произвольные локальные команды формы. Об этих командах мы поговорим немного позже (см. раздел «Если не хватает стандартных команд», стр. 230).
В самом общем случае существует три варианта: ■■ автоматический – состав команд формы определяется системой полностью автоматически; ■■ комбинированный – состав команд формы определяется системой автоматически, а разработчик, используя редактор форм, корректирует его; ■■ ручной – состав команд формы определяется полностью разработчиком.
Автоматическое формирование состава команд формы При автоматическом формировании состава команд система включает в форму: ■■ стандартные команды формы; ■■ глобальные параметризуемые команды, для параметров которых в форме есть значения подходящего типа. ВНИМАНИЕ!
Глобальные независимые команды автоматически в форму не включаются.
Для команд из различных источников система использует разные правила видимости по умолчанию: ■■ все стандартные команды формы видимы, ■■ все глобальные параметризуемые команды действия видимы, ■■ все глобальные параметризуемые навигационные команды невидимы. Для автоматического размещения команд система использует командную панель формы и панель навигации того вспомогательного окна (рис. 7.179), в котором форма отображается (в дальнейшем изложении – панель навигации формы).
Автоматический вариант является самым быстрым и наименее затратным с точки зрения разработки прикладного решения – система все делает самостоятельно. Комбинированный вариант, вероятно, используется чаще всего. При таком подходе разработчик вмешивается в работу системы только тогда, когда набор команд, сформированный системой, не обеспечивает требуемых функциональных возможностей по обработке данных формы. В подавляющем большинстве случаев вмешательство выражается в простом расширении состава команд формы. Ручной же вариант предоставляет максимум возможностей по управлению составом команд формы и их размещением. Однако он требует от разработчика выполнения значительного объема кропотливой работы.
Том 1
Рис. 7.179. Вспомогательное окно с формой документа «Расход товара»
215
Глава 7. Командный интерфейс прикладных решений
Стандартные команды формы Стандартные команды формы автоматически размещаются в командной панели формы. В нее всегда включаются все команды, предоставленные расширением формы, а также команда Справка, предоставленная формой (рис. 7.180).
Рис. 7.181. Команда настройки формы
Включение в командную панель команд Сохранить параметры… и Восстановить параметры… определяется значением свойства формы Сохранение данных в настройках. По умолчанию это свойство имеет значение Не использовать, и команды не включаются в командную панель (рис. 7.182). Рис. 7.180. Командная панель формы заполнена автоматически
Включение в командную панель команды Изменить форму… определяется значением свойства формы Разрешить изменять форму. По умолчанию свойство имеет значение Истина, и команда включается в командную панель (рис. 7.181).
216
Профессиональная разработка в системе «1С:Предприятие 8»
«Командуем» формами
Рис. 7.182. Команды сохранения и восстановления параметров
ПРИМЕЧАНИЕ
Часть команд отображается непосредственно в командной панели и в меню Все действия, а часть – только в меню Все действия.
Если в составе элементов формы присутствуют таблицы, то для размещения команд обработки табличных данных также используется командная панель. В дереве элементов формы она располагается сразу под соответствующим табличным элементом (рис. 7.183).
Рис. 7.183. Команды обработки табличных данных
ПРИМЕЧАНИЕ
При автоматическом формировании набора команд формы списка форма имеет объединенную командную панель, в которой размещены как команды формы, так и команды таблицы.
Глобальные параметризуемые команды При автоматическом формировании состава команд в форму включаются только те глобальные параметризуемые команды, которые в качестве параметра могут принимать ссылку на основной реквизит формы или на реквизиты основного реквизита формы. Размещение по умолчанию глобальных параметризуемых команд определяется их категорией и группой.
Том 1
217
Глава 7. Командный интерфейс прикладных решений Категории стандартных команд предопределены и не могут быть изменены. А вот группу (внутри категории), в которой будет размещена команда, разработчик может изменить.
Для включения произвольной глобальной параметризуемой команды в командную панель формы в свойстве Группа этой команды должна быть выбрана группа команд с категорией Командная панель формы.
Категория и группа произвольных (как общих, так и подчиненных) команд определяются разработчиком путем выбора значения в свойстве Группа этой команды (см. раздел «Особенности размещения», стр. 196).
Например, в созданной нами форме в командную панель формы включена команда Поступление денег, которая создает соответствующий документ на основании обрабатываемого документа расхода (см. рис. 7.184). Для команды в качестве параметра передается ссылка на обрабатываемый документ (из свойства Ссылка основного реквизита формы).
Разработчик может настроить видимость автоматически включенных в форму глобальных параметризуемых команд. А вот удалить их система не позволит. Глобальные параметризуемые команды действий размещаются в командной панели формы. В редакторе формы эти команды отображаются на закладке Командный интерфейс редактора команд (рис. 7.184).
Глобальные параметризуемые навигационные команды размещаются в панели навигации формы. В редакторе формы эти команды отображаются на закладке Командный интерфейс редактора команд (рис. 7.185).
Рис. 7.185. Глобальная параметризуемая навигационная команда в форме
Для включения произвольной глобальной параметризуемой команды в панель навигации формы в свойстве Группа этой команды должна быть выбрана группа команд с категорией Панель навигации формы. ПРИМЕЧАНИЕ Рис. 7.184. Глобальная параметризуемая команда действий в форме
218
По умолчанию эти команды невидимы и панель навигации не отображается. Отображение панели навигации формы мы настроили в пользовательском режиме.
Профессиональная разработка в системе «1С:Предприятие 8»
«Командуем» формами Например, в созданной нами форме в панель навигации формы включена команда Регистр продаж, которая открывает список записей регистра продаж, сформированных обрабатываемым документом (см. рис. 7.185). Для команды в качестве параметра передается ссылка на обрабатываемый документ (из свойства Ссылка основного реквизита формы). ВНИМАНИЕ!
Если форма (например, форма списка документов) открывается в основном окне приложения, то панель навигации формы не отображается (независимо от настройки видимости навигационных команд), и команды, размещенные в ней, недоступны.
ПРИМЕЧАНИЕ
Для исключения ошибок времени выполнения менеджеру по ценам установим право Чтение на справочники Склады, Организации и Валюты.
Для пользователя Администратор установлены все права на документ Расход товара. При построении формы документа (и формы списка документов) в состав доступных включены все стандартные команды формы, включенные в нее на этапе разработки (рис. 7.186).
Доступность команд формы для пользователя При создании формы для пользователя прикладного решения система учитывает его права, определяемые ролью, и значения функциональных опций. Из этого следует, что набор команд формы, доступный конкретному пользователю, может отличаться от состава команд, включенных в форму на этапе разработки. Как и в случае с видимостью, для команд из разных источников система использует разные правила для автоматического определения их доступности: ■■ доступность стандартных команд, предоставленных формой, не зависит от ролевой настройки прав и значений функциональных опций; ■■ доступность стандартных команд, предоставленных расширением основного реквизита формы, зависит от ролевой настройки прав пользователя, а значения функциональных опций на доступность команд не влияют; ■■ доступность глобальных команд зависит от ролевой настройки прав пользователя и значений функциональных опций. Для демонстрации влияния ролевой настройки прав на доступный пользователю набор команд включим документ Расход товара в подсистему Ценообразование. Подробнее
Механизм включения описан в разделе «Стандартные команды», стр. 157.
Для роли Менеджер по ценам установим права Чтение и Просмотр на документ. Для подчиненной документу произвольной команды Печать расходной накладной право Просмотр снимем. Подробнее
Механизм установки прав описан в разделе «Система прав доступа», стр. 161.
Том 1
Рис. 7.186. Стандартные команды, доступные пользователям с разными ролями
Для пользователя же с ролью Менеджер по ценам разрешен только просмотр документов Расход товара. При построении формы документа (и формы списка документов) для этого пользователя система исключила из состава доступных команды расширения основного реквизита, выполняющие запрещенные пользователю операции с документом – создания, удаления, проведения документа и т. д. (см. рис. 7.186). Доступность глобальных команд в форме определяется их доступностью в глобальном командном интерфейсе, который формируется при запуске системы от имени того или иного пользователя.
219
Глава 7. Командный интерфейс прикладных решений Это значит, что команды, недоступные пользователю в глобальном командном интерфейсе, также недоступны ему в форме. Например, для пользователя Администратор установлено право на использование команды печати документа Расход товара. При построении формы документа (и формы списка документов) в состав доступных включена эта глобальная команда (рис. 7.187).
Для демонстрации их влияния на доступность команд формы добавим подчиненную справочнику Виды цен произвольную команду Печать ценников для вида цены в группу печатные формы командной панели. Для этой команды установлена зависимость от функциональной опции Ценообразование по видам цен. В случае, когда эта функциональная опция имеет значение Истина, команда печати ценников для вида цен включена в состав доступных команд формы (рис. 7.188).
Рис. 7.187. Глобальные команды, доступные пользователям с разными ролями
В отличие от администратора, пользователь Менеджер по ценам не имеет права на печать документа Расход товара. При построении формы документа (и формы списка документов) для этого пользователя система исключила из состава доступных команду печати расходной накладной (см. рис. 7.187). Помимо набора прав, на состав глобальных команд, доступных пользователю в форме, влияют значения функциональных опций.
Рис. 7.188. При истинном значении функциональной опции команда печати ценников доступна
Подробнее
Раздел «Управляем командами формы», стр. 221.
220
Профессиональная разработка в системе «1С:Предприятие 8»
«Командуем» формами В случае же, когда функциональная опция имеет значение Ложь, команда в форме недоступна, хотя в редакторе она включена в состав команд формы (рис. 7.189).
Управляем командами формы Начнем с настройки командной панели формы. Ее отображением для пользователя (и ее положением) может управлять разработчик. Вариант размещения командной панели в форме определяется значением свойства формы Положение командной панели. По умолчанию значением свойства является Авто и командная панель присутствует в форме. Если же для свойства установить значение Нет, то в форме командной панели не будет (рис. 7.190).
Рис. 7.189. При ложном значении функциональной опции команда печати ценников недоступна
Рис. 7.190. Управление наличием командной панели в форме
Естественно, в этом случае будут недоступны все команды, размещаемые в командной панели формы.
Том 1
221
Глава 7. Командный интерфейс прикладных решений Кроме возможности полного отключения командной панели, разработчик может управлять вариантом ее «наполнения» командами. Для этого используется свойство Автозаполнение.
Мы не будем формировать набор команд полностью в ручном режиме. Нам достаточно разобраться в том, как этот набор изменить (по сравнению с автоматическим режимом).
В случае, когда флажок Автозаполнение сброшен (рис. 7.191), состав команд панели формируется разработчиком вручную.
Комбинируя возможность автозаполнения командной панели и возможность ручного управления составом команд, можно с минимальными затратами времени и сил сформировать требуемый состав команд формы.
Стандартные команды формы Состав используемых стандартных команд формы можно определить в свойстве формы (и в свойстве таблицы) Состав команд. Настройка выполняется в окне Состав, вызываемом через гиперссылку Открыть (рис. 7.192).
Рис. 7.191. Автозаполнение у командных панелей отключено
При установленном флажке состав команд формируется автоматически – так, как было описано ранее. Но и в случае автозаполнения система позволяет разработчику повлиять на состав команд, включаемых в командную панель формы (и в командную панель таблицы).
222
Рис. 7.192. Настройка состава доступных стандартных команд формы
Для исключения команды необходимо снять флажок рядом с соответствующей командой. Снимем флажки у команд Перечитать и Скопировать. Эти команды исключены и из состава доступных пользователю, и из состава команд формы в редакторе команд, то есть они становятся недоступными и разработчику (рис. 7.193).
Профессиональная разработка в системе «1С:Предприятие 8»
«Командуем» формами В результате в дереве элементов появился новый элемент формы с типом Кнопка, подчиненный элементу Командная панель, и открылось окно свойств добавленного элемента. Свойство Команда автоматически заполнено значением Закрыть – командой, которую мы перетащили в командную панель (рис. 7.194).
Рис. 7.193. «Выключенные» стандартные команды в интерфейсе отсутствуют
ПРИМЕЧАНИЕ
При формировании состава командной панели свойство Состав команд имеет более высокий приоритет, чем свойства Разрешить изменять форму и Сохранение данных в настройках.
Для добавления команды в форму необходимо создать элемент формы Кнопка, который позволяет вызвать выполнение команды, и связать с этим элементом добавляемую команду. Обычно кнопка располагается в командной панели – подчинена узлу Командная панель в дереве элементов формы. Команда, вызываемая кнопкой, задается в свойстве кнопки Имя команды. Проще всего перетащить команду из окна редактора команд на командную панель или на форму в дереве элементов. В этом случае связывание кнопки и команды выполняется автоматически. Перетащим команду Закрыть на командную панель формы.
Том 1
Рис. 7.194. Форма с добавленной вручную командой «Закрыть»
Для добавленной вручную команды разработчик может настроить доступность и видимость команды, ее расположение и представление, вариант отображения команды и другие аспекты ее поведения. Настройка выполняется путем задания значений свойствам того элемента формы, с которым команда связана.
223
Глава 7. Командный интерфейс прикладных решений ВНИМАНИЕ!
Фактически выполняется настройка не самой команды, а элемента формы, с которым команда связана.
Место отображения добавленной команды в командной панели можно настроить. Для этого используется свойство кнопки Только во всех действиях: ■■ Да – команда размещается только в меню Все действия; ■■ Нет – команда размещается и в меню Все действия, и в командной панели; ■■ Авто – решение о месте размещения команды принимается системой. Для кнопки Закрыть оставим значение по умолчанию Авто (рис. 7.195) – команда будет доступна и непосредственно в командной панели, и в меню Все действия.
Рис. 7.195. Выбор варианта размещения команды в командной панели
ВНИМАНИЕ!
Если все доступные команды отображаются кнопками в командной панели, меню Все действия в командной панели отсутствует.
Для настройки представления команды используются свойства Заголовок, Отображение.
224
Свойство Заголовок позволяет задать текст, представляющий команду. Для кнопки Закрыть зададим текст «Закрыть форму». Свойство Отображение позволяет задать вариант представления команды: ■■ Текст – в представлении команды присутствует только текст; ■■ Картинка – в представлении команды присутствует только пиктограмма; ■■ Картинка и текст – в представлении команды присутствует и текст, и пиктограмма; ■■ Авто – решение о представлении команды принимает система. Для кнопки Закрыть зададим значение Текст. В результате наших настроек представление команды Закрыть изменилось (рис. 7.196).
Рис. 7.196. Измененное представление команды «Закрыть»
ПРИМЕЧАНИЕ
Если для кнопки определена пиктограмма, то в меню Все действия в любом случае отображается и текст, и пиктограмма.
Кроме размещения, может потребоваться настроить доступность команды (без удаления ее из командной панели). Для этого используется свойство Профессиональная разработка в системе «1С:Предприятие 8»
«Командуем» формами Доступность кнопки, с которой связана команда. Если для команды Закрыть снять флажок в свойстве Доступность, то команда станет недоступной
для выбора пользователем. В интерфейсе недоступные команды имеют «бледный» вид – отображаются серым цветом (рис. 7.197).
Рис. 7.198. Свойства, управляющие видимостью команды
При настройке видимости можно:
Рис. 7.197. Командная панель с недоступной командой «Закрыть»
Кроме доступности, разработчик может управлять и видимостью команды. Для этого используются свойства кнопки Видимость и Пользовательская видимость (рис. 7.198). Свойство Видимость предназначено для настройки видимости команды в соответствии с реализуемой разработчиком логикой работы прикладного решения. Настройка видимости выполняется установкой (команда видима) или снятием (команда невидима) флажка у свойства. При эксплуатации прикладного решения пользователь не может изменить значение свойства Видимость. Свойство Пользовательская видимость определяет, какие команды в форме будут видимы по умолчанию, а какие по умолчанию скрыты. Состав видимых по умолчанию команд можно настроить в разрезе ролей. Настройка пользовательской видимости выполняется в окне Настройка видимости, вызываемом через гиперссылку Открыть свойства (см. рис. 7.198). Том 1
■■ установить общую видимость по умолчанию – флажок Видимость; определяет видимость для тех ролей, у которых флажок установлен в «третье» значение (серый фон); ■■ установить видимость по умолчанию в разрезе ролей – элементы списка Видимость по ролям; определяет видимость по умолчанию для конкретной роли. При определении видимости по умолчанию для конкретного пользователя значения, установленные для его ролей, складываются по логическому ИЛИ. При эксплуатации прикладного решения пользователь имеет возможность изменить значение свойства Пользовательская видимость. ПРИМЕЧАНИЕ
Для вызова окна настройки используется команда Настроить форму… Если пользователь перенастроил видимость команд по умолчанию, то система при создании формы для определения видимости команд будет учитывать и настройки разработчика, и настройки пользователя. ВНИМАНИЕ!
Для пользователя будут видимы только те команды, у которых установлено и свойство Видимость, и свойство Пользовательская видимость.
225
Глава 7. Командный интерфейс прикладных решений Давайте для команды Закрыть свойство Видимость установим, а пользовательскую видимость определим следующим образом (см. рис. 7.198): ■■ общая видимость установлена, ■■ для роли Менеджер по ценам видимость сброшена, ■■ для остальных ролей видимость имеет «третье» значение. Теперь при запуске системы от имени менеджера по закупкам команда Закрыть по умолчанию невидима, а для остальных ролей она видима (рис. 7.199).
Рис. 7.200. Добавление элемента формы «Группа – Группа кнопок»
Рис. 7.199. Ограничение видимости команды по умолчанию для роли
При настройке размещения команды в командной панели можно объединять в логические группы. Для этого используется элемент формы с типом Группа. Давайте выделим в отдельную группу команду Закрыть. Сначала добавим в командную панель подчиненный элемент с типом Группа – группа кнопок (рис. 7.200). В дереве элементов появится новый, и для него откроется окно свойств (рис. 7.201). Заполним свойства элемента формы: ■■ Имя – «ГруппаЗакрыть»; ■■ Заголовок – «Группа закрыть» (используется, когда группа имеет вид Подменю); ■■ Подсказка – «Команды закрытия формы».
226
Рис. 7.201. Группа с командой «Закрыть»
Профессиональная разработка в системе «1С:Предприятие 8»
«Командуем» формами Теперь перетащим на группу кнопку Закрыть. В результате нашей настройки команды, принадлежащие группе, в интерфейсе визуально выделены разделителями (см. рис. 7.201). Как и для кнопки, для группы кнопок можно настраивать доступность и видимость. Настройки, сделанные для группы, будут применены ко всем командам, включенным в эту группу. Помимо командной панели, кнопку можно расположить и непосредственно на форме – подчинить узлу Форма в дереве элементов формы. Это можно сделать так же, как и при заполнении командной панели – перетаскиванием команды. Однако перетащить команду необходимо не на узел Командная панель, а на узел Форма в дереве элементов формы. Также можно воспользоваться командой Добавить (аналогично тому, как мы добавляли группу) и выбрать добавляемый элемент формы с типом Кнопка. ВНИМАНИЕ!
В случае использования команды Добавить не происходит автоматического связывания элемента формы Кнопка с командой. Разработчик должен настроить связь самостоятельно в свойстве кнопки Команда.
Добавим новую кнопку командой. В результате в дереве элементов появится новый элемент с типом Кнопка, подчиненный элементу Форма, и откроется окно свойств добавленного элемента (рис. 7.202).
Переместим кнопку под командную панель формы. Для этого используем команды перемещения Вверх/Вниз (или клавиатурные сокращения Ctrl + Shift + Up и Ctrl + Shift + Down). ПРИМЕЧАНИЕ
Для кнопок, автоматически размещенных системой в командной панели, изменить порядок их следования невозможно.
Заполним свойства кнопки (см. рис. 7.202): ■■ ■■ ■■ ■■
Имя – «ОтменаПроведения»; Заголовок – «Отмена проведения»; Отображение – «Картинка и текст»; Картинка – «Отмена проведения».
Для свойства Имя команды выберем в диалоге выбора команд вызываемую команду Отмена проведения. В диалоге выбора команды можно выбрать не только стандартные команды формы, а вообще все команды, доступные в контексте формы. Для выбора команд служат соответствующие закладки диалога – Команды формы, Стандартные команды и Глобальные команды. В результате выполненных действий в форме появилась новая кнопка, расположенная под командной панелью формы (рис. 7.203).
Рис. 7.203. Добавленная команда в интерфейсе
ПРИМЕЧАНИЕ
Если кнопка добавляется в командную панель и с ней связывается команда, уже автоматически размещенная системой в этой командной панели, добавляемая команда замещает существующую. Рис. 7.202. Кнопка на форме, связанная с командой «Отмена проведения»
Том 1
227
Глава 7. Командный интерфейс прикладных решений Для кнопки, расположенной на форме, применимы те же настройки, что и для кнопки командной панели. ПРИМЕЧАНИЕ
Команды, связанные с кнопками формы, недоступны в меню Все действия командной панели формы.
На этом мы закончим рассмотрение стандартных локальных команд формы и займемся глобальными командами.
Глобальные команды Разработчик может расширить (по сравнению с автоматически размещенными) состав глобальных команд, доступных в форме. При этом система не ограничивает разработчика в выборе места размещения добавляемой команды. Однако следует учитывать, что в панели навигации рекомендуется располагать «безопасные» команды – те, которые не приводят к модификации данных, не запускают обработки и т. д. Основное назначение команд в панели навигации – сформировать контекст выполнения каких-либо действий по обработке данных. Соответственно, в командной панели формы рекомендуется размещать команды, которые обрабатывают данные – заполняют, пересчитывают, печатают, записывают в информационную базу и т. д. С другой стороны, система не позволит удалить из формы автоматически включенные глобальные команды. Она позволит лишь настроить их видимость и размещение. Как и для стандартных, добавление глобальных команд проще всего выполнить перетаскиванием требуемой команды из редактора команд (закладка Глобальные команды) в редактор командного интерфейса (закладка Командный интерфейс), в узел Панель навигации или в узел Командная панель. Например, добавим в форму глобальную параметризованную команду действия Печать штрихкода, которая подчинена справочнику Товары. Команда является командой действия, поэтому добавим ее в группу Печатные формы командной панели формы (рис. 7.204).
Рис. 7.204. Глобальная команда, добавленная вручную
При необходимости разработчик может настроить видимость и размещение глобальных параметризованных команд. При этом для команд, помещенных в форму автоматически, необходимо сбросить соответствующие признаки – Автовидимость и Автоположение. В противном случае будет использована видимость и размещение команд, формируемые системой по умолчанию. ПРИМЕЧАНИЕ
Для команд, добавленных вручную, система не определяет признаки Автовидимость и Автозаполнение, то есть разработчик самостоятельно размещает команды и устанавливает их видимость.
Настройку размещения можно выполнить перетаскиванием команды мышью в нужную группу. Настройка видимости выполняется в окне Настройка видимости по правилам, совпадающим с настройкой видимости элементов формы Кнопка.
228
Профессиональная разработка в системе «1С:Предприятие 8»
«Командуем» формами Давайте переместим команду Печать расходной в группу Важное и сделаем ее невидимой по умолчанию для роли Менеджер по ценам (рис. 7.205).
Теперь добавим в форму глобальную параметризованную навигационную команду Цены товаров. Эта команда не предназначена для обработки данных, поэтому добавим ее в панель навигации формы, в группу См. также (рис. 7.207).
Рис. 7.205. Настройка размещения и видимости добавленной глобальной команды
В результате выполненной настройки для пользователя с ролью Менеджер по ценам команда печати невидима, а для остальных ролей – видима (рис. 7.206).
Рис. 7.207. Добавлена глобальная навигационная команда «Цены товаров»
Настройка видимости и размещения команд в панели навигации выполняется аналогично настройке команд в командной панели. Видимость по умолчанию для команды изменять не будем – она будет видима всем ролям. Обратите внимание: для роли Менеджер по ценам появилась доступная навигационная команда, причем она видима по умолчанию. Вследствие этого во вспомогательном окне с формой документа Расход товара отобразилась панель навигации с добавленной командой (см. рис. 7.207). Теперь мы знаем, как сформировать набор команд формы, используя стандартные команды формы и глобальные команды командного интерфейса. Рис. 7.206. Для разных ролей у команды «Печать расходной» различная видимость по умолчанию
Том 1
А что делать, если функциональности этих команд не хватает? Об этом мы поговорим в следующем разделе.
229
Глава 7. Командный интерфейс прикладных решений
Если не хватает стандартных команд В случае, когда для реализации функциональных возможностей формы стандартных команд не хватает, разработчик может создать необходимое количество произвольных команд формы. Такие команды создаются в редакторе команд на закладке Команды формы. Давайте создадим произвольную команду подбора товаров в документе Расход товара. Для создания произвольной команды воспользуемся командой Добавить на закладке Команды формы в редакторе команд. В результате в список произвольных команд формы будет добавлена новая команда и для нее откроется окно свойств (рис. 7.208).
Рис. 7.209. Произвольная команда формы добавлена в интерфейс
ПРИМЕЧАНИЕ
Как и для произвольных глобальных команд, сам функционал команды мы реализовывать не будем.
Рис. 7.208. Добавление произвольной команды формы
Заполним для команды свойства: ■■ Имя – «ПодборТовара»; ■■ Заголовок – «Подбор товара»; ■■ Подсказка – «Подбор товара для продажи». Для произвольной команды формы необходимо написать программный код исполнения.
230
Процедура исполнения команды располагается в модуле формы. Используя свойство Действие произвольной команды, необходимо связать команду с процедурой исполнения. Также можно выбрать команду Открыть (кнопка с лупой справа от поля выбора свойства Действия). В этом случае в модуле формы будет объявлена процедура исполнения команды, и эта процедура автоматически будет выбрана в свойстве Действия (см. рис. 7.208). Разработчику останется только написать программный код исполнения команды. Для предоставления пользователю доступа к созданной команде последнюю необходимо связать с элементом формы типа Кнопка, аналогично стандартным командам формы. Профессиональная разработка в системе «1С:Предприятие 8»
«Командуем» формами Перетащим команду в редактор элементов на командную панель таблицы Товары. В результате пользователь получил возможность выбора команды Подбор товара из командной панели таблицы товаров (рис. 7.209). Настройка размещения и видимости произвольных команд выполняется аналогично настройке стандартных команд – и стандартная, и произвольная команды связываются с элементом формы одного и того же типа Кнопка. А доступность и видимость фактически настраиваются уже для этого элемента. Кроме настройки доступности элемента формы, для произвольной команды разработчик может настроить ее доступность в разрезе ролей с помощью свойства Использование самой команды. Настройка выполняется в диалоговом окне Настройка использования (рис. 7.210).
■■ доступность команды для конкретной роли пользователя – если рядом с ролью в списке Использование по ролям флажок установлен, то команда доступна для роли; если сброшен, то недоступна; если же флажок установлен в «третье» значение (на сером фоне), то для роли используется значение общей доступности. Например, для пользователя с ролью Менеджер по ценам команда Подбор товара недоступна (флажок сброшен), см. рис. 7.210. Для этого пользователя в командной панели таблицы Товары команды нет. Доступность произвольных команд также можно поставить в зависимость от значений функциональных опций. Для такой настройки используется свойство команды Функциональные опции. Например, зададим зависимость команды Подбор товара от значения функциональной опции Работа с торговым оборудованием (рис. 7.211).
Рис. 7.211. Настройка доступности произвольной команды от функциональной опции Рис. 7.210. Настройка доступности произвольной команды в разрезе ролей
При этом разработчик может определить: ■■ общую доступность команды – если флажок Использование в диалоговом окне установлен, то команда доступна всем ролям с «третьим» значением флажка; Том 1
Для одного и того же пользователя при истинном значении функциональной опции команда доступна, а при ложном – недоступна (рис. 7.212). ВНИМАНИЕ!
Свойства команды Доступность и Функциональные опции имеют приоритет перед свойствами элемента управления Кнопка.
231
Глава 7. Командный интерфейс прикладных решений В состав команд формы входят: ■■ стандартные команды формы – обеспечивают работу с формой; ■■ стандартные команды расширения основного реквизита формы – обеспечивают обработку данных формы; ■■ стандартные команды расширений табличных элементов формы – обеспечивают обработку данных формы; ■■ произвольные команды формы – назначение команды определяется разработчиком; Глобальные команды, доступные в форме, включают в себя: ■■ независимые глобальные команды; ■■ часть параметризованных глобальных команд – те, для которых в форме существует источник параметра требуемого типа. При разработке командного интерфейса формы разработчик должен ответить на вопросы:
Рис. 7.212. Зависимость доступности команды от значения функциональной опции
Краткие итоги Все команды, которые могут присутствовать в форме, можно разделить на два класса (рис. 7.213): ■■ локальные команды формы – обеспечивают доступ к функциональности формы; ■■ глобальные команды – обеспечивают доступ к функциональности приложения.
■■ какие действия нужно будет выполнять с данными – для обработки данных используются команды формы; ■■ какие дополнительные данные (помимо данных формы) должны быть доступны и какие дополнительные действия (помимо обработки данных формы) необходимо выполнять – для обеспечения этой функциональности используется подмножество глобальных команд; ■■ каким пользователям будут доступны команды – выполнить ролевую настройку доступности; ■■ как должна выглядеть форма – настроить размещение и видимость команд. Для редактирования состава команд формы, их расположения и видимости используется редактор формы. В редакторе формы описывается состав команд командной панели формы и состав команд панели навигации вспомогательного окна приложения, в котором форма отображается. Часть команд в командную панель и в панель навигации помещается системой автоматически. В редакторе форм разработчик эти команды удалить не может, но он может настроить видимость этих команд в разрезе ролей пользователей. Для того чтобы пользователь смог вызвать команду, она должна быть связана с элементом формы Кнопка (закладка Элементы редактора форм) или помещена в командный интерфейс (закладка Командный интерфейс редактора форм).
Рис. 7.213. Классификация команд формы
232
Профессиональная разработка в системе «1С:Предприятие 8»
Конструирование форм
Глава 8. Разработка форм Конструирование форм
Форма «1С:Предприятия» Концепция построения форм В данном разделе будет освещаться вопрос создания и конструирования управляемых форм в режиме Конфигуратор. Форма является важнейшим связующим звеном в цепи «пользователь – данные». Именно в формах мы редактируем данные, вводим новую информацию, видим результаты работы. Формы «1С:Предприятия» наделены различными возможностями, как построения, так и отображения данных. В большинстве случаев от разработчика не требуется заботиться о том, как на экране будет выглядеть тот или иной элемент, система сама сможет позаботиться об этом. От разработчика требуется правильно настроить интерфейсные свойства объекта конфигурации, на основании которых и будет построено нужное представление. Управляя размещением элементов в форме, разработчик должен «посоветовать» системе те или иные способы группировки элементов, порядок их размещения. Естественно, платформа предоставляет возможности взять под контроль некоторые этапы разработки формы, но данное действие не является приоритетным. Задача разработчика состоит не в детальном, «попиксельном», размещении элементов на форме, не в описании сложных привязок, а в логическом описании состава формы. Необходимо описать состав формы в виде дерева элементов, которые будут отображать данные, добавить в описание необходимые реквизиты и команды. Скомпоновать элементы в логические группы, определить порядок обхода элементов формы.
Существует возможность перенастройки командных панелей формы, дополнительных кнопок у элементов формы, объединения элементов в группы, распределения их по страницам, настройки колонок списков. Однако все эти возможности призваны лишь помочь системе в построении формы, а не полностью заменить это построение ручным способом. Помимо простого открытия форм для просмотра или редактирования данных, существует возможность открытия с установленным отбором, с выделением каких-либо конкретных данных из общего числа. Помочь в этом может, например, программная установка отборов и параметризированные команды. При построении форм системой учитываются не только настройки самой формы, сделанные разработчиком. Влияние на поведение формы и ее элементов оказывают настройки прав пользователей, ролей, доступных пользователю, применяемые к сеансу работы приложения функциональные опции – тоже новшество управляемого приложения, настройки, которые делал сам пользователь в сеансе своей работы. Отдельно стоит упомянуть о возможностях форм сообщать пользователю об ошибках, возникающих в процессе работы. Например, это может быть сообщение о незаполненном поле, данные в которое должны быть внесены обязательно. Система сообщит о таком типе ошибки, выделив и активизировав именно этот элемент.
Формы как элемент общения программы с пользователем Помимо «стандартных» форм различных объектов конфигурации (справочников, документов, регистров и пр.), существует одна особенная форма – рабочий стол. Именно с него и начинается работа пользователя с системой.
Полученное от разработчика описание формы, другие факторы, влияющие на внешний вид и функциональность формы, помогут системе построить форму на экране и тем самым освободить ресурсы разработчика не для «рисования», а для разработки функциональности конкретного прикладного решения.
Можно сказать, что рабочий стол призван быть лицом разрабатываемого приложения, его визитной карточкой. Именно на рабочий стол необходимо при проектировании интерфейса приложения выносить всю необходимую в первую очередь информацию. Это могут быть списки наиболее часто используемых документов, справочников, данные отчетов, формы обработок.
Разработчик может влиять на расположение и внешний вид элементов формы. Для этого у него в руках инструмент свойств элементов формы.
Сказать, что на рабочем столе отображаются просто данные, неверно. На рабочем столе отображаются формы других объектов конфигурации.
Том 1
233
Глава 8. Разработка форм И, как уже было сказано ранее, на рабочий стол оказывает влияние все то, что способно повлиять на любую форму прикладного решения – права доступа, функциональные опции, настройки пользователя. Именно отображение других форм и выделяет рабочий стол из всех форм конфигурации. Подробнее
Раздел «Рабочий стол», стр. 279.
Формы «1С:Предприятия» являются независимыми от объектов конфигурации. Это означает, что форма может быть подчинена какому-либо объекту конфигурации, например справочнику, но отображать данные совсем другого объекта, например, документа. Для формы может быть назначен основной реквизит, который частично определяет поведение формы, то, какие данные в такой форме можно просматривать, редактировать, как будет вести себя форма в той или иной ситуации.
Процесс создания и открытия формы, отображающей объектные данные (у формы определен основной реквизит), выглядит так: ■■ ■■ ■■ ■■
объект считывается из базы данных на сервере; объект конвертируется в данные формы (создание формы на сервере); объект удаляется из памяти; данные формы передаются на клиента (создание формы на клиенте).
Запись данных формы в информационную базу происходит только на сервере: ■■ ■■ ■■ ■■
данные формы получаются с клиента, данные формы конвертируются в объект, объект записывается в базу данных, объект удаляется из памяти.
Графически все вышесказанное можно изобразить в виде схемы (рис. 8.1).
Некоторые формы открываются не в окне основного приложения, а в отдельном вспомогательном окне. Таким образом, переключаться между формами в некоторых случаях можно с помощью панели задач операционной системы. Для навигации по прикладному решению существует основное окно. Для решения задач, не связанных с навигацией по приложению, например, создание новых элементов справочников, добавление документов, подготовка отчетности, используются вспомогательные окна. Количество вспомогательных окон платформой не ограничивается. Модальные окна применяются для вспомогательных задач, например, ввод и выбор каких-либо данных. «1С:Предприятие» позволяет вообще не описывать форму в конфигураторе. При обращении к объекту в пользовательском режиме система сгенерирует необходимую форму самостоятельно. Если разработчиком прикладного решения не планируется вносить изменения в работу и поведение формы, например, менять порядок обхода элементов, добавлять команды, описывать с помощью встроенного языка алгоритмы заполнения, то создавать форму в режиме Конфигуратор необязательно.
Рис. 8.1. Взаимодействие формы и базы данных
Среда существования формы
В процессе своего создания форма проходит через определенный фильтр различных факторов (рис. 8.2), влияющих на ее внешний вид. Это совокупность ролей (прав доступа), назначенных пользователю разработчиком прикладного решения, функциональные опции приложения, настройки, сделанные пользователем в предыдущем и текущем сеансе работы.
Форма существует одновременно и на сервере, и на клиенте. Связь элементов формы с данными информационной базы осуществляется с помощью реквизитов формы (данные формы). Все данные, которые планируется отображать или редактировать в форме, должны быть обязательно описаны в виде реквизитов.
Между клиентом и сервером происходит обмен не только данными формы, но и ее оформительскими свойствами. К оформительским относятся все свойства формы, влияющие на ее внешний вид. Таким образом, достигается полное соответствие внешнего вида формы и на клиенте, и на сервере.
234
Профессиональная разработка в системе «1С:Предприятие 8»
Конструирование форм
Рис. 8.3. Выбор типа общей формы
Рис. 8.2. Процесс открытия формы
Создание формы Создание формы с помощью конструктора
Флажок Использовать стандартные команды позволяет автоматически добавить в интерфейс подсистемы, в состав которой будет входить форма, команды ее открытия. Существует несколько способов создать форму, подчиненную какомулибо объекту конфигурации: ■■ воспользоваться кнопкой Открыть (рис. 8.4) в палитре свойств объекта конфигурации, у нужного типа формы;
Создание новой формы начинается с конструктора форм. Модификация формы, созданной конструктором, осуществляется в редакторе формы. Подробнее
Раздел «Редактирование формы», стр. 240.
В конфигурации могут существовать формы, подчиненные объектам конфигурации, и общие формы. Общие формы располагаются в дереве конфигурации, в ветке Общие – Общие формы. Конструктор форм различает, какая форма будет создаваться – подчиненная объекту или общая. При создании общей формы конструктор предлагает выбрать тип формы из двух возможных (рис. 8.3): ■■ Произвольная форма – данные, с которыми будет взаимодействовать форма, будут определены разработчиком в дальнейшем, в процессе разработки; ■■ Форма констант – форма, с помощью которой будет осуществляться взаимодействие с константами конфигурации. По умолчанию конструктор общих форм предлагает создать произвольную форму. Связано это с тем, что, как правило, форма редактирования констант в прикладном решении одна, и в подавляющем большинстве случаев разработчик будет создавать именно произвольные общие формы.
Рис. 8.4. Создание формы кнопкой «Открыть»
■■ выделить в дереве конфигурации ветвь Формы объекта, для которого будет создаваться форма, и воспользоваться либо контекстным меню, либо кнопкой Добавить на панели дерева конфигурации (рис. 8.5);
Рис. 8.5. Создание формы кнопкой «Добавить»
Том 1
235
Глава 8. Разработка форм ■■ открыть окно редактирования объекта конфигурации, перейти на закладку Формы и воспользоваться либо кнопкой Открыть у необходимого типа формы, либо кнопкой командной панели этого окна Добавить, либо контекстным меню в списке форм (рис. 8.6).
■■ для объекта Журнал документов – это форма журнала (рис. 8.9);
Рис. 8.9. Типы форм объекта «Журнал документов»
■■ для объекта Отчет – это форма отчета, варианта, настроек (рис. 8.10);
Рис. 8.6. Создание формы из окна редактирования объекта
При использовании любого из вышеперечисленных способов будет открыто окно конструктора формы объекта конфигурации. В зависимости от вида объекта, его свойств конструктором будут предложены характерные для текущего режима создания типы форм: ■■ для объекта Справочник это будет форма списка, выбора, элемента. Если справочник иерархический, то возможно создание формы группы и выбора группы (рис. 8.7);
Рис. 8.10. Типы форм объекта «Отчет»
■■ для объекта Обработка это форма обработки (рис. 8.11);
Рис. 8.11. Типы форм объекта «Обработка»
■■ для объекта План видов характеристик – это форма списка, выбора, вида. Если план видов характеристик иерархический, то возможно создание формы группы и выбора группы. Если объект неиерархический, то создание форм группы недоступно (рис. 8.12);
Рис. 8.7. Типы форм объекта «Справочник»
■■ для объекта Документ – это форма списка, выбора, документа (рис. 8.8);
Рис. 8.12. Типы форм объекта «План видов характеристик»
■■ для объекта План счетов – это форма списка, выбора, счета (рис. 8.13);
Рис. 8.8. Типы форм объекта «Документ» Рис. 8.13. Типы форм объекта «План счетов»
236
Профессиональная разработка в системе «1С:Предприятие 8»
Конструирование форм ■■ для объекта План видов расчета – это форма списка, выбора, вида (рис. 8.14);
Рис. 8.14. Типы форм объекта «План видов расчета»
■■ для объекта Регистр сведений – это форма списка, записи, набора записей (рис. 8.15);
Рис. 8.15. Типы форм объекта «Регистр сведений»
■■ для объекта Регистр накопления – это форма списка и набора записей (рис. 8.16).
Рис. 8.16. Типы форм объекта «Регистр накопления»
■■ для объекта Регистр бухгалтерии – это форма списка и набора записей (рис. 8.17);
■■ для объекта Бизнес-процесс – это форма списка, выбора, бизнеспроцесса (рис. 8.19);
Рис. 8.19. Типы форм объекта «Бизнес-процесс»
■■ для объекта Задача – это форма списка, выбора, задачи (рис. 8.20);
Рис. 8.20. Типы форм объекта «Задача»
■■ для объекта Критерий отбора – это форма критерия отбора (рис. 8.21);
Рис. 8.21. Типы форм объекта «Критерий отбора»
■■ для объекта План обмена – это форма списка, выбора и узла (рис. 8.22).
Рис. 8.17. Типы форм объекта «Регистр бухгалтерии»
■■ для объекта Регистр расчета – это форма списка и форма набора записей (рис. 8.18);
Рис. 8.22. Типы форм объекта «План обмена»
Кроме всех перечисленных форм, для любого из объектов конфигурации можно создать тип формы Произвольная. Такая форма после создания не связана ни с какими данными конфигурации. Действия, которые можно будет выполнять в такой форме, целиком и полностью будут зависеть от желания и способностей разработчика формы.
Рис. 8.18. Типы форм объекта «Регистр расчета»
Том 1
237
Глава 8. Разработка форм Формы, связанные через свой основной реквизит с объектами конфигурации, уже наделены определенными свойствами, характеристиками, методами. Состав таких свойств, характеристик, методов зависит от объекта конфигурации.
конфигурации создаваемый тип форм еще не создавался (нет формы создаваемого типа), то флажок Назначить форму основной устанавливается автоматически.
Например, форму редактирования констант можно создать с помощью контекстного меню ветви конфигурации Константы (рис. 8.23). Созданная таким образом форма будет размещаться в ветви конфигурации Общие формы.
Рис. 8.23. Создание формы констант
При выборе того или иного типа создаваемой формы конструктор форм автоматически формирует Имя и Синоним формы. При формировании учитывается наличие у объекта конфигурации формы с таким именем. Если такая форма существует, то к имени создаваемой формы добавится числовой показатель (рис. 8.24).
Рис. 8.25. Создание основной формы
В дальнейшем основную форму объекта можно переопределить. Как это сделать, будет рассказано в разделе, посвященном редактору форм. Для некоторых типов форм конструктор предоставляет возможность использовать их одновременно в качестве формы элемента и формы группы (рис. 8.26).
Рис. 8.24. Формирование имени формы
Если разработчика не устраивает имя формы, которое предлагает конструктор, то его можно изменить. При этом возможно автоматическое формирование и нового синонима формы. Синоним формы – имя, под которым форма может фигурировать в интерфейсе пользователей прикладного решения. Синоним формы также можно изменить. При необходимости можно определить создаваемую форму в качестве основной формы для объекта конфигурации. Для этого необходимо установить флажок Назначить форму основной (рис. 8.25). Если для объекта
238
Рис. 8.26. Назначение формы в качестве нескольких основных форм
На этом работу с конструктором форм можно закончить (кнопка Готово) или перейти к следующему шагу (кнопка Далее), который позволит продолжить конструирование формы. На этом шаге разработчик дает указания конструктору форм на необходимость использования реквизитов объекта (или состава констант для формы констант) в создаваемой форме. Делается это с помощью установки соответствующего флажка. Профессиональная разработка в системе «1С:Предприятие 8»
Конструирование форм Здесь же можно определить, сколько колонок с элементами формы будет применяться для отображения данных (рис. 8.27).
Рис. 8.28. Сообщения об ошибках при копировании форм
Кроме копирования с использованием буфера обмена операционной системы, также доступен метод перетаскивания форм с помощью мыши. Необходимо лишь захватить нужную форму и перетащить в новое место. Копируемые формы можно подчинять другим объектам конфигурации. Так, например, мы можем скопировать форму некоего объекта в другой объект. Если в объекте, куда осуществляется копирование, уже существует форма с таким именем, то новой форме будет присвоено имя, к которому добавится порядковый номер (рис. 8.29). Рис. 8.27. Определение состава формы в конструкторе форм
ВНИМАНИЕ!
Управлять порядком следования элементов разрабатываемой формы в данном окне конструктора формы разработчик не может. Это можно сделать либо предварительно (определив порядок реквизитов объекта), либо после окончания работы конструктора (в окне редактора формы). ПРИМЕЧАНИЕ
Все настройки, сделанные на втором шаге в конструкторе форм, можно потом изменить, поэтому сильно задумываться, например, о количестве колонок элементов, если вы еще не представляете в уме внешнего вида формы, не следует.
Отказаться от создания новой формы можно на любом этапе работы конструктора форм. Для этого необходимо или закрыть окно стандартным для всех окон операционной системы способом, или нажать кнопку Отмена.
Рис. 8.29. Формирование имени формы при копировании
ВНИМАНИЕ!
При копировании формы происходит только лишь ее переподчинение в дереве конфигурации. Назначение формы, данные, с которыми она взаимодействует, при копировании не изменяются. Это означает, что, например, если скопировать форму справочника в другой справочник, то форма по-прежнему будет работать с данными первого справочника.
Создание формы методом копирования Кроме создания форм с помощью конструктора, разработчику прикладного решения доступен вариант создания формы с помощью метода копирования. Через буфер обмена операционной системы можно скопировать формы как текущей, так и любой произвольной конфигурации. При этом если платформа не может правильно сопоставить какие-либо свойства формы, свойства ее реквизитов, типы значений и прочее, разработчик будет об этом немедленно уведомлен (рис. 8.28). Том 1
239
Глава 8. Разработка форм
Редактирование формы Описание редактора формы Для редактирования формы в конфигураторе используется специализированный редактор форм. Окно редактора форм разбито на несколько областей (рис. 8.30), каждая из которых отвечает за ту или иную функциональность будущей формы.
Рис. 8.31. Модуль формы
Рис. 8.30. Окно редактора формы
1. Описывается состав и порядок элементов, из которых состоит форма, команды интерфейса, которые могут выполняться в форме. 2. Описывается состав реквизитов формы, а также команды, выполняемые внутри формы. 3. Представлен внешний вид формы, как она может выглядеть на экране пользователя, с учетом описанных реквизитов, элементов, команд формы. При изменении каких-либо настроек в окнах редактора они тут же применяются и изменяют вид формы.
Рис. 8.32. Редактор модуля формы
С помощью закладки Параметры редактора формы можно попасть в окно редактирования параметров формы (рис. 8.33).
Программный модуль описывает работу формы на встроенном языке. Для редактирования модуля формы можно воспользоваться закладкой Модуль, которая расположена внизу редактора форм. В модуле формы располагаются обработчики событий формы, элементов формы, команд формы. Помимо предопределенных обработчиков событий разработчик прикладного решения может создавать в модуле формы свои процедуры и функции (рис. 8.31). Модуль формы, так же как и другие модули конфигурации, редактируется в специализированном редакторе, в котором для удобства работы разработчика предусмотрены различные интерфейсные команды и меню (рис. 8.32).
240
Рис. 8.33. Редактирование параметров формы
С помощью параметров формы организовано управление функциональностью формы при ее открытии в пользовательском режиме работы Профессиональная разработка в системе «1С:Предприятие 8»
Конструирование форм приложения. Если это имеет смысл, разработчик может изменить параметры формы уже в процессе ее работы. Кроме параметров, описанных разработчиком формы, при ее вызове и работе доступны параметры, автоматически предоставляемые расширением формы. Для разных объектов конфигурации, определяющих основной реквизит формы, набор параметров различается.
Иерархия элементов формы Форма описывается разработчиком прикладного решения в виде иерархического дерева (рис. 8.36).
На состав параметров формы, предоставляемых основным реквизитом формы, влияет окружение объекта конфигурации, его свойства. Примером может служить параметр Основание, если это форма документа и этот документ может вводиться на основании какого-либо объекта. Подробнее
Раздел «Параметры и реквизиты формы», стр. 284. Раздел «Открытие форм», стр. 285.
Создание, изменение и удаление элементов формы, команд, реквизитов и прочее осуществляются с помощью кнопок командных панелей соответствующих областей редактора формы (рис. 8.34).
Рис. 8.36. Иерархия элементов формы
Все элементы формы подчинены корневому элементу Форма. Свойства элементов дерева зависят от свойств, которыми наделены элементы вышестоящего уровня. При этом каждый из элементов обладает своими уникальными свойствами, характерными только для него. Влияние свойств элементов дерева друг на друга (имеются в виду одинаковые свойства, например Ширина) является обоюдным. Таким образом, свойства нижнего уровня могут оказывать влияние на свойства верхнего уровня иерархии, и наоборот. Подробнее
Примеры влияния свойств элементов дерева друг на друга рассматриваются в разделе «Примеры конструирования форм», стр. 269.
Рис. 8.34. Командные панели редактора формы
Кроме того, для осуществления ряда действий доступны контекстные меню и перетаскивание с помощью мыши (рис. 8.35).
Свойства элементов верхнего уровня иерархии оказывают влияние на подчиненные элементы не только в процессе работы приложения, но и на этапе разработки. Такая зависимость достаточно хорошо видна при добавлении новых элементов формы. Так, например, свойство Вид элемента формы зависит от расположения элемента в иерархии элементов формы.
Свойства формы Форма обладает рядом свойств, которые присущи ей всегда. Ряд свойств формы определяется ее основным реквизитом. Именно основной реквизит формы определяет ее поведение, вид, состав команд, другие дополнительные возможности, предоставляемые разработчику формы и ее пользователю.
Рис. 8.35. Контекстное меню редактора формы
Том 1
Для редактирования свойств формы необходимо воспользоваться контекстным меню формы (пункт меню Свойства) в дереве объектов конфигурации либо контекстным меню (пункт меню Свойства) ветви Форма в области редактирования элементов формы редактора формы (рис. 8.37).
241
Глава 8. Разработка форм Подробнее
Раздел «Влияние объектов конфигурации на форму», стр. 253.
Положение командной панели
Рис. 8.37. Открытие окна «Свойства» формы
Свойство ПоложениеКоманднойПанели определяет положение командной панели формы. Свойство может принимать одно из четырех значений: Нет, Авто, Верх (рис. 8.40), Низ (рис. 8.41). По умолчанию системой устанавливается значение Авто. Это означает, что командная панель располагается вверху.
Рассмотрим основные свойства формы (рис. 8.38).
Рис. 8.40. Расположение командной панели формы сверху
Рис. 8.38. Основные свойства формы
Заголовок Свойство Заголовок определяет заголовок формы (рис. 8.39), как его будет видеть разработчик в окне предварительного просмотра формы и пользователь во время работы с формой. Заголовок формы может быть дополнен системной информацией, полученной из свойств объекта конфигурации, связанных с расширенным представлением объектов, списков. Такое влияние на свойство Заголовок возможно, если установлено свойство АвтоЗаголовок.
Рис. 8.41. Расположение командной панели формы снизу
Доступность Доступность. Снятие флажка у этого свойства означает, что все элементы
формы недоступны (рис. 8.42).
для
редактирования
пользователем
формы
Рис. 8.42. Управление доступностью формы
Режим открытия окна
Рис. 8.39. Заголовок формы
242
Свойство РежимОткрытияОкна определяет, в каком окне будет открываться форма. Возможны значения Независимый и Блокировать окно владельца. Режим Блокировать окно владельца похож на модальный режим, однако, в отличие от модального режима, при открытии формы из встроенного языка работа модуля не останавливается. При открытии происходит блокировка только «родительского» окна, другие окна приложения остаются доступными. В режиме Независимый окно формы не препятствует возможности переключения между окнами приложения. В таком режиме форма живет своей, не мешающей остальным формам жизнью. Профессиональная разработка в системе «1С:Предприятие 8»
Конструирование форм
Ширина, высота
Условное оформление
Ширина, Высота. Свойства позволяют задать размеры формы. При этом
Гиперссылка Открыть позволяет открыть окно Настройка условного оформления. В данном окне можно настроить, например, выделение цветом некоторого элемента в зависимости от значений других элементов формы.
дочерние элементы формы будут отмасштабированы так, чтобы все они уместились на форме. Если это невозможно, у формы появятся горизонтальные и вертикальные полосы прокрутки. Значения свойств задаются числом условных символов. Значение по умолчанию 0 означает автоматический подбор свойства. При автоматическом подборе свойств системой будет сделана попытка размещения элементов формы таким образом, чтобы полосы прокрутки не были задействованы. Там, где это возможно, элементы формы будут отмасштабированы.
Группировка Возможные значения свойства Вертикальная или Горизонтальная. Свойство определяет режим группировки подчиненных элементов формы. При значении Вертикальная элементы формы располагаются сверху вниз. При значении Горизонтальная элементы будут располагаться слева направо. Настройка влияет только на элементы верхнего уровня иерархии подчиненных элементов. Порядок расположения элементов формы, находящихся внутри групп, определяется свойством Группировка соответствующей группы элементов.
Ширина подчиненных элементов Свойство ШиринаПодчиненныхЭлементов позволяет автоматически формировать ширину элементов формы. Применять данное свойство имеет смысл только при горизонтальной группировке элементов формы. Подробнее
Пример влияния свойства рассматривается в разделе «Примеры конструирования форм», стр. 269.
Проверять заполнение автоматически Установленный флажок ПроверятьЗаполнениеАвтоматически означает автоматическую проверку заполнения реквизитов формы при работе пользователя. Подробнее
Механизм проверки заполнения реквизитов формы рассматривается в разделе «Окно сообщений формы», стр. 268, и в разделе «Проверка заполнения», стр. 310.
Подробнее
Примеры рассматриваются в разделе «Как настроить условное оформление динамического списка», стр. 278, и в разделе «Оформление списков», стр. 332.
Разрешить изменять форму Флажок РазрешитьИзменятьФорму определяет возможность изменения формы в пользовательском режиме работы. ВНИМАНИЕ!
Настройка форм в пользовательском режиме работы является стандартной возможностью, предоставляемой платформой. Это означает, что пользователь может изменить порядок элементов формы, перегруппировать их, изменить их видимость. С помощью свойства РазрешитьИзменятьФорму такую возможность можно пресечь. Вместо запрещения изменения всей формы разработчик может применять «точечные» запреты для конкретных элементов формы. Свойства, с помощью которых можно запрещать изменения элементов формы, рассматриваются ниже в разделах, посвященных элементам формы. Примеры настройки свойств рассматриваются в разделе «Как и зачем объединять элементы формы в группы», стр. 269.
Виды элементов формы В форме используются пять элементов: ■■ Группа: □□ Обычная группа; □□ Группа – Страницы; □□ Группа – Командная панель; ■■ Поле; ■■ Кнопка; ■■ Таблица; ■■ Декорация: □□ Декорация – Надпись; □□ Декорация – Картинка. Для того чтобы добавить в состав формы новый элемент определенного вида, необходимо воспользоваться одним из этих пяти элементов.
Том 1
243
Глава 8. Разработка форм Для отображения различных данных прикладного решения необходимо изменять свойство элемента формы Вид.
■■ Поле картинки. Поле, отображающее картинку (рис. 8.47);
При добавлении нового элемента редактором формы будет проанализировано свойство Данные (с каким реквизитом будет связан элемент формы). В зависимости от этого платформа позволит выбрать один из нескольких возможных видов этого элемента. Открытие свойств элементов формы ничем не отличается от рассматриваемого ранее открытия свойств формы.
Поле Элемент формы Поле предназначен для отображения примитивных типов данных, текстовых, табличных, HTML-документов, диаграмм, календарей, индикаторов. Тип данных, которые отображает элемент Поле, влияет на то, какие значения может принимать его свойство Вид. ■■ Поле надписи. Поле, недоступное для непосредственного редактирования (рис. 8.43) в пользовательском режиме работы;
Рис. 8.47. Элемент формы «Поле картинки»
■■ Поле текстового документа. Поле для редактирования и просмотра текстовых данных (рис. 8.48);
Рис. 8.43. Элемент формы «Поле надписи»
■■ Поле ввода. Поле, допускающее редактирование данных (рис. 8.44);
Рис. 8.44. Элемент формы «Поле ввода»
■■ Поле переключателя. Поле, позволяющее выбрать один из нескольких вариантов значения с помощью отметки нужного (рис. 8.45); Рис. 8.45. Элемент формы «Поле переключателя»
Рис. 8.48. Элемент формы «Поле текстового документа»
■■ Индикатор. Поле, предназначенное для графического отображения текущего состояния реквизита формы (рис. 8.49). Данные поля должны иметь числовой тип данных;
Рис. 8.49. Элемент формы «Индикатор»
■■ Поле полосы регулирования. Поле, предназначенное для ввода числовых данных с помощью шкалы (рис. 8.50);
■■ Поле HTML-документа. Поле для редактирования и просмотра HTMLресурсов (рис. 8.46); Рис. 8.50. Элемент формы «Поле полосы регулирования»
■■ Флажок. Поле, предназначенное для отображения или установки одного из значений (рис. 8.51). Применяются флажки с двумя состояниями (включен, выключен) или с тремя (включен, выключен, не определен); Рис. 8.46. Элемент формы «Поле HTML-документа»
244
Рис. 8.51. Элемент формы «Флажок»
Профессиональная разработка в системе «1С:Предприятие 8»
Конструирование форм ■■ Поле календаря. Поле, предназначенное для выбора и отображения даты в виде календаря (рис. 8.52). Для добавления на форму элемента Поле календаря необходим реквизит типа Дата;
■■ Поле диаграммы. Поле, отображающее различные виды диаграмм (рис. 8.55). Для добавления элемента формы Поле диаграммы необходимо добавить форме реквизит типа Диаграмма;
Рис. 8.52. Элемент формы «Поле календаря»
■■ Поле графической схемы. Поле для просмотра и редактирования графических схем (рис. 8.53), созданных в специализированном редакторе, входящем в состав «1С:Предприятия». Для добавления элемента Поле графической схемы необходимо добавить форме реквизит типа Графическая схема (рис. 8.54);
Рис. 8.55. Элемент формы «Поле диаграммы»
■■ Поле диаграммы Ганта. Поле, отображающее диаграмму Ганта (рис. 8.56). Для добавления элемента формы Поле диаграммы Ганта необходимо добавить форме реквизит типа ДиаграммаГанта;
Рис. 8.56. Элемент формы «Поле диаграммы Ганта»
Рис. 8.53. Элемент формы «Поле графической схемы»
■■ Поле дендрограммы. Поле, отображающее связи объектов; ■■ Поле табличного документа. Поле, в котором отображаются и редактируются данные. Как правило, используется для отображения результатов работы отчетов (рис. 8.57), печатных форм. Может использоваться для ввода данных. Для добавления элемента формы Поле табличного документа необходимо добавить форме реквизит типа Табличный документ.
Рис. 8.57. Элемент формы «Поле табличного документа»
Рис. 8.54. Тип реквизита «Графическая схема»
Том 1
245
Глава 8. Разработка форм
Группа Элемент формы Группа предназначен для группировки других элементов формы, их выделения, для создания командных панелей, подменю, групп кнопок, страниц. Свойство Вид элемента формы Группа может принимать значения: ■■ Обычная группа. Элемент формы, предназначенный для логической группировки других элементов формы (рис. 8.58). Элемент Обычная группа может не отображаться на форме, выполняя при этом функции группировки других элементов. Может отображаться в виде Рамка группы, Линия, Отступ;
Рис. 8.58. Элемент формы «Обычная группа»
■■ Командная панель. Элемент формы, предназначенный для группировки кнопок и команд (рис. 8.59);
■■ Группа кнопок. Элемент формы, подчиненный элементу Командная панель, позволяющий сгруппировать кнопки в логические группы. Сам элемент не отображается на форме, но кнопки одной группы отделяются от кнопок другой группы вертикальными линиями; ■■ Страницы. Элемент формы, представляющий собой набор страниц (рис. 8.61);
Рис. 8.61. Элемент формы «Страницы»
■■ Страница. Элемент формы, который может быть создан только как подчиненный элементу Страницы. Представляет собой отдельную страницу с данными (рис. 8.62). В пользовательском режиме работы страницы, на которых отсутствуют данные, не отображаются.
Рис. 8.59. Элемент формы «Командная панель»
■■ Подменю. Элемент формы, подчиненный элементу Командная панель и представляющий собой выпадающее меню (рис. 8.60);
Рис. 8.62. Элемент формы «Страница»
Рис. 8.60. Элемент формы «Подменю»
246
Профессиональная разработка в системе «1С:Предприятие 8»
Конструирование форм
Таблица Элемент формы Таблица (рис. 8.63) предназначен для отображения и редактирования различных табличных данных. У Таблицы могут быть свои командные панели, контекстные меню. Поля колонок элемента Таблица могут принимать различные виды.
■■ Кнопка формы. Элемент формы (рис. 8.66), представляет собой кнопку, расположенную не на командной панели формы. Если для кнопки не назначена команда, которая будет выполняться при нажатии, то кнопка в пользовательском режиме не отображается.
Рис. 8.63. Элемент формы «Таблица»
Кнопка Элемент формы Кнопка предназначен для создания кнопок, гиперссылок. Свойство Вид элемента формы Кнопка может принимать значения: ■■ Кнопка командной панели. Элемент представляет собой обыкновенную кнопку (рис. 8.64). Если для кнопки не назначена команда, которая будет выполняться при нажатии, то кнопка в пользовательском режиме не отображается.
Рис. 8.64. Элемент формы «Кнопка командной панели»
Рис. 8.66. Элемент формы «Кнопка формы»
Для всех элементов формы характерно наличие контекстного меню, вызываемого с помощью мыши или клавиатуры. В большинстве случаев во время работы приложения контекстные меню формируются платформой автоматически. Однако для повышения уровня работы пользователей с формами разработчик может вмешаться в этот процесс и повлиять на состав контекстного меню. Получить доступ к контекстному меню элемента формы можно через контекстное меню элемента формы в редакторе форм (рис. 8.67).
■■ Гиперссылка. Элемент формы (рис. 8.65). Если для гиперссылки не назначена команда, которая будет выполняться при нажатии, то гиперссылка в пользовательском режиме не отображается.
Рис. 8.65. Элемент формы «Гиперссылка» Рис. 8.67. Доступ к контекстному меню элемента формы
Том 1
247
Глава 8. Разработка форм После включения пункта контекстного меню элемента формы Показать контекстное меню для текущего элемента появится возможность доступа к его контекстному меню. Если разработчик желает модифицировать автоматически формируемое контекстное меню элемента формы, то флажок Автозаполнение в свойствах Контекстное меню элемента снимать не следует (рис. 8.68). В случае необходимости формирования полностью своего контекстного меню флажок следует снять.
Рис. 8.68. Автозаполнение контекстного меню
Свойства элементов формы Свойства элементов формы оказывают влияние как на внешний вид элементов в пользовательском режиме работы, так и на функциональность этих элементов. Перечень и описание всех свойств элементов формы не входят в задачи книги. В рамках текущего раздела будут рассмотрены лишь некоторые из них. Подробнее
Свойства, связанные с проверкой заполнения элементов формы, рассматриваются в разделе «Окно сообщений формы», стр. 268.
Рис. 8.69. Свойство элемента формы «Положение заголовка»
Активизировать элемент формы при ее открытии можно, установив свойство Активизировать по умолчанию. Это поможет избавить пользователя от лишних действий по переходу на нужный элемент формы и обратит его внимание на самый важный (с точки зрения работы приложения) элемент.
Свойства группы Давайте ознакомимся с некоторыми свойствами элемента формы Группа вида Обычная группа (рис. 8.70), каковым и является элемент формы с именем Шапка.
Свойства, оказывающие влияние на видимость элементов формы, рассматриваются в разделе «Примеры конструирования форм», стр. 269.
Свойство элемента формы Имя предназначено для задания уникального имени элемента в пределах формы. По имени можно обращаться к элементам формы из встроенного языка. Свойство Заголовок позволяет системе сформировать понятную для пользователя подпись элемента формы. Для многих элементов формы доступно свойство Положение заголовка, которое позволяет управлять расположением подписи элемента формы (рис. 8.69). Через свойство Данные определяется связь элемента формы с теми данными, которые будут отображаться и редактироваться. При установленном свойстве Пропускать при вводе элемент будет пропускаться при обходе элементов формы клавишей Enter.
248
Рис. 8.70. Свойства элемента формы «Группа»
Профессиональная разработка в системе «1С:Предприятие 8»
Конструирование форм ■■ Ширина, Высота – свойства позволяют управлять шириной и высотой группы. Значения задаются в символах. При значении 0 действует автоматический расчет. Значения, введенные в поля, влияют не только на саму группу, но и на ее подчиненные элементы; ■■ Разрешить изменение состава – определяет возможность редактирования состава группы в пользовательском режиме работы; ■■ Группировка – свойство может принимать два значения: Горизонтальная и Вертикальная. Определяет, как будут группироваться подчиненные элементы. Примером вертикальной группировки (рис. 8.71) служат элементы групп Предприятия и Организации. Обе эти группы объединены горизонтальной группировкой Настройки.
■■ Ширина подчиненных элементов – свойство, позволяющее управлять шириной подчиненных элементов группы. Возможны значения Авто, Одинаковая (рис. 8.72), Левый широкий, Левый очень широкий, Левый узкий, Левый очень узкий.
Рис. 8.71. Группировка элементов формы
■■ Отображение – свойство, оказывающее влияние на внешний вид элемента формы Группа. Так, группа Предприятия имеет свойство Отображение – Линия (рис. 8.71), а группа Организации – Рамка группы. ВНИМАНИЕ!
На практике применять различное отображение элементов формы Группа в одной форме не стоит. Для демонстрации всех возможных вариантов оформления элементов формы лучше создать специализированную демонстрационную форму и ловить восхищенные взгляды пользователей, демонстрируя именно ее.
Рис. 8.72. Управление свойством «Ширина подчиненных элементов»
■■ Для элемента формы Группа вида Страницы интерес представляет свойство Отображение страниц (рис. 8.73). Данное свойство управляет положением закладок страницы. Если используется вариант свойства Нет, то при наличии нескольких страниц их переключение можно осуществлять только средствами встроенного языка.
Рис. 8.73. Свойство «Отображение страниц»
Том 1
249
Глава 8. Разработка форм ■■ Свойство Горизонтальное положение элемента формы Группа вида Командная панель позволяет управлять положением кнопок на панели (рис. 8.74).
■■ Свойство Маска позволяет задать маску для ввода символов (рис. 8.76).
Рис. 8.74. Свойство «Горизонтальное положение»
Свойства поля ■■ Свойства Ширина, Высота управляют размерами элемента Поле при формировании внешнего вида формы. ■■ Свойство Горизонтальное положение позволяет управлять расположением элемента на форме.
Рис. 8.76. Свойство «Маска»
■■ Свойство Режим пароля при установке значения Да будет заменять вводимые символы специализированным символом (рис. 8.77).
Наибольший интерес (в плане разнообразия свойств и частоты использования) представляет элемент формы Поле с видом Поле ввода. ■■ Свойство Выбирать тип влияет на поведение системы при выборе типа данных реквизита, который обслуживает поле ввода. Проявляется это в случае использования реквизита составного типа данных (рис. 8.75).
Рис. 8.77. Свойство «Режим пароля»
■■ Свойства Список выбора (рис. 8.78, позволяет задать список, из которого можно выбирать значения в поле ввода); Кнопка списка выбора (позволяет явно указать наличие у Поля ввода кнопки); Высота списка выбора и Ширина списка выбора (управляют шириной и высотой выпадающего списка) позволяют управлять выпадающим списком для выбора значения. Рис. 8.75. Свойство «Выбирать тип»
250
Профессиональная разработка в системе «1С:Предприятие 8»
Конструирование форм ■■ Свойства Минимальное значение и Максимальное значение позволяют ограничить ввод числовых значений. При этом системой будет контролироваться соответствие вводимого числа заданным критериям. ■■ Свойство Быстрый выбор позволяет выбирать значения ссылочных типов из списка, а не из формы выбора. Свойством имеет смысл пользоваться, если у реквизита, отображаемого элементом, это свойство не установлено или его действие необходимо переопределить. ■■ Свойство Выбор групп и элементов позволяет ограничить выборку данных, например, только элементами иерархического справочника. ■■ Свойство Связи параметров выбора позволяет задать значение отбора для возможных вариантов выбора (рис. 8.80). Если источником данных для таблицы является динамический список, то значение свойства Связи параметров выбора участвует в формировании отбора системы компоновки данных. Рис. 8.78. Свойство «Список выбора»
■■ Свойство Расширенное редактирование позволяет использовать в поле дополнительные символы (табуляция) и поиск. ■■ Свойство Формат редактирования позволяет задать с помощью Конструктора форматной строки формат вводимых данных (рис. 8.79).
Рис. 8.79. Свойство «Формат редактирования»
Том 1
Рис. 8.80. Свойство «Связи параметров выбора»
251
Глава 8. Разработка форм ■■ Свойство Автоотметка незаполненного предназначено для информирования пользователя о незаполненном обязательном поле. Такое поле будет выделяться с помощью красной линии (рис. 8.81).
Свойства таблицы ■■ Свойство Положение командной панели определяет расположение командной панели таблицы. ■■ Свойство Отображение позволяет установить вариант отображения данных. Возможны значения: □□ Список. Данные отображаются в виде обычного (плоского) списка (рис. 8.83);
Рис. 8.81. Свойство «Автоотметка незаполненного»
■■ Свойство Автовыбор незаполненного позволяет значительно повысить качество работы пользователя с элементом управления. При его установке в значение Да, в случае редактирования данных ссылочного типа, при активизации элемента окно выбора значения будет открываться системой автоматически. ■■ Свойство Связь по типу позволяет указать элемент формы, которым будет определяться тип значения выбираемых в поле данных (рис. 8.82).
Рис. 8.83. Отображение таблицы в виде списка
□□ Иерархический список. Данные отображаются в виде списка с учетом иерархии групп и элементов (рис. 8.84);
Рис. 8.84. Отображение таблицы в виде иерархического списка
□□ Дерево. Данные отображаются в виде дерева (рис. 8.85).
Рис. 8.82. Свойство «Связь по типу»
252
Рис. 8.85. Отображение таблицы в виде дерева
Профессиональная разработка в системе «1С:Предприятие 8»
Конструирование форм ■■ Свойство Вывод управляет возможностями сохранения, печати и копирования данных, отображаемых элементом формы Таблица. ■■ Свойства Автообновление и Период автообновления позволяют управлять возможностями автоматического обновления данных таблицы.
Свойства кнопки ■■ Свойство Только во всех действиях определяет, будет ли отображаться кнопка еще где-нибудь (в местах, определенных разработчиком формы), кроме подменю Все действия. ■■ Свойство Отображение определяет вариант отображения кнопки на экране (Авто, Текст, Картинка, Картинка и текст).
Как добавить новые элементы формы Для того чтобы добавить новый элемент формы, необходимо воспользоваться одним из способов, предоставляемых редактором формы: ■■ воспользоваться конструктором формы. Работа конструктора рассматривается в разделе «Создание формы с помощью конструктора», стр. 235. При таком способе будет создана новая форма, однако если объекту конфигурации в процессе разработки после создания формы был добавлен новый реквизит или табличная часть, то эти изменения можно будет учесть; ■■ воспользоваться кнопкой командной панели области Элементы редактора формы (рис. 8.86);
Рис. 8.87. Кнопка контекстного меню для добавления элементов формы
Влияние объектов конфигурации на форму Объекты конфигурации определяют не только функциональность будущей формы через ее основной реквизит, но и оказывают влияние на внешний вид формы, на поведение ее элементов. На форму влияют как свойства самого объекта конфигурации, так и свойства его реквизитов. С помощью свойств объектов конфигурации в управляемом приложении формируется заголовок формы. Однако такое влияние на заголовок формы оказывается не всегда. У разработчика приложения остается возможность ручного формирования заголовка формы.
Заголовок формы Рассмотрим небольшой пример, в котором будут задействованы свойства объекта конфигурации, оказывающие влияние на формирование заголовка формы объекта (формы элемента справочника, формы документа, формы задачи). По умолчанию для вновь созданной формы ее заголовок формируется полностью в автоматическом режиме. Это означает, что свойство формы Заголовок не заполнено, а флажок АвтоЗаголовок установлен. При такой установке свойств на автоматически формируемый заголовок формы оказывает влияние свойство объекта конфигурации Имя (рис. 8.88).
Рис. 8.86. Кнопка командной панели для добавления элементов формы
■■ воспользоваться контекстным меню области Элементы редактора формы (рис. 8.87); ■■ использовать возможности перетаскивания из других окон с помощью мыши; ■■ непосредственно перед добавлением нового элемента формы можно спозиционироваться на элементе верхнего уровня, в подчинение которому планируется поместить новый элемент. Перемещать элементы формы по дереву иерархии можно с помощью мыши (перетаскивание) или кнопок Переместить вверх, Переместить вниз. Том 1
Рис. 8.88. Формирование заголовка формы по свойству «Имя»
253
Глава 8. Разработка форм После записи такого элемента в информационную базу в формировании заголовка формы участвует еще и свойство объекта Основное представление (рис. 8.89).
Организация для справочника Организации, Договор для справочника Договоры. Свойство участвует в формировании названия команды
в управляемом интерфейсе приложения. ПРИМЕЧАНИЕ
Согласно методикам разработки фирмы «1С» свойство Представление объекта заполняется в том случае, если Синоним объекта не представляет собой краткое и четкое описание объекта в единственном числе.
Рис. 8.89. Заголовок формы после записи элемента
Если у объекта конфигурации заполнено свойство Синоним, то в формировании заголовка участвует уже оно, а свойство Имя игнорируется (рис. 8.90). ПРИМЕЧАНИЕ
Согласно методикам разработки фирмы «1С» свойство Синоним объекта конфигурации подлежит обязательному заполнению и должно содержать четкое, краткое, всеобъемлющее описание объекта.
Рис. 8.91. Формирование заголовка формы по свойству «Представление объекта»
В случае использования свойства Расширенное представление объекта в заголовке формы отображается именно оно (рис. 8.92). Остальные рассмотренные свойства (ПредставлениеОбъекта, Синоним) могут использоваться платформой только в том случае, если расширенное представление объекта не задано. ПРИМЕЧАНИЕ
Согласно методикам разработки фирмы «1С» свойство Расширенное представление объекта используется в том случае, если Представление объекта или его Синоним не дают полного представления о наименовании объекта. Свойство заполняется в единственном числе.
Рис. 8.90. Формирование заголовка формы по свойству «Синоним»
У объектов конфигурации существует ряд интерфейсных свойств, влияющих на заголовок формы в пользовательском режиме работы. Нами будут рассмотрены свойства Представление объекта и Расширенное представление объекта. При
формировании заголовка формы, если свойство Представление объекта заполнено, приоритет отдается именно ему (рис. 8.91).
Свойство задается в единственном числе и показывается как название одного объекта, например, Контрагент для справочника Контрагенты,
254
Рис. 8.92. Формирование заголовка формы по свойству «Расширенное представление объекта»
Профессиональная разработка в системе «1С:Предприятие 8»
Конструирование форм Если возникает необходимость задания собственного заголовка формы, то возможности автоматического формирования заголовка можно совмещать с текстом, введенным вручную. Для этого необходимо оставить флажок АвтоЗаголовок и применить свой Заголовок формы (рис. 8.93).
При создании нового документа используется его расширенное представление (если оно задано), рис. 8.95.
Рис. 8.95. Заголовок формы нового документа
После записи документа в базу данных заголовок формируется по правилу Имя или Синоним объекта конфигурации плюс представление ссылки на документ (рис. 8.96).
Рис. 8.96. Заголовок формы записанного документа
Рис. 8.93. Свойства «АвтоЗаголовок» и «Заголовок» формы
При формировании формы объекта конфигурации Задача система руководствуется наименованием задачи, ее номером, датой и одним из свойств объекта конфигурации, отвечающих за представление объекта (рис. 8.97).
Если для формы необходимо применять только собственный заголовок, то свойство АвтоЗаголовок необходимо снять (рис. 8.94).
Рис. 8.94. Использование свойства формы «Заголовок»
Немного по другим правилам в управляемом приложении формируются заголовки форм документа и задачи. Том 1
Рис. 8.97. Формирование заголовка формы задачи
255
Глава 8. Разработка форм ПРИМЕЧАНИЕ
Свойства объектов конфигурации, отвечающие за представление объектов и списков, влияют не только на формы, но и на интерфейс всего приложения. По каким правилам формируется интерфейс пользователя, рассказано в главе 7 «Командный интерфейс прикладных решений», стр. 145.
Интерфейсные свойства реквизитов объектов конфигурации В управляемом приложении некоторые интерфейсные свойства существуют не только у элементов формы, но и у реквизитов объектов конфигурации. Это означает, что при установке такого свойства для реквизита оно автоматически действует на все формы, в которых данный реквизит отображается (при условии использования объекта в качестве основного реквизита формы). Если у элемента формы есть аналогичное свойство, то оно позволяет переопределить для данной конкретной формы действие свойства.
Выбор групп и элементов В случае организации выбора в элемент формы данных иерархических объектов базы данных (групп, элементов), например справочников, выборку можно ограничить с помощью настройки свойства Выбор групп и элементов. Таким образом, если по логике работы формы пользователю необходимо предоставить для выбора только группы справочника, то, установив свойство в значение Группы, разработчик ограничит варианты выбора данных информационной базы.
Быстрый выбор Часто для повышения производительности действий пользователей и удобства их работы выбор элементов удобно делать не в отдельном окне формы выбора, а в списке. Реализовать подобную настройку выбора элементов можно с помощью установки свойства Быстрый выбор (рис. 8.99).
ВНИМАНИЕ!
Если свойство существует у реквизита объекта и у элемента формы, который отображает данный реквизит, то использовать рекомендуется свойство реквизита. Аналогичным свойством элемента формы необходимо пользоваться только для переопределения значения свойства.
Большинство свойств реквизита, которые влияют на поведение элемента формы, находятся в разделе Представление его свойств (рис. 8.98).
Рис. 8.99. Быстрый выбор значений
Проверка заполнения Свойство Проверка заполнения отвечает за автоматическую проверку заполнения реквизита (обязательный реквизит). При установке свойства у элемента формы изменится визуальное представление – элемент будет подчеркнут красной линией. В случае необходимости переопределения свойства нужно будет воспользоваться обработчиком ПроверкаЗаполнения данного объекта. Рис. 8.98. Раздел «Представление» свойств реквизитов
Подробнее
Пример использования данного свойства рассматривается в разделе «Окно сообщений формы», стр. 268.
256
Профессиональная разработка в системе «1С:Предприятие 8»
Конструирование форм
Значение заполнения Свойство Значение заполнения позволяет указать начальное значение реквизита. Для выбора доступны значения, созданные разработчиком в режиме Конфигуратор (перечисления, предопределенные элементы). Примером использования свойства может служить установка вида номенклатуры при создании нового элемента справочника. По умолчанию реквизит устанавливается в значение Товар (рис. 8.100).
Программно объект можно заполнить, вызвав его метод Заполнить(). У метода существует параметр Данные заполнения, исходя из которого и происходит заполнение реквизитов объекта. Еще одним из способов заполнения реквизитов формы первоначальными данными является вызов глобального метода ОткрытьФорму(). Если в метод передать параметр формы ЗначенияЗаполнения, то форма будет открываться с учетом переданных в параметре значений.
Связи параметров выбора В ряде задач, решаемых пользователями с помощью элементов формы, необходимо ограничивать количество предлагаемых для выбора данных. Так, например, после выбора в документе поставщика товаров, при выборе договора желательно видеть только те из них, которые заключены именно с этим поставщиком, а не все договоры, которые есть в соответствующем справочнике. Сделать это можно с помощью настройки свойства Связи параметров выбора (рис. 8.101). В окне Связи параметров выбора существует возможность отказаться от параметра открываемой формы, который был предложен системой, и выбрать другой.
Рис. 8.100. Свойство «Значение заполнения»
Заполнять из данных заполнения Не менее интересным является флажок Заполнять из данных заполнения. При определенных обстоятельствах данный флажок может отменять значение свойства Значение заполнения. Для некоторых реквизитов флажок Заполнять из данных заполнения устанавливается автоматически. Если разработчик заинтересован в том, чтобы его данные из свойства Значение заполнения использовались всегда, флажок Заполнять из данных заполнения должен быть снят. Если флажок Заполнять из данных заполнения установлен и происходит интерактивное создание нового объекта, то реквизит будет заполняться с учетом установленного отбора. Подробнее
Пример такого заполнения рассматривается в разделе «Примеры конструирования форм», стр. 269.
При интерактивном вводе на основании в структуру данных заполнения формы передается ссылка на объект-основание, и реквизиты создаваемого объекта заполняются исходя из значений реквизитов основания. Том 1
Рис. 8.101. Использование свойства «Связи параметров выбора»
подробнее
Пример использования свойства рассматривается в разделе «Примеры конструирования форм», стр. 269.
257
Глава 8. Разработка форм
Связь по типу Свойство Связь по типу позволяет указать реквизит объекта, который будет поставлять тип значения для текущего реквизита. Указание такой связи используется в том случае, если необходимо, например, дать возможность пользователям самим определять дополнительные свойства тех или иных объектов базы данных.
Например, для реквизита Родитель справочника Контрагенты настроено свойство Синоним (рис. 8.103), и в формах реквизит Родитель фигурирует уже как Группа.
Форма выбора В свойстве Форма выбора можно указать, какая из форм объекта будет использоваться в качестве основной формы выбора значения реквизита.
Стандартные реквизиты объектов конфигурации У каждого из видов объектов конфигурации набор стандартных реквизитов различается. Например, у документов это Номер, Дата, Пометка удаления, Ссылка, Проведен. Разработчик имеет возможность редактирования свойств стандартных реквизитов объектов в специальном окне. Состав свойств каждого из этих реквизитов различается и зависит от типа данных реквизита. Большинство свойств стандартных реквизитов совпадают со свойствами реквизитов объектов и свойствами элементов формы, и нами уже рассмотрены. Влияние, которое стандартные реквизиты оказывают на формы, ничем не отличается от влияния любых других свойств (обычных реквизитов, элементов формы).
Рис. 8.103. Синоним стандартного реквизита
Реквизиты формы Достаточно часто при разработке прикладных решений перед разработчиками стоит задача размещения на форме различных данных, не связанных с каким-либо определенным объектом. Это могут быть данные подчиненных справочников, регистров, таблицы, полученные в результате работы операторов встроенного языка. ВНИМАНИЕ!
В формах все данные, предназначенные для изменения, должны быть описаны в редакторе формы в виде реквизитов.
Во многих разделах главы уже неоднократно упоминался основной реквизит формы. Такой реквизит автоматически добавляется конструктором формы, если форма создается подчиненной объекту конфигурации и выбирается вид формы этого объекта, а не произвольная форма. По умолчанию у такой формы после ее создания есть только один реквизит, который и является основным (рис. 8.104).
Рис. 8.102. Открытие списка стандартных реквизитов
258
Флажок Использовать всегда позволяет влиять на передачу данных формы в процессе ее работы между клиентской частью и серверной. Флажок оказывает влияние на внутреннее наполнение формы и не влияет на пользовательское представление. Профессиональная разработка в системе «1С:Предприятие 8»
Конструирование форм Со свойством Проверка заполнения можно познакомиться в разделе «Окно сообщений формы», стр. 268.
Добавление нового реквизита формы выполняется способом – с помощью кнопки командной панели.
стандартным
Важнейшим свойством, которое определяет не только то, что за данные будет поставлять форме реквизит, но и как будет выглядеть элемент формы, отображающий эти данные, является Тип (рис. 8.106).
Рис. 8.104. Основной реквизит формы
К снятию данного флажка разработчиком формы необходимо относиться весьма осмотрительно. С одной стороны, можно получить экономию ресурсов (трафика) при передаче данных формы между клиентской и серверной частью (это если пользователь скрыл элемент формы в настройках); с другой стороны, такой элемент может быть задействован в коде, а он скрыт пользователем, и в данных формы его нет. По умолчанию флажок установлен, и снимать его нужно только при полной уверенности в его ненужности. Реквизиты формы обладают набором свойств (рис. 8.105), позволяющих влиять на их поведение.
Рис. 8.106. Установка свойства «Тип»
подробнее
Пример расширения состава редактируемых данных с помощью модификации формы путем добавления новых реквизитов формы рассматривается в разделе «Примеры конструирования форм», стр. 269.
Командный интерфейс формы Панель навигации Командный интерфейс формы формируется системой автоматически, на основании анализа объектов конфигурации. Рис. 8.105. Свойства реквизита формы
подробнее
Функциональные и интерфейсные свойства реквизитов формы (Функциональные опции, Просмотр, Редактирование) рассматриваются в разделе «Управление видимостью элементов формы», стр. 261.
Том 1
Так, например, после добавления в дерево конфигурации подчиненного справочника или регистра сведений, у которого тип значения измерения является ссылкой на текущий справочник и при этом установлен признак свойства измерения Ведущее (рис. 8.107), в форме текущего справочника системой автоматически будут сформированы команды для открытия форм объектов конфигурации, содержащих зависимые данные.
259
Глава 8. Разработка форм При этом у разработчика формы есть возможность повлиять на видимость таких команд в пользовательском режиме работы (рис. 8.110).
Рис. 8.110. Управление видимостью команд «Панели навигации» формы Рис. 8.107. Свойство измерения «Ведущее»
Такие команды будут доступны в окне самой формы, в пользовательском режиме работы (рис. 8.108), в панели навигации формы.
Одновременно с разработчиком влиять на состав команд пользовательского режима работы может и платформа, анализируя права доступа пользователей. Вернее, сперва платформа (анализ прав пользователя), а уже потом разработчик.
Командная панель Если на основании какого-либо объекта информационной базы можно вводить новые данные, например, на основании элемента справочника Контрагенты можно ввести документ Доверенность (рис. 8.111), то в форме элемента основания системой формируется предопределенное подменю Создать на основании.
Рис. 8.108. Команды «Панели навигации» формы
В режиме разработки формы такие команды можно увидеть и отредактировать в редакторе форм. Они будут находиться среди глобальных параметризуемых команд (рис. 8.109).
Рис. 8.111. Объект-основание для текущего объекта
Рис. 8.109. Редактирование командного интерфейса формы
260
В пользовательском режиме работы такое подменю формируется в командной панели формы (рис. 8.112). Такой способ ввода новых объектов базы данных позволяет значительно повысить производительность работы пользователей, уменьшить количество допущенных в работе Профессиональная разработка в системе «1С:Предприятие 8»
Конструирование форм ошибок, избавить от постоянного нудного и однообразного ввода одних и тех же данных.
При этом для удобства работы разработчика все команды разделены на три категории:
Рис. 8.112. Подменю «Создать на основании»
■■ Команды формы. Именно в данном окне с помощью кнопки Добавить можно создавать новые команды формы. При этом все создаваемые команды являются «программируемыми». Описание алгоритма работы команд выполняется разработчиком в модуле формы, с помощью встроенного языка; ■■ Стандартные команды. В данном разделе сгруппированы все команды, которые предоставляются основным реквизитом формы. Если на форме есть элементы, отображающие списки (наборы записей, динамические списки, табличные части объектов и так далее), то команды таких элементов также присутствуют в данной категории команд (рис. 8.115).
Управлять видимостью подменю Создать на основании, а также его составом можно в процессе разработки формы (рис. 8.113).
Рис. 8.115. Стандартные команды формы
■■ Глобальные команды. Команды этой группы могут являться параметризованными и непараметризованными. Это команды глобального командного интерфейса. Параметризованные команды отображаются в форме, только если для них в форме существует источник параметров с соответствующим типом данных. Рис. 8.113. Управление видимостью команд командной панели формы
Команды формы Помимо заполнения каких-либо элементов формы пользователю достаточно часто приходится командовать форме, что сделать в том или ином случае. Все команды, которые могут быть назначены кнопкам и использованы в форме, сгруппированы в окне команд (рис. 8.114).
Рис. 8.114. Команды формы
Том 1
Управление видимостью элементов формы Влияние прав и ролей пользователя на элементы формы Для ограничения доступа к данным информационной базы в пользовательском режиме работы в среде «1С:Предприятия» применяются объекты конфигурации Роли. Каждая роль, присутствующая в том или ином прикладном решении, описывает набор прав доступа к объектам информационной базы. Так как работа пользователя с объектами информационной базы происходит в формах, права доступа к таким объектам законным образом влияют на внешний вид формы. В форме права доступа и роли пользователей оказывают влияние на все элементы формы, на реквизиты формы, на состав ее команд и системных командных панелей. Кроме того, оказывается косвенное влияние через объекты конфигурации и их реквизиты.
261
Глава 8. Разработка форм Однако ограничение доступа к данным и удобство пользования теми данными, к которым имеется доступ, – это два разных вопроса. И для решения второго вопроса существует ряд свойств, помогающих разработчику настроить доступ к разрешенным данным удобным для пользователя образом. Эти свойства носят вполне понятные названия и не требуют уточнения. Например,
для элементов формы это свойство Пользовательвидимость (рис. 8.116); для реквизитов формы доступны два свойства – Просмотр и Редактирование (рис. 8.117); для командного интерфейса формы – это Видимость (рис. 8.118). ская
Как видно из приведенных рисунков, разработчик может либо полностью запретить видимость (просмотр, редактирование) того или иного элемента формы (реквизита, команды), либо применять запрет для конкретной роли. Для элементов формы полное выключение свойства Видимость у родительского элемента, например Группы, означает исключение из пользовательского интерфейса формы всех дочерних элементов. Рассмотрим несколько примеров. Для этого будем использовать демонстрационную базу «Разработка форм, пример 1». В демонстрационной базе определены несколько ролей. Для каждой из ролей настроены те или иные права доступа на объекты конфигурации. Кроме того, как уже было сказано в начале раздела, платформа предоставляет возможность настройки прав доступа на реквизиты объектов, на табличные части, на стандартные реквизиты, на состав команд формы, на командный интерфейс формы, на реквизиты формы и ее элементы.
Пример 1 Роли Полные права конфигурации на справочник Номенклатура даны все возможные права (рис. 8.119). Рис. 8.116. Свойство «Пользовательская видимость» элементов формы
Рис. 8.117. Свойство «Просмотр» реквизита формы
Рис. 8.119. Справочник «Номенклатура». Права «Полные права»
С помощью команд командной панели формы списка номенклатуры (ФормаСписка1) пользователь с ролью Полные права может делать с элементами и группами справочника все что угодно (рис. 8.120).
Рис. 8.118. Свойство «Видимость» командного интерфейса формы
262
Роли Полные права доступно право Интерактивное добавление, и в пользовательском интерфейсе формы списка справочника есть команды создания и копирования. Право Интерактивная пометка на удаление дает возможность помечать объекты, предназначенные к удалению, и соответствующая кнопка командной панели доступна. Право Редактирование дает возможность изменять данные объекта информационной базы и сохранять эти изменения. Профессиональная разработка в системе «1С:Предприятие 8»
Конструирование форм
Рис. 8.122. Командная панель формы. Менеджер по продажам
Из командной панели формы исчезли команды, связанные с созданием, копированием, удалением новых объектов базы данных. Рис. 8.120. Командная панель формы. Полные права
Если разработчику прикладного решения необходимо ограничить пользователя в его возможностях по интерактивному редактированию состава информационной базы, то следует прибегнуть к настройке ролей. Ограничение по составу возможностей редактирования данных представлено для роли Менеджер по продажам (рис. 8.121).
Пример 2 В демонстрационной базе роли Полные права установлены права доступа на регистр сведений Контактная информация, и состав кнопок подменю Перейти формы элемента справочника Контрагенты (ФормаЭлемента2) выглядит так, как это задумал разработчик (рис. 8.123).
Рис. 8.123. Состав подменю «Перейти». Полные права
Роли Менеджер по продажам на регистр сведений Контактная информация никакие права не назначены, и потому платформа ограничила состав определенного разработчиком подменю (рис. 8.124). Рис. 8.121. Справочник «Номенклатура». Права «Менеджер по продажам»
Как видно из рисунка, пользователю с такими правами разрешено просматривать и редактировать данные базы данных. Результат влияния прав доступа пользователя на состав командных панелей формы можно увидеть, осуществив запуск прикладного решения под пользователем с правами Менеджер по продажам (рис. 8.122). Том 1
Таким образом, разработчик прикладного решения имеет возможность изменять состав командных панелей формы, не прибегая к созданию «индивидуальных» форм, для всех определенных в конфигурации ролей. Для достижения нужного эффекта достаточно лишь правильно раздать роли и настроить права доступа.
263
Глава 8. Разработка форм
Рис. 8.124. Состав подменю «Перейти». Менеджер по продажам
Рис. 8.126. Форма элемента. Полные права
Пример 3 Настройки ролей и прав доступа влияют не только на состав командных панелей формы. Точно такому же воздействию подвергаются и все дочерние элементы формы, связанные с реквизитами объекта конфигурации или его табличными частями. Такое влияние прав доступа можно увидеть на примере формы элемента справочника Номенклатура (ФормаЭлемента2). Так, для роли Полные права установлены полные права доступа к табличной части справочника Поставщики, а для роли Менеджер по продажам такие права не установлены (рис. 8.125).
Рис. 8.127. Форма элемента. Менеджер по продажам
Если внимательно рассмотреть форму, представленную на рис. 8.127, то можно заметить, что вместе с табличной частью Поставщики исчезла и страница, на которой разработчик поместил эту табличную часть в редакторе формы. Произошло это потому, что при проектировании подчиненных элементов страницы формы на ней ничего, кроме табличной части, размещено не было (рис. 8.128). Таким образом, определив состав страницы панели, платформа скрыла от пользователя и бесполезную для него страницу формы.
Рис. 8.125. Права доступа к табличной части
В пользовательском режиме работы тем пользователям, которым доступна роль Полные права, форма элемента справочника будет представлена в полном виде (рис. 8.126), а вот пользователям с ролью Менеджер по продажам придется только мечтать о возможности просматривать и редактировать табличную часть Поставщики (рис. 8.127).
264
Рис. 8.128. Состав страницы формы
Скрытие платформой в пользовательском режиме работы других элементов формы (поля ввода, флажки и другие) происходит по точно такому же принципу, который был продемонстрирован выше. Профессиональная разработка в системе «1С:Предприятие 8»
Конструирование форм
Пример 4 Возможности изменения форм в зависимости от настройки прав доступа не ограничиваются только управлением видимостью элементов. В зависимости от предоставленных прав доступа платформа может просто запретить редактирование данных, оставив их при этом на экране пользователя. Запретим роли Менеджер по продажам редактировать реквизит Комментарий документа ПоступлениеТоваров (рис. 8.129).
с этими реквизитами, и на команды формы, а значит, на кнопки формы, кнопки командных панелей. В демонстрационной базе определена одна функциональная опция Учет НДС. Как ясно из названия опции, она отвечает за возможность ведения учета НДС в прикладном решении. Реквизиты объектов конфигурации, табличные части и прочие элементы формы связываются с определенными функциональными опциями в соответствующем редакторе.
Пример 1 Рассмотрим влияние функциональных опций на форму на примере документа Реализация товаров. Свяжем функциональную опцию Учет НДС с реквизитами табличной части Товары: Ставка НДС, Сумма НДС. Для этого необходимо открыть состав функциональной опции и отметить флажком те реквизиты объекта (рис. 8.131), которые, по мнению разработчика (или по требованию заказчика), должны быть связаны с функциональной опцией. Рис. 8.129. Отключение права «Редактирование»
В пользовательском режиме работы элемент формы Комментарий (ФормаДокумента1) будет присутствовать на форме, однако отредактировать его значение невозможно (рис. 8.130).
Рис. 8.130. Доступность реквизитов объекта
Влияние функциональных опций на элементы формы Функциональные опции предназначены для оперативного управления функционалом прикладного решения в процессе его внедрения или работы без изменения конфигурации. Создание функциональных опций разработчиком осуществляется на этапе разработки конфигурации. В форме функциональные опции могут влиять на ее реквизиты, а значит, и на элементы формы (поля ввода, таблицы, страницы и прочие), связанные Том 1
Рис. 8.131. Назначение функциональных опций реквизитам
Кроме этого, в нашей демонстрационной базе функциональная опция Учет НДС связана со справочником Ставки НДС, что, впрочем, вполне логично для прикладного решения. Таким образом, управление функциональной опцией Учет НДС будет оказывать влияние не только на формы приложения, но и на его интерфейс, о чем рассказывается в разделе «Влияние функциональных опций на командный интерфейс», стр. 183.
265
Глава 8. Разработка форм Чтобы увидеть влияние функциональных опций на команды, выполняемые в форме, разместим кнопку Открыть ставки НДС на командной панели табличной части Товары. В качестве выполняемой нажатием кнопки команды выберем глобальную команду СтавкиНДС (рис. 8.132).
Рис. 8.134. Состояние функциональной опции «Учет НДС»
Рис. 8.132. Косвенная связь кнопки с функциональной опцией
Проделав все вышеописанное, мы с вами осуществили косвенную связь кнопки командной панели формы с функциональной опцией. Несмотря на то, что связь косвенная, функциональная опция окажет свое влияние на видимость кнопки.
Установив флажок Вести учет НДС и записав изменения в информационную базу, мы тем самым включим функциональную опцию Учет НДС, и функционал, связанный с ней, будет доступен пользователям прикладного решения (рис. 8.135).
По умолчанию в пользовательском режиме работы мы не увидим ни кнопки, которую только что создали, ни колонок табличной части, которые связали с функциональной опцией Учет НДС (рис. 8.133).
Рис. 8.135. Документ «Реализация товаров»
Пример 2
Рис. 8.133. Документ «Реализация товаров по умолчанию»
Отсутствие элементов формы, связанных с функциональной опцией Учет НДС, связано с тем, что соответствующая функциональная опция в прикладном решении неактивна (рис. 8.134).
266
Связывать между собой кнопки формы (командных панелей) и функциональные опции можно не только косвенно. Как уже можно было заметить, связь осуществляется не с самой кнопкой, а с командой, которая будет выполняться при ее нажатии. Для реализации примера скопируем существующую форму элемента справочника Номенклатура (ФормаЭлемента3). Добавим команду формы ЗаполнитьСтавкуНДС. Свойству команды Функциональная опция присвоим значение Учет НДС. Таким образом, мы определим участие функционала команды только при включенном учете НДС. В модуле формы необходимо Профессиональная разработка в системе «1С:Предприятие 8»
Конструирование форм создать обработчик команды. Сделать это можно с помощью соответствующей кнопки свойства команды Действие (рис. 8.136).
Рис. 8.138. Кнопка формы
Рис. 8.136. Связь команды с функциональной опцией
Для создания элемента управления командой воспользуемся методом перетаскивания. Захватим мышью команду Заполнить ставку НДС и перетащим ее в корень элементов формы, на ветку Форма (рис. 8.137).
Рис. 8.137. Создание элемента формы перетаскиванием
В результате этих нехитрых действий редактор формы создаст кнопку, которая и будет управлять нашей командой (рис. 8.138). Для того чтобы кнопка превратилась в гиперссылку, достаточно изменить ее свойство Вид с Кнопка формы на Гиперссылка (рис. 8.139). Результат преобразования можно сразу же оценить в окне предварительного просмотра формы. Так как команда, выполняемая при нажатии гиперссылки Заполнить ставку НДС, связана с функциональной опцией, то, естественно, гиперссылка будет доступна только при включенной функциональной опции Учет НДС. Том 1
Рис. 8.139. Изменение кнопки на гиперссылку
ВНИМАНИЕ!
Для того чтобы увидеть новую форму элемента справочника Номенклатура в пользовательском режиме работы, не забудьте назначить ее как форму элемента справочника по умолчанию.
267
Глава 8. Разработка форм
Окно сообщений формы Окно сообщений формы предназначено для информирования пользователя о различных событиях. В процессе работы прикладного решения окно появляется в двух случаях: ■■ сообщения сгенерированы программным способом. Вся работа по созданию таких сообщений целиком и полностью лежит на разработчике прикладного решения. Для вывода сообщений используются команды встроенного языка (см. раздел «Сообщения пользователю», стр. 321); ■■ сообщения возникли вследствие попытки сохранить объект, не заполнив при этом обязательный для заполнения реквизит. Такие сообщения генерируются системой автоматически, на основании настроек, сделанных разработчиком прикладного решения в процессе редактирования свойств формы или ее дочерних элементов. В этом разделе рассматривается второй случай появления окна сообщений, так как именно такой вариант возникновения окна сообщений настраивается средствами визуального конструирования форм.
Рис. 8.141. Поле, обязательное для заполнения
При попытке сохранения объекта системой генерируется сообщение об ошибке, которое показывается в окне сообщений. Одновременно с окном сообщений открывается окно с указателем на поле, в котором допущена ошибка (рис. 8.142). В случае наличия нескольких ошибок переход по окнам с указателями на ошибочные поля осуществляется с помощью стрелок навигации.
Для того чтобы сделать реквизит объекта обязательным для заполнения, необходимо изменить его свойство Проверка заполнения со значения Не проверять, устанавливаемого платформой по умолчанию, на значение Выдавать ошибку (рис. 8.140).
Рис. 8.142. Сообщение об ошибке
В случае попытки повторного сохранения или проведения объекта окно сообщений будет очищено и сообщения об ошибках будут сгенерированы снова.
Рис. 8.140. Настройка проверки заполнения реквизита
В пользовательском режиме работы поле, обязательное для заполнения, выделяется с помощью красной линии подчеркивания (рис. 8.141). Обязательным для заполнения можно сделать не только реквизит объекта, но и его табличную часть. В этом случае системой контролируется наличие хотя бы одной строки в проверяемой табличной части.
268
Если сообщение связано с каким-либо реквизитом другого объекта информационной базы, то системой будет открыта форма этого объекта, и сообщение с указателем на ошибочное поле будет отображено уже в этом окне. Таким образом, система сама контролирует правильность заполнения обязательных данных и препятствует возникновению ошибок в базе данных, освобождая при этом разработчика прикладного решения от программирования реакции на ошибочные действия пользователя.
Профессиональная разработка в системе «1С:Предприятие 8»
Конструирование форм
Примеры конструирования форм Рассмотрение вопроса построения и модификации форм будет производиться на сквозном примере. В разделе будет рассмотрен пример создания нового документа «Расходный кассовый ордер 1» и его основных форм. В качестве эталона нами будет использован документ «Расходный кассовый ордер», который присутствует в демонстрационной базе «Разработка форм, пример 1».
Снимем флажок Отображать заголовок, так как в данном случае выводить название группы на форму не имеет ни малейшего смысла. Свойство Отображение установим в Нет. Подчиним группе элементы формы Номер и Дата и поместим ее под командной панелью формы (рис. 8.144).
Как и зачем объединять элементы формы в группы По умолчанию форма, созданная конструктором форм для нашего демонстрационного документа (рис. 8.143), вряд ли может являться образцом изыска и удобства работы. Это и не входит в задачи конструктора форм. Его задача – сгенерировать форму, пригодную для ввода, редактирования, просмотра данных. С этой задачей конструктор справился блестяще.
Рис. 8.144. Группировка элементов «Номер» и «Дата»
Итак, форма стала более приятной на вид. Все ли на этом? Нет. Например, мы хотим, чтобы состав группы НомерДата не изменялся пользователем в процессе настройки. Рис. 8.143. Форма документа
Итак, чем же может помочь объединение элементов в группы? Сделать форму более читаемой, более удобной для просмотра и работы. Сгруппировать элементы формы в логические группы, объединив в них близкие, согласно логике работы приложения и формы, связанные данные. Это позволит рассматривать форму как некий каталог, в котором каждая группа (в нашем случае группа элементов) объединяет в себе близкие по характеристикам и назначению данные. Добавим в форму элемент Группа – Обычная группа. Свойству Имя присвоим значение НомерДата. Свойство Группировка установим в значение Горизонтальная.
Том 1
ПРИМЕЧАНИЕ
Вполне возможно, что вы считаете иначе и не согласны с мнением автора по поводу группы НомерДата. В таком случае рассматривайте этот пример лишь в качестве учебного (что так и есть на самом деле), а на практике поступайте так, как велит вам сердце, или разум, или что-то еще, присущее только вам, ну или логика работы вашего приложения.
Пользователь в режиме 1С:Предприятие может изменять внешний вид этой формы по своему усмотрению. Например, мой труд может выглядеть, как на рис. 8.145 или как на рис. 8.146, а то и вообще как на рис. 8.147.
269
Глава 8. Разработка форм Может, некоторым разработчикам это и придется по нраву, но лично автор такого бы не пережил, и потому поступим вот так: для группы НомерДата свойство РазрешитьИзменениеСостава установим в Ложь (снимем флажок). Это не позволит пользователю добавлять в группу новые элементы или удалять существующие.
Как изменить состав кнопок элементов формы Представим себя на месте пользователя нашей формы. Ему (пользователю) по неизвестным нам причинам необходимо очистить поле, в котором уже выбран контрагент.
Рис. 8.145. Пользовательская настройка группы элементов 1
Наш пользователь не читает документацию (то ли из-за отсутствия времени, то ли из-за лени, а может, еще и другие причины есть) и о горячих клавишах ничего не слышал. Кроме этого, он не знает о наличии у элемента формы контекстного меню, в котором есть команда очистки. Пользователь просто привык очищать поле кнопкой очистки (в виде крестика). Но эта кнопка не добавляется по умолчанию в управляемую форму. К счастью, выход есть. Необходимо лишь указать платформе на обязательное присутствие кнопки в элементе формы (рис. 8.148).
Рис. 8.146. Пользовательская настройка группы 2
Рис. 8.148. Изменение состава кнопок элемента формы
Рис. 8.147. Пользовательская настройка формы 3
270
Профессиональная разработка в системе «1С:Предприятие 8»
Конструирование форм
Как добавить поле «Договор» и связать его с контрагентом Менеджеры вашего предприятия удачно приобрели несколько партий товаров, и руководство пришло к выводу, что оплаты поставщикам необходимо привязывать не только к контрагентам, но и договорам с ними (ибо товар приобретали каждый раз по разным условиям).
Однако воспользоваться этим свойством элемента формы – значит, допустить методологическую ошибку. Если вы так и поступили, то вам стоит перечитать теоретические разделы этой главы («Редактирование формы», стр. 240, «Влияние объектов конфигурации на форму», стр. 253). Дело в том, что часть свойств элементов формы есть и у реквизитов объектов, а значит, более правильно настраивать это там (рис. 8.151).
Задача вам ясна, с теорией модификации формы вы уже знакомы по разделу «Редактирование формы» (стр. 240), так что вперед. Добавим в метаданные документа реквизит ДоговорКонтрагента, разместим его на форме и ограничим пользователя в выборе договоров. После добавления реквизита в метаданные документа (рис. 8.149) он доступен для формы в списке реквизитов (рис. 8.150).
Рис. 8.149. Реквизиты документа
Рис. 8.151. Настройка отбора договоров по контрагенту
Как же все это работает? Да очень просто. Список договоров строится с помощью системы компоновки данных, на отбор которой и влияет свойство Связи параметров выбора. Вполне очевидно, что во всех формах нашего документа нам будет необходим отбор договоров по текущему контрагенту. Вот поэтому мы и настроили его на уровне не одной формы, а реквизита объекта.
Как добавить в форму табличную часть Рис. 8.150. Где искать новый реквизит объекта
Для получения положительного результата доработки осталось лишь добавить отбор договоров по контрагенту, и премия в кармане. Для создания такого отбора нужно использовать свойство Связи параметров выбора. Том 1
Поработав некоторое время с нашим документом, бухгалтерия вносит предложение: дать возможность закрывать одним документом несколько сделок, по нескольким договорам. Способов решения поставленной задачи существует немало. Мы рассмотрим классический вариант с использованием табличной части документа.
271
Глава 8. Разработка форм В табличной части должны быть реквизиты Договор, ПриходныйДокумент, Сумма. Тип значения реквизита ПриходныйДокумент установим в ДокументСсылка.ПоступлениеТоваров. Табличную часть назовем Оплаты. ВНИМАНИЕ!
Если вы для реквизита Договор не заполнили свойство Связи параметров выбора, то сейчас самое время сделать это. Для чего это делается, рассказано в предыдущем разделе.
Как добавить в форму панель со страницами Прежде всего, необходимо уточнить: в управляемом приложении нет элемента формы Панель, а есть элемент Группа, свойство Вид которого имеет значение Страницы. Добавим в дерево элементов формы новую группу, определив свойство Вид в Страницы (рис. 8.153).
Самый простой способ добавления табличной части в форму – это перетаскивание из раздела редактора формы Реквизиты. Зацепим мышью табличную часть Оплаты и бросим в раздел Элементы. Если вы не промахнулись, то платформа предложит вам автоматически создать колонки будущей таблицы. Можете соглашаться с этим. Исправить созданное можно всегда. Вот собственно и все с точки зрения конструирования формы. Форма несколько непривычна (много реквизитов, таблица, а что к чему непонятно), и неопытный пользователь наверняка в ней запутается (рис. 8.152). Как немного поправить ситуацию, расскажем далее. Рис. 8.153. Элемент «Группа» вида «Страницы»
Чтобы сделать форму более привлекательной и понятной для непосвященного в способы работы с нашим приложением пользователя, добавим на форму несколько страниц, в которых разместим элементы формы. Добавим в подчинение группе Страницы группы, свойство Вид которых будет иметь значение Страница (рис. 8.154).
Рис. 8.152. Таблица, отображающая табличную часть документа
Рис. 8.154. Страницы формы
272
Профессиональная разработка в системе «1С:Предприятие 8»
Конструирование форм Для того чтобы страницы стали видны в форме, перегруппируем элементы формы так, чтобы элементы ДоговорКонтрагента и Сумма размещались на странице ПлатежПоСделке, а таблица Оплаты – на странице ПлатежПоСделкам (рис. 8.155).
Рис. 8.156. Тип реквизита «ДинамическийСписок» Рис. 8.155. Распределение элементов по страницам
Как добавить в форму таблицу, отображающую произвольные данные Согласно регламенту работы компании, деятельность которой мы с вами взялись автоматизировать, после оплаты поставленных товаров (оплата в программе, а значит и в банке) принято уведомлять об этом поставщиков. Таким образом, перед нами стоит задача добавления на форму документа контактных данных поставщика. Раз перечень контактных данных жестко не определен, например, только рабочий телефон менеджера, то наиболее оптимальным для вывода заранее неизвестного количества данных является таблица. Как нам уже известно, для того чтобы что-то отображалось на форме, это что-то должно быть описано в виде реквизита формы. Добавим форме новый реквизит КонтактнаяИнформация. Тип значения реквизита ДинамическийСписок (рис. 8.156). Динамический список может получать данные из таблиц базы данных. Это может быть, например, список справочника, список документов, список значений регистра сведений. Для того чтобы динамический список работал с такими данными, необходимо указать их в свойстве ОсновнаяТаблица (рис. 8.157). Том 1
Рис. 8.157. Свойство «ОсновнаяТаблица»
С помощью свойства НастройкаСписка можно произвести необходимые настройки отбора, группировки, сортировки отображаемых данных. Динамический список может получать данные из результата произвольного запроса, который необходимо определить в свойстве НастройкаСписка. Для того чтобы использовать произвольный запрос, необходимо установить флажок ПроизвольныйЗапрос (рис. 8.158).
273
Глава 8. Разработка форм В некоторых случаях использовать дополнительные страницы, таблицы и динамические списки вовсе не обязательно. Платформа позволяет выводить связанную с неким реквизитом информацию в эту же форму и осуществлять переключение между такими данными с помощью панели навигации формы. Если открыть в редакторе формы Глобальные команды, то можно увидеть, что нам доступна параметризуемая команда открытия контактной информации, связанной с реквизитом Контрагент (рис. 8.160).
Рис. 8.158. Свойство «ПроизвольныйЗапрос»
Свойство Динамическое считывание данных отвечает за считывание данных из базы данных порциями, что позволяет экономить ресурсы системы. Для решения поставленной перед нами задачи мы воспользуемся первым способом (задание основной таблицы) и выберем таблицу регистра сведений Контактная информация. Добавим форме еще одну страницу и разместим на ней таблицу с контактной информацией (рис. 8.159).
Рис. 8.160. Дополнительные команды формы
Такую команду достаточно перетащить в панель навигации формы. Всю остальную работу за нас сделает система при построении и отображении формы на экране (рис. 8.161).
Рис. 8.161. Отображение контактной информации Рис. 8.159. Отображение контактной информации
274
Отбор (рис. 8.162), который был при этом установлен системой, не потребовал от разработчика ни строчки кода. Профессиональная разработка в системе «1С:Предприятие 8»
Конструирование форм Исправить сложившуюся ситуацию достаточно просто. Необходимо лишь создать аналог старой кнопки Перейти. Первое, что необходимо сделать, это отключить возможность формирования команд перехода к регистрам платформой (если Видимость кто-то включил). Сделать это можно в окне редактирования командного интерфейса формы, рассматриваемого в разделе «Редактирование командного интерфейса», стр. 168 (рис. 8.164).
Рис. 8.162. Установленный системой отбор
Если рассматривать наш пример с контактной информацией, то второй способ (с помощью команды панели навигации формы) является наиболее предпочтительным и рекомендуемым.
Создание подменю «Перейти» старого образца
Рис. 8.164. Отключение команд панели навигации формы
Практически для любого документа прикладного решения характерно наличие движений по тем или иным регистрам. Документ, рассматриваемый нами, не является исключением.
В командную панель формы необходимо добавить элемент формы Группа с видом Подменю. Имя группы – Перейти (рис. 8.165).
По умолчанию платформа располагает команды перехода к регистрам, по которым документ может делать движения, в панели навигации формы (рис. 8.163), если включена видимость соответствующей команды. Это может быть не совсем удобно пользователю, особенно если он работал с приложениями, разработанными для старых версий платформы.
Рис. 8.165. Создание подменю «Перейти»
Чтобы создать кнопки подменю Перейти, можно воспользоваться возможностями перетаскивания команд в раздел элементов формы. Интересующая нас команда находится в разделе Глобальные команды редактора формы. После добавления кнопки в подменю Перейти оно автоматически становится видимым в окне предварительного просмотра формы и в пользовательском режиме работы (рис. 8.166). Рис. 8.163. Кнопки перехода к движениям документа
Том 1
275
Глава 8. Разработка форм
Рис. 8.168. Установленный пользователем отбор
Рис. 8.166. Кнопка перехода к движениям документа
Мы уже говорили о том, что сложная структура нашего документа не позволяет нам эффективно использовать методы копирования или ввода на основании (если это предусмотрено) документа. Пользователю необходимо лишь автоматизировать заполнение нескольких реквизитов.
Как создать и заполнить объект с учетом установленного отбора списка
Этого легко добиться, если установить у нужного реквизита документа свойство Заполнять из данных заполнения. Установим этот флажок у реквизита документа Контрагент (рис. 8.169).
Достаточно часто у пользователя возникает необходимость проанализировать некие данные, например, существующие документы определенного контрагента, и, обнаружив расхождения, создать еще один документ. При этом часто копирование документа или ввод на основании не дают положительного эффекта – необходимо изменять достаточно большое количество реквизитов, и что-то можно просто оставить по ошибке, хотя нужно бы поменять. Выходом из сложившейся ситуации может быть использование отборов в списке и установка флажка Заполнять из данных заполнения у нужных реквизитов объекта. Итак, наш пользователь, получив от контрагента список оплат, просматривает тот же список в своей информационной базе (рис. 8.167).
Рис. 8.169. Установка свойства «Заполнять из данных заполнения»
После такой настройки новый объект конфигурации (наш документ) будет при создании заполнять свои реквизиты (у которых установлен флажок Заполнять из данных заполнения) исходя из установленных пользователем отборов списка (рис. 8.170). ВНИМАНИЕ! Рис. 8.167. Форма списка документов
Для лучшего восприятия данных пользователем устанавливается отбор по нужному контрагенту (рис. 8.168).
276
Заполнение будет происходить только при интерактивном создании документа (кнопка Создать). В списке должен быть установлен именно отбор. Если, например, пользователь применял поиск по полю Контрагент, то отбор в списке не устанавливается (рис. 8.171) и реквизит заполнен не будет.
Профессиональная разработка в системе «1С:Предприятие 8»
Конструирование форм Для осуществления задуманного необходимо лишь перетащить реквизит ИНН в элемент формы Список. Все остальное платформа сделает за нас сама (рис. 8.172).
Рис. 8.170. Заполнение документа с учетом установленного отбора
Рис. 8.172. Отображение «ИНН» в списке документов
Данные, которые отображаются в колонке таблицы ИНН, будут получены через точку (рис. 8.173).
Рис. 8.171. Результат поиска в списке
Рис. 8.173. Свойство «ПутьКДанным»
Как отобразить в списке реквизиты реквизитов
Как сгруппировать данные в списке
Динамический список позволяет без каких-либо трудностей расширить перечень информации, отображаемой элементом формы Таблица. Причем эта задача легко решается с помощью средств визуального конструирования.
Существуют два пути решения поставленной задачи. Первый – в конфигураторе, во время разработки формы. Этот путь следует применять, если подобная группировка будет необходима максимальному количеству пользователей формы. Второй путь – в пользовательском режиме работы.
Итак, у контрагента существует реквизит ИНН, который необходимо видеть в списке документов наряду с другими реквизитами документа.
Сразу оговоримся, что речь пойдет о настройке динамических списков. Обычные таблицы значений, списки значений подобной настройке не поддаются.
Том 1
277
Глава 8. Разработка форм Рассмотрим форму списка документа Расходный кассовый ордер 1. Элемент формы с именем Список отображает данные, имеющие тип Динамический список (рис. 8.174). Это как раз то, что нам необходимо.
Рис. 8.174. Тип «Динамический список»
Чтобы настроить группировку, необходимо открыть свойства реквизита формы Список и нажать на гиперссылку свойства Настройка списка (рис. 8.175).
Рис. 8.176. Настройка группировок
Рис. 8.177. Группировки списка
Как настроить условное оформление динамического списка Условное оформление динамических списков, так же как и группировки, настраивается в окне настройки динамического списка (см. предыдущий раздел). Рис. 8.175. Открытие настроек динамического списка
Настройки производятся на закладке Условное оформление (рис. 8.178).
На закладке Группировка окна Динамический список (рис. 8.176) можно настроить необходимые группировки. В пользовательском режиме список документов будет выглядеть так, как мы его настроили (рис. 8.177). ПРИМЕЧАНИЕ
Несмотря на то, что Динамический список формируется с помощью системы компоновки данных, получить итоги по группировкам нельзя.
278
Рис. 8.178. Настройка условного оформления
В поле Оформление (рис. 8.179).
настраивается
способ
оформления
данных
Профессиональная разработка в системе «1С:Предприятие 8»
Конструирование форм Результат в пользовательском режиме будет выглядеть вот так (рис. 8.182).
Рис. 8.179. Настройка оформления
В поле Условие настраиваются условия отбора данных, которые необходимо оформлять (рис. 8.180).
Рис. 8.182. Условное оформление списка
Аналогичным образом в конфигурации может быть настроено условное оформление и самой формы. Для этого используется гиперссылка Условное оформление в палитре свойств формы.
Рабочий стол
Рис. 8.180. Настройка условия
В поле Оформляемые поля настраивается список полей, которые будут выделены. Если необходимо выделить всю строку, то выбор полей осуществлять не нужно (рис. 8.181).
Рис. 8.181. Настройка оформляемых полей
Том 1
Рабочий стол не является формой управляемого приложения в прямом смысле этого слова. Можно сказать, что рабочий стол строится разработчиком прикладного решения из уже имеющихся в конфигурации форм и команд. При этом форма обязательно должна быть создана и включена в состав конфигурации. Использовать автоматически генерируемые формы рабочий стол не умеет. В прикладном решении рабочий стол представлен в единственном экземпляре. Добраться до рабочего стола при разработке прикладного решения можно через свойства разрабатываемой конфигурации или контекстное меню (рис. 8.183).
Рис. 8.183. Открытие рабочего стола в режиме «Конфигуратор»
279
Глава 8. Разработка форм Создание и редактирование рабочего стола происходят в специализированном редакторе (рис. 8.184).
■■ Две колонки одинаковой ширины. Формы будут располагаться в две колонки. Переносить форму из одной колонки в другую можно с помощью кнопок, расположенных между колонками редактора рабочего стола. Горизонтальный размер форм в разных колонках будет одинаковым (рис. 8.186).
Рис. 8.184. Редактор «Рабочая область рабочего стола»
Формы, отображаемые на рабочем столе в пользовательском режиме работы, могут располагаться в одну или две колонки. Настройка количества колонок с формами осуществляется с помощью выбора одного из предопределенных значений поля Шаблон рабочего стола. При этом доступны следующие значения: ■■ Одна колонка. Формы будут располагаться вертикально, одна под другой (рис. 8.185). Управлять последовательностью форм можно с помощью кнопок Переместить вверх, Переместить вниз. Рис. 8.186. Шаблон «Две колонки одинаковой ширины»
■■ Две колонки разной ширины (2:1). Формы будут располагаться, как и в предыдущем примере, однако ширина форм первой колонки будет в два раза больше ширины форм второй колонки рабочего стола (рис. 8.187).
Рис. 8.185. Шаблон «Одна колонка» Рис. 8.187. Шаблон «Две колонки разной ширины»
280
Профессиональная разработка в системе «1С:Предприятие 8»
Конструирование форм Добавление форм в состав рабочего стола производится стандартным способом – с помощью кнопки командной панели. При этом разработчику необходимо выбрать конкретную форму, указав ее в списке (рис. 8.188).
Если видимая часть, отведенная форме в рабочем столе, меньше, чем высота формы, то у последней появляется вертикальная полоса прокрутки (рис. 8.190).
Рис. 8.190. Полосы прокрутки формы рабочего стола
Рис. 8.188. Добавить форму
Разработчик прикладного решения может влиять на состав рабочего стола, отображаемого в пользовательском режиме работы, с помощью настройки видимости форм (рис. 8.191).
Кроме управления шириной форм рабочего стола с помощью ширины колонок, возможно управление их высотой. Высота форм задается в строках, и для каждой из форм она своя (рис. 8.189).
Рис. 8.191. Настройка видимости форм рабочего стола
Рис. 8.189. Задание высоты форм
Том 1
Настройка видимости форм является особенно важной для тех категорий пользователей, которые обладают наиболее полными правами на объекты конфигурации или совмещают несколько ролей прикладного решения. Только таким образом можно будет избежать «каши» на рабочем столе такого пользователя.
281
Глава 8. Разработка форм Состав рабочего стола приложения зависит от прав доступа, которыми обладает пользователь прикладного решения. Так, если совокупность ролей пользователя не дает прав на просмотр некой формы объекта конфигурации, то такая форма не будет отображаться на рабочем столе (рис. 8.192).
Рис. 8.193. Влияние функциональных опций на рабочий стол
Рис. 8.192. Влияние прав доступа на рабочий стол
Функциональные опции, реализованные в прикладном решении, также оказывают влияние на отображение форм, населяющих рабочий стол пользователя (рис. 8.193). Пользовательские настройки, которые могут повлиять на состав рабочего стола, можно вызвать с помощью контекстного меню панели навигации (рис. 8.194).
282
Рис. 8.194. Пользовательская настройка рабочего стола
Профессиональная разработка в системе «1С:Предприятие 8»
Программирование форм
Программирование форм
Форма как элемент клиент-серверного взаимодействия Прежде чем рассматривать конкретные примеры программирования в формах, нужно иметь четкое представление о том, что представляет собой форма. В предыдущих разделах главы уже давались общие сведения о ее устройстве и функционировании, сейчас же мы рассмотрим форму более подробно и именно с точки зрения ее внутреннего, «программного» устройства. Форма – это программный объект, который создается в процессе работы прикладного решения в режиме 1С:Предприятие. Форма может быть создана платформой, без участия разработчика. Либо она может быть создана по инициативе разработчика в результате выполнения алгоритма, описанного разработчиком на встроенном языке. В «1С:Предприятии» нет «единого пространства» для выполнения кода на встроенном языке. Каждый фрагмент кода выполняется в некотором контексте.
Рис. 8.195. Формы, созданные разработчиком
По большому счету, не углубляясь в детали, таких контекстов два: это контекст клиента и контекст сервера. С одной стороны, контекст определяет «программное окружение», в котором исполняется код: доступные свойства, методы, набор объектов встроенного языка, которые можно использовать. С другой стороны, контекст определяет физическое место (конкретный компьютер), на котором выполняется этот код. Подробнее
Раздел «Контекст исполнения модулей», стр. 47. Раздел «Программные компоненты клиент-серверной архитектуры», стр. 119.
Раз мы говорим о «программировании форм», то это значит, что программный объект формы создается платформой на основе того описания, которое существует в дереве объектов конфигурации, то есть на основе объекта конфигурации Форма (рис. 8.195). Потому что в «1С:Предприятии» могут существовать формы, не описанные в конфигурации. Формы, которые платформа генерирует автоматически. Но в такие формы разработчик не может добавить свой код. Каждый такой объект конфигурации Форма, описанный в дереве объектов конфигурации, имеет модуль, в котором разработчик располагает собственные процедуры на встроенном языке (рис. 8.196). Эти процедуры вызываются в определенные, заранее известные моменты работы формы (программного объекта) и определяют ее нестандартное, отличное от других форм поведение и возможности. Том 1
Рис. 8.196. Модуль формы
Так вот, основная особенность формы как программного объекта заключается в том, что она существует одновременно и на клиенте, и на сервере. Соответственно модуль формы, процедуры, написанные в этом модуле, исполняются не в каком-то одном определенном контексте (только в контексте клиента или только в контексте сервера). Для каждой процедуры в модуле формы разработчик в явном виде указывает контекст ее исполнения: на сервере или на клиенте. Для этого используются директивы компиляции.
283
Глава 8. Разработка форм Подробнее
Раздел «Модуль управляемой формы», стр. 53. Раздел «Исполнение модуля формы на клиенте и на сервере», стр. 54.
Общий подход к программированию форм Работа системы «1С:Предприятие» всегда начинается на компьютере пользователя – пользователь запускает приложение и соединяется с информационной базой. Уже в этот момент в работу вступает серверная часть «1С:Предприятия» – выполняется соединение с кластером серверов, аутентификация подключающегося пользователя в информационной базе, формирование основного окна системы, рабочего стола и передача его назад, на клиента. В дальнейшем этот процесс повторяется неоднократно: выполнение каких-либо действий начинается в клиентском приложении, затем управление передается на сервер, он выполняет некоторые действия и возвращает управление на клиента. То есть клиентское приложение вызывает сервер для выполнения каких-либо действий, сервер выполняет их и возвращает управление и результат этих действий обратно, клиентскому приложению. Механизмы платформы, отвечающие за это взаимодействие, оптимизированы для того, чтобы обеспечивать приемлемую скорость работы системы даже на низкоскоростных каналах связи. Однако кроме платформы такое взаимодействие может вызвать и сам разработчик в результате работы своего алгоритма на встроенном языке. Например, когда из процедуры, исполняющейся на клиенте, он вызывает процедуру, которая должна исполняться на сервере. В этом случае также происходит вызов сервера, управление передается на него, выполняется требуемая процедура, и управление возвращается обратно на клиента, в ту процедуру, из которой был осуществлен вызов. Поскольку заранее неизвестно, каким именно образом клиент подключен к серверу, такой серверный вызов может быть «совсем незаметным» для системы или, наоборот, очень «затратным». Например, в том случае, когда используются мобильные каналы связи. Поэтому к вызовам сервера разработчик должен относиться очень внимательно. В противном случае быстродействие и производительность разрабатываемой системы могут оказаться очень низкими. Из этого следуют несколько важных тезисов, определяющих общий подход к программированию форм. Разработчик должен понимать, что он не просто кодирует некий прикладной алгоритм, а в явном виде программирует отдельно клиентскую и отдельно серверную части приложения.
284
Разработчик должен управлять частотой вызовов сервера и объемом передаваемой информации. В разрабатываемой конфигурации код, реализующий бизнес-логику, должен быть четко отделен от кода, реализующего интерфейс. Структура кода должна определяться не прикладной логикой решаемой задачи, а логикой клиент-серверного взаимодействия. Клиентский код пишется не как последовательность действий, которую нужно выполнить. Прежде всего, он продумывается как сценарий передачи управления с клиента на сервер и обратно. Несмотря на то, что форма существует одновременно и на клиенте, и на сервере, клиент и сервер нужно рассматривать не как единое пространство выполнения приложения, а скорее как два взаимодействующих приложения. Полезно мысленно представить вызов сервера как «непростой процесс»: ■■ система формирует обращение к серверу, передает его по каналу связи, потом выполняет его на сервере, возвращает ответ по каналу связи… ■■ если тонкий клиент работает, например, через GPRS, то каждый вызов – это примерно 1,5 секунды! ■■ хочется, чтобы с прикладным решением работали удаленные пользователи? Тогда нужно думать о каждом вызове сервера! На протяжении последующих разделов эти рекомендации будут неоднократно повторяться и объясняться более подробно. Сейчас же важно усвоить следующее: программирование форм – это отдельное непростое занятие, требующее взвешенного и методически грамотного использования имеющихся возможностей платформы. Подробнее
Раздел «Общие рекомендации по оптимизации клиент-серверного взаимодействия», стр. 391.
Параметры и реквизиты формы Вы уже знаете, что форма, как правило, содержит некоторое количество реквизитов и некоторое количество параметров. И те и другие позволяют хранить некоторые данные, доступны в редакторе формы на соответствующих закладках, и те и другие разработчик может добавить самостоятельно, по своему желанию. Для этого в редакторе формы существуют две закладки: Реквизиты и Параметры (рис. 8.197). В чем же различие между параметрами и реквизитами формы? Для каких задач нужно использовать реквизиты, а для каких – параметры?
Профессиональная разработка в системе «1С:Предприятие 8»
Программирование форм
Параметры Параметры формы, в отличие от реквизитов, предназначены для управления функциональностью формы при ее открытии и, грубо говоря, существуют лишь в момент создания и открытия формы. После создания или открытия формы все параметры, кроме ключевых параметров, удаляются, т. к. для дальнейшей работы формы они уже не нужны. Ключевые параметры – это особый вид параметров, значения которых могут потребоваться и после того, как форма создана. Например, для того, чтобы найти именно этот экземпляр формы среди других открытых форм.
Выводы Рис. 8.197. Реквизиты и параметры формы
Реквизиты Реквизиты формы предназначены для хранения данных, с которыми работает форма. В реквизитах хранятся те данные, которые отображаются и редактируются в элементах формы, а также те данные, которые не отображаются, но используются формой в процессе ее работы. Вся совокупность данных, хранящихся в реквизитах формы, называется данные формы. Этот термин мы будем использовать в дальнейшем. Каждый элемент формы, позволяющий изменять данные, связан с некоторым реквизитом формы. Когда пользователь изменяет данные в элементе формы, аналогичные изменения происходят и в связанном с ним реквизите. Верно и обратное. Когда реквизит формы изменяется программно, изменяется и значение, отображаемое в связанном с ним элементе формы. Не все реквизиты формы обязательно должны отображаться в форме. Часть реквизитов может быть не связана с элементами формы, а данные, хранящиеся в таких реквизитах, предназначены не для отображения или интерактивного редактирования, а для обеспечения внутренних алгоритмов работы формы или для программного взаимодействия с этой формой из встроенного языка. Можно сказать, что реквизиты формы составляют часть программного интерфейса формы, с помощью которого строится взаимодействие с этой формой «извне» – из других форм или из фрагментов программного кода. Важным моментом является то, что реквизиты формы существуют на протяжении всего времени существования самой формы.
Том 1
Итак, подытоживая сказанное, можно отметить, что для хранения, отображения, изменения данных, для взаимодействия с формой извне, для хранения служебных данных нужно использовать реквизиты формы. Для того чтобы создать и открыть форму в том виде и в том состоянии, в котором хочется, нужно использовать параметры формы. Следующая глава как раз будет посвящена имеющимся способам открытия форм, и в ней мы будем оперировать различными параметрами формы.
Открытие форм Самый первый, наверное, вопрос, который возникает у разработчиков, начинающих знакомиться с формами: а как открыть форму? В этой главе мы рассмотрим общий подход и несколько конкретных примеров открытия форм в типичных ситуациях.
Последовательность событий при открытии формы При открытии формы нового объекта (элемента справочника, документа) и при открытии формы существующего объекта возникает различная последовательность событий. Если открывается форма нового объекта, то сначала происходит начальное заполнение объекта данными (событие Обработка заполнения в модуле объекта, форма которого открывается), а затем вызываются два события формы: сначала на сервере (При создании на сервере) и затем на клиенте (При открытии). Эти два события позволяют подготовить форму к открытию (рис. 8.198).
285
Глава 8. Разработка форм форму, которая «сама по себе» не существует, а существует, только если открыта родительская форма. Потому что обработчик При открытии – последний перед открытием формы, в котором можно отказаться от ее открытия. И если не происходит отказа от открытия родительской формы, то, значит, она наверняка будет открыта. Подробнее
Что касается других событий, то, например, о событии Обработка заполнения и механизме начального заполнения объектов мы поговорим подробно в разделе «Начальное заполнение», стр. 305. Рис. 8.198. Последовательность событий при открытии формы нового объекта
Слева показан клиентский контекст, в котором вызываются события формы. Посередине и справа – серверный контекст, в котором вызываются как события формы, так и события самого прикладного объекта, форма которого открывается. Если открывается форма существующего объекта, то последовательность событий будет иной (рис. 8.199). Сначала на сервере вызываются два события формы. Одно (При чтении на сервере) – чтобы подготовить дополнительные данные, которые зависят от данных объекта. Другое (При создании на сервере) – чтобы максимально подготовить форму к открытию. И наконец, на клиенте вызывается еще одно событие формы (При открытии), чтобы выполнить действия, связанные с открытием формы, которые на сервере выполнить невозможно.
А о событии При чтении на сервере мы поговорим в разделе, описывающем преобразование данных объекта в данные формы и обратно, «Преобразование прикладных данных в данные формы», стр. 294.
Общая методика открытия форм Общий подход к открытию форм следующий. Для открытия формы используется метод глобального контекста ОткрытьФорму(). Он доступен только в контексте клиентов: толстого клиента, тонкого клиента и веб-клиента. На сервере открыть форму нельзя. Этот метод содержит ряд параметров, которые позволяют указать, какая именно форма должна быть открыта, и задать некоторые свойства открываемой формы. Значения передаваемых параметров либо применяются платформой автоматически, либо разработчик может применить их самостоятельно в обработчике события формы При создании на сервере. Рассмотрим наиболее типичные случаи.
Основная форма нового объекта Подробнее
Рис. 8.199. Последовательность событий при открытии формы существующего объекта
Из всех перечисленных событий нас прежде всего будут интересовать два события формы: При создании на сервере и При открытии. Все, что можно сделать на сервере для подготовки формы к открытию, нужно делать в обработчике события При создании на сервере. В обработчике события При открытии нужно делать только то, что на сервере сделать невозможно. Например, выдать предупреждение, задать вопрос. Или же выполнить те действия, которые выполняются именно тогда, когда форма наверняка открывается. Например, открыть связанную
286
Примеры можно посмотреть в демонстрационной базе «Разработка форм, пример 2», панель действий, группа команд Открыть основную форму, глобальные команды Объекта, Группы, Списка, Выбора, Выбора группы.
Открыть основную форму справочника Товары можно следующим образом (листинг 8.1): Листинг 8.1. Открытие основной формы нового объекта
ОткрытьФорму("Справочник.Товары.ФормаОбъекта");
Первым параметром метода передается имя той формы, которую нужно открыть. Оно образуется по определенным правилам. Сначала Профессиональная разработка в системе «1С:Предприятие 8»
Программирование форм указывается полное имя объекта конфигурации (в данном случае Справочник.Товары), а после него, через точку, стандартное имя основной формы (ФормаОбъекта). Все стандартные имена основных форм перечислены в синтакс-помощнике в описании метода ОткрытьФорму() (рис. 8.200).
Таким образом можно открыть как автогенерируемые формы, так и формы, которые созданы разработчиком в конфигурации и назначены основными для объектов конфигурации. Однако существуют две особенности, связанные с открытием стандартных форм, о которых будет сказано далее.
Форма констант Первая особенность связана с формой констант. Нет возможности из встроенного языка открыть автогенерируемую форму констант. Можно открыть только форму констант, созданную в конфигурации (листинг 8.3). Листинг 8.3. Открытие формы констант, созданной в конфигурации
ОткрытьФорму("ОбщаяФорма.ФормаКонстант");
Здесь
ФормаКонстант
– это имя созданной формы.
Аналогичным образом можно открыть и другие общие формы конфигурации. Подробнее
Пример можно посмотреть в демонстрационной базе «Разработка форм, пример 2», панель действий, группа команд Сервис, глобальная команда Открыть форму констант. Рис. 8.200. Метод «ОткрытьФорму()» в синтакс-помощнике
Форма группы
Единственной сложностью тут является то, что имя формы указывается как строка, и поэтому писать его нужно внимательно, не забывая о том, что имя класса объектов конфигурации указывается в единственном числе: Справочник, Документ и т. д.).
Вторая особенность связана с формой группы иерархического справочника или иерархического плана видов характеристик.
Поскольку кроме имени формы никаких других параметров не указывается, в случае формы объекта будет создан новый объект и открыта его форма. Подробнее
Как открыть форму существующего объекта, рассказано в разделе «Форма существующего объекта», стр. 289.
В случае же форм списка и выбора просто будут открыты соответствующие формы (листинг 8.2). Листинг 8.2. Открытие основных форм списка и выбора
ОткрытьФорму("Справочник.Товары.ФормаСписка"); ОткрытьФорму("Справочник.Товары.ФормаВыбора"); ОткрытьФорму("Справочник.Товары.ФормаВыбораГруппы");
Том 1
Указывая имя формы в методе ОткрытьФорму(), мы лишь определяем, какая форма должна быть открыта. Но не определяем особенности элемента данных, который будет отображаться в этой форме. В случае с документами или линейными справочниками никакой проблемы не возникнет. Все элементы данных в таких структурах равнозначны. Однако если справочник не линейный, а иерархический, то он содержит как «обычные» элементы, так и элементы, являющиеся группами. Если при открытии формы не делать специальных указаний, платформа стандартно будет создавать именно новый элемент, а не группу. Поэтому если мы хотим открыть форму новой группы, то помимо указания имени открываемой формы нужно еще указать, что должна создаваться именно новая группа, а не элемент. Для этого используются параметры формы. Некоторый стандартный набор параметров существует у самого объекта встроенного языка Форма. В режиме 1С:Предприятие к этим параметрам,
287
Глава 8. Разработка форм которые существуют у любой формы, добавляется еще некоторое количество параметров, поставляемых расширением формы. Параметры формы описаны в синтакс-помощнике (рис. 8.201).
Рис. 8.202. Расширения формы в синтакс-помощнике
Подробнее Рис. 8.201. Параметры формы в синтакс-помощнике
Все возможные расширения также перечислены в синтакс-помощнике. У каждого из них свой состав параметров, которые они добавляют к параметрам формы (рис. 8.202). Какое именно расширение будет добавлено к конкретной форме, зависит от типа основного реквизита формы. Например, если форма отображает данные элемента справочника, то основной реквизит такой формы будет иметь тип СправочникОбъект.<имя>, а к форме будет добавлено расширение справочника. У расширения справочника есть параметр ЭтоГруппа. Если в этот параметр передать значение Истина, то будет создана именно новая группа, а не новый элемент. Параметры
формы
можно
передать
вторым
параметром
метода
ОткрытьФорму(). Так как может быть указано сразу несколько параметров,
то они передаются в виде структуры. Каждый элемент этой структуры содержит имя параметра и его значение (листинг 8.4). Листинг 8.4. Открытие основной формы новой группы
ПараметрыФормы = Новый Структура("ЭтоГруппа", Истина); ОткрытьФорму("Справочник.Товары.ФормаГруппы", ПараметрыФормы);
288
Пример можно посмотреть в демонстрационной базе «Разработка форм, пример 2», панель действий, группа команд Открыть основную форму, глобальная команда Группы.
Произвольная форма Открыть форму, не назначенную основной для справочника Товары, можно следующим оператором (листинг 8.5): Листинг 8.5. Открытие произвольной формы
ОткрытьФорму("Справочник.Товары.Форма.ПроизвольнаяФормаТовара");
Здесь первым параметром метода также передается полное имя той формы, которую нужно открыть. Но поскольку открываемая форма не назначена основной, то после полного имени объекта конфигурации (Справочник.Товары) нужно указать слово Форма, а затем – имя нужной формы (ПроизвольнаяФормаТовара), как она названа в конфигураторе. Подробнее
Пример можно посмотреть в демонстрационной базе «Разработка форм, пример 2», панель действий, группа команд Сервис, глобальная команда Открыть произвольную форму.
Профессиональная разработка в системе «1С:Предприятие 8»
Программирование форм
Форма существующего объекта Чтобы открыть форму существующего элемента, нужно указать, какой именно элемент нас интересует. Для этого также используются параметры формы. У расширения справочника есть параметр Ключ. Если в этот параметр передать ссылку на существующий элемент справочника, то будет открыта форма именно этого элемента, а не нового. Например, если из формы списка организаций нужно открыть форму той организации, на которой находится курсор, сделать это можно следующим способом (листинг 8.6): Листинг 8.6. Открытие основной формы существующего объекта
СсылкаНаЭлементСправочника = Элементы.Список.ТекущаяСтрока; ПараметрыФормы = Новый Структура("Ключ", СсылкаНаЭлементСправочника); ОткрытьФорму("Справочник.Организации.ФормаОбъекта", ПараметрыФормы); Подробнее
Пример можно посмотреть в демонстрационной базе «Разработка форм, пример 2», список организаций, команда Открыть форму элемента. Это локальная команда формы списка справочника Организации.
к серверу, например когда нужно открыть форму элемента иерархического справочника. Платформа будет выполнять дополнительное обращение к серверу для того, чтобы определить, является ли элемент группой или нет, так как для элемента и для группы нужно открывать разные формы. В то же время эта информация может быть заранее известна разработчику внутри его алгоритма, и, используя метод ОткрытьФорму(), разработчик может открывать нужную форму без дополнительных обращений к серверу. Подробнее
Пример, подробно описывающий эту ситуацию, можно посмотреть в разделе «Использование стандартных полей запроса в динамических списках на клиенте», стр. 414.
Открыть список, чтобы курсор был на нужном элементе Одна из типичных задач при работе с формами списков – это открытие формы с одновременным позиционированием на конкретном элементе списка. Для решения такой задачи можно использовать параметр ТекущаяСтрока, который поставляется расширением динамического списка (рис. 8.203).
Чтобы получить ссылку на выделенный элемент списка, мы обращаемся к элементу формы Список и получаем его свойство ТекущаяСтрока. Затем мы создаем структуру ПараметрыФормы для передачи параметров в открываемую форму. В этой структуре будет единственный элемент с ключом Ключ и значением полученной ссылки. После этого открывается форма объекта в соответствии с переданной структурой параметров. В заключение следует заметить, что в том случае, когда кроме ссылки на объект никакие параметры в открываемую форму передавать не нужно и нужна именно основная форма существующего объекта, можно использовать более простой способ – с помощью функции глобального контекста ОткрытьЗначение(), листинг 8.7. Листинг 8.7. Использование метода «ОткрытьЗначение()»
ОткрытьЗначение(Элементы.Список.ТекущаяСтрока);
Такой способ обладает меньшей универсальностью, но в некоторых случаях он экономит много времени и сил. Например, в рассмотренном нами случае одна такая строка может заменить всю написанную нами ранее процедуру из трех строк. Однако нужно внимательно относиться к использованию этого метода. В некоторых случаях он может вызывать дополнительные обращения Том 1
Рис. 8.203. Параметр «ТекущаяСтрока» в синтакс-помощнике
289
Глава 8. Разработка форм Например, для того чтобы сразу увидеть открытый элемент в списке товаров, нужно, находясь в форме элемента справочника Товары, открыть форму списка товаров так, чтобы курсор находился на этом элементе. Для этого можно создать локальную команду формы элемента, которая будет выполнять следующий код (листинг 8.8). Листинг 8.8. Открытие формы списка с позиционированием на некотором элементе
ПараметрыФормы = Новый Структура("ТекущаяСтрока", Объект.Ссылка); ОткрытьФорму("Справочник.Товары.ФормаСписка", ПараметрыФормы); Подробнее
Пример можно посмотреть в демонстрационной базе «Разработка форм, пример 2», форма элемента справочника Товары, команда Найти в списке. Это локальная команда формы элемента справочника Товары.
Список подчиненного справочника с отбором по владельцу Другая типичная задача – открытие списка подчиненного справочника. Для ее реализации можно использовать параметр Отбор, который также поставляется расширением динамического списка. В этот параметр нужно передать условие на отбор элементов подчиненного справочника по некоторому владельцу. Например, это может выглядеть следующим образом. Справочник РасчетныеСчета подчинен справочнику Организации. В форме элемента справочника Организации (ссылка на этот элемент доступна как Объект. Ссылка) можно выполнить следующий код (листинг 8.9). Листинг 8.9. Открытие формы подчиненного справочника с отбором по владельцу
УсловияОтбора = Новый Структура("Владелец", Объект.Ссылка) ПараметрыФормы = Новый Структура("Отбор", УсловияОтбора); ОткрытьФорму("Справочник.РасчетныеСчета.ФормаСписка", ПараметрыФормы);
Сначала создается структура, содержащая условия отбора (УсловияОтбора). В нашем случае условие будет одно, но, вообще говоря, их может быть несколько. Затем эта структура устанавливается как значение параметра формы.
Отбор
И в заключение открывается форма списка подчиненного справочника, в которую передается структура параметров формы.
290
Подробнее
Пример можно посмотреть в демонстрационной базе «Разработка форм, пример 2», форма элемента справочника Организации, команда Показать расчетные счета. Это локальная команда формы элемента справочника Организации.
Передача параметров в произвольный запрос динамического списка Еще одна задача, которая может возникать при открытии формы, заключается в том, что динамический список, содержащийся в форме, может содержать произвольный запрос с параметрами. И при открытии формы нужно передавать в этот список конкретные значения этих параметров. Эта задача тоже решается с помощью параметров формы. Только это будут уже не стандартные параметры формы, предоставляемые платформой, а параметры формы, созданные разработчиком в конфигураторе. В эти параметры нужно передать требуемые значения, а в обработчике события формы При создании на сервере установить эти значения параметрам запроса в динамическом списке. Рассмотрим эту задачу на примере списка регистра ЦеныТоваров. В форме списка этого регистра содержится динамический список с произвольным запросом (листинг 8.10). Листинг 8.10. Запрос динамического списка
ВЫБРАТЬ РегистрСведенийЦеныТоваров.Период, РегистрСведенийЦеныТоваров.Товар, РегистрСведенийЦеныТоваров.Цена ИЗ РегистрСведений.ЦеныТоваров КАК РегистрСведенийЦеныТоваров ГДЕ РегистрСведенийЦеныТоваров.Товар = &Товар И РегистрСведенийЦеныТоваров.Период >= &НачалоПериода И РегистрСведенийЦеныТоваров.Период <= &КонецПериода
У этого запроса есть три параметра: Товар, НачалоПериода и КонецПериода. Для нормального функционирования формы значения этих параметров должны быть заданы при открытии формы, иначе в результате открытия формы будет получена ошибка. В форме элемента справочника Товары есть команда Цены в декабре, которая показывает цены на этот товар, установленные только в декабре 2009 года.
Профессиональная разработка в системе «1С:Предприятие 8»
Программирование форм Подробнее
Пример можно посмотреть в демонстрационной базе «Разработка форм, пример 2», форма элемента справочника Товары, команда Цены в декабре. Это локальная команда формы элемента справочника Товары, она открывает список регистра ЦеныТоваров.
Чтобы передать собственные параметры в форму, желательно создать их в редакторе формы. Вообще говоря, делать это не обязательно. Любые параметры, переданные в метод ОткрытьФорму(), будут доступны в обработчике события формы При создании на сервере. Но все же лучше создать их у формы в явном виде. Тогда, во-первых, в модуле формы не придется проверять, существуют такие параметры или нет. А во-вторых, явное создание параметров формы облегчает поддержку прикладного решения теми разработчиками, которые не участвовали в его создании. Итак, создадим у формы списка регистра сведений три параметра: НачалоПериода, КонецПериода (тип Дата) и Товар (тип СправочникСсылка. Товары), рис. 8.204.
Листинг 8.12. Обработчик события «При создании на сервере»
&НаСервере Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка) Список.Параметры.УстановитьЗначениеПараметра("НачалоПериода", Параметры.НачалоПериода); Список.Параметры.УстановитьЗначениеПараметра("КонецПериода", Параметры.КонецПериода); Список.Параметры.УстановитьЗначениеПараметра("Товар", Параметры.Товар); КонецПроцедуры
Метод «ПолучитьФорму()» Кроме метода ОткрытьФорму() существует и другой метод глобального контекста, который может быть использован для открытия форм, – ПолучитьФорму(). По составу параметров этот метод очень похож на ОткрытьФорму(). Разница заключается в том, что ПолучитьФорму() лишь возвращает форму, не открывая ее. В дальнейшем эта форма может быть открыта с помощью своего метода Открыть(). Такой способ открытия формы можно использовать в тех случаях, когда должны выполняться различные сложные действия в зависимости от того, из какого фрагмента кода открывается форма. В этом случае после получения формы может быть, например, вызвана ее экспортная процедура, выполняющая настройку формы в зависимости от «контекста» ее вызова (листинг 8.13). Листинг 8.13. Получение и открытие формы
Рис. 8.204. Параметры формы
Теперь в форме элемента справочника Товары создадим команду ЦеныВДекабре со следующим текстом (8.11). Листинг 8.11. Текст команды «ЦеныВДекабре»
ПараметрыФормы = Новый Структура("НачалоПериода, КонецПериода, Товар", '20091201000000', '20091231235959', Объект.Ссылка); ОткрытьФорму("РегистрСведений.ЦеныТоваров.Форма.ФормаСписка", ПараметрыФормы);
Этой командой мы открываем форму списка регистра сведений и передаем ей значения трех параметров. В самой форме регистра сведений, в обработчике события формы При создании на сервере, установим переданные значения в качестве параметров произвольного запроса динамического списка следующим образом (листинг 8.12).
Том 1
Перем СсылкаНаТаблицуСтилей; ФормаРедактора = ПолучитьФорму("Обработка.УниверсальныйРедактор.Форма"); ФормаРедактора.РедактироватьHTMLТекст("Пример HTML-текста", СсылкаНаТаблицуСтилей); ФормаРедактора.Открыть(); Подробнее
Пример можно посмотреть в демонстрационной базе «Разработка форм, пример 2», панель действий, группа команд Сервис, глобальная команда Открыть текст в редакторе.
В данном примере используется форма обработки УниверсальныйРедактор. Подразумевается, что обработка может редактировать как обычный текст, так и HTML-текст. Также подразумевается, что в зависимости от того, какой текст передается для редактирования, в самой обработке он определенным образом оформляется и подготавливается для редактирования.
291
Глава 8. Разработка форм Так как эта подготовка текста к редактированию не зависит от контекста, в котором вызван редактор, а определяется лишь видом редактируемого текста, в модуле формы этой обработки существуют две экспортируемые процедуры, позволяющие получить и подготовить к редактированию обычный текст (РедактироватьОбычныйТекст()) и HTML-текст (РедактироватьHTMLТекст()).
Для этого кроме основной формы обработки (Форма) создадим форму ПараметрыЗаполнения. Эта форма будет открываться модально из основной формы и возвращать коды стандартных команд.
В приведенном примере как раз получается форма этой обработки, и с помощью экспортируемой процедуры РедактироватьHTMLТекст() ей передается текст, который нужно подготовить к редактированию. После этого форма обработки открывается.
В обработчике этой команды откроем форму ПараметрыЗаполнения модально (листинг 8.14).
Чтобы открыть модально форму ПараметрыЗаполнения, в основной форме обработки создадим команду ЗадатьПараметрыЗаполнения и расположим ее в подгруппе Дополнительно в командной панели формы.
Листинг 8.14. Обработчик команды «ЗадатьПараметрыЗаполнения»
Модальное открытие формы
Результат = ОткрытьФормуМодально( "Обработка.ЗаполнениеДанных.Форма.ПараметрыЗаполнения");
Во многих случаях форма открывается для того, чтобы пользователь обязательно выполнил какие-то действия или ввел какие-то данные, без которых дальнейшая работа программы будет невозможна.
Теперь в форме ПараметрыЗаполнения в командную панель формы перенесем три стандартные команды: ОК, Пропустить, Отмена (рис. 8.205).
В таких случаях используется открытие формы в модальном режиме. В этом случае дальнейшее выполнение программного кода будет остановлено до тех пор, пока пользователь не закроет модальную форму. При этом все другие открытые формы прикладного решения будут недоступны. Для этого используется метод глобального контекста дально().
ОткрытьФормуМо-
Модальная форма может быть закрыта с помощью стандартных интерактивных команд формы либо из встроенного языка методом Закрыть(). Если форма закрывается с помощью стандартных интерактивных команд, то метод ОткрытьФормуМодально() возвращает код возврата диалога, соответствующий команде, с помощью которой модальная форма была закрыта. Если форма закрывается из встроенного языка методом Закрыть(), то в параметр этого метода разработчик может передать произвольное значение, которое будет возвращено в вызывающий код. Рассмотрим эти возможности на примере обработки, которая из своей основной формы открывает две другие формы для получения дополнительных данных. Подробнее
Пример можно посмотреть в демонстрационной базе «Разработка форм, пример 2», обработка ЗаполнениеДанных.
Рис. 8.205. Кнопки стандартных команд в командной панели
Форма ПараметрыЗаполнения после своего закрытия одной из этих стандартных команд вернет в переменную Результат код возврата диалога, значения которого описаны в системном перечислении КодВозвратаДиалога. Поэтому вернемся в основную форму обработки и проанализируем возвращаемый результат, выведя в форму обработки сообщение, соответствующее нажатой кнопке в форме ПараметрыЗаполнения (листинг 8.15).
Сначала рассмотрим, как возвращать результаты выполнения стандартных интерактивных команд формы.
292
Профессиональная разработка в системе «1С:Предприятие 8»
Программирование форм Листинг 8.15. Обработчик команды «ЗадатьПараметрыЗаполнения»
Результат = ОткрытьФормуМодально("Обработка.ЗаполнениеДанных.Форма.ПараметрыЗаполнения"); Сообщение = Новый СообщениеПользователю; Если Результат = КодВозвратаДиалога.ОК Тогда Сообщение.Текст = "В форме нажата стандартная кнопка ОК"; ИначеЕсли Результат = КодВозвратаДиалога.Пропустить Тогда Сообщение.Текст = "В форме нажата стандартная кнопка Пропустить"; ИначеЕсли Результат = КодВозвратаДиалога.Отмена Тогда Сообщение.Текст = "В форме нажата стандартная кнопка Отмена"; Иначе Сообщение.Текст = "Обработка этой команды в форме не предусмотрена"; КонецЕсли; Сообщение.Сообщить();
Теперь рассмотрим вторую возможность – возврат произвольного значения из формы, открытой модально. Для этого создадим еще одну форму обработки – ДобавлениеТекста. В ней создадим строковый реквизит (Текст) и поле для его редактирования. Добавим команду ЗакончитьВводТекста, по которой будем возвращать введенный пользователем текст (рис. 8.206).
А в основной форме обработки добавим команду ДобавитьТекст, которая будет модально открывать форму ДобавлениеТекста и показывать текст, введенный в ней пользователем (листинг 8.17). Листинг 8.17. Обработчик команды «ДобавитьТекст»
Результат = ОткрытьФормуМодально("Обработка.ЗаполнениеДанных.Форма.ДобавлениеТекста"); Сообщение = Новый СообщениеПользователю; Сообщение.Текст = "В форме введен текст: " + Результат; Сообщение.Сообщить();
Открытие и запуск отчета Последняя задача, которую мы рассмотрим в этой главе, это открытие формы отчета и выполнение этого отчета без дополнительных действий со стороны пользователя. Например, есть отчет ЦеныТоваров. Он показывает последние цены, установленные на товары. Задача в том, чтобы по команде в форме товаров сразу запускать этот отчет с отбором, установленным по тому товару, на котором находится курсор в списке. Выполнить эту задачу помогут два параметра, которые поставляются расширением отчета: Отбор и СформироватьПриОткрытии. Параметр Отбор позволяет установить отбор в отчете, задав значения полей или параметров отчета. А параметр СформироватьПриОткрытии позволяет сразу же выполнить отчет, после того как его форма будет получена на сервере. Подробнее
Пример можно посмотреть в демонстрационной базе «Разработка форм, пример 2», форма списка справочника Товары, команда ЦенаТовара. Это локальная команда формы списка справочника Товары.
Итак, создадим форму списка справочника Товары и добавим в нее команду ЦенаТовара. Текст этой команды будет выглядеть следующим образом (листинг 8.18). Рис. 8.206. Команда «ЗакончитьВводТекста» в форме «ДобавлениеТекста»
Листинг 8.18. Обработчик команды «ЦенаТовара»
Обработчик команды ЗакончитьВводТекста будет выглядеть совсем просто (листинг 8.16).
УсловияОтбора = Новый Структура("Товар", Элементы.Список.ТекущаяСтрока); ПараметрыФормы = Новый Структура("Отбор, СформироватьПриОткрытии", УсловияОтбора, Истина); ОткрытьФорму("Отчет.ЦеныТоваров.ФормаОбъекта", ПараметрыФормы);
Листинг 8.16. Обработчик команды «ЗакончитьВводТекста»
Закрыть(Текст);
Том 1
Сначала создаем структуру УсловияОтбора, которая задаст единственное условие отбора – по тому товару, на котором установлен курсор в списке (Элементы.Список.ТекущаяСтрока).
293
Глава 8. Разработка форм Затем сформируем структуру для параметров формы (ПараметрыФормы), описав в ней значения двух параметров – Отбор и СформироватьПриОткрытии. В заключение, как и раньше, открываем форму отчета (ОткрытьФорму()), указав имя формы и параметры, предназначенные для открываемой формы.
Преобразование прикладных данных в данные формы Встроенный язык содержит целый ряд объектов, предназначенных для чтения и модификации объектных данных, хранящихся в базе данных. Это такие типы, как СправочникОбъект.<имя>, ДокументОбъект.<имя> и т. д. Однако работа с этими типами данных возможна только в контексте сервера. Форма же и на клиенте, и на сервере для отображения таких объектных данных использует специальные универсальные типы.
Рис. 8.208. Преобразование данных объекта в данные формы
После того как форма полностью подготовлена, она передается с сервера на клиента (рис. 8.209).
Поэтому при открытии форм объектов платформа выполняет автоматическое преобразование данных из типов объектов в типы, поддерживаемые формой. При записи данных объектов из формы происходит обратное преобразование. Рассмотрим эти процессы подробнее. Когда открывается форма существующего объекта, платформа читает его данные из базы данных и создает в памяти соответствующий этим данным объект встроенного языка (рис. 8.207). Например, СправочникОбъект.<имя>.
Рис. 8.209. Передача формы на клиента
Обратное преобразование выполняется аналогичным образом. Сначала форма передается с клиента на сервер (рис. 8.210).
Рис. 8.207. Чтение данных существующего объекта
После этого данные объекта преобразуются в данные основного реквизита формы. Как правило, основной реквизит формы имеет имя Объект (рис. 8.208).
294
Рис. 8.210. Передача формы на сервер
После этого основной реквизит формы преобразуется в соответствующий объект встроенного языка, позволяющий модифицировать данные в базе данных. Например, СправочникОбъект.<имя> (рис. 8.211). Профессиональная разработка в системе «1С:Предприятие 8»
Программирование форм
Рис. 8.211. Преобразование данных формы в прикладной объект
Затем данные объекта записываются в базу данных (рис. 8.212). Рис. 8.213. Преобразование данных элемента справочника в «ДанныеФормыСтруктура»
Никаких специфических методов ДанныеФормыСтруктура иметь не будет. Это касается и стандартных методов объекта справочника (например, Записать()), и методов, описанных разработчиком в модуле объекта (например, экспортируемая процедура ПересчитатьЦены()).
Рис. 8.212. Запись данных прикладного объекта в базу данных
Существуют четыре типа универсальных данных формы, в которые преобразуются типы, доступные только на сервере: ■■ ■■ ■■ ■■
ДанныеФормыСтруктура, ДанныеФормыКоллекция, ДанныеФормыДерево, ДанныеФормыСтруктураСКоллекцией.
Это простые типы данных в том смысле, что они по сути представляют собой определенным образом организованные структуры данных и не содержат никакого специфического поведения, зависящего от данных. В какой именно тип будут преобразованы серверные данные, зависит от самих этих данных. Преобразование выполняется в те универсальные типы, которые наиболее хорошо подходят для описания исходного типа данных. Например, данные типа СправочникОбъект.Товары будут преобразованы в тип ДанныеФормыСтруктура (рис. 8.213). Элементы этой структуры будут содержать значения реквизитов справочника Товары. Реквизиты примитивных типов в форме будут иметь тот же тип, что и у серверного объекта. Например, Код и Наименование будут иметь тип Строка. Том 1
Реквизиты ссылочного типа, например СсылкаНаПоставщика типа СправочникСсылка.Поставщики, будут иметь такой же тип, как и на сервере – СправочникСсылка.<имя>. Однако программный объект ссылки в форме, в контексте клиента очень сильно ограничен в своих возможностях. Практически единственное, что можно сделать со ссылкой на клиенте, – это получить ее значение. Ну и еще проверить, является ли эта ссылка пустой. Создание объектов от ссылки, получение значений через точку от ссылки на клиенте недоступны. Это возможно только на сервере. Как уже говорилось выше, для системных процессов, таких как запись, проведение объекта из формы, подобное преобразование выполняется платформой автоматически. Однако встроенный язык при необходимости позволяет разработчику выполнять такие преобразования самостоятельно. Для этого используются процедуры глобального контекста ДанныеФормыВЗначение() и ЗначениеВДанныеФормы(). ПРИМЕЧАНИЕ
Аналогичные методы существуют и у формы: РеквизитФормыВЗначение() и ЗначениеВРеквизитФормы(). Подробнее они будут рассмотрены в разделе «Работа с данными объекта в форме», стр. 297, в разделе «Запись данных объекта в единой транзакции за один серверный вызов», стр. 421, и в разделе «Реализация пересчета данных объекта в модуле объекта или в модуле формы в зависимости от логики объекта», стр. 432.
295
Глава 8. Разработка форм
Контекстные и внеконтекстные серверные вызовы Теперь рассмотрим подробнее, что происходит при контекстных и при внеконтекстных серверных вызовах в форме. Для упрощения рассказа мы опустим тонкости оптимизации и кеширования, которые выполняет при этом платформа, так как на суть описываемых действий это не влияет. Когда из клиентской процедуры/функции вызывается серверная (с директивой компиляции &НаСервере) процедура/функция, происходит передача всей формы на сервер. Сначала контекст формы (реквизиты формы, элементы формы, параметры формы) специальным образом упаковываются и подготавливаются к передаче на сервер (рис. 8.214).
Рис. 8.216. Выполнение кода на встроенном языке из модуля формы
На рисунке темным цветом выделены те данные, которые, возможно, были изменены на сервере в процессе выполнения серверной процедуры. После того как исполнение кода на сервере будет закончено, происходит обратное действие. Контекст формы упаковывается и передается обратно на клиента, в клиентскую часть формы (рис. 8.217).
Рис. 8.214. Подготовка контекста формы и передача его на сервер
На рисунке темным цветом выделены те данные, которые, возможно, были изменены на клиенте. На сервере создается серверная часть формы, полученный контекст разворачивается в данные, элементы и реквизиты формы, после чего инициализируется модуль формы (рис. 8.215).
Рис. 8.217. Упаковка контекста формы и передача его на клиента
На клиенте происходит синхронизация контекста формы: имеющийся контекст заменяется контекстом, полученным с сервера. А на сервере происходит уничтожение серверной части формы (рис. 8.218).
Рис. 8.218. Замена контекста на клиенте и уничтожение серверной части формы Рис. 8.215. Получение контекста формы и инициализация серверной части модуля формы
После того как программный объект формы будет полностью подготовлен к работе, выполняется код той процедуры/функции, которая была вызвана с клиента (рис. 8.216).
296
Таким образом, контекстный вызов формы – довольно затратный и непростой процесс. Использовать все время только контекстные вызовы сервера было бы расточительно и непроизводительно. Поэтому контекстные вызовы сервера рекомендуется использовать тогда, когда обойтись без них очень трудно или невозможно вообще. Профессиональная разработка в системе «1С:Предприятие 8»
Программирование форм В то же время есть масса ситуаций, когда нужно выполнять некоторые действия на сервере, но контекст формы при этом не нужен. Для этого используются внеконтекстные серверные вызовы, когда из клиентской процедуры вызывается серверная процедура с директивой компиляции &НаСервереБезКонтекста.
Подробнее
В этом случае из модуля клиентской части формы выполнение кода сразу же передается на сервер, во внеконтекстную процедуру. После ее выполнения осуществляется возврат на клиента (рис. 8.219).
Работа с данными объекта в форме
Пример, подробно описывающий эту ситуацию, можно посмотреть в разделе «Использование контекстных серверных процедур для пересчета данных коллекций форм», стр. 406.
В этом разделе мы рассмотрим несколько простых примеров работы с данными объекта в форме. Они помогут понять общие подходы к основным действиям.
Пример 1 В качестве первого примера рассмотрим ситуацию, когда мы находимся в форме документа и нам нужно получить какой-либо его реквизит. Например, номер документа или значение реквизита Поставщик. Подробнее Рис. 8.219. Неконтекстный вызов серверной процедуры/функции
Внеконтекстный вызов проще, эффективнее и производительнее. Именно его рекомендуется использовать в большинстве случаев. Однако не стоит увлекаться фанатичной погоней за производительностью, осуществляя только внеконтекстные вызовы и передавая контекст формы в параметрах вызываемой процедуры. Во-первых, всегда следует искать золотую середину между «читабельностью» программы и ее производительностью. Можно так «заоптимизировать» прикладное решение, что разобраться в нем через некоторое время не сможет уже никто, включая самого автора.
Пример можно посмотреть в демонстрационной базе «Разработка форм, пример 3», форма документа Накладная, группа команд Примеры, команда Значение реквизита. Это локальная команда формы документа Накладная.
Данные объекта, которые отображаются в форме (в нашем случае данные документа), находятся всегда в основном реквизите формы. В подавляющем большинстве случаев этот реквизит имеет имя Объект. По крайней мере именно такое имя дает ему платформа, когда с помощью конструктора создает форму объекта. В нашем случае это именно так (рис. 8.220).
Во-вторых, контекстные вызовы сервера мы рассматривали упрощенно. На самом деле платформа очень серьезно оптимизирует объем данных, передаваемых между клиентом и сервером. Например, при открытии формы на клиента передается только часть данных, которую видит в данный момент пользователь. С клиента на сервер передаются не все данные, а только те, которые были изменены на клиенте. При изменении данных на сервере на клиента также передаются не все данные, а только те, которые были изменены. Поэтому если на сервере требуется обращаться к большому массиву данных, которые хранятся в данных формы, то выгоднее выполнить именно контекстный серверный вызов. Потому что в этом случае платформа эффективно выполнит передачу данных формы на сторону сервера, там сконструирует соответствующий контекст и обратно перешлет данные на клиента.
Том 1
Рис. 8.220. Стандартное имя основного реквизита формы объекта
Основной реквизит формы содержит набор подчиненных реквизитов, соответствующих реквизитам прикладного объекта. Поэтому для того, чтобы обратиться, например, к номеру документа, нужно указать имя реквизита формы и через точку – имя подчиненного реквизита, хранящего номер документа.
297
Глава 8. Разработка форм В нашем случае, для того чтобы сообщить номер документа и поставщика, нужно будет выполнить следующий код (листинг 8.19). Листинг 8.19. Получение значения реквизита формы
Сообщение = Новый СообщениеПользователю; Сообщение.Текст = Объект.Номер + Символы.ПС + Строка(Объект.Поставщик); Сообщение.Сообщить();
Номер документа имеет тип Строка, поэтому мы выводим его просто как Объект.Номер, а значение реквизита Поставщик имеет тип ссылки. Поэтому для того, чтобы включить его в текстовую строку, мы получаем строковое представление этого ссылочного значения, преобразуя его к типу Строка: Строка(Объект.Поставщик).
Пример 2 Второй пример, который мы рассмотрим, будет заключаться в том, чтобы получить реквизит от ссылочного значения, хранящегося в реквизите формы. Как раз у документа Накладная есть реквизит ссылочного типа – Поставщик. Мы будем получать ИНН этого поставщика. Подробнее
Пример можно посмотреть в демонстрационной базе «Разработка форм, пример 3», форма документа Накладная, группа команд Примеры, команда Реквизит от ссылки. Это локальная команда формы документа Накладная.
Мы, как и в предыдущем примере, по-прежнему находимся в модуле формы на клиенте. В контексте клиента, как мы уже упоминали выше, ссылочные типы очень сильно ограничены в своих возможностях. В частности, нельзя получить значение реквизита от ссылки «через точку». Это можно сделать только в контексте сервера. Поэтому для решения нашей задачи мы создадим серверную внеконтекстную функцию, которую вызовем с клиента и передадим в нее ссылку на поставщика. В теле функции, на сервере, мы получим ИНН поставщика и вернем его на клиента. Локальная команда формы, вызывающая серверную функцию, будет выглядеть следующим образом (листинг 8.20). Листинг 8.20. Обработчик локальной команды формы
&НаКлиенте Процедура РеквизитОтСсылки(Команда) Сообщение = Новый СообщениеПользователю; Сообщение.Текст = ПолучитьИННПоставщика(Объект.Поставщик); Сообщение.Сообщить(); КонецПроцедуры
298
Здесь в текст сообщения мы помещаем то, что вернет нам серверная функция ПолучитьИННПоставщика(). Эту функцию мы опишем в модуле формы следующим образом (листинг 8.21). Листинг 8.21. Серверная функция для получения реквизита от ссылочного значения
&НаСервереБезКонтекста Функция ПолучитьИННПоставщика(Поставщик) Возврат Поставщик.ИНН; КонецФункции
То есть на сервере мы сразу же получаем значение реквизита «через точку» от полученной ссылки. Обратите внимание еще раз. Эта функция не использует контекст формы. Потому что все, что нам нужно передать на сервер, – это только ссылка, и мы передаем ее в параметре функции. Использовать контекстный вызов и «гонять» на сервер весь контекст формы только ради того, чтобы на сервере взять из него значение одного реквизита формы, было бы слишком расточительно.
Пример 3 Третий пример, который мы рассмотрим, будет заключаться в вызове экспортируемой процедуры объекта. Наш документ как раз имеет одну такую процедуру, которая позволяет пересчитать все цены, содержащиеся в табличной части документа, и применить к ним скидку в 10 %. Подробнее
Пример можно посмотреть в демонстрационной базе «Разработка форм, пример 3», форма документа Накладная, группа команд Примеры, команда Метод объекта. Это локальная команда формы документа Накладная.
Поскольку для вызова такой процедуры необходимо прежде всего иметь сам объект, мы поступим следующим образом. Выполним контекстный серверный вызов. На сервере преобразуем основной реквизит формы в прикладной объект, выполним экспортируемую функцию этого объекта и преобразуем объект обратно в основной реквизит формы. В результате выполненные на сервере изменения данных формы будут автоматически переданы на клиента, когда на него вернется выполнение программного кода. Локальная команда формы, вызывающая серверную процедуру, будет выглядеть следующим образом (листинг 8.22). Профессиональная разработка в системе «1С:Предприятие 8»
Программирование форм Листинг 8.22. Обработчик локальной команды формы
&НаКлиенте Процедура МетодОбъекта(Команда) ПересчитатьЦеныНаСервере(); КонецПроцедуры
Контекстная серверная функция ПересчитатьЦеныНаСервере() будет выглядеть следующим образом (листинг 8.23). Листинг 8.23. Серверная функция для вызова экспортируемой функции объекта
&НаСервере Процедура ПересчитатьЦеныНаСервере() ОбъектДокумента = РеквизитФормыВЗначение("Объект", Тип("ДокументОбъект.Накладная")); ОбъектДокумента.НачислитьСкидку(10); ЗначениеВРеквизитФормы(ОбъектДокумента, "Объект"); КонецПроцедуры
Рис. 8.221. Последовательность событий при открытии формы существующего объекта
Теперь же мы можем представить ее более подробно (рис. 8.222).
В этой функции сначала мы преобразуем данные реквизита формы Объект в прикладной объект типа ДокументОбъект.Накладная. После этого мы вызываем экспортируемую процедуру этого прикладного объекта – НачислитьСкидку(). В результате ее работы все цены, содержащиеся в табличной части объекта, будут уменьшены на 10 %. Затем мы преобразуем данные прикладного объекта обратно в реквизит формы Объект. То есть новые цены в табличной части теперь будут и в форме, которая пока находится на сервере. Когда выполнение всех серверных процедур, которые мы вызвали, будет закончено, контекст формы на сервере будет собран, отправлен на клиента и там автоматически обновлен. В результате мы увидим в открытом документе на клиенте уже новые цены в табличной части документа.
Последовательность событий при открытии формы объекта Теперь, когда мы знакомы с тем, как открыть нужную нам форму, и понимаем, как в принципе форма функционирует, рассмотрим подробно последовательность событий, которые возникают при открытии формы существующего объекта. Этот пример мы рассмотрим как наиболее сложный и типичный. Ранее, на рис. 8.199, мы уже видели эту последовательность событий. Напомним ее (рис. 8.221). Рис. 8.222. Последовательность действий и событий при открытии формы существующего объекта
Том 1
299
Глава 8. Разработка форм
Чтение данных прикладного объекта Когда платформа получает интерактивную или программную команду открыть форму объекта, прежде всего на сервере создается программный объект формы. После этого создается программный объект, соответствующий типу основного реквизита формы, и из базы данных читаются данные этого объекта. На схеме (рис. 8.222) объект отмечен темным цветом. Это означает, что он содержит данные, прочитанные из базы данных. Затем платформа выполняет преобразование данных объекта в данные формы. Об этом мы говорили в разделе «Преобразование прикладных данных в данные формы», стр. 294.
Событие «При чтении на сервере» После этого вызывается первое событие формы – При
чтении на сервере.
В чем особенность этого события? Зачем именно в этот момент нам предлагается вмешаться в «процесс»? Посмотрим. Событие вызывается у формы. Причем поставляется это событие не самой формой, а ее расширением, определяемым типом основного реквизита формы. То есть это какая-то особенная ситуация, связанная с тем, что открывается не просто форма, а именно форма этого объекта.
Сам прикладной объект удаляется из памяти сервера, т. к. для дальнейших действий он уже не нужен. И вызывается второе и последнее событие формы на сервере – При создании на сервере.
Событие «При создании на сервере» Что изменилось по сравнению с предыдущим событием? Нет прикладного объекта. Это последнее событие перед тем, как форма отправится на клиента. Это событие формы, то есть оно не зависит от того, какие данные форма отображает, и существует у всех форм. Значит, в этом событии нужно полностью подготовить саму форму к открытию. Именно форму, ее внешнее представление. Данные мы уже полностью подготовили в предыдущем обработчике события. Ранее мы уже использовали это событие, когда изучали различные способы открытия форм. Например, для того, чтобы установить значения параметров произвольного запроса в динамическом списке (стр. 290). Также в этом событии можно отказаться от открытия формы, если по каким-либо причинам она не должна быть открыта (листинг 8.25). Для этого параметр Отказ нужно установить в значение Истина. Листинг 8.25. Объявление обработчика события «При создании на сервере»
&НаСервере Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
Данные формы уже заполнены данными объекта, в то же время сам объект все еще существует в памяти сервера и доступен в обработчике этого события через параметр ТекущийОбъект (листинг 8.24).
Также здесь можно отказаться от стандартной обработки события, выполняемой платформой (СтандартнаяОбработка = Ложь). Стандартная обработка, выполняемая платформой, зависит от типа основного реквизита открываемой формы.
Листинг 8.24. Объявление обработчика события «При чтении на сервере»
Например, для формы списка это будет передача в динамический список параметров, указанных при открытии формы. Если в примере «Открыть список, чтобы курсор был на нужном элементе» (стр. 289) в форме списка справочника Товары отменить стандартную обработку, то не будет выполняться позиционирование курсора на нужную строку в списке.
&НаСервере Процедура ПриЧтенииНаСервере(ТекущийОбъект)
Очевидно, что здесь мы можем подготовить дополнительные данные формы, которые зависят от данных объекта. Существование самого объекта полезно тем, что мы можем воспользоваться всей его функциональностью, например вызвать какую-либо его экспортируемую процедуру или получить значение через точку от его реквизита ссылочного типа. Это избавляет нас от необходимости преобразовывать данные формы в объект. После обработки события При чтении на сервере данные формы, вообще говоря, могут уже отличаться от тех данных, которые содержатся в прикладном объекте. Поэтому на схеме форма отмечена темным цветом. Это означает, что она содержит измененные данные.
300
Аналогично если в примере «Список подчиненного справочника с отбором по владельцу» (стр. 290) в форме списка справочника РасчетныеСчета отменить стандартную обработку, то не будет выполняться отбор списка по владельцу. Для форм отчетов стандартная обработка заключается в загрузке варианта и пользовательских настроек отчета. Кроме этого, стандартная обработка передает в отчет параметры отбора и выполняет автоматический запуск отчета. Например, если в примере «Открытие и запуск отчета» (стр. 293) в форме отчета ЦеныТоваров отменить стандартную обработку, то в отчет не будет передаваться отбор и не будет выполняться автоматическое формирование отчета. Профессиональная разработка в системе «1С:Предприятие 8»
Программирование форм
Событие «При открытии» После обработки события При создании на сервере форма передается на клиента, и программный объект формы удаляется из памяти сервера. На клиенте вызывается последнее событие формы – При открытии. Для чего может понадобиться событие на клиенте?
При открытии,
обрабатываемое
Во-первых, это последнее событие, в котором можно отказаться от открытия формы (Отказ = Истина), листинг 8.26. Листинг 8.26. Объявление обработчика события «При открытии»
&НаКлиенте Процедура ПриОткрытии(Отказ)
Если отказа не происходит, это значит, что форма точно будет открыта. И значит, можно выполнить какие-то действия, которые должны выполняться только тогда, когда форма гарантированно открывается. Например, открыть связанную форму, которая сама по себе не существует, а существует только в том случае, если открыта основная форма. Во-вторых, в этом событии можно выполнить те действия, которые невозможно выполнить на сервере. Например, выдать предупреждение пользователю или настроить COM-объект HTML-документа, содержащийся в поле HTML-документа. После обработки события При открытии форма открывается на клиенте и становится видима пользователю.
Последовательность событий при записи объекта из формы Последовательность событий, возникающих при записи объекта из формы, значительно больше и сложнее. Мы рассмотрим ее на примере команды Записать и закрыть, когда данные объекта записываются и после этого форма закрывается. Поскольку схема получается довольно большой, разделим ее на три части: ■■ до записи данных в базу данных, ■■ запись данных, ■■ после записи. Первая часть будет выглядеть следующим образом (рис. 8.223).
Рис. 8.223. Последовательность действий и событий при записи объекта. Начало
Событие «Перед записью» Когда в форме вызывается запись объекта, прежде всего в форме на клиенте вызывается событие Перед записью. Синтаксис вызова этого обработчика выглядит следующим образом (листинг 8.27). Листинг 8.27. Объявление обработчика события «Перед записью»
&НаКлиенте Процедура ПередЗаписью(Отказ, ПараметрыЗаписи)
В этом обработчике можно проанализировать, что все вспомогательные данные, необходимые для записи объекта, подготовлены. И если это не так, отказаться от записи, установив параметр Отказ в значение Истина. Дело в том, что на клиенте могут существовать объекты, недоступные на сервере, например, СОМ-объект HTML-документа. Поэтому проверки, связанные с подобными объектами, нужно производить именно в клиентской процедуре. Также в этом обработчике доступны для анализа параметры записи, созданные платформой или переданные разработчиком. Подробнее
Раздел «Параметры записи», стр. 305.
Том 1
301
Глава 8. Разработка форм
Проверка заполнения После обработки события Перед записью платформа выполняет контекстный серверный вызов. Контекст формы упаковывается, передается на сервер. На сервере создается программный объект формы. Из полученного контекста заполняются реквизиты, элементы, параметры формы, инициализируется модуль формы, и в дело вступает механизм проверки заполнения. Его работа заключается в последовательном вызове двух событий: одного – у формы, и второго – у того объекта, который будет записан. Работа механизма проверки заполнения подробно рассматривается в разделе «Проверка заполнения» (стр. 310), поэтому сейчас мы не будем подробно останавливаться на назначении каждого из событий. Опишем их лишь в общих чертах. Сначала вызывается событие формы Обработка проверки заполнения на сервере. После этого выполняется преобразование данных формы в данные прикладного объекта: в памяти сервера создается прикладной объект, соответствующий типу основного реквизита формы, и его данные заполняются из данных формы. Затем вызывается событие прикладного объекта Обработка проверки заполнения.
Событие «Перед записью на сервере» После того как механизм проверки заполнения закончил свою работу, на сервере вызывается событие формы Перед записью на сервере. Чем интересен этот обработчик? Как мы говорили выше, в процессе проверки заполнения произошло «разделение» формы на форму и прикладной объект, данные которого будут записаны в базу данных. Это определяет ряд особенностей дальнейшей работы. Обработчик Перед записью на сервере – первый, в котором появляется возможность доступа как к данным основного реквизита формы (через его имя, как правило, Объект), так и к самому объекту, который будет записан. Этот объект система передает в обработчик в параметре ТекущийОбъект. Напомним описание вызова этого обработчика (листинг 8.28). Листинг 8.28. Объявление обработчика события «Перед записью на сервере»
Процедура ПередЗаписьюНаСервере(Отказ, ТекущийОбъект, ПараметрыЗаписи)
Что важно понимать, находясь в этом обработчике? Данные, доступные через основной реквизит формы Объект, «мертвы». Мертвы в том смысле, что их изменение не даст никакого результата. Их можно только анализировать.
302
При этом также нужно понимать, что эти данные – это не то, что будет записано в информационную базу. Это то, что «приехало» с клиента и «пережило» проверку заполнения. Поэтому и анализировать их можно только с точки зрения того «а что же было». А записан в информационную базу будет ТекущийОбъект. Отсюда еще два замечания: ■■ если нужно принять решение о том, можно записывать данные или нельзя, нужно анализировать ТекущийОбъект; ■■ если нужно модифицировать записываемые данные (например, дописать служебную информацию в реквизиты), использовать нужно ТекущийОбъект. Все попытки изменить данные через реквизит формы Объект ни к чему не приведут. В информационную базу эти данные записаны не будут, а перед тем как форма «поедет» обратно на клиента, ее данные будут замещены данными записанного в информационную базу объекта. Таким образом, все изменения, внесенные в Объект, пропадут. Также нужно понимать, что все действия, выполняемые в этом обработчике (отказ от записи, изменение данных объекта), должны быть связаны именно с тем фактом, что данные записываются именно из формы. При программной записи объекта (методом объекта) форма будет отсутствовать, следовательно, и это событие вызываться не будет. Поэтому если какие-либо алгоритмы должны выполняться при любом способе записи данных объекта, а не только при записи из формы, их следует размещать в обработчике события объекта (Перед записью), а не в обработчике события формы.
Запись данных в базу данных После обработки события формы Перед записью на сервере в СУБД открывается транзакция записи и начинается процесс записи данных прикладного объекта в базу данных, который представлен на рисунке 8.224. Прежде всего, вызывается событие объекта Перед записью. В этом событии можно отказаться от записи данных. Причем эта проверка будет выполняться всегда, независимо от того, каким способом данные объекта записываются. После обработки события Перед записью данные записываются в базу данных, но транзакция не закрывается. После записи данных вызывается еще одно событие объекта – При записи. Это событие предназначено для того, чтобы выполнить действия над дополнительными данными, которые неразрывно связаны с основными данными объекта и не могут быть изменены независимо от основных данных. Поскольку это событие обрабатывается в транзакции записи основных данных, гарантируется синхронность изменения основных и вспомогательных данных. Либо и те и другие будут записаны, либо и те и другие изменения будут отменены при отмене транзакции. Профессиональная разработка в системе «1С:Предприятие 8»
Программирование форм конкретное значение ссылки на этот элемент в информационной базе. Конечно, все это справедливо только в том случае, если не выполнялось программное изменение ссылки до или после записи. Итак, по поводу этого обработчика можно сделать следующее замечание: ■■ если нужно выполнять какие-то действия, связанные с записанным объектом, и при этом, например, нужна ссылка на этот объект, необходимо использовать ТекущийОбъект.Ссылка; ■■ если нужно изменить записанные данные перед отправкой их на клиента, необходимо использовать ТекущийОбъект. Основной реквизит формы Объект можно использовать только для сравнения того, что «было», с тем, что «записалось». Изменять его бессмысленно, т. к. он будет замещен данными из ТекущийОбъект.
Событие «После записи на сервере» Рис. 8.224. Последовательность действий и событий при записи объекта. Продолжение
После обработки события объекта При записи, пока транзакция открыта, на сервере вызывается событие формы При записи на сервере. Назначение этого обработчика аналогично предыдущему, чтобы записать в базу данных дополнительную информацию, связанную с данными записываемого объекта. Ведь совсем не обязательно, что все исходные данные для записи дополнительной информации находятся в самом объекте. Они могут находиться и в форме. Как раз для таких случаев и предназначено это событие.
После того как обработано событие формы При записи на сервере, транзакция записи в СУБД закрывается, и начинается процесс передачи данных на клиента и закрытия формы. Он выглядит следующим образом (рис. 8.225).
Описание процедуры, обрабатывающей это событие, выглядит следующим образом (листинг 8.29). Листинг 8.29. Объявление обработчика события «При записи на сервере»
Процедура ПриЗаписиНаСервере(Отказ, ТекущийОбъект, ПараметрыЗаписи)
Находясь в этом обработчике, важно понимать, что имеет смысл работать только с теми данными объекта, которые доступны через ТекущийОбъект. Здесь ТекущийОбъект – это именно то, что было записано в информационную базу. Те данные, которые доступны через основной реквизит формы Объект, – это «старые» данные, это то, что было в форме, когда она «приехала» на сервер. Изменять эти данные бесполезно, потому что после выхода из этого обработчика они будут заменены данными, содержащимися в ТекущийОбъект. Иногда имеет смысл их анализировать. Например, в случае записи нового объекта тут будет следующая ситуация. Объект.Ссылка, скорее всего, будет содержать пустую ссылку (т. к. пока новый объект не записан, у него нет ссылки). В то же время ТекущийОбъект.Ссылка будет содержать уже Том 1
Рис. 8.225. Последовательность действий и событий при записи объекта. Окончание
303
Глава 8. Разработка форм После завершения транзакции записи выполняется преобразование данных записанного объекта в данные формы. После этого вызывается событие формы После записи на сервере. Это третий и последний обработчик, в котором по отдельности доступны данные формы, и объект, который был записан. Вызов этого обработчика также содержит ТекущийОбъект и похож на предыдущие (листинг 8.30).
Событие «После записи»
Листинг 8.30. Объявление обработчика события «После записи на сервере»
Событие «Перед закрытием»
Процедура ПослеЗаписиНаСервере(ТекущийОбъект, ПараметрыЗаписи)
Так как мы рассматриваем ситуацию записи объекта и закрытия его формы, то после обработки на клиенте события После записи на клиенте же вызывается событие Перед закрытием.
Однако здесь назначение ТекущийОбъект – прямо противоположное тому, что было до этого. Объясним подробнее. В этом обработчике данные записанного объекта уже помещены в форму. Поэтому «живым» в этом обработчике является уже основной реквизит формы Объект. А ТекущийОбъект существует лишь для того, чтобы дать возможность разработчику выполнить какие-то вспомогательные действия. Что обычно делают в этом обработчике? Обработчик – в модуле формы, значит, предполагаются действия над формой. Обработчик вызывается после окончания транзакции записи – значит, это действия, которые должны быть выполнены только в том случае, когда объект 100 % записан. Например, вывод в форме некоторой дополнительной информации, связанной с основными данными объекта. Или выполнение каких-либо действий, которые должны быть выполнены только в том случае, когда объект гарантированно записан. Отсюда последние замечания: ■■
изменять бессмысленно – он будет уничтожен при выходе из обработчика; ■■ если для выполнения связанных действий нужны какие-то данные или методы объекта, нужно использовать ТекущийОбъект, а не пытаться получать их через основной реквизит формы. ТекущийОбъект
В обработчике этого события также выполняются действия над формой, которые должны быть выполнены только в случае 100 % записи данных объекта. Те действия, которые требуют интерактивного взаимодействия с пользователем или которые невозможно выполнить на сервере.
Основное назначение этого события – проанализировать, можно закрывать форму или нельзя. И если нельзя, то отказаться от ее закрытия. Описание процедуры обработчика этого события выглядит следующим образом (листинг 8.31). Листинг 8.31. Объявление обработчика события «Перед закрытием»
&НаКлиенте Процедура ПередЗакрытием(Отказ, СтандартнаяОбработка)
Установка параметра Отказ в значение Истина позволяет отказаться от закрытия формы. А запрет стандартной обработки (СтандартнаяОбработка = Ложь) позволяет отказаться от стандартных действий, которые опять-таки определяются типом основного реквизита формы. Например, в случае с формой справочника стандартные действия платформы будут заключаться в следующем. Если форма модифицирована и окно формы закрывается клавишей Esc или нажатием кнопки закрытия окна, то платформа сообщит о том, что данные формы модифицированы, и предложит либо записать их, либо закрыть без сохранения изменений, либо отказаться от закрытия формы. Если в этой ситуации отказаться от стандартной обработки, то форма будет закрыта без вопросов в любом случае, независимо от того, модифицированы в ней данные или нет.
Передача формы на клиента
Событие «При закрытии»
После обработки события После записи на сервере форма передается на клиента. В памяти сервера уничтожается прикладной объект. Измененные реквизиты, элементы и параметры формы, требуемые для отображения, передаются на клиента. Уничтожается объект формы на сервере. После этого на клиенте вызывается событие формы После записи.
После обработки события Перед закрытием форма закрывается, пользователь перестает ее видеть. Однако программный объект формы все еще существует, и на клиенте вызывается событие формы При закрытии. Назначение этого события в том, чтобы выполнить действия, которые должны быть выполнены только в случае 100 % закрытия формы. Например, закрыть вспомогательную форму, существующую только в том случае, если открыта основная форма. После обработки этого события программный объект формы удаляется из памяти клиента.
304
Профессиональная разработка в системе «1С:Предприятие 8»
Программирование форм
Параметры записи
Начальное заполнение
Запись данных объекта в форме может быть выполнена средствами встроенного языка. Для этого у многих расширений формы существует метод Записать(). У этого метода есть единственный параметр – ПараметрыЗаписи. Он содержит структуру произвольных параметров записи.
Механизм начального заполнения позволяет описать правила и алгоритмы, по которым новые объекты, интерактивно создаваемые в информационной базе, будут заполнены некоторыми данными.
Некоторые расширения форм объектов добавляют собственные предопределенные параметры записи. Например, расширение документа добавляет параметры РежимЗаписи и РежимПроведения, расширение задачи – параметр ВыполнитьЗадачу. Подробнее о предопределенных параметрах можно прочитать в синтакспомощнике, в описании события Перед записью для разных расширений формы или в описании других событий, перечисленных ниже. Наряду с предопределенными параметрами разработчик может добавлять и собственные параметры. Эти параметры разработчик может использовать в различных обработчиках событий записи в зависимости от своих нужд. Таких событий, в которых будут доступны параметры записи, пять. На рисунке 8.226 они выделены рамкой.
Механизм начального заполнения ориентирован исключительно на интерактивную работу. При создании новых объектов средствами встроенного языка он не вызывается. Но при необходимости разработчик может его задействовать для того, чтобы имитировать интерактивное создание новых объектов. Начальное заполнение вызывается в следующих случаях интерактивного создания нового объекта: ■■ командой Создать в панели действий или в списке; ■■ командой ввода на основании; ■■ при программном вызове методов глобального ОткрытьФорму() или ПолучитьФорму(); ■■ при программном вызове методов объектов Заполнить().
контекста
Кроме перечисленных способов есть еще один способ интерактивного создания нового объекта – копированием. Этот случай обрабатывается платформой отдельно, и механизм начального заполнения при этом не задействуется. Механизм начального заполнения имеет несколько составляющих, часть из них доступна в режиме Конфигуратор, часть – во встроенном языке в режиме 1С:Предприятие:
Рис. 8.226. События, в которых доступны параметры записи
В любом из этих обработчиков параметры записи можно изменять, добавлять, удалять – все выполненные изменения будут переданы в следующий обработчик. Том 1
■■ во-первых, в конфигураторе можно задать конкретные значения, которыми автоматически будут заполнены реквизиты нового объекта. У реквизитов есть свойство Значение заполнения; ■■ во-вторых, в конфигураторе можно разрешить платформе в некоторых случаях самостоятельно заполнить реквизиты нового объекта подходящими данными. У реквизитов есть свойство Заполнять из данных заполнения; ■■ в-третьих, во встроенном языке разработчик может описать собственные алгоритмы заполнения реквизитов данными в обработчике события объекта Обработка заполнения. Это событие вызывается в тех случаях, которые были перечислены выше у прикладных объектов (справочников, документов и т. д.) и у набора записей регистра сведений. Рассмотрим каждый из этих трех элементов подробнее. В качестве примера мы будем использовать демонстрационную базу «Разработка форм, пример 4».
305
Глава 8. Разработка форм
Свойство «Значение заполнения» У реквизитов объектов конфигурации существует свойство Значение заполнения. Если реквизит примитивного типа (Строка, Число, Дата, Булево), то в свойстве можно задать любое значение этого типа, которым платформа автоматически заполнит этот реквизит у нового объекта. Если реквизит имеет тип ссылки или перечисления, то в этом свойстве можно задать предопределенный элемент или конкретное значение перечисления. подробнее
Пример можно посмотреть в демонстрационной базе «Разработка форм, пример 4», документ Накладная, реквизит Склад.
Например, у документа Накладная может быть реквизит Склад с типом ссылки на справочник Склады. А в справочнике Склады может существовать предопределенный элемент Главный склад. Тогда прямо в конфигураторе можно указать, что в новых документах реквизит Склад будет сразу же заполнен ссылкой на главный склад (рис. 8.227).
Рис. 8.228. Автоматическое заполнение реквизита для новых объектов
Свойство «Заполнять из данных заполнения» Другая возможность обеспечить начальное заполнение данных нового объекта – это разрешить платформе в некоторых ситуациях сделать это автоматически. Для этого используется другое свойство реквизитов объекта конфигурации – Заполнять из данных заполнения. Если это свойство установлено, платформа автоматически заполнит значение такого реквизита из данных заполнения в том случае, если они представляют собой структуру, содержащую отборы, и имя одного из условий отбора совпадает с именем этого реквизита. Вообще в данные заполнения платформа может передавать различные типы значений.
Рис. 8.227. Свойство «Значение заполнения»
В демонстрационной базе можно создать новую накладную (командой в панели действий или командой в списке) и убедиться, что склад в новой накладной заполнен (рис. 8.228).
Например, если просто создается новый объект, то в данных заполнения будет значение Неопределено. Если новый объект создается вводом на основании, то в данных заполнения будет ссылка на объект, являющийся основанием. Но во всех этих случаях платформа не будет автоматически заполнять реквизиты из данных заполнения. Автоматическое заполнение будет только в том случае, когда данные заполнения содержат структуру, состоящую из условий отбора. Когда в данных заполнения может оказаться такая структура? ■■ во-первых, когда новый объект вводится командой Создать из списка, в котором установлены некоторые отборы. Тогда все эти отборы платформа автоматически поместит в данные заполнения;
306
Профессиональная разработка в системе «1С:Предприятие 8»
Программирование форм ■■ во-вторых, когда новый объект вводится в результате программного вызова методов ОткрытьФорму(), ПолучитьФорму() или метода объекта Заполнить(). Во все эти методы разработчик самостоятельно может передать структуру, содержащую нужные отборы. Рассмотрим оба этих случая.
Создание объекта из отобранного списка подробнее
Пример можно посмотреть в демонстрационной базе «Разработка форм, пример 4», документ Накладная, реквизит Поставщик.
Сначала рассмотрим случай, когда, например, в списке накладных установлен отбор и пользователь нажимает кнопку Создать в командной панели списка. При этом у накладной существует реквизит Поставщик, для которого установлено свойство Заполнять из данных заполнения (рис. 8.229).
Рис. 8.230. Отбор, установленный в списке накладных
Рис. 8.229. Свойство «Заполнять из данных заполнения»
В режиме 1С:Предприятие в списке накладных установлены отборы по поставщику и по складу (рис. 8.230). Командой Создать списка можно создать новую накладную и убедиться, что поставщик будет заполнен тем значением, по которому был установлен отбор – Поставщик 3 (рис. 8.231). При этом склад будет по-прежнему заполнен значением Главный склад, т. к. в конфигураторе оно указано как значение заполнения.
Рис. 8.231. Автоматическое заполнение реквизитов данными отбора
Если в конфигураторе для реквизита Склад тоже установить свойство Заполнять из данных заполнения, то тогда при создании из отобранного списка и поставщик, и склад будут заполнены значениями отбора, несмотря на то, что для склада установлено значение заполнения (рис. 8.232). Том 1
307
Глава 8. Разработка форм А затем в клиентской процедуре создадим структуру, содержащую отбор по поставщику (ЭлементыОтбора) и передадим ее в параметр формы ЗначенияЗаполнения (листинг 8.33). Листинг 8.33. Установка значения заполнения при открытии формы
&НаКлиенте Процедура ОбработкаКоманды(ПараметрКоманды, ПараметрыВыполненияКоманды) СсылкаНаПоставщика = ПолучитьПоставщикаНаСервере(); ЭлементыОтбора = Новый Структура("Поставщик", СсылкаНаПоставщика); ПараметрыФормы = Новый Структура("ЗначенияЗаполнения", ЭлементыОтбора); ОткрытьФорму("Документ.Накладная.ФормаОбъекта", ПараметрыФормы); КонецПроцедуры
В результате выполнения такой команды будет открыта форма новой накладной, в которой поставщик будет заполнен значением Поставщик 1 (рис. 8.233). Рис. 8.232. Приоритет данных заполнения перед значением заполнения
Программная установка данных заполнения Теперь рассмотрим второй случай, когда данные заполнения устанавливаются программно. Например, выполняется метод встроенного языка ОткрытьФорму(). Как говорилось выше, при программном открытии формы есть возможность задать значения параметров формы. Для решения нашей задачи предназначен параметр расширения формы ЗначенияЗаполнения. Подробнее
Пример можно посмотреть в демонстрационной базе «Разработка форм, пример 4», глобальная команда Открыть форму.
Например, мы хотим открыть форму и сразу же указать, что реквизит Поставщик должен быть заполнен некоторой конкретной ссылкой. Для этого создадим серверную функцию, которая вернет эту самую ссылку на поставщика (листинг 8.32). Листинг 8.32. Серверная функция, возвращающая ссылку на поставщика
&НаСервере Функция ПолучитьПоставщикаНаСервере() Возврат Справочники.Поставщики.НайтиПоКоду("000000001"); КонецФункции
308
Рис. 8.233. Результат программной установки значения заполнения
В ситуации, когда новый объект полностью создается и записывается без участия пользователя, можно использовать метод объекта Заполнить(), чтобы смоделировать создание объекта по тем правилам и алгоритмам, которые используются при интерактивном создании. Подробнее
Пример можно посмотреть в демонстрационной базе «Разработка форм, пример 4», глобальная команда Заполнить.
Профессиональная разработка в системе «1С:Предприятие 8»
Программирование форм Например, находясь на сервере, можно создать новый объект накладной и затем вызвать у него метод Заполнить(). В этот метод передать значения, необходимые для начального заполнения, например поставщика. При интерактивном создании накладной расширение формы автоматически устанавливает дату нового документа. В программном создании накладной форма не участвует, поэтому в структуре данных заполнения нужно передать еще и значение для поля Дата, иначе записать такую накладную не удастся. А для того чтобы платформа обработала его автоматически, в конфигураторе у стандартного реквизита накладной Дата нужно установить свойство Заполнять из данных заполнения (листинг 8.34). Листинг 8.34. Использование метода «Заполнить()»
&НаСервере Процедура СоздатьИЗаписатьОбъектНаСервере() СсылкаНаПоставщика = Справочники.Поставщики.НайтиПоКоду("000000002"); ЭлементыОтбора = Новый Структура("Поставщик, Дата", СсылкаНаПоставщика, ТекущаяДата()); ОбъектНакладной = Документы.Накладная.СоздатьДокумент(); ОбъектНакладной.Заполнить(ЭлементыОтбора); ОбъектНакладной.Записать(); КонецПроцедуры
Для остальных стандартных реквизитов, как в нашем случае для даты, нужно это свойство устанавливать самостоятельно, если планируется использовать возможность их автоматического заполнения.
Событие «Обработка заполнения» Если разработчика не устраивают значения заполнения, установленные в конфигураторе, или значения, переданные в данные заполнения, он может реализовать собственный алгоритм заполнения нового объекта данными. Для этого у объекта есть событие Обработка заполнения, которое может быть обработано в серверной процедуре. Чтобы лучше представлять себе возможности программной обработки заполнения, рассмотрим еще раз последовательность, в которой платформа использует те или иные элементы механизма заполнения (рис. 8.235).
В результате выполнения такой команды будет создана и записана новая накладная с текущей датой и поставщиком Поставщик 2. Значение для реквизита Склад будет взято из его свойства Значение заполнения (рис. 8.234).
Рис. 8.235. Последовательность автоматического заполнения реквизитов нового объекта
Сначала будет вызван обработчик события и выполнен его код.
Рис. 8.234. Результат использования метода «Заполнить()»
Следует заметить, что для стандартных реквизитов Родитель, Владелец и для ведущих измерений регистров сведений платформа автоматически в конфигураторе устанавливает свойство Заполнять из данных заполнения. Том 1
Обработка
заполнения
Если после выхода из этого обработчика его параметр СтандартнаяОбработка будет иметь значение Ложь, то платформа не будет пытаться самостоятельно заполнить реквизиты нового объекта, а сразу же вызовет событие формы При создании на сервере. Если же после выхода из обработчика значение его параметра СтандартнаяОбработка будет Истина (по умолчанию), то сначала платформа попытается заполнить значения реквизитов из данных заполнения.
309
Глава 8. Разработка форм Если после этого реквизит все еще будет иметь значение своего типа по умолчанию, то платформа попытается заполнить его значением заполнения, указанным в конфигураторе. Если же после данных заполнения реквизит будет иметь значение, отличное от значения по умолчанию, то значение заполнения использоваться не будет, даже если оно указано для этого реквизита. Таким образом, находясь в обработчике Обработка заполнения, разработчик может, проанализировав данные заполнения, самостоятельно заполнить реквизиты нового объекта и затем использовать или не использовать возможности стандартной обработки заполнения. Какие возможны варианты? Мы уже говорили о них, перечислим еще раз: ■■ если данные заполнения имеют значение Неопределено, это значит, что новый объект создается командой Создать в панели действий или командой Создать из списка, в котором отсутствуют отборы; ■■ если данные заполнения являются ссылкой, то выполняется ввод на основании и разработчик должен самостоятельно обработать это значение: либо сохранить его в реквизите формы, либо на основе этих данных заполнить несколько реквизитов формы; ■■ если данные заполнения – это структура, значит, новый объект создается командой Создать из отобранного списка, или в общем случае разработчик создает его программно, передавая эту структуру через методы ОткрытьФорму(), ПолучитьФорму() или Заполнить(). В качестве примера рассмотрим процедуру Обработка заполнения документа Накладная (листинг 8.35). Подробнее
Пример можно посмотреть в демонстрационной базе «Разработка форм, пример 4», модуль документа Накладная, процедура ОбработкаЗаполнения(). Листинг 8.35. Различные варианты обработки автоматического заполнения
Процедура ОбработкаЗаполнения(ДанныеЗаполнения, СтандартнаяОбработка) Сообщение = Новый СообщениеПользователю; Если ДанныеЗаполнения = Неопределено Тогда Сообщение.Текст = "Ввод новой накладной"; ИначеЕсли ТипЗнч(ДанныеЗаполнения) = Тип("СправочникСсылка.Поставщики") Тогда Сообщение.Текст = "Ввод накладной на основании поставщика"; Поставщик = ДанныеЗаполнения; ИначеЕсли ТипЗнч(ДанныеЗаполнения) = Тип("Структура") Тогда Сообщение.Текст = "Ввод накладной из отобранного списка"; СтандартнаяОбработка = Ложь;
310
ОтобранныйПоставщик = Неопределено; Если ДанныеЗаполнения.Свойство("Поставщик", ОтобранныйПоставщик) Тогда Поставщик = ОтобранныйПоставщик; КонецЕсли; КонецЕсли; Сообщение.Сообщить(); КонецПроцедуры
В этой процедуре для наглядности в каждом из возможных вариантов выводится информационное сообщение. При обычном вводе (Если ДанныеЗаполнения = Неопределено Тогда) не выполняется никаких действий, документ заполняется стандартным способом – реквизит Склад заполняется своим значением заполнения. При вводе на основании поставщика (ИначеЕсли нения)
=
ТипЗнч(ДанныеЗаполТип("СправочникСсылка.Поставщики") Тогда) реквизиту
Поставщик устанавливается значение того поставщика, на основании
которого введена эта накладная. И также используются возможности стандартного заполнения – реквизит Склад заполняется своим значением заполнения.
При вводе из отобранного списка (ИначеЕсли ТипЗнч(ДанныеЗаполнения) = Тип("Структура") Тогда) стандартное заполнение не используется (склад не заполняется), а из переданного отбора берется только значение для реквизита Поставщик (другие элементы отбора игнорируются).
Проверка заполнения Механизм проверки заполнения позволяет автоматически проверить, заполнены ли указанные реквизиты объекта. Такая проверка выполняется при интерактивном вводе объекта, перед его записью. Поля реквизитов, для которых должно проверяться заполнение, автоматически выделяются в форме красным подчеркиванием. Если перед записью объекта эти поля окажутся не заполнены, запись не будет выполнена, а в форме будут выданы сообщения об ошибках, привязанные к незаполненным реквизитам (рис. 8.236). Механизм проверки заполнения ориентирован исключительно на интерактивную работу, при записи объектов средствами встроенного языка он не вызывается. Но при необходимости имитировать интерактивную запись объекта разработчик может вызвать этот механизм из встроенного языка. Суть проверки заполнения заключается в том, что у реквизитов объектов конфигурации, у табличных частей, у реквизитов табличных частей и у реквизитов форм есть свойство Проверка заполнения. Стандартное значение этого свойства – Не проверять. Оно означает, что реквизит не участвует в проверке заполнения. Профессиональная разработка в системе «1С:Предприятие 8»
Программирование форм
Рис. 8.236. Сообщения пользователю
Однако если это свойство установить в значение Выдавать ошибку, то перед записью платформа будет проверять, что значение реквизита отличается от значения его типа по умолчанию. А для табличных частей будет проверять, что в табличной части есть хотя бы одна строка (рис. 8.237).
Рис. 8.237. Свойство «Проверка заполнения»
Рис. 8.238. Сообщения о незаполненности реквизитов
А при попытке записать документ с пустой строкой в табличной части сообщения будут следующими (рис. 8.239).
Рис. 8.239. Сообщения о незаполненности табличной части
Пример можно посмотреть в демонстрационной базе «Разработка форм, пример 5», документ Накладная, реквизиты Склад, Поставщик, табличная часть Товары, реквизиты табличной части Товар, Количество, Цена, Валюта, форма документа, реквизит Ответственный.
С помощью мыши или курсора можно перемещаться по сообщениям в окне Сообщения, при этом выделенное сообщение будет показано в форме в специальном окне, размещенном под тем элементом, в котором допущена ошибка. Нажимая кнопки Предыдущее сообщение и Следующее сообщение, пользователь может перемещаться по форме и заполнять пропущенные данные.
Например, в документе Накладная проверка заполнения может быть указана для его реквизитов, табличной части и реквизитов табличной части. Тогда при попытке записать незаполненный документ платформа выдаст следующие сообщения (рис. 8.238).
Естественно, во встроенном языке разработчик может описать собственные алгоритмы проверки заполнения реквизитов данными. Для этого предназначены два события. Событие формы Обработка проверки заполнения на сервере и событие прикладного объекта, редактируемого в форме, – Обработка проверки заполнения.
Подробнее
Том 1
311
Глава 8. Разработка форм
Заполнение и проверка заполнения
Свойство «Проверка заполнения»
Прежде чем подробнее рассматривать механизм проверки заполнения, хотелось бы обратить внимание на то, что в платформе есть два интерактивных, созвучных между собой механизма: механизм заполнения и механизм проверки заполнения.
Относительно свойства Проверка заполнения хочется сделать следующее замечание. Хотя стандартно для новых реквизитов платформа устанавливает это свойство в значение Не проверять, для некоторых стандартных реквизитов, наоборот, платформа автоматически включает это свойство при создании объектов конфигурации.
Не следует их путать. Заполнение – это: ■■ свойства реквизитов объектов конфигурации Значение заполнения, Заполнять из данных заполнения; ■■ обработчик объекта Обработка заполнения; ■■ заполнение выполняется при интерактивном создании нового объекта. подробнее
Раздел «Начальное заполнение», стр. 305.
Проверка заполнения – это: ■■ свойства реквизитов объектов конфигурации Проверка заполнения; ■■ обработчик формы Обработка проверки заполнения на сервере и обработчик объекта Обработка проверки заполнения; ■■ проверка заполнения выполняется при интерактивной записи объекта.
Такими реквизитами являются, например, Наименование и Владелец для справочника, Дата для документа и так далее. подробнее
Документация «1С:Предприятие 8.2. Руководство разработчика», раздел 5.6.8.1.
Поэтому в тех случаях, когда требуется реализовать нестандартное поведение системы, эти свойства для стандартных реквизитов нужно установить в значение Не проверять или программно исключить эти реквизиты из проверки заполнения (рис. 8.241).
Для большей наглядности можно представить следующую схему (рис. 8.240).
Рис. 8.241. Проверка заполнения для стандартных реквизитов
Программная обработка проверки заполнения Каким образом разработчик может повлиять на стандартную проверку заполнения, выполняемую платформой? Для этого у него есть два события. Одно событие – Обработка проверки заполнения на сервере – можно обработать в модуле формы. Другое событие – Обработка проверки заполнения – можно обработать в модуле прикладного объекта.
Рис. 8.240. Заполнение и проверка заполнения
312
Все, что относится к проверкам реквизитов основного объекта формы, нужно обрабатывать в модуле объекта. Профессиональная разработка в системе «1С:Предприятие 8»
Программирование форм Обработчик в форме нужен потому, что форма может иметь данные, не относящиеся к объекту, и свои причины для проверки. И тот и другой обработчик имеют два параметра: Отказ и ПроверяемыеРеквизиты. В параметр ПроверяемыеРеквизиты платформа передает массив имен тех реквизитов, заполненность которых должна быть проверена. Разработчик может поступить несколькими способами: ■■ проверить заполненность реквизитов самостоятельно и очистить массив ПроверяемыеРеквизиты, чтобы платформа не выполняла их проверку (листинг 8.36). Листинг 8.36. Самостоятельная проверка всех реквизитов
Если Поставщик = Справочники.Поставщики.ПустаяСсылка() Тогда Сообщение = Новый СообщениеПользователю; Сообщение.Текст = "Необходимо заполнить поставщика!"; Сообщение.Поле = "Поставщик"; Сообщение.УстановитьДанные(ЭтотОбъект); Сообщение.Сообщить(); Отказ = Истина; КонецЕсли; // Проверка остальных реквизитов. // ... // Очистить массив проверяемых реквизитов, чтобы платформа // не выполняла их автоматическую проверку. ПроверяемыеРеквизиты.Очистить(); подробнее
Пример можно посмотреть в демонстрационной базе «Разработка форм, пример 5», модуль документа Накладная, процедура ОбработкаПроверкиЗаполнения, снять комментарии для варианта Пример 1.
Если ИндексПоляПоставщик <> Неопределено Тогда ПроверяемыеРеквизиты.Удалить(ИндексПоляПоставщик); КонецЕсли; КонецЕсли; подробнее
Пример можно посмотреть в демонстрационной базе «Разработка форм, пример 5», модуль документа Накладная, процедура ОбработкаПроверкиЗаполнения, снять комментарии для варианта Пример 2.
■■ добавить в массив ПроверяемыеРеквизиты какие-то реквизиты, чтобы платформа проверила и их тоже (листинг 8.38). Листинг 8.38. Добавление новых реквизитов для автоматической проверки
ПроверяемыеРеквизиты.Добавить("Комментарий"); подробнее
Пример можно посмотреть в демонстрационной базе «Разработка форм, пример 5», модуль документа Накладная, процедура ОбработкаПроверкиЗаполнения, снять комментарии для варианта Пример 3.
■■ очистить массив ПроверяемыеРеквизиты, чтобы ничего не проверять ни самому, ни платформе (листинг 8.39). Листинг 8.39. Отказ от автоматической проверки реквизитов
ПроверяемыеРеквизиты.Очистить(); подробнее
Пример можно посмотреть в демонстрационной базе «Разработка форм, пример 5», модуль документа Накладная, процедура ОбработкаПроверкиЗаполнения, снять комментарии для варианта Пример 4.
■■ проверить часть реквизитов самостоятельно, удалить их из массива ПроверяемыеРеквизиты, а оставшиеся реквизиты оставить на проверку платформе (листинг 8.37).
Нужно заметить, что состав массива ПроверяемыеРеквизиты различен в обработчике формы и в обработчике объекта.
Листинг 8.37. Частичная проверка заполненности реквизитов
В обработчике объекта в этом массиве содержатся имена реквизитов объекта, которые требуют проверки (рис. 8.242).
Если Поставщик = Справочники.Поставщики.ПустаяСсылка() Тогда Сообщение = Новый СообщениеПользователю; Сообщение.Текст = "Необходимо заполнить поставщика!"; Сообщение.Поле = "Поставщик"; Сообщение.УстановитьДанные(ЭтотОбъект); Сообщение.Сообщить(); Отказ = Истина; // Удалить поставщика из массива проверяемых реквизитов. ИндексПоляПоставщик = ПроверяемыеРеквизиты.Найти("Поставщик");
Том 1
Рис. 8.242. Массив реквизитов, проверяемых в объекте
313
Глава 8. Разработка форм В обработчике формы содержатся имена реквизитов формы, которые требуют проверки. И если есть реквизиты объекта, которые нужно проверять, то содержится имя основного реквизита формы, содержащего данные объекта (рис. 8.243).
Рис. 8.243. Массив реквизитов, проверяемых в форме
Параметр Отказ нужен для того, чтобы отказаться от записи объекта. Не от проверки заполненности, а именно от записи. Чтобы отказаться от проверки объектов, нужно очистить массив ПроверяемыеРеквизиты. Если установить параметр Отказ при обработке события в объекте, то после выполнения обработчика Обработка проверки заполнения процесс записи будет прекращен (рис. 8.244).
Рис. 8.245. Использование параметра «Отказ» в обработчике формы
Вывод сообщений с привязкой к элементам формы При самостоятельной проверке заполненности реквизитов, естественно, возникает желание вывести такие же сообщения об ошибках, которые выводит и система, чтобы они были привязаны к тем элементам формы, в которых значения не заполнены. Для этого используется специальный механизм платформы – механизм сообщений пользователю. Подробнее об этом механизме можно прочитать в разделе «Сообщения пользователю», стр. 321. Здесь мы рассмотрим только некоторые примеры его использования. подробнее
Пример можно посмотреть в демонстрационной базе «Разработка форм, пример 5», модуль документа Накладная, процедура ОбработкаПроверкиЗаполнения, снять комментарии для варианта Пример 5.
Рис. 8.244. Использование параметра «Отказ» в обработчике объекта
Если параметр Отказ установить в форме, то дальнейшее поведение системы будет зависеть от того, есть ли в списке проверяемых реквизитов основной реквизит формы (рис. 8.243). Если есть, отработает проверка заполнения в объекте, и на этом все закончится (рис. 8.244). Если нет (например, разработчик очистил этот список), то обработчик в модуле объекта вызываться не будет (рис. 8.245).
314
Чтобы вывести такое сообщение из модуля объекта (в обработчике события Обработка проверки заполнения), нужно создать новый объект СообщениеПользователю, задать текст этого сообщения. Также нужно указать, с каким реквизитом формы будет связано это сообщение. Для этого используется свойство Поле (Сообщение.Поле = "Поставщик"). Таким образом, мы указываем, что сообщение должно быть привязано к тому элементу формы, который отображает значение реквизита Поставщик. Мы указали, к какому реквизиту привязать сообщение. Но неизвестно, в какой форме находится этот реквизит. Ведь наш код выполняется в модуле объекта, и у нас нет информации о каких-либо открытых формах. Профессиональная разработка в системе «1С:Предприятие 8»
Программирование форм Сейчас мы не будем подробно углубляться в этот вопрос, скажем лишь, что для того, чтобы сообщение было правильно привязано в форме нашего объекта, нужно задать значения еще двух свойств: ПутьКДанным и КлючДанных. Эти свойства платформа может заполнить самостоятельно, если выполнить метод УстановитьДанные() и передать в него тот программный объект, в модуле которого мы находимся. Ну и собственно для показа сообщения используется метод Сообщить(). Допустим, нужно (рис. 8.246).
проверить
заполненность
реквизита
Поставщик
Рис. 8.247. Сообщение о незаполненном реквизите
Теперь рассмотрим ситуацию, когда нужно сообщить об отсутствии строк в табличной части Товары (рис. 8.248).
Рис. 8.246. Реквизит «Поставщик», заполненность которого нужно проверить
Это можно выполнить следующим образом (листинг 8.40). Листинг 8.40. Привязка сообщения к реквизиту объекта
Если Поставщик = Справочники.Поставщики.ПустаяСсылка() Тогда Сообщение = Новый СообщениеПользователю; Сообщение.Поле = "Поставщик"; // имя реквизита Сообщение.УстановитьДанные(ЭтотОбъект); Сообщение.Текст = "Нужно заполнить поставщика!"; Сообщение.Сообщить(); Отказ = Истина; // не выполнять запись КонецЕсли;
В результате, если поставщик не заполнен, мы будем иметь такое сообщение в форме (рис. 8.247). Обратите внимание, что после выдачи сообщения пользователю мы отменяем дальнейшую запись объекта (Отказ = Истина). Если этого не сделать, объект будет записан, несмотря на все наши сообщения, а если выполнялась команда Записать и закрыть, то форма тоже будет закрыта, несмотря на то, что в нее были выведены сообщения. Том 1
Рис. 8.248. Табличная часть, заполненность которой нужно проверить
Это можно выполнить следующим образом (листинг 8.41). Листинг 8.41. Привязка сообщения к табличной части
Если Товары.Количество() = 0 Тогда Сообщение = Новый СообщениеПользователю; Сообщение.Поле = "Товары"; // имя табличной части Сообщение.УстановитьДанные(ЭтотОбъект); Сообщение.Текст = "Нужно заполнить список полученных товаров!"; Сообщение.Сообщить(); Отказ = Истина; // не выполнять запись КонецЕсли;
Здесь в свойстве Поле указывается имя табличной части.
315
Глава 8. Разработка форм В результате, если табличная часть пуста, мы будем иметь такое сообщение в форме (рис. 8.249).
Листинг 8.42. Привязка сообщения к реквизиту табличной части
Если Товары[1].Цена = 0 Тогда Сообщение = Новый СообщениеПользователю; // Индекс строки табличной части и имя поля. Сообщение.Поле = "Товары[1].Цена"; Сообщение.УстановитьДанные(ЭтотОбъект); Сообщение.Текст = "Нужно написать цену товара!"; Сообщение.Сообщить(); Отказ = Истина; // не выполнять запись КонецЕсли;
Здесь в свойстве Поле указывается путь к нужному полю табличной части. Сначала с помощью индекса указывается строка (Товары[1]), затем через точку указывается поле в этой строке (Цена). В результате, если цена не заполнена, мы будем иметь такое сообщение в форме (рис. 8.251). Рис. 8.249. Сообщение о незаполненной табличной части
Теперь допустим, нужно сообщить о том, что в некоторой строке табличной части не заполнено какое-то поле, например, во второй строке пустое поле Цена (рис. 8.250).
Рис. 8.251. Сообщение о незаполненном реквизите табличной части
В ситуации, когда нужно самостоятельно проверять заполненность какихлибо реквизитов формы (а не реквизитов объекта), все обстоит несколько проще. Такие проверки нужно делать в обработчике события формы Обработка проверки заполнения на сервере.
Рис. 8.250. Реквизит табличной части, заполненность которого нужно проверить
Поскольку код этого обработчика выполняется в контексте формы, нет необходимости устанавливать для сообщения данные (Сообщение.УстановитьДанные(…)). Достаточно лишь указать имя реквизита формы, к данным которого будет привязано сообщение.
Это можно выполнить следующим образом (листинг 8.42).
подробнее
Пример можно посмотреть в демонстрационной базе «Разработка форм, пример 5», модуль формы документа Накладная, снять комментарии с процедуры ОбработкаПроверкиЗаполненияНаСервере.
316
Профессиональная разработка в системе «1С:Предприятие 8»
Программирование форм Например, нужно проверить реквизит формы Ответственный (рис. 8.252).
Проверка заполнения и функциональные опции Использование функциональных опций определяет некоторые особенности проверки заполнения. Функциональные опции позволяют автоматически скрыть/отобразить элементы интерфейса, которые связаны с функциональностью, не использующейся в данном прикладном решении (или, наоборот, использующейся). Функциональные опции бывают независимые и параметризуемые.
Рис. 8.252. Реквизит формы, заполненность которого нужно проверить
Это может выглядеть следующим образом (листинг 8.43). Листинг 8.43. Привязка сообщения к реквизиту формы
Если СокрЛП(Ответственный) = "" Тогда Сообщение = Новый СообщениеПользователю; Сообщение.Поле = "Ответственный"; Сообщение.Текст = "Нужно написать фамилию ответственного!"; Сообщение.Сообщить(); // Удалить ответственного из массива проверяемых реквизитов, // чтобы платформа не проверяла его автоматически еще раз. ИндексОтветственного = ПроверяемыеРеквизиты.Найти("Ответственный"); Если ИндексОтветственного <> Неопределено Тогда ПроверяемыеРеквизиты.Удалить(ИндексОтветственного); КонецЕсли; КонецЕсли;
Если функциональная опция независимая, то ее значение неизменно для всей конфигурации в целом. подробнее
Пример можно посмотреть в демонстрационной базе «Разработка форм, пример 5», функциональная опция УчетПоСкладам.
Оно может храниться, например, в константе типа Булево. Истина – функциональная опция включена, Ложь – выключена (рис. 8.254).
В результате, если ответственный не заполнен, мы будем иметь такое сообщение в форме (рис. 8.253).
Рис. 8.254. Независимая функциональная опция
В этом случае все просто и понятно. Если, например, реквизит Склад связан с такой функциональной опцией, то, когда опция выключена, реквизит не отображается в форме и платформа не проверяет его заполненность, не включает его в массив проверяемых реквизитов. Если функциональная опция включена, реквизит отображается в форме и его заполненность проверяется. Рис. 8.253. Сообщение о незаполненном реквизите формы
Том 1
317
Глава 8. Разработка форм С параметризуемыми функциональными опциями дело обстоит сложнее. Их значение не постоянно для всей конфигурации. Параметризуемая опция в одном документе может иметь значение Истина (быть включенной), а в другом – иметь значение Ложь (быть выключенной). Все зависит от ее параметра. Поясним на примере.
какого именно поставщика нужно брать для выяснения значения функциональной опции. Например, в форме накладной при изменении значения поля Поставщик может выполняться следующий код (листинг 8.44). Листинг 8.44. Установка параметра функциональной опции
подробнее
Пример можно посмотреть в демонстрационной базе «Разработка форм, пример 5», функциональная опция ВалютныйУчет.
Допустим, есть параметризуемая функциональная опция ВалютныйУчет. Она определяет, нужно ли использовать различные валюты при расчетах с поставщиками. Особенность заключается в том, что все зависит от конкретного поставщика. С одним поставщиком расчеты ведутся только в рублях и никак иначе. А с другим поставщиком расчеты могут производиться как в рублях, так и в валюте. Пусть значение такой функциональной опции хранится в реквизите РасчетыВВалюте справочника Поставщики (рис. 8.255).
ПараметрыОпций = Новый Структура("Поставщик", Объект.Поставщик); УстановитьПараметрыФункциональныхОпцийФормы(ПараметрыОпций);
Таким образом, платформе сообщается, что в данный момент параметр функциональной опции должен быть равен тому поставщику, которого выбрал пользователь в поле Поставщик. Имея эту информацию, дальше платформа самостоятельно выясняет значение функциональной опции и скрывает или, наоборот, отображает реквизит табличной части Валюта. Теперь вернемся к проверке заполнения. Поскольку от разработчика зависит, как и в какой момент в конкретной форме будут установлены параметры функциональных опций, проверяемые реквизиты, связанные с параметризуемыми функциональными опциями, всегда присутствуют в массиве ПроверяемыеРеквизиты. Если в конкретной ситуации заполненность этого реквизита проверять не нужно, разработчик самостоятельно должен удалить его из массива проверяемых реквизитов. Рассмотрим это на примере. подробнее
Пример можно посмотреть в демонстрационной базе «Разработка форм, пример 5», модуль документа Накладная, процедура ОбработкаПроверкиЗаполнения, снять комментарии для варианта Пример 6.
Выполним команду Настройки в панели действий рабочего стола (рис. 8.256).
Рис. 8.255. Параметризуемая функциональная опция
Поставщиков в базе данных может существовать много. У одних этот реквизит может иметь значение Истина, у других – Ложь. Какого именно поставщика взять для определения значения функциональной опции? Для этого как раз и служит параметр функциональной опции (в нашем примере Поставщик). В каждом конкретном случае он определяет, реквизит
318
Рис. 8.256. Включение/выключение функциональной опции
Профессиональная разработка в системе «1С:Предприятие 8»
Программирование форм Сейчас учет по складам включен, в списке накладных есть колонка Склад, а в самой накладной есть поле Склад. Выключим учет по складам и закроем форму настроек. Создадим новую накладную (рис. 8.257).
В данном случае независимая функциональная опция включена, и поэтому платформа автоматически включила связанный с ней реквизит Склад в проверку.
В ней уже нет поля Склад.
Теперь рассмотрим работу параметризуемой функциональной опции ВалютныйУчет. С этой функциональной опцией связан реквизит табличной части Валюта.
Заполним все требуемые поля, запишем и закроем накладную.
Создадим новую накладную и выберем поставщика Поставщик валютный. В табличной части появится колонка Валюта (рис. 8.259).
Рис. 8.257. Новая накладная при выключенном учете по складам
Никаких сообщений о незаполненности реквизита Склад мы не получим, т. к. платформа автоматически исключила его из числа проверяемых реквизитов, потому что независимая функциональная опция УчетПоСкладам выключена. Включим учет по складам и снова откроем эту же накладную. В ней появилось поле Склад, и оно не заполнено. Таким его и оставим. Реквизит Ответственный требует заполнения, но не сохраняется в базе данных. Такова логика работы нашей демонстрационной формы. Поэтому сейчас для чистоты эксперимента заполним его еще раз.
Рис. 8.259. Колонка «Валюта» в табличной части
Заполним все требуемые поля, кроме валюты, и попробуем записать документ. Мы получим сообщение о том, что поле Валюта не заполнено (рис. 8.260).
После этого попробуем записать документ. Мы получим сообщение о том, что реквизит Склад не заполнен (рис. 8.258).
Рис. 8.260. Сообщение о незаполненном поле «Валюта» Рис. 8.258. Сообщение о незаполненном поле «Склад»
Том 1
319
Глава 8. Разработка форм Теперь, так и не заполняя поле Валюта, выберем другого поставщика – Поставщик рублевый 2. Колонка Валюта исчезнет. Попробуем записать документ. Документ запишется без сообщений об ошибках. Таким образом, в одном случае реквизит Валюта проверяется, а в другом – нет. Хотя и в одном, и в другом случае он присутствует в массиве проверяемых реквизитов. Как это достигается? Откроем модуль документа, процедуру пример 6.
ОбработкаПроверкиЗаполнения,
В ней присутствует следующий код, который в зависимости от значения функциональной опции перед записью исключает реквизит Валюта из проверки (листинг 8.45).
Проверка заполнения и проверка при записи Еще раз хочется обратить внимание на то, что проверка заполнения – это механизм, ориентированный исключительно на интерактивный ввод данных пользователем. Он автоматически вызывается расширениями форм. Но могут быть ситуации, когда программно реализуется некоторый алгоритм, который должен имитировать для пользователя интерактивный ввод данных. В этом случае проверку заполнения можно вызвать с помощью методов ПроверитьЗаполнение(), реализованных у объектов, наборов записей регистров и формы. Важно понимать, что проверка заполнения не является частью записи объекта. Она специально выделена отдельно (рис. 8.261).
Листинг 8.45. Исключение реквизита из проверки в зависимости от значения функциональной опции
СтруктураПараметров = Новый Структура("Поставщик", Поставщик); // Если функциональная опция "Валютный учет" выключена... Если НЕ ПолучитьФункциональнуюОпцию("ВалютныйУчет", СтруктураПараметров) Тогда // ...не проверять заполненность поля "Валюта" табличной части. ИндексПоляВалюта = ПроверяемыеРеквизиты.Найти("Товары.Валюта"); Если ИндексПоляВалюта <> Неопределено Тогда ПроверяемыеРеквизиты.Удалить(ИндексПоляВалюта); КонецЕсли; КонецЕсли;
Во встроенном языке существует метод глобального контекста ПолучитьФункциональнуюОпцию(). Он позволяет узнать значение параметризуемой функциональной опции. Кроме имени функциональной опции ему нужно передать и значение ее параметра. Значение параметра передается в виде структуры, которая содержит имя параметра и значение параметра. В нашем случае такой структурой является СтруктураПараметров, где в качестве значения используется поставщик, выбранный в поле Поставщик накладной. Таким образом, если метод возвращает значение Ложь (выбран поставщик без расчетов в валюте, функциональная опция выключена), выполняется условие Если…, и из массива проверяемых реквизитов удаляется реквизит табличной части Валюта. Если функциональная опция включена, ничего не происходит, и платформа проверяет значение реквизита Валюта.
Рис. 8.261. Проверка заполнения и запись объекта
Таким образом, есть два отдельных вопроса. Первый вопрос – все ли реквизиты объекта заполнены. Второй вопрос – можно ли записывать объект в информационную базу. Запись объекта может происходить в самых разных ситуациях: обмен данными, генерация данных обработкой. Это может быть программный код, который «очень хорошо знает», что с объектом нужно сделать и что в нем нужно записать. Поэтому если просто записывать объект из встроенного языка, автоматическая проверка заполнения не вызывается. Если же запись объекта вызывается из формы, использующей стандартное расширение форм, то это расширение вызовет автоматическую проверку заполнения. Естественно, в какой-то момент может возникнуть вопрос: что проверять перед записью, а что – в проверке заполнения?
320
Профессиональная разработка в системе «1С:Предприятие 8»
Программирование форм Чтобы решить, нужно, по сути, ответить на вопрос: что является неотемлемой частью технической логики объекта, не зависящей от способа ввода данных? Такой частью, без которой он существовать не может?
измерением не имеют смысла в информационной базе, каким бы образом они в нее ни попали: в результате интерактивного ввода или в результате выполнения программного кода.
Наверняка какие-то проверки нужно выполнять перед записью. Но они, во-первых, должны быть очень быстрыми (потому что у вас может происходить массовая генерация объектов) и, во-вторых, должны быть очень «жестокими». То есть вообще в базу данных никогда не должен попасть объект «без такого вот значения».
Сообщения пользователю
А проверка заполнения может содержать больший объем проверок, ориентированных именно на то, что не хочется пользователю дать возможность ввести «вот такое» интерактивно.
■■ во-первых, сообщения выводятся в окно сообщений формы (или в окно сообщений основного окна) и накапливаются в нем. Таким образом, пользователь может последовательно или выборочно выполнять рекомендации, содержащиеся в этих сообщениях; ■■ во-вторых, сообщения могут привязываться к элементам формы. В результате пользователь не только быстро находит поле, которое требует исправления, но и быстро выполняет это исправление. Как только сообщение отображается рядом с нужным полем формы, это поле сразу же переходит в режим редактирования; ■■ в-третьих, сообщения могут относиться не только к той форме, в которой они выведены, но и к другим формам. В этом случае при двойном щелчке на таком сообщении будет открыта форма, к которой относится это сообщение, и в этой форме сообщение будет спозиционировано рядом с нужным элементом формы. Рассмотрим подробнее, каким образом сообщение определяет тот элемент формы, около которого оно должно быть отображено.
Пару слов следует сказать о свойстве Запрет незаполненных значений, которое существует у измерений регистров. Если это свойство установлено у измерения, то платформа автоматически будет проверять при записи наборов записей, что измерение заполнено (рис. 8.262).
Сообщения пользователю – удобный инструмент для оповещения пользователя об ошибках в заполнении тех или иных данных. Можно выделить три ключевые возможности сообщений пользователю:
Сообщение имеет три свойства, которые позволяют ему точно позиционироваться возле нужного элемента формы: КлючДанных, ПутьКДанным и Поле (рис. 8.263).
Рис. 8.262. Свойство «Запрет незаполненных значений»
На первый взгляд может показаться, что и там, и там проверяется заполненность, что это одно и то же. Тут нужно понимать, что проверка заполнения – это исключительно интерактивная проверка; проверка того, что пользователь ввел интерактивно. В отличие от этого, запрет незаполненных значений – это неотъемлемая часть бизнес-логики регистра. Она означает, что записи с незаполненным Том 1
Рис. 8.263. Назначение свойств объекта «СообщениеПользователю»
321
Глава 8. Разработка форм Выполнение любого программного кода всегда начинается на клиенте – из какой-нибудь активной формы или из основного окна. Все сообщения пользователю платформа всегда выводит в активное окно. Если такого окна нет, а есть только основное окно, сообщение будут выведено в основное окно. Когда сообщение оказывается в окне какой-либо формы, первым делом анализируется ссылка, содержащаяся в свойстве КлючДанных. ■■ Если эта ссылка совпадает с данными, содержащимися в основном реквизите формы, значит, сообщение предназначено этой форме. Затем ищется реквизит формы, имя которого указано в свойстве ПутьКДанным. После этого ищется подчиненный реквизит, имя которого указано в свойстве Поле. В результате после двойного щелчка на сообщении оно отображается рядом с нужным элементом формы. ■■ Другой сценарий – когда ссылка, содержащаяся в свойстве КлючДанных, не совпадает с данными, содержащимися в основном реквизите формы. Это означает, что сообщение предназначено другой форме – основной форме того объекта, ссылка на который содержится в ключе данных. В этом случае после двойного щелчка на сообщении будет открыта основная форма объекта, ссылка на который содержится в ключе данных, а далее сообщение будет спозиционировано рядом с нужным элементом формы по принципу, описанному выше. Оба рассмотренных случая, когда заполнены все три свойства сообщения, являются наиболее общими и универсальными. Они позволяют правильно воспользоваться сообщением независимо от того, в какой форме оно оказалось.
Теперь рассмотрим все эти ситуации на небольшом практическом примере. подробнее
Пример можно посмотреть в демонстрационной базе «Разработка форм, пример 6».
Допустим, у нас есть обработка ПроведениеДокументов. Задача этой обработки – провести (перепровести) выбранный документ некоторым специальным образом, который не требуется для обычного ежедневного учета. То есть при таком проведении помимо «обычных» данных формируются дополнительные данные, требуемые для расчетов с отдельными поставщиками. Алгоритм расчета этих данных сложен, таких поставщиков немного, данные требуются эпизодически. Поэтому существует отдельная обработка для получения этих данных. Наша задача будет заключаться в том, чтобы: ■■ проверить правильность заполнения всех полей в обработке и выдать сообщения, если какие-то поля не заполнены; ■■ выполнить проведение документа «сложным» образом, из обработки, и выдать сообщение, если «что-то не так»; ■■ обеспечить «обычное», ежедневное проведение документа и выдачу сообщений о недостатке списываемых товаров на складе. Обработка имеет реквизит Документ, в котором содержится ссылка на обрабатываемый документ Накладная. Кроме этого, форма обработки имеет реквизит Комментарий, в который должен быть записан произвольный комментарий при интерактивном выполнении обработки (рис. 8.264).
Но могут быть и другие варианты. Например, если точно известно, что сообщение может оказаться только в одной-единственной форме (например, когда оно формируется в этой самой форме), можно не указывать КлючДанных. В этом случае будет считаться, что сообщение относится именно к той форме, в которой оно оказалось. При этом если сообщение должно быть привязано не к реквизиту основного объекта, а к реквизиту формы, также не нужно указывать ПутьКДанным, достаточно указать только Поле. Есть и еще одна ситуация, которая может возникнуть при работе с сообщениями. Может оказаться так, что для сообщения будет указан КлючДанных и Поле. А свойство ПутьКДанным не будет заполнено. В этой ситуации сообщение автоматически заполнит свойство ПутьКДанным именем основного реквизита формы. Той, в которой оно оказалось (если ключ данных совпадает), или той, которая будет открыта при двойном щелчке на сообщении.
322
Рис. 8.264. Реквизиты формы
Документ является реквизитом обработки для того, чтобы была возможность программного запуска обработки без использования ее формы. Профессиональная разработка в системе «1С:Предприятие 8»
Программирование форм Для выполнения нашего алгоритма в форме обработки существует локальная команда ПровестиДокументы, которая вызывает процедуру ПровестиДокументы в модуле формы (листинг 8.46). Листинг 8.46. Обработчик локальной команды формы
&НаКлиенте Процедура ПровестиДокументы(Команда) // Использовать стандартный механизм проверки заполнения, // реализуемый платформой для обработки. Если ПроверитьЗаполнение() Тогда // Выполнить собственный алгоритм обработки данных. НаСервере(); КонецЕсли; КонецПроцедуры
В этой процедуре сначала вызывается стандартная проверка заполнения, реализуемая платформой, – Если ПроверитьЗаполнение() Тогда.
Сначала исключаем комментарий из массива проверяемых реквизитов. Затем, если комментарий «пустой», формируем и выводим сообщение. В сообщении мы заполняем только свойство Поле. В данном случае активной формой будет форма обработки, и сообщение попадет в нее. Поэтому достаточно указать лишь поле, остальные свойства сообщения не понадобятся (рис. 8.265, 8.266).
Рис. 8.265. Заполнение свойств сообщения
Метод формы ПроверитьЗаполнение() вызывает сначала проверку заполнения в форме, а затем – в объекте обработки. Аналогично тому, как выполняется проверка заполнения при интерактивной записи объектов из формы. подробнее
Раздел «Проверка заполнения», стр. 310.
Сначала будет вызвано событие Обработка проверки заполнения на сервере у формы. В обработчике этого события нам нужно проверить заполненность реквизита формы Комментарий и вывести сообщение (листинг 8.47). Листинг 8.47. Обработчик события «Обработка проверки заполнения на сервере»
&НаСервере Процедура ОбработкаПроверкиЗаполненияНаСервере(Отказ, ПроверяемыеРеквизиты) ИндексКомментария = ПроверяемыеРеквизиты.Найти("Комментарий"); Если ИндексКомментария <> Неопределено Тогда ПроверяемыеРеквизиты.Удалить(ИндексКомментария); КонецЕсли; Если СокрЛП(Комментарий) = "" Тогда Сообщение = Новый СообщениеПользователю; Сообщение.Поле = "Комментарий"; Сообщение.Текст = "Нужно написать комментарий."; Сообщение.Сообщить(); Отказ = Истина; КонецЕсли; КонецПроцедуры
Том 1
Рис. 8.266. Сообщение, привязанное к реквизиту формы
После того как будет обработано событие в форме, платформа вызовет аналогичное событие у объекта обработки – Обработка проверки заполнения. В обработчике этого события нам нужно проверить заполненность реквизита обработки Документ и вывести сообщение (листинг 8.48). Листинг 8.48. Обработчик события «Обработка проверки заполнения»
Процедура ОбработкаПроверкиЗаполнения(Отказ, ПроверяемыеРеквизиты) ПроверяемыеРеквизиты.Очистить(); Если Документ = Документы.Накладная.ПустаяСсылка() Тогда Сообщение = Новый СообщениеПользователю; Сообщение.Поле = "Документ"; Сообщение.УстановитьДанные(ЭтотОбъект); Сообщение.Текст = "Нужно выбрать какую-нибудь накладную."; Сообщение.Сообщить(); Отказ = Истина; КонецЕсли; КонецПроцедуры
323
Глава 8. Разработка форм Сначала мы очищаем массив проверяемых реквизитов, т. к. все проверки будем выполнять самостоятельно. Затем проверяем заполненность реквизита Документ, и если он не заполнен (Если Документ = Документы.Накладная.ПустаяСсылка()), формируем и выводим сообщение. Тут все уже несколько сложнее, чем в форме. Проверка заполнения в модуле обработки может быть вызвана и из формы обработки, и программно, без использования формы обработки. А это значит, что формируемое сообщение может попасть не только в форму обработки, для которой оно предназначено, но и в какую-нибудь другую форму.
Рис. 8.267. Заполнение свойств сообщения
Поэтому нужно заполнить все свойства сообщения, чтобы, попав в другую форму, сообщение «знало», что нужно открыть форму обработки и именно в ней спозиционироваться возле поля Документ. Свойство Поле мы заполняем самостоятельно – Сообщение.Поле = "Документ". А для того чтобы заполнить два других свойства, КлючДанных и ПутьКДанным, мы воспользуемся возможностями, предоставляемыми платформой. Дело в том, что при выполнении некоторых определенных действий платформа запоминает соответствие объекта, который отображается в форме, и имени основного реквизита этой формы. Например, когда в форме объекта выполняется стандартная команда записи или когда в форме вызывается метод ПроверитьЗаполнение(). «Запоминанием» этого соответствия занимается расширение формы, определяемое основным реквизитом. Соответствие запоминается для того, чтобы в модуле объекта можно было бы им воспользоваться для правильного формирования сообщения. Ведь в общем случае, попав в модуль объекта, мы не знаем, из какой формы мы в него попали, не знаем, как в этой форме называется основной реквизит формы. Поэтому прежде чем перейти в модуль объекта, платформа запоминает, какие данные (ссылку) содержит основной реквизит формы и как он называется. В случае с обработкой платформа запомнит только имя основного реквизита формы обработки. В платформе не существует типа ссылки на обработку, поэтому запоминать просто нечего. Затем в модуле обработки мы просто пишем Сообщение.УстановитьДанные(ЭтотОбъект); и у сообщения будет установлено свойство ПутьКДанным – "Объект". КлючДанных останется незаполненным, так как заполнить его просто нечем. В результате сообщение окажется в форме обработки с незаполненным свойством КлючДанных. Поэтому платформа будет пытаться (и это ей удастся) привязать его к форме обработки, используя значения свойств ПутьКДанным и Поле (рис. 8.267, 8.268).
324
Рис. 8.268. Сообщение, привязанное к реквизиту обработки
Поскольку оба раза при проверке заполнения мы устанавливали параметр Отказ обработчиков в значение Истина, после обработки события Обработка проверки заполнения дальнейшее выполнение действий останавливается. Метод ПроверитьЗаполнение() возвращает Ложь, и наша процедура НаСервере() не выполняется. Пока на этом остановимся и обратим внимание на документ Накладная. В модуле документа в процедуре ОбработкаПроведения находится код, который формирует движения документа. А после него для примера формируются и выводятся два сообщения. Предполагается, что наша накладная имеет «два повода» для проведения – обычное повседневное проведение и «специальное» проведение, выполняемое только из этой обработки. Чтобы отличать, каким образом в данный момент проводится накладная, в модуле накладной существует экспортируемая переменная ПроведениеИзОбработки (листинг 8.49). Листинг 8.49. Экспортируемая переменная
Перем ПроведениеИзОбработки Экспорт;
При любом проведении значение этой переменной сначала устанавливается в Ложь (последняя строка модуля – тело модуля), листинг 8.50. Листинг 8.50. Инициализация экспортируемой переменной
ПроведениеИзОбработки = Ложь;
Профессиональная разработка в системе «1С:Предприятие 8»
Программирование форм Это значение будет говорить нам о том, что проведение документа выполняется не из обработки. И в этом случае мы контролируем остатки и выводим сообщение, если товара на складе недостаточно (листинг 8.51). Листинг 8.51. Сообщение в случае, когда проведение выполняется не из обработки
// Проверить, есть ли на складе достаточное количество товара // в случае оперативного проведения. // ... Сообщение = Новый СообщениеПользователю; Сообщение.Поле = "Товары[0].Количество"; Сообщение.Текст = "На складе есть только 5 единиц товара."; Сообщение.УстановитьДанные(ЭтотОбъект); Сообщение.Сообщить(); Отказ = Истина;
Здесь, как и в модуле обработки, мы используем возможность платформы самостоятельно устанавливать данные для сообщения (Сообщение.УстановитьДанные(ЭтотОбъект);).
Рис. 8.270. Сообщение, привязанное к реквизиту документа
Если проведение документа будет выполняться стандартной командой из формы документа, то расширение формы документа автоматически установит соответствие объекта и реквизита формы. Таким образом, КлючДанных и ПутьКДанным будут заполнены, и сообщение будет привязано к нужному полю (рис. 8.269, 8.270).
Рис. 8.271. Сообщение в основном окне приложения
При двойном щелчке на этом сообщении будет открыта форма накладной, т. к. у сообщения установлен КлючДанных. Платформа автоматически заполнит свойство ПутьКДанным именем основного реквизита формы и правильно привяжет его к полю Количество (рис. 8.272, 8.273).
Рис. 8.269. Заполнение свойств сообщения
Если проведение будет выполняться, например, стандартной командой из формы списка (Все действия – Провести), то такого соответствия автоматически установлено не будет. Выполнение метода Сообщение.УстановитьДанные(ЭтотОбъект); приведет лишь к тому, что будет установлено свойство КлючДанных – ссылка на объект документа. Свойство ПутьКДанным останется незаполненным. При этом сообщение попадет в основное окно приложения (рис. 8.271). Том 1
Рис. 8.272. Заполнение свойств сообщения
325
Глава 8. Разработка форм В модуле документа, в обработке проведения, анализируем значение переменной ПроведениеИзОбработки, выполняем уже другие проверки и выводим другое сообщение, не такое, как при обычном проведении (листинг 8.54). Листинг 8.54. Сообщение в случае проведения из обработки
Рис. 8.273. Сообщение, привязанное к реквизиту формы
Таким образом, если при формировании сообщения мы используем метод УстановитьДанные() при любом способе проведения документа, сообщение отработает правильно, в какой бы форме оно не оказалось. Теперь вернемся к обработке, заполним поля документа и комментарий и нажмем кнопку Провести документы. В модуле формы будет вызвана процедура НаСервере(), листинг 8.52.
Если ПроведениеИзОбработки Тогда // Проверить, подходит ли поставщик для выполнения задуманной операции. Сообщение = Новый СообщениеПользователю; Сообщение.Поле = "Документ"; Сообщение.ПутьКДанным = "Объект"; Сообщение.Текст = "Выбран неудачный документ. Расчеты с этим поставщиком были прекращены в прошлом году."; Сообщение.Сообщить();
Мы хотим, чтобы это сообщение отображалось не в форме документа, а в форме обработки, и было привязано к полю Документ. Поэтому в свойстве Поле мы указываем "Документ", а в свойстве ПутьКДанным – Объект, так как Документ – это подчиненный реквизит объекта обработки. КлючДанных мы не указываем (рис. 8.274).
Листинг 8.52. Серверная процедура в модуле формы обработки
&НаСервере Процедура НаСервере() // Получить объект документа. ОбъектДокумента = Объект.Документ.ПолучитьОбъект(); // Провести документ. ОбъектДокумента.ПроведениеИзОбработки = Истина; ОбъектДокумента.Записать(РежимЗаписиДокумента.Проведение); КонецПроцедуры
В ней мы получаем объект документа от ссылки, хранящейся в реквизите Документ. Затем устанавливаем значение экспортируемой переменной ПроведениеИзОбработки модуля документа в Истина. В процедуре обработки проведения документа это будет означать для нас, что проведение выполняется «сложным» способом, из обработки. И после этого вызываем проведение документа в неоперативном режиме (листинг 8.53). Листинг 8.53. Проведение документа в неоперативном режиме
ОбъектДокумента.Записать(РежимЗаписиДокумента.Проведение);
326
Рис. 8.274. Заполнение свойств сообщения
Во-первых, у нас его нет. Ключом данных должна быть ссылка на объект обработки, а такой тип в платформе отсутствует. Вообще говоря, это не очень хорошо, т. к. снижает универсальность нашего сообщения. Если оно попадет не в форму обработки, то не сможет правильно отработать. С другой стороны, вероятность того, что оно попадет не в форму обработки, очень мала. Если предполагается, что обработка будет использоваться только интерактивно, тогда можно допустить, что в другую форму это сообщение не попадет никогда. А раз так, то свойств Поле и ПутьКДанным будет достаточно для того, чтобы правильно привязать сообщение в форме обработки. Проверим (рис. 8.275). При использовании сообщений всегда следует помнить о том, что присутствие сообщений в форме не препятствует ее закрытию. Профессиональная разработка в системе «1С:Предприятие 8»
Программирование форм ПРИМЕЧАНИЕ
Пример использования этого объекта будет рассмотрен далее (стр. 328).
Рис. 8.275. Сообщение, привязанное к реквизиту обработки
Поэтому если вывод сообщений используется в стандартных процедурах проверки заполнения, всегда следует отказываться от продолжения работы. Для этого параметр Отказ этих обработчиков нужно устанавливать в значение Истина. В других случаях следует самостоятельно заботиться о том, чтобы форма не была закрыта при появлении в ней сообщений, например, анализируя какой-нибудь служебный реквизит объекта в процедуре формы ПередЗакрытием().
Способы информирования пользователя Начав говорить о сообщениях пользователю, имеет смысл взглянуть более широко на то, какие существуют способы информирования пользователей вообще и в каких ситуациях следует применять тот или иной способ.
■■ сообщения, с которыми нужно ознакомиться после окончания некоторого процесса, сообщения о проделанной работе. Такие сообщения могут включать информацию о том, что сделано, ее можно посмотреть, но можно и не смотреть. Для таких сообщений следует использовать метод глобального контекста ПоказатьОповещениеПользователя(). Оповещение выводится в специальном, постепенно затухающем окне и дублируется в информационной панели основного окна приложения (рис. 8.278).
Рис. 8.278. Оповещение пользователя
■■ сообщения, с которыми обязательно нужно ознакомиться до начала или после окончания некоторого процесса. Для вывода таких сообщений хорошо подходит метод Предупреждение(), выводящий на экран модальное окно (рис. 8.279).
Все сообщения, предназначенные пользователю, можно разделить на несколько основных категорий: ■■ сообщения о неудачном окончании некоторого процесса. Такие сообщения возникают тогда, когда возникло некоторое исключение. Они информируют пользователя о причинах неудачи. Для таких случаев рекомендуется использовать объект СообщениеПользователю. Он был подробно рассмотрен в предыдущей главе (рис. 8.276).
Рис. 8.279. Предупреждение
Если не указан тайм-аут, то для продолжения работы обязательно требуется реакция пользователя на это сообщение. Рассмотрим все перечисленные способы на небольшом примере. подробнее
Рис. 8.276. Сообщение пользователю
■■ сообщения, которые отражают ход работы. Такие сообщения нужны для информирования пользователя о текущем этапе работы. Для этого хорошо подходит метод глобального контекста Состояние(). Он выводит на экран панель состояния, снабженную индикатором (рис. 8.277).
Пример можно посмотреть в демонстрационной базе «Разработка форм, пример 7».
Пусть в конфигурации существует справочник Товары, у которого перед записью проверяется заполненность реквизита Наименование. Для этого в модуле объекта, в процедуре ОбработкаПроверкиЗаполнения, используется сообщение пользователю (листинг 8.55, рис. 8.280).
Рис. 8.277. Состояние
Том 1
327
Глава 8. Разработка форм Листинг 8.55. Использование сообщения пользователю
ПроверяемыеРеквизиты.Очистить(); Если СокрЛП(Наименование) = "" Тогда Сообщение = Новый СообщениеПользователю; Сообщение.Поле = "Наименование"; Сообщение.УстановитьДанные(ЭтотОбъект); Сообщение.Текст = "Не заполнено наименование товара!"; Сообщение.Сообщить(); Отказ = Истина; КонецЕсли; Рис. 8.281. Предупреждение Листинг 8.57. Серверная функция
Рис. 8.280. Сообщение пользователю
Кроме
этого,
в
конфигурации
существует
глобальная
команда
ГенерацияТоваров, которая заполняет справочник Товары элементами
в тестовых целях.
Перед началом работы пользователю выдается сообщение о предполагаемых действиях и о том, что он может прервать выполнение этих действий (листинг 8.56). Листинг 8.56. Использование предупреждения
Предупреждение("Будет добавлено 1000 товаров. |Выполнение можно прервать, нажав сочетание клавиш Ctrl + Break", , "Добавление товаров");
Для этого используется предупреждение, которое прерывает дальнейшее выполнение кода до тех пор, пока пользователь не ознакомится с этим сообщением и не нажмет кнопку ОК (рис. 8.281). После этого происходит добавление элементов в справочник Товары. Добавление элементов в справочник может быть выполнено только на сервере, и для этого используется серверная функция НаСервере(). Она добавляет в справочник 100 элементов (листинг 8.57). Для того чтобы пользователь имел возможность прервать процесс добавления элементов в справочник, серверная функция вызывается в цикле несколько раз, то есть добавление элементов выполняется порциями по 100 штук (листинг 8.58).
328
&НаСервере Функция НаСервере(НомерВызова) Для Счетчик = 1 по 100 Цикл ОбъектТовара = Справочники.Товары.СоздатьЭлемент(); ОбъектТовара.Наименование = "Товар_" + Строка(НомерВызова * 100 + Счетчик); ОбъектТовара.Записать(); КонецЦикла; Возврат ОбъектТовара.Ссылка; КонецФункции Листинг 8.58. Вызов серверной функции
Для Счетчик = 0 по 9 Цикл ПоследняяДобавленнаяСсылка = НаСервере(Счетчик); Состояние("Добавление товаров", 10 + Счетчик * 10, "Выполняется автоматическое заполнение справочника Товары", БиблиотекаКартинок.СоздатьЭлементСписка); ОбработкаПрерыванияПользователя(); КонецЦикла;
Каждый раз после выполнения функции проверяется, не нажал ли пользователь комбинацию клавиш Ctrl + Break. Для этого вызывается метод глобального контекста ОбработкаПрерыванияПользователя(). Кроме этого, каждый раз после вызова серверной функции выводится окно состояния, отображающее ход процесса с помощью индикатора (10 + Счетчик * 10), листинг 8.59, рис. 8.282.
Профессиональная разработка в системе «1С:Предприятие 8»
Программирование форм Листинг 8.59. Вывод состояния
Состояние("Добавление товаров", 10 + Счетчик * 10, "Выполняется автоматическое заполнение справочника Товары", БиблиотекаКартинок.СоздатьЭлементСписка);
Рис. 8.282. Состояние
В данном случае состояние используется, во-первых, для того, чтобы информировать пользователя о том, что система выполняет какие-то действия, а во-вторых, для того, чтобы пользователь мог примерно оценить время, оставшееся до окончания действий. Серверная функция возвращает ссылку на последний элемент, добавленный в справочник Товары. Эта ссылка используется для того, чтобы после добавления всех элементов обновить список товаров, расположенный на рабочем столе (листинг 8.60). Листинг 8.60. Обновление списка товаров
// Обновить список товаров на рабочем столе. ОповеститьОбИзменении(ПоследняяДобавленнаяСсылка);
Также эта ссылка используется в оповещении, которое выдается по окончании процесса (листинг 8.61, рис. 8.283). Листинг 8.61. Вывод оповещения пользователя
ПоказатьОповещениеПользователя("Данные заполнены", ПолучитьНавигационнуюСсылку(ПоследняяДобавленнаяСсылка), "Открыть последний добавленный товар", БиблиотекаКартинок.Справочник);
Рис. 8.284. Оповещение в информационной панели
Обновление данных в динамических списках Зачастую запись тех или иных объектов в базу данных выполняется программно, из встроенного языка. Запись в базу данных возможна только на сервере, и в этом случае, естественно, открытые в клиентском приложении формы ничего не знают о том, что данные в базе данных изменились. А ведь эти формы могут содержать списки тех объектов, которые мы изменяли или добавляли в базу данных. Сама по себе информация в этих списках не обновится. Разработчик должен предпринять специальные действия для того, чтобы динамические списки, существующие в открытых формах, перечитали данные и начали отображать новую, измененную информацию. Для этого существует несколько способов, которые можно применять в зависимости от конкретной ситуации. Рассмотрим их по порядку, от наиболее универсального к менее универсальному. подробнее
Пример можно посмотреть в демонстрационной базе «Разработка форм, пример 8», обработка ВариантыОбновления.
Метод «ОповеститьОбИзменении()» Рис. 8.283. Оповещение во всплывающем окне
Ссылка позволяет открыть форму последнего добавленного товара сразу же, из оповещения, или позже, из информационной панели основного окна (рис. 8.284). Сообщение о том, что система закончила выполнение действий, является чисто информационным. В общем случае оно не требует от пользователя никаких действий. Поэтому используется оповещение, исчезающее с экрана в случае отсутствия реакции пользователя. Том 1
Наиболее простым и наиболее частым является использование метода глобального контекста ОповеститьОбИзменении(). В этот метод передается единственный параметр – ссылка на объект (или ключ записи), об изменении которого нужно оповестить формы. Этот метод уведомит все динамические списки, расположенные в созданных (не обязательно открытых) на клиенте формах, об изменении этого объекта, и они обновят свои данные. Но есть особенность: этот метод не обновит те динамические списки, у которых не задана основная таблица.
329
Глава 8. Разработка форм Эта процедура возвращает ссылку на тот товар, который был добавлен. А в процессе выполнения некоторого алгоритма на клиенте может выполняться следующий код (листинг 8.63). Листинг 8.63. Использование метода «ОповеститьОбИзменении()»
СсылкаНаНовыйЭлемент = ДобавитьЭлементНаСервере (); ОповеститьОбИзменении(СсылкаНаНовыйЭлемент);
Сначала вызывается серверная процедура и добавляется новый товар, а затем полученная ссылка передается в метод ОповеститьОбИзменении(). В результате во всех открытых формах, отображающих список товаров, появится новый товар. Исключением будет лишь специальная форма списка, в которой для динамического списка не назначена основная таблица (рис. 8.285).
Метод «Оповестить()» Второй способ связан с тем, что мы заранее должны прописать некоторый код в тех формах, в которых нужно что-то обновлять. Но зато тут уже мы можем полностью манипулировать этими формами так, как хочется. Рис. 8.285. Обновление данных методом «ОповеститьобИзменении()»
Преимущество этого способа заключается в том, что нам ничего не нужно знать об открытых формах, не нужно «влезать» внутрь этих форм – платформа все сделает сама. подробнее
Пример можно посмотреть в демонстрационной базе «Разработка форм, пример 8», обработка ВариантыОбновления, локальная команда формы ОповеститьОбИзменении.
Например, в модуле формы может существовать серверная процедура, добавляющая новый элемент в справочник Товары (листинг 8.62). Листинг 8.62. Серверная процедура
&НаСервереБезКонтекста Функция ДобавитьЭлементНаСервере () ОбъектТовара = Справочники.Товары.СоздатьЭлемент(); ОбъектТовара.Наименование = "Новый товар" + Строка(ТекущаяДата()); ОбъектТовара.Записать(); Возврат ОбъектТовара.Ссылка; КонецФункции
330
Суть этого способа заключается в том, что существует метод глобального контекста Оповестить(). Он отсылает оповещение всем созданным (не обязательно открытым) формам. Если в форме написан обработчик события ОбработкаОповещения(), то в этом обработчике можно обработать это сообщение и выполнить нужную модификацию формы. подробнее
Пример можно посмотреть в демонстрационной базе «Разработка форм, пример 8», обработка ВариантыОбновления, локальная команда формы Оповестить.
Например, как и раньше, в серверной процедуре добавляется новый товар. После этого вызывается метод Оповестить(), в котором передается идентификатор события – произвольная строка, по которой в форме можно будет понять, какой алгоритм следует выполнить (листинг 8.64). Листинг 8.64. Использование метода «Оповестить()»
СсылкаНаНовыйЭлемент = ДобавитьЭлементНаСервере (); Оповестить("ОбновитьСписокТоваров");
Во всех формах, в которых может понадобиться обновление списка товаров, создается обработчик события ОбработкаОповещения(). Например, он может выглядеть следующим образом (листинг 8.65). Профессиональная разработка в системе «1С:Предприятие 8»
Программирование форм Листинг 8.65. Обработчик события «Обработка оповещения»
&НаКлиенте Процедура ОбработкаОповещения(ИмяСобытия, Параметр, Источник) Если ИмяСобытия = "ОбновитьСписокТоваров" Тогда Элементы.Список.Обновить(); КонецЕсли; КонецПроцедуры
В результате во всех открытых формах, в которых существует обработчик события ОбработкаОповещения(), появится новый товар. В том числе и в тех формах, которые расположены на рабочем столе (рис. 8.286).
подробнее
Пример можно посмотреть в демонстрационной базе «Разработка форм, пример 8», обработка ВариантыОбновления, локальная команда формы ПолучитьФорму.
Для получения формы используется метод глобального контекста ПолучитьФорму(), листинг 8.66. Листинг 8.66. Получение формы и обновление списка
СсылкаНаНовыйЭлемент = ДобавитьЭлементНаСервере (); Форма = ПолучитьФорму("Справочник.Товары.ФормаСписка"); Форма.Элементы.Список.Обновить();
Так как четвертый параметр в этом методе не указывается, то будет получена уже открытая форма. Затем обновляется список, расположенный в этой форме. В результате в форме списка товаров появится новый товар. Остальные формы останутся без изменений (рис. 8.287).
Рис. 8.286. Обновление данных методом «Оповестить()»
Обновление формы извне Способ, описанный далее, можно использовать тогда, когда нам точно известна форма, в которой нужно что-то обновить, и известно, что эта форма открыта. Идея заключается в том, чтобы получить саму открытую форму, получить список, расположенный в этой форме, и обновить его. Том 1
Рис. 8.287. Обновление данных в конкретном списке
Этот способ имеет два недостатка.
331
Глава 8. Разработка форм Во-первых, нужно точно знать устройство формы, как называется ее таблица, отображающая данные динамического списка. Если по каким-то причинам ее имя изменится, форма перестанет обновляться. Во-вторых, таким способом не удастся обновить формы, расположенные в основном окне приложения: на рабочем столе или открытые в разделах прикладного решения, так как их нельзя получить из встроенного языка.
таблица будет иметь стандартное имя Список, да и хорошо бы проверить тип объектов, которые отображаются в этом списке… Поэтому здесь просто приведен один из возможных вариантов тех действий, которые требуется выполнить в открытых формах. В результате в форме списка товаров и в специальной форме появится новый товар. Формы, открытые в основном окне приложения, останутся без изменений (рис. 8.288).
Коллекция окон Последний, четвертый, способ удобен тогда, когда нужно выполнить одинаковые действия со всеми отрытыми формами. Можно получить коллекцию открытых окон приложения, обойти ее и от каждого окна попробовать получить содержащуюся в нем форму. Затем, как и в предыдущем способе, обновить список, расположенный в этой форме. подробнее
Пример можно посмотреть в демонстрационной базе «Разработка форм, пример 8», обработка ВариантыОбновления, локальная команда формы ПолучитьОкна.
Коллекцию открытых окон приложения можно получить с помощью метода глобального контекста ПолучитьОкна(), листинг 8.67. Листинг 8.67. Работа с коллекцией окон
СсылкаНаНовыйЭлемент = ДобавитьЭлементНаСервере(); КоллекцияОкон = ПолучитьОкна(); Для Каждого Окно из КоллекцияОкон Цикл Если НЕ Окно.Основное Тогда // От основного окна нельзя получить формы. Форма = Окно.ПолучитьСодержимое(); СписокТоваров = Форма.Элементы.Найти("Список"); // Если есть элемент Список, обновить его. Если СписокТоваров <> Неопределено Тогда СписокТоваров.Обновить(); КонецЕсли; КонецЕсли; КонецЦикла;
В этом примере, получив очередное окно, мы проверяем, что это окно не является основным окном приложения (Если НЕ Окно.Основное Тогда). Как уже говорилось выше, от основного окна получить формы не удастся. После этого в полученной форме мы ищем элемент с именем Список и, если он есть, обновляем его. На самом деле алгоритм поиска того, что нужно обновлять, может быть более сложным. Ведь совсем не обязательно
332
Рис. 8.288. Обновление данных в конкретном списке
Оформление списков «1С:Предприятие» позволяет различным образом оформлять данные, представленные в списках. Самые большие возможности оформления предоставляют динамические списки. Для них можно задавать отбор, сортировку, группировать данные по значению и применять условное оформление. Эти возможности доступны разработчику интерактивно в конфигураторе и пользователю, также интерактивно, в режиме 1С:Предприятие. Возможности по оформлению статических списков (табличных частей, таблиц значений, деревьев значений и пр.) значительно меньше. К ним может быть применено только условное оформление, которое разработчик интерактивно задает в конфигураторе. Профессиональная разработка в системе «1С:Предприятие 8»
Программирование форм Однако все упомянутые возможности оформления списков доступны из встроенного языка в режиме 1С:Предприятие. Таким образом, разработчик может не только реализовать собственный алгоритм оформления динамического списка, но и предоставить, например, пользователю возможность задать условное оформление для табличной части документа. Рассмотрим на двух простых примерах, каким образом можно оформить «обычные» и динамические списки.
Динамические списки Для того чтобы познакомиться с возможностями оформления динамического списка, создадим четыре команды, которые в режиме 1С:Предприятие позволят нам задать отбор, порядок, группировку и условное оформление списка документов.
Отбор подробнее
Пример можно посмотреть в демонстрационной базе «Разработка форм, пример 9», форма списка документа Накладная, команда Отбор. Это локальная команда этой формы.
Любое оформление динамических списков возможно на клиенте. Поэтому для программной установки отбора в списке накладных мы будем использовать локальную команду формы списка. Обработчик этой команды выглядит следующим образом (листинг 8.68). Листинг 8.68. Установка отбора динамического списка
&НаКлиенте Процедура Отбор(Команда) Отбор = Список.Отбор.Элементы; Если Отбор.Количество() > 0 Тогда Сообщение = Новый СообщениеПользователю; Сообщение.Текст = "Отбор уже задан. Команда не выполнена."; Сообщение.Сообщить(); Возврат; КонецЕсли; УсловиеОтбора = Отбор.Добавить(Тип("ЭлементОтбораКомпоновкиДанных")); УсловиеОтбора.ЛевоеЗначение = Новый ПолеКомпоновкиДанных("НаКонтроле"); УсловиеОтбора.ВидСравнения = ВидСравненияКомпоновкиДанных.Равно; УсловиеОтбора.ПравоеЗначение = Истина; КонецПроцедуры
Том 1
Список – это реквизит формы, содержащий динамический список. Его свойство Отбор может содержать произвольное количество элементов,
описывающих условия отбора в этом списке. Эти условия могут быть заданы разработчиком в конфигураторе или пользователем в режиме 1С:Предприятие.
Поэтому, прежде чем ставить собственные условия отбора в списке, мы должны каким-то образом обработать ситуацию, когда в списке уже имеются условия отбора. В реальной жизни возможны различные алгоритмы, но, поскольку у нас всего лишь демонстрационный пример, мы поступим просто. Если для динамического списка уже заданы какие-то условия отбора, мы не будем предпринимать никаких действий и предложим пользователю самостоятельно удалить имеющиеся условия отбора (листинг 8.69). Листинг 8.69. Анализ имеющихся условий отбора
Отбор = Список.Отбор.Элементы; Если Отбор.Количество() > 0 Тогда Сообщение = Новый СообщениеПользователю; Сообщение.Текст = "Отбор уже задан. Команда не выполнена."; Сообщение.Сообщить(); Возврат; КонецЕсли;
Если же никаких условий отбора еще не задано, мы зададим одно условие. Для этого в коллекцию элементов отбора добавим новый элемент (листинг 8.70). Листинг 8.70. Добавление нового условия отбора
УсловиеОтбора = Отбор.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
В простом случае отбора может быть перечислено несколько элементов, которые объединяются по условию И. В более сложных случаях отборов несколько элементов могут объединяться в группы, и для каждой группы можно задать собственное условие объединения элементов: И, ИЛИ, НЕ. Таким образом, в коллекции условий отбора могут находиться как элементы, так и группы. В нашем простом примере мы добавляем один элемент, но если вы захотите формировать сложные условия, нужно будет добавлять группы (Тип("ГруппаЭлементовОтбораКомпоновкиДанных")), устанавливать их свойство ТипГруппы и уже в эти группы добавлять отдельные элементы. Итак, после того как элемент добавлен, нужно задать условие отбора.
333
Глава 8. Разработка форм У нашей накладной есть булев реквизит НаКонтроле, который проставляется для накладных, требующих особого внимания (рис. 8.289).
Рис. 8.290. Полный список накладных
После того как мы выполним команду Отбор, в списке останутся только накладные на контроле (рис. 8.291).
Рис. 8.289. Реквизит «НаКонтроле»
Мы хотим, чтобы в результате наших действий в списке отображались только те накладные, которые на контроле. Условие отбора задается с помощью свойств ЛевоеЗначение, ВидСравнения и ПравоеЗначение. В нашем случае левое значение – это поле НаКонтроле (листинг 8.71). Листинг 8.71. Установка левого значения
УсловиеОтбора.ЛевоеЗначение = Новый ПолеКомпоновкиДанных("НаКонтроле");
Это поле мы создаем конструктором Новый, указывая имя поля. Условие сравнения – равенство. Оно задается с помощью системного перечисления (листинг 8.72).
Рис. 8.291. Накладные на контроле
Если мы откроем настройку списка (Все действия – Настроить список…), то увидим, что появилось условие отбора (рис. 8.292).
Листинг 8.72. Установка вида сравнения
УсловиеОтбора.ВидСравнения = ВидСравненияКомпоновкиДанных.Равно;
Правое значение –
Истина
(листинг 8.73).
Листинг 8.73. Установка правого значения
УсловиеОтбора.ПравоеЗначение = Истина;
Таким образом должны быть отобраны только те накладные, у которых поле НаКонтроле содержит значение Истина. Запустим конфигурацию в режиме 1С:Предприятие. Откроется полный список накладных (рис. 8.290).
334
Рис. 8.292. Отбор в настройках динамического списка
Профессиональная разработка в системе «1С:Предприятие 8»
Программирование форм Это то самое условие, которое мы добавили из встроенного языка. Пользователь может его изменить, отключить, удалить. Если требуется сделать это условие недоступным и невидимым для пользователя, то в обработчик команды Отбор нужно добавить следующую строчку кода (листинг 8.74). Листинг 8.74. Установка недоступности для пользователя условия отбора
УсловиеОтбора.РежимОтображения = РежимОтображенияЭлементаНастройкиКомпоновкиДанных.Недоступный;
Сортировка Подробнее
Пример можно посмотреть в демонстрационной базе «Разработка форм, пример 9», форма списка документа Накладная, команда Сортировка. Это локальная команда этой формы.
Для сортировки динамического списка будем использовать локальную команду формы со следующим текстом (листинг 8.75).
задано платформой. Мы будем отключать его использование и добавлять собственное условие. Если условий несколько, сообщим об этом пользователю и не будем выполнять никаких действий (листинг 8.76). Листинг 8.76. Анализ имеющихся условий сортировки
Сортировка = Список.Порядок.Элементы; Если Сортировка.Количество() = 1 Тогда Сортировка[0].Использование = Ложь; ИначеЕсли Сортировка.Количество() > 1 Тогда Сообщение = Новый СообщениеПользователю; Сообщение.Текст = "Уже задано несколько условий сортировки. Команда не выполнена."; Сообщение.Сообщить(); Возврат; КонецЕсли;
После этого добавляем свое новое условие сортировки (листинг 8.77). Листинг 8.77. Добавление нового условия сортировки
Листинг 8.75. Установка сортировки динамического списка
УсловиеСортировки = Сортировка.Добавить(Тип("ЭлементПорядкаКомпоновкиДанных"));
&НаКлиенте Процедура Сортировка(Команда)
Поскольку мы собираемся самостоятельно указать, по какому полю сортировать список, мы добавляем «обычный» элемент порядка. Но существует возможность добавить и автоэлемент порядка (Тип("АвтоЭлементПорядкаКомпоновкиДанных")). Тогда платформа самостоятельно, на основе имеющегося описания запроса динамического списка определит, по каким полям нужно выполнять сортировку.
Сортировка = Список.Порядок.Элементы;
Если Сортировка.Количество() = 1 Тогда
Сортировка[0].Использование = Ложь;
ИначеЕсли Сортировка.Количество() > 1 Тогда
Сообщение = Новый СообщениеПользователю; Сообщение.Текст = "Уже задано несколько условий сортировки. Команда не выполнена."; Сообщение.Сообщить(); Возврат;
КонецЕсли;
УсловиеСортировки = Сортировка.Добавить(Тип("ЭлементПорядкаКомпоновкиДанных")); УсловиеСортировки.Поле = Новый ПолеКомпоновкиДанных("Склад"); УсловиеСортировки.ТипУпорядочивания = НаправлениеСортировкиКомпоновкиДанных.Убыв;
Итак, после того как новый элемент порядка добавлен, нужно указать поле, по которому будет выполняться сортировка, и направление сортировки. В нашем случае сортировать будем по полю Склад (листинг 8.78). Листинг 8.78. Установка поля, по которому будут выполняться сортировки
УсловиеСортировки.Поле = Новый ПолеКомпоновкиДанных("Склад");
А направление сортировки будет по убыванию значения этого поля (листинг 8.79).
КонецПроцедуры
Листинг 8.79. Установка направления сортировки
Как правило, динамический список всегда содержит некоторое условие сортировки. Например, список документов платформа стандартно сортирует по дате документа.
УсловиеСортировки.ТипУпорядочивания = НаправлениеСортировкиКомпоновкиДанных.Убыв;
Поэтому анализировать имеющиеся условия сортировки мы будем следующим образом. Если условие одно, будем считать, что это условие Том 1
Поскольку поле Склад – это ссылочное поле (содержит ссылки на элементы справочника Склады), то сортировка фактически будет выполняться не по самим значениям ссылок, а по их представлениям, то есть по наименованиям складов, которые являются строками.
335
Глава 8. Разработка форм Запустим конфигурацию в режиме 1С:Предприятие. Откроется список накладных, который стандартно отсортирован платформой по возрастанию даты (рис. 8.293).
Первое – это стандартная сортировка по дате, которую мы отключили, но не удалили. А второе – это то самое условие, которое мы добавили из встроенного языка. Пользователь может его отключить или удалить.
Группировка Подробнее
Пример можно посмотреть в демонстрационной базе «Разработка форм, пример 9», форма списка документа Накладная, команда Группировка. Это локальная команда этой формы.
Для группировки динамического списка мы также будем использовать локальную команду формы (листинг 8.80). Рис. 8.293. Стандартная сортировка списка
После того как мы выполним команду Сортировка, список будет отсортирован по убыванию наименования склада (рис. 8.294).
Рис. 8.294. Сортировка по полю «Склад»
Если мы откроем настройку списка, то увидим, что существуют два условия сортировки (рис. 8.295).
Листинг 8.80. Установка группировки
&НаКлиенте Процедура Группировка(Команда) ГруппировкаСписка = Список.Группировка.Элементы; Если ГруппировкаСписка.Количество() > 0 Тогда Сообщение = Новый СообщениеПользователю; Сообщение.Текст = "Группировка уже задана. Команда не выполнена."; Сообщение.Сообщить(); Возврат; КонецЕсли; ЭлементГруппировки = ГруппировкаСписка.Добавить(Тип("ПолеГруппировкиКомпоновкиДанных")); ЭлементГруппировки.Поле = Новый ПолеКомпоновкиДанных("Поставщик"); Элементы.Список.НачальноеОтображениеДерева = НачальноеОтображениеДерева.НеРаскрывать; КонецПроцедуры
Здесь, так же как и в случае с отбором, для простоты примера не будем выполнять никаких действий, если условия группировки уже заданы (листинг 8.81). Листинг 8.81. Анализ имеющихся условий группировки
Рис. 8.295. Сортировка в настройках динамического списка
336
ГруппировкаСписка = Список.Группировка.Элементы; Если ГруппировкаСписка.Количество() > 0 Тогда Сообщение = Новый СообщениеПользователю; Сообщение.Текст = "Группировка уже задана. Команда не выполнена."; Сообщение.Сообщить(); Возврат; КонецЕсли;
Профессиональная разработка в системе «1С:Предприятие 8»
Программирование форм Если условия группировки не заданы, добавим новый элемент группировки (листинг 8.82). Листинг 8.82. Добавление нового элемента группировки
После того как мы выполним команду Группировка, для каждого поставщика будет создана своя группа, в которой будут находиться документы этого поставщика. Все группы будут свернуты, за исключением той, в которой находится текущая строка списка (рис. 8.297).
ЭлементГруппировки = ГруппировкаСписка.Добавить(Тип("ПолеГруппировкиКомпоновкиДанных"));
Как и в случае с сортировкой, можно использовать автополя группировки, но мы добавим обычное поле, чтобы самостоятельно задать его значение. Группировать список будем по значению поля Поставщик (листинг 8.83). Листинг 8.83. Добавление поля, по которому будет осуществляться группировка
ЭлементГруппировки.Поле = Новый ПолеКомпоновкиДанных("Поставщик");
Дополнительно, для «красоты», укажем, что все группы списка должны быть свернуты. Для этого мы обратимся не к динамическому списку (реквизиту), а к таблице формы, которая этот динамический список отображает. Воспользуемся ее свойством НачальноеОтображениеДерева (листинг 8.84).
Рис. 8.297. Группировка по поставщику
Если мы откроем настройку списка, то увидим, что появилось условие группировки (рис. 8.298).
Листинг 8.84. Установка свойств таблицы
Элементы.Список.НачальноеОтображениеДерева = НачальноеОтображениеДерева.НеРаскрывать;
У системного перечисления, которое мы использовали, есть еще и два других значения: РаскрыватьВерхнийУровень и РаскрыватьВсеУровни. При необходимости можно использовать их. Платформа не предоставляет возможности как-либо скрывать/раскрывать отдельные группы сгруппированного динамического списка из встроенного языка. Это можно сделать только интерактивно. Запустим конфигурацию в режиме 1С:Предприятие. Откроется список накладных, который стандартно представлен в виде линейного списка (рис. 8.296). Рис. 8.298. Группировка в настройках динамического списка
Это то самое условие, которое мы добавили из встроенного языка. Пользователь может его изменить, отключить, удалить.
Условное оформление Подробнее
Пример можно посмотреть в демонстрационной базе «Разработка форм, пример 9», форма списка документа Накладная, команда Условное оформление. Это локальная команда этой формы. Рис. 8.296. Список без группировки
Том 1
Для условного оформления динамического списка будем использовать локальную команду формы со следующим текстом (листинг 8.85).
337
Глава 8. Разработка форм Листинг 8.85. Установка условного оформления
Теперь для этого элемента нужно задать:
&НаКлиенте Процедура УсловноеОформление(Команда)
■■ само оформление, которое будет применяться (цвет, жирность шрифта и пр.); ■■ условие, при выполнении которого это оформление будет применяться; ■■ поля, которые таким образом будут оформлены.
УО = Список.УсловноеОформление.Элементы; Если УО.Количество() > 0 Тогда Сообщение = Новый СообщениеПользователю; Сообщение.Текст = "Условное оформление уже задано. Команда не выполнена."; Сообщение.Сообщить(); Возврат; КонецЕсли; ЭлементУО = УО.Добавить(); // Оформление: цвет фона – светлый лосось. ЭлементУО.Оформление.УстановитьЗначениеПараметра("ЦветФона", WebЦвета.ЛососьСветлый); // Условие: поле НаКонтроле равно Истина. ЭлементУсловия = ЭлементУО.Отбор.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных")); ЭлементУсловия.ЛевоеЗначение = Новый ПолеКомпоновкиДанных("НаКонтроле"); ЭлементУсловия.ВидСравнения = ВидСравненияКомпоновкиДанных.Равно; ЭлементУсловия.ПравоеЗначение = Истина; // Оформляемое поле: Номер. ОформляемоеПоле = ЭлементУО.Поля.Элементы.Добавить(); ОформляемоеПоле.Поле = Новый ПолеКомпоновкиДанных("Номер"); КонецПроцедуры
Здесь также для простоты примера не будем выполнять никаких действий, если условное оформление уже задано (листинг 8.86). Листинг 8.86. Анализ имеющихся элементов условного оформления
УО = Список.УсловноеОформление.Элементы; Если УО.Количество() > 0 Тогда Сообщение = Новый СообщениеПользователю; Сообщение.Текст = "Условное оформление уже задано. Команда не выполнена."; Сообщение.Сообщить(); Возврат; КонецЕсли;
Если же условное оформление не задано, добавим новый элемент, описывающий условное оформление (листинг 8.87). Листинг 8.87. Добавление нового элемента условного оформления
ЭлементУО = УО.Добавить();
338
Оформление задается путем установки значений имеющихся предопределенных параметров оформления. В нашем примере мы указываем, что поля будут выделяться другим цветом фона – светлый лосось (листинг 8.88). Листинг 8.88. Установка оформления, которое будет применяться
// Оформление: цвет фона светлый лосось. ЭлементУО.Оформление.УстановитьЗначениеПараметра("ЦветФона", WebЦвета.ЛососьСветлый);
Для задания условия, при котором будет применяться оформление, мы используем уже знакомый нам по первому примеру отбор компоновки данных. В коллекцию условий отбора добавим новый элемент и зададим для него левое значение, вид сравнения и правое значение (листинг 8.89). Листинг 8.89. Добавление условий, при которых будет применяться оформление
// Условие: поле НаКонтроле равно Истина. ЭлементУсловия = ЭлементУО.Отбор.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных")); ЭлементУсловия.ЛевоеЗначение = Новый ПолеКомпоновкиДанных("НаКонтроле"); ЭлементУсловия.ВидСравнения = ВидСравненияКомпоновкиДанных.Равно; ЭлементУсловия.ПравоеЗначение = Истина;
В результате оформление будет применяться в тех строках, где поле НаКонтроле имеет значение Истина. То есть мы «подсветим» документы, требующие особого внимания. В заключение укажем, какие поля будут «подсвечиваться». Если не указывать ничего, то будет «подсвечена» вся строка. Но мы добавим новое поле в коллекцию оформляемых полей и укажем, что оформляться будет только одно поле – Номер (листинг 8.90). Листинг 8.90. Установка оформляемого поля
// Оформляемое поле: Номер. ОформляемоеПоле = ЭлементУО.Поля.Элементы.Добавить(); ОформляемоеПоле.Поле = Новый ПолеКомпоновкиДанных("Номер");
Запустим конфигурацию в режиме 1С:Предприятие. Откроется список накладных, который стандартно не содержит никакого условного оформления (рис. 8.299).
Профессиональная разработка в системе «1С:Предприятие 8»
Программирование форм
Табличная часть Возможность условного оформления нединамических списков мы рассмотрим на примере табличной части документа. Будем выделять те строки документа, в которых количество товара больше 10. Подробнее
Пример можно посмотреть в демонстрационной базе «Разработка форм, пример 9», форма документа Накладная, команда Условное оформление. Это локальная команда этой формы. Рис. 8.299. Список без условного оформления
После того как мы выполним команду Условное оформление, номера документов 2 и 5 будут выделены цветом фона. Именно эти документы находятся на контроле (рис. 8.300).
При оформлении нединамических списков есть несколько особенностей. Во-первых, для динамических списков условное оформление являлось свойством самого реквизита формы. Чтобы оформить нединамические списки, нужно использовать условное оформление самой формы. Во-вторых, задать оформление динамического списка можно было прямо на клиенте. Условное же оформление формы можно задать только на сервере. В остальном программная работа с условным оформлением нединамических списков ничем не отличается от рассмотренного выше примера. Для того чтобы оформить табличную часть накладной, создадим локальную команду формы, в которой вызовем контекстную серверную процедуру (листинг 8.91). Листинг 8.91. Вызов серверной процедуры для оформления формы
Рис. 8.300. Условное оформление списка
Если мы откроем настройку списка, то увидим, что появилось условное оформление (рис. 8.301).
&НаКлиенте Процедура УсловноеОформление(Команда) ОформитьНаСервере(); КонецПроцедуры
А в серверной (листинг 8.92).
процедуре
выполним
условное
оформление
Листинг 8.92. Условное оформление формы
Рис. 8.301. Условное оформление в настройках динамического списка
Это то самое условие, которое мы добавили из встроенного языка. Пользователь может его изменить, отключить, удалить. Том 1
&НаСервере Процедура ОформитьНаСервере() Если УсловноеОформление.Элементы.Количество() > 0 Тогда Сообщение = Новый СообщениеПользователю; Сообщение.Текст = "Условное оформление уже задано. Команда не выполнена"; Сообщение.Сообщить(); Возврат; КонецЕсли; ЭлементУО = УсловноеОформление.Элементы.Добавить();
339
Глава 8. Разработка форм // Оформление: цвет фона – зеленая лужайка. ЭлементУО.Оформление.УстановитьЗначениеПараметра("ЦветФона", WebЦвета.ЗеленаяЛужайка); // Условие: количество в табличной части больше 10. ЭлементУсловия = ЭлементУО.Отбор.Элементы. Добавить(Тип("ЭлементОтбораКомпоновкиДанных")); ЭлементУсловия.ЛевоеЗначение = Новый ПолеКомпоновкиДанных("Объект.Товары.Количество"); ЭлементУсловия.ВидСравнения = ВидСравненияКомпоновкиДанных.Больше; ЭлементУсловия.ПравоеЗначение = 10; // Оформляемое поле: товар в табличной части. ОформляемоеПоле = ЭлементУО.Поля.Элементы.Добавить(); ОформляемоеПоле.Поле = Новый ПолеКомпоновкиДанных("ТоварыТовар"); КонецПроцедуры
Из особенностей здесь можно сказать об именах полей, которые используются в условии оформления и в коллекции оформляемых полей. В динамических списках не вызывает затруднений указать правильное имя поля. Как правило, имена полей в реквизите (динамическом списке) и в таблице совпадают. Так было в предыдущем примере (рис. 8.302).
Рис. 8.303. В условии оформления указывается поле реквизита формы
А в коллекции оформляемых полей нужно указывать имя поля таблицы – ТоварыТовар (листинг 8.94, рис. 8.304). Листинг 8.94. В коллекции оформляемых полей указывается имя поля таблицы
ОформляемоеПоле.Поле = Новый ПолеКомпоновкиДанных("ТоварыТовар");
Рис. 8.302. Имена реквизитов и элементов в динамическом списке
Мы накладывали условие на поле реквизита НаКонтроле, а оформляли поле таблицы Номер. При этом можно было не задумываться, в каком случае чье поле указывается. В случае с табличной частью имена большей частью не совпадают. Поэтому когда описывается условие оформления, нужно помнить, что указывается поле реквизита формы – Объект.Товары.Количество (листинг 8.93, рис. 8.303). Листинг 8.93. В условии оформления указывается поле реквизита формы
ЭлементУсловия.ЛевоеЗначение = Новый ПолеКомпоновкиДанных("Объект.Товары.Количество");
340
Рис. 8.304. В коллекции оформляемых полей указывается имя поля таблицы
Теперь запустим конфигурацию в режиме 1С:Предприятие и откроем накладную № 6. Ее табличная часть не содержит никакого условного оформления (рис. 8.305). Профессиональная разработка в системе «1С:Предприятие 8»
Программирование форм
Дополнительные колонки в списках Одна из часто встречающихся задач – добавить собственные колонки с дополнительными данными в динамический список или в табличную часть документа. Обе эти задачи решаются относительно просто. В случае с динамическим списком нужно использовать произвольный запрос, который выведет требуемые поля данных. В случае с табличной частью решение может быть более сложным, и оно зависит от того, какие именно данные хочется показать в дополнительных колонках. Рис. 8.305. Табличная часть без условного оформления
После того как мы выполним команду Условное оформление, товар Товар 2 будет выделен цветом фона, потому что количество этого товара больше 10 (рис. 8.306).
Динамический список Подробнее
Пример можно посмотреть в демонстрационной базе «Разработка форм, пример 10», форма списка справочника Товары.
Для примера возьмем стандартную форму списка товаров, созданную конструктором. В этой форме находится динамический список, отображающий товары и некоторые их реквизиты (рис. 8.307).
Рис. 8.306. Оформленная табличная часть
Пользователь не имеет стандартной возможности изменять условное оформление формы, поэтому в данной ситуации он не сможет отключить или удалить условное оформление, добавленное нами. Напоследок хочется сделать еще одно небольшое замечание. В отличие от динамических списков, в условном оформлении формы обязательно нужно указывать оформляемые поля. Если хочется выделить всю строку табличной части, нужно указать все поля, которые в ней содержатся.
Том 1
Рис. 8.307. Динамический список в форме
В списке отображаются только два реквизита справочника: Наименование и Код, хотя на самом деле справочник содержит также реквизиты Артикул и Сорт (рис. 8.308).
341
Глава 8. Разработка форм Платформа, создавая динамический список, включила в него все поля, связанные со справочником Товары, но только два поля поместила в таблицу формы: Наименование и Код. Поэтому наша задача решается очень просто. Нужно перетащить мышью поля Артикул и Сорт в дерево элементов, в таблицу Список (рис. 2.310).
Рис. 8.308. Реквизиты справочника «Товары»
Это стандартное поведение конструктора. Он включает в список только необходимые реквизиты справочника. Другие реквизиты разработчик может добавить самостоятельно, если в этом есть необходимость. У нас как раз есть такая необходимость. Мы хотим дополнительно отображать в этом списке колонки – Артикул и Сорт. Поскольку эти поля являются реквизитами справочника, отобразить их в списке будет очень просто. Если мы раскроем реквизит формы Список, то увидим, что нужные нам поля уже есть в составе этого реквизита (рис. 2.309). Рис. 8.310. Добавление колонок в список
Если теперь запустить конфигурацию в режиме 1С:Предприятие, мы увидим, что в списке товаров отображаются две дополнительные колонки: Артикул и Сорт (рис. 8.311).
Рис. 8.311. Новые колонки в списке
Рис. 8.309. Поля динамического списка
342
Итак, мы рассмотрели простой случай, когда в динамический список нужно добавить дополнительные колонки, отображающие данные реквизитов. Профессиональная разработка в системе «1С:Предприятие 8»
Программирование форм Теперь рассмотрим более сложный случай, когда дополнительные данные не являются реквизитами объекта, содержащегося в основной таблице динамического списка.
После этого состав свойств этого реквизита изменится. Нажав на гиперссылку Настройка списка, мы увидим стандартный текст запроса и сможем его изменить (рис. 8.314).
В демонстрационной базе существует периодический регистр сведений Цены. В нем хранятся цены на товары (рис. 8.312).
Рис. 8.312. Структура регистра «Цены»
Теперь наша задача будет заключаться в том, чтобы в списке товаров показать в отдельной колонке актуальную цену товара. Для этого нам понадобится изменить текст запроса, который содержится в динамическом списке. В свойствах реквизита формы, содержащего динамический список, установим флажок Произвольный запрос (рис. 8.313). Рис. 8.314. Настройка динамического списка
Заменим существующий текст запроса следующим (листинг 8.95). Листинг 8.95. Произвольный запрос динамического списка
ВЫБРАТЬ СправочникТовары.Ссылка, СправочникТовары.ПометкаУдаления, СправочникТовары.Предопределенный, СправочникТовары.Код, СправочникТовары.Наименование, СправочникТовары.Артикул, СправочникТовары.Сорт, ЦеныСрезПоследних.Цена ИЗ РегистрСведений.Цены.СрезПоследних КАК ЦеныСрезПоследних ЛЕВОЕ СОЕДИНЕНИЕ Справочник.Товары КАК СправочникТовары ПО ЦеныСрезПоследних.Товар = СправочникТовары.Ссылка
Рис. 8.313. Свойство «Произвольный запрос»
Том 1
Этим запросом мы дополнительно выводим поле Цена, соединяясь с виртуальной таблицей среза последних этого регистра.
343
Глава 8. Разработка форм Нажмем ОК в диалоге Динамический список, вернемся к форме и развернем реквизит формы Список. Теперь среди его полей появилось поле Цена. Как и раньше, просто перетащим его в таблицу формы (рис. 8.315).
Табличная часть подробнее
Пример можно посмотреть в демонстрационной базе «Разработка форм, пример 10», форма документа Накладная.
Добавление дополнительных колонок в табличную часть также рассмотрим на двух примерах. «Экспериментировать» будем со стандартной формой документа Накладная. Его табличная часть содержит колонки Номер строки, Товар, Количество, Цена и Сумма (рис. 8.317).
Рис. 8.315. Добавление нового поля
Теперь осталось запустить конфигурацию в режиме 1С:Предприятие и убедиться в том, что в списке товаров отображается еще одна дополнительная колонка, содержащая актуальную цену товара (рис. 8.316).
Рис. 8.317. Поля табличной части
Как мы помним из предыдущего примера, у товара есть реквизит Артикул, который нам тоже хотелось бы видеть в табличной части этого документа. Рис. 8.316. Новая колонка в динамическом списке
344
Чтобы добавить Артикул, развернем реквизит формы Объект, развернем его табличную часть Товары, развернем реквизит Товар и увидим интересующее нас поле Артикул. Перетащим его в таблицу формы Товары (рис. 8.318). Профессиональная разработка в системе «1С:Предприятие 8»
Программирование форм Но как быть в том случае, когда добавляемые данные не являются реквизитом, а должны быть получены в результате некоторых вычислений? В этом случае все будет несколько сложнее. В реквизит формы, описывающий табличную часть документа, нужно будет добавить собственное поле и заполнить его данными в определенных обработчиках формы документа. Чтобы не усложнять пример алгоритмами, не относящимися к сути, мы добавим в документ еще один реквизит товара – Сорт. Это позволит нам в обработчиках событий при заполнении собственной колонки данными просто писать Товар.Сорт. В реальной же ситуации тут будет некоторый алгоритм, который по имеющейся ссылке на товар будет получать данные, необходимые для отображения. Итак, сначала в реквизит формы, в табличную часть, добавим собственное поле СортТовара, имеющее тип ссылки на значение перечисления Сорт (рис. 8.320).
Рис. 8.318. Добавление нового поля в таблицу
Теперь останется только запустить конфигурацию в режиме 1С:Предприятие и убедиться, что в табличной части накладной отображается колонка с артикулом товара (рис. 8.319).
Рис. 8.320. Добавление реквизита формы Рис. 8.319. Новая колонка в табличной части
Затем перетащим это поле в таблицу формы Товары (рис. 8.321).
Все просто потому, что добавляемые данные являются реквизитом товара, который сам по себе уже отображается в табличной части документа.
Теперь начнем создавать обработчики событий, в которых колонка СортТовара будет заполняться данными.
Том 1
345
Глава 8. Разработка форм Листинг 8.97. Обработчик события «При изменении»
// Заполнение поля дополнительной колонки при изменении товара в табличной части. &НаКлиенте Процедура ТоварыТоварПриИзменении(Элемент) // Алгоритм, по которому поле дополнительной колонки заполняется данными. ДанныеСтроки = Элементы.Товары.ТекущиеДанные; ДанныеСтроки.СортТовара = ПолучитьСортТовара(ДанныеСтроки.Товар); КонецПроцедуры &НаСервереБезКонтекста Функция ПолучитьСортТовара(Товар) Возврат Товар.Сорт; КонецФункции
Для того чтобы дополнительная колонка была заполнена данными при копировании или при вводе накладной на основании другого объекта, создадим обработчик события формы При создании на сервере (листинг 8.98). Листинг 8.98. Обработчик события «При создании на сервере»
Рис. 8.321. Добавление поля таблицы
Для того чтобы дополнительная колонка была заполнена данными при чтении существующей накладной из базы данных, создадим обработчик события формы При чтении на сервере (листинг 8.96). Листинг 8.96. Обработчик события «При чтении на сервере»
// Заполнение дополнительной колонки при чтении существующего объекта. &НаСервере Процедура ПриЧтенииНаСервере(ТекущийОбъект) // Алгоритм, по которому дополнительная колонка заполняется данными. Для Каждого СтрокаДанных Из Объект.Товары Цикл СтрокаДанных.СортТовара = СтрокаДанных.Товар.Сорт; КонецЦикла КонецПроцедуры
Для того чтобы поле дополнительной колонки было заполнено данными при изменении строки табличной части или при добавлении новой строки, создадим обработчик При изменении поля таблицы ТоварыТовар. Поскольку это клиентский обработчик формы, для получения данных из базы данных будем вызывать серверную процедуру (листинг 8.97).
346
// Заполнение дополнительной колонки при копировании или вводе на основании. &НаСервере Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка) // Алгоритм, по которому дополнительная колонка заполняется данными. Для Каждого СтрокаДанных Из Объект.Товары Цикл Если НЕ ЗначениеЗаполнено(СтрокаДанных.СортТовара) Тогда СтрокаДанных.СортТовара = СтрокаДанных.Товар.Сорт; КонецЕсли; КонецЦикла КонецПроцедуры
И, наконец, предусмотрим ситуацию, когда данные накладной могут быть изменены в процессе ее записи. На этот случай создадим обработчик события формы После записи на сервере (листинг 8.99). Листинг 8.99. Обработчик события «После записи на сервере»
// Заполнение дополнительной колонки, если данные были изменены при записи. &НаСервере Процедура ПослеЗаписиНаСервере(ТекущийОбъект, ПараметрыЗаписи) // Алгоритм, по которому дополнительная колонка заполняется данными. Для Каждого СтрокаДанных Из Объект.Товары Цикл Если НЕ ЗначениеЗаполнено(СтрокаДанных.СортТовара) Тогда СтрокаДанных.СортТовара = СтрокаДанных.Товар.Сорт; КонецЕсли; КонецЦикла КонецПроцедуры
Профессиональная разработка в системе «1С:Предприятие 8»
Программирование форм Теперь осталось запустить конфигурацию в режиме 1С:Предприятие и убедиться, что при любых манипуляциях с накладной данные колонки Сорт заполняются правильно (рис. 8.322).
Для решения этой задачи используется идентификатор (рис. 8.323).
Рис. 8.323. Использование идентификатора для получения строки реквизита
Находясь в таблице формы, узнать идентификатор текущей строки просто. Его возвращает свойство таблицы ТекущаяСтрока. Рис. 8.322. Новая колонка в табличной части
Работа с таблицей в форме При работе с табличной частью документа или просто произвольной таблицей значений, расположенной в форме, зачастую возникает необходимость выборочной или групповой обработки данных, содержащихся в таблице.
Имея этот идентификатор, найти соответствующий ему элемент коллекции, содержащейся в реквизите, тоже просто. У коллекции есть метод НайтиПоИдентификатору(), который вернет нужный элемент коллекции. В обратную сторону все работает похожим образом (рис. 8.324).
Особенность заключается в том, что для выполнения простейших действий с текущей строкой можно не обращаться к данным (реквизиту формы), а получить нужные значения прямо из элемента формы Таблица. Для этого используется свойство таблицы ТекущиеДанные. Однако для выполнения более сложных или массовых операций требуется доступ непосредственно к данным формы, то есть к ее реквизиту. Реквизит формы может иметь разный тип, например, в случае табличной части это будет ДанныеФормыКоллекция, а в случае дерева значений – ДанныеФормыДерево. Сути дела это не меняет. В любом случае реквизит формы является некоторой коллекцией. И когда мы «переходим» от элемента формы, в котором какая-то строка является текущей, к реквизиту, нужно уметь однозначно определить, какой элемент этой коллекции соответствует текущей строке таблицы. И наоборот, зная некоторый элемент коллекции, содержащейся в реквизите, нужно уметь сделать текущей строкой таблицы ту, которая соответствует этому элементу коллекции.
Том 1
Рис. 8.324. Использование идентификатора для установки текущей строки таблицы
Имея некоторый элемент коллекции, содержащейся в реквизите, мы можем получить его идентификатор с помощью его метода ПолучитьИдентификатор(). Останется только присвоить этот идентификатор текущей строке таблицы, чтобы спозиционироваться на нужной строке. Рассмотрим работу с таблицей на двух примерах. Первый будет заключаться в том, чтобы обойти поля таблицы в нужной последовательности, а второй – в том, чтобы сохранить текущую строку таблицы после массированного изменения данных.
347
Глава 8. Разработка форм
Ввод данных по колонкам Сразу оговоримся, что этот пример не совсем хорош. Мы будем использовать сообщения пользователю, но не по назначению. Сообщение пользователю предназначено для того, чтобы прервать действие и указать на элемент формы, содержащий неправильные данные. Мы же будем использовать их для того, чтобы «подсказывать» пользователю, в какой элемент формы необходимо ввести данные. Полезное свойство сообщений заключается в том, что если сообщение выводится с привязкой к элементу формы, то этот элемент сразу же переходит в режим редактирования. Таким образом, пользователю остается всего лишь ввести в него правильные данные. Сценарий, который мы будем реализовывать, имеет под собой вполне реальную основу. Зачастую оператору, вводящему накладную, удобно вводить ее не по строкам, а по столбцам. Сначала вводится вся номенклатура – первая колонка. Затем вводится все количество – вторая колонка. После этого вводится вся цена – третья колонка. В конце контролируется итоговая сумма, и если есть расхождения, они исправляются путем построчной проверки сумм. Такой сценарий удобен тем, что на каждом этапе выполняются однотипные действия, которые легко сверять с бумажным документом. Сначала – подбор номенклатуры. Затем – ввод чисел. подробнее
Пример можно посмотреть в демонстрационной базе «Разработка форм, пример 11», форма документа Накладная, обработчик ТоварыКоличествоПриИзменении() реквизита ТоварыКоличество таблицы.
Для того чтобы реализовать этот сценарий, напишем обработчик события При изменении для того реквизита таблицы, который предполагается заполнять по колонке. В нашем случае таким реквизитом будет ТоварыКоличество (рис. 8.325). Обработчик будет выглядеть следующим образом (листинг 8.100). Листинг 8.100. Обработчик события «При изменении»
СтрокаКоллекции = Объект.Товары.НайтиПоИдентификатору(Элементы.Товары.ТекущаяСтрока); ИндексСтрокиКоллекции = Объект.Товары.Индекс(СтрокаКоллекции); Если Объект.Товары.Количество() > ИндексСтрокиКоллекции + 1 Тогда Сообщение = Новый СообщениеПользователю; Сообщение.КлючДанных = Объект.Ссылка; Сообщение.ПутьКДанным = "Объект"; Сообщение.Поле = "Товары[" + Строка(ИндексСтрокиКоллекции + 1) + "].Количество"; Сообщение.Текст = "Введите количество товара"; Сообщение.Сообщить(); КонецЕсли;
348
Рис. 8.325. Реквизит «ТоварыКоличество»
Сначала мы находим строку коллекции, которая соответствует текущей строке таблицы (листинг 8.101). Листинг 8.101. Получение строки коллекции
СтрокаКоллекции = Объект.Товары.НайтиПоИдентификатору(Элементы.Товары.ТекущаяСтрока);
Затем получаем индекс этой строки в коллекции, т. к. нам нужно будет привязать сообщение к следующей строке таблицы. Следующая строка будет иметь индекс на единицу больше, чем текущая (листинг 8.102). Листинг 8.102. Получение индекса строки коллекции
ИндексСтрокиКоллекции = Объект.Товары.Индекс(СтрокаКоллекции);
После этого мы формируем сообщение пользователю и привязываем его к полю Количество, находящемуся в следующей строке таблицы (листинг 8.103). Листинг 8.103. Привязка сообщения к полю «Количество»
Сообщение.Поле = "Товары[" + Строка(ИндексСтрокиКоллекции + 1) + "].Количество";
Условие Если… нужно для того, чтобы не формировать сообщение в том случае, когда редактируется последняя строка таблицы (листинг 8.104). Профессиональная разработка в системе «1С:Предприятие 8»
Программирование форм Листинг 8.104. Контроль окончания редактируемой таблицы
Листинг 8.105. Сортировка таблицы реквизита
Если Объект.Товары.Количество() > ИндексСтрокиКоллекции + 1 Тогда
&НаКлиенте Процедура СортироватьБезВыгрузки(Команда) Объект.Товары.Сортировать("Цена"); КонецПроцедуры
В результате, если запустить систему в режиме 1С:Предприятие и заполнить номенклатуру в документе Накладная, мы сможем затем последовательно ввести количество номенклатуры, просто набирая его на клавиатуре и нажимая клавишу Ввод. Позиционирование на нужном элементе управления и вход в режим редактирования будут выполняться автоматически. Кроме этого, сообщение в форме всегда будет подсказывать текущую позицию ввода, что удобно для сверки с документом (рис. 8.326).
Рис. 8.326. Позиционирование на следующем поле и подсказка
Сохранение текущей строки после загрузки данных
Допустим, перед выполнением этого действия текущей была, например, третья строка табличной части (рис. 8.327).
Рис. 8.327. Текущая строка перед выполнением сортировки
Тогда после выполнения сортировки эта же строка останется текущей. Она уже не будет третьей, но это будет та же самая строка (рис. 8.328).
Второй пример поможет понять некоторые особенности работы с коллекцией, которая хранит данные таблицы в реквизите формы. Мы будем рассматривать ситуацию, когда эти данные обрабатываются по некоторому непростому алгоритму. В примере мы будем всего лишь сортировать данные, но в реальной жизни это может быть гораздо более сложный алгоритм обработки. подробнее
Пример можно посмотреть в демонстрационной базе «Разработка форм, пример 11», форма документа Накладная, команды Сортировать без выгрузки, Сортировать с выгрузкой (неправильно), Сортировать с выгрузкой (правильно). Это локальные команды формы.
Итак, наша задача – отсортировать табличную часть документа по возрастанию значений в колонке Цена. Самый простой способ – обратиться непосредственно к реквизиту формы и выполнить его метод Сортировать(), листинг 8.105. Том 1
Рис. 8.328. Текущая строка после сортировки
Теперь рассмотрим другой случай. Допустим, для выполнения нашего алгоритма нужно выгрузить данные из реквизита в таблицу значений, обработать их и затем загрузить обратно (команда Сортировать с выгрузкой (неправильно)), листинг 8.106.
349
Глава 8. Разработка форм Листинг 8.106. Сортировка с выгрузкой и загрузкой. Неправильный вариант
Листинг 8.107. Сортировка с выгрузкой и загрузкой. Правильный вариант
&НаКлиенте Процедура СортироватьСВыгрузкойНеправильно(Команда) НаСервереНеправильно(); КонецПроцедуры
&НаКлиенте Процедура СортироватьСВыгрузкойПравильно(Команда) НаСервереПравильно(); КонецПроцедуры
&НаСервере Процедура НаСервереНеправильно() ТЗ = Объект.Товары.Выгрузить(); ТЗ.Сортировать("Цена"); Объект.Товары.Загрузить(ТЗ); КонецПроцедуры
&НаСервере Процедура НаСервереПравильно() СтрокаКоллекции = Объект.Товары.НайтиПоИдентификатору(Элементы.Товары.ТекущаяСтрока); ИндексСтрокиКоллекции = Объект.Товары.Индекс(СтрокаКоллекции); ТЗ = Объект.Товары.Выгрузить(); СтрокаВыгруженнойТаблицы = ТЗ.Получить(ИндексСтрокиКоллекции); ТЗ.Сортировать("Цена"); ИндексСтрокиПослеСортировки = ТЗ.Индекс(СтрокаВыгруженнойТаблицы); Объект.Товары.Загрузить(ТЗ); СтрокаКоллекции = Объект.Товары.Получить(ИндексСтрокиПослеСортировки); Элементы.Товары.ТекущаяСтрока = СтрокаКоллекции.ПолучитьИдентификатор(); КонецПроцедуры
В этом случае результат окажется другим. Строки, как и раньше, будут отсортированы, однако текущей станет первая строка таблицы (рис. 8.329).
Прежде всего, оказавшись на сервере, мы находим ту строку реквизита, которая соответствует текущей строке в таблице формы (листинг 8.108, рис. 8.330). Листинг 8.108. Получение строки в коллекции реквизита
СтрокаКоллекции = Объект.Товары.НайтиПоИдентификатору(Элементы.Товары.ТекущаяСтрока); Рис. 8.329. Сброс текущей строки после сортировки
Так происходит потому, что после загрузки данных в реквизит формы в нем фактически оказывается новая коллекция данных. Они могут не совпадать с теми данными, которые были из реквизита выгружены. Поэтому текущей становится первая строка таблицы, что соответствует стандартному поведению платформы. Однако мы знаем, что данные, которые загружены, те же самые, поменялся лишь порядок строк. Как в этом случае сохранить правильную текущую строку?
Рис. 8.330. Получение строки в коллекции реквизита
Затем мы получаем индекс этой строки (листинг 8.109, рис. 8.331). Листинг 8.109. Получение индекса строки в реквизите
ИндексСтрокиКоллекции = Объект.Товары.Индекс(СтрокаКоллекции);
Рассмотрим третий вариант (команда Сортировать с выгрузкой (правильно)), листинг 8.107. Рис. 8.331. Получение индекса строки в реквизите
350
Профессиональная разработка в системе «1С:Предприятие 8»
Программирование форм Этот индекс понадобится нам в дальнейшем, чтобы найти по нему эту же строку, но уже в таблице значений, в которую мы выгрузим данные (листинг 8.110).
Зная этот индекс, мы можем загрузить данные обратно в реквизит и найти уже в нем ту строку, которая соответствует «текущей» (листинг 8.113, рис. 8.335).
Листинг 8.110. Получение строки в таблице значений
Листинг 8.113. Получение строки в реквизите
ТЗ = Объект.Товары.Выгрузить(); СтрокаВыгруженнойТаблицы = ТЗ.Получить(ИндексСтрокиКоллекции);
Объект.Товары.Загрузить(ТЗ); СтрокаКоллекции = Объект.Товары.Получить(ИндексСтрокиПослеСортировки);
Поскольку в процессе выгрузки мы не преобразовывали таблицу (не изменяли порядок и количество строк), то наша строка в реквизите и аналогичная строка в выгруженной таблице значений будут иметь одинаковые индексы (рис. 8.332).
Рис. 8.335. Получение строки в реквизите
И в заключение, зная «текущую строку» в реквизите, мы можем спозиционировать курсор в таблице формы на нужную нам строку, используя идентификатор (листинг 8.114, рис. 8.336). Рис. 8.332. Получение строки в таблице значений
Теперь, после того как в переменной СтрокаВыгруженнойТаблицы мы запомнили «текущую строку» таблицы значений, можно эту таблицу значений сортировать (листинг 8.111, рис. 8.333).
Листинг 8.114. Позиционирование текущей строки в таблице формы
Элементы.Товары.ТекущаяСтрока = СтрокаКоллекции.ПолучитьИдентификатор();
Листинг 8.111. Сортировка таблицы значений
ТЗ.Сортировать("Цена");
Рис. 8.336. Позиционирование текущей строки в таблице формы
Если теперь посмотреть, как это работает в режиме 1С:Предприятие, мы увидим, что после сортировки текущей остается та строка, которая была ею перед началом действия. Рис. 8.333. Сортировка таблицы значений
Работа с файлами и картинками
В отсортированной таблице значений порядок строк поменялся, и нам нужно определить, какой же индекс стал теперь у нашей «текущей строки» (листинг 8.112, рис. 8.334).
Тонкий клиент и веб-клиент имеют разные возможности по работе с файлами и картинками.
Листинг 8.112. Получение индекса строки в таблице значений
ИндексСтрокиПослеСортировки = ТЗ.Индекс(СтрокаВыгруженнойТаблицы);
Поскольку веб-клиент является типичным веб-приложением, он ничего не знает о локальной файловой системе компьютера, на котором работает. Его собственные стандартные возможности заключаются лишь в том, чтобы поместить один файл на сервер или получить один файл из базы данных. Причем и в одном и в другом случае передается только один файл, и эта операция интерактивна в том смысле, что отсутствуют какие-либо средства программной работы с локальной файловой системой клиентского компьютера.
Рис. 8.334. Получение индекса строки в таблице значений
Том 1
351
Глава 8. Разработка форм Исходный файл для помещения на сервер должен быть выбран пользователем интерактивно, или путь к нему должен быть указан в явном виде. Аналогично и при получении файла из базы данных – его конечное местоположение должно быть выбрано пользователем интерактивно или в явном виде указано в программном коде. Тонкий клиент является Windows-приложением и имеет более широкие возможности работы с файлами. В частности, он поддерживает множественный экспорт и импорт файлов и предоставляет программные средства для работы с локальной файловой системой клиентского компьютера. Для того чтобы веб-клиент смог выполнять такие же действия, на клиентском компьютере необходимо установить и подключить расширение работы с файлами. Это отдельный компонент платформы, его установка и подключение выполняются автоматически средствами встроенного языка. Однако использование расширения работы с файлами снижает общую безопасность системы: в браузере Microsoft Internet Explorer требуется разрешение на установку и использование ActiveX, а в браузере Mozilla Firefox необходимо предоставление расширенных привилегий. Пользователь веб-клиента попросту может не иметь подобных прав, если работа выполняется на публичном компьютере или в организации, использующей определенную политику безопасности.
Рис. 8.337. Помещение файла во временное хранилище
Временное хранилище – это набор служебных файлов кластера, в которых в течение ограниченного времени могут храниться произвольные данные до помещения их в базу данных. На втором этапе, когда пользователь принимает решение сохранить редактируемые данные в базе данных, файл из временного хранилища помещается в какой-либо реквизит, имеющий тип ХранилищеЗначения, и эти данные записываются в базу данных (рис. 8.338).
Поэтому при работе с файлами и картинками следует в обязательном порядке реализовывать алгоритмы, использующие стандартные, общие для тонкого и веб-клиента возможности работы с файлами. Кроме этого, можно реализовать и другую ветку алгоритма, использующую расширенные возможности работы с файлами. Но эта ветка должна быть опциональной, дополнительной. Нельзя обязательно заставлять пользователя использовать расширение работы с файлами, ведь у него может не быть прав на его установку.
Стандартные возможности Стандартные возможности работы с файлами реализуются двумя методами встроенного языка: ПоместитьФайл() и ПолучитьФайл(). – помещает файл с пользовательского компьютера на сервер «1С:Предприятия». ПоместитьФайл()
– получает файл из информационной базы и помещает его на клиентский компьютер. ПолучитьФайл()
Помещение файла в информационную базу выполняется в два этапа. Сначала с помощью метода ПоместитьФайл() файл с клиентского компьютера помещается во временное хранилище (рис. 8.337).
352
Рис. 8.338. Перемещение файла из временного хранилища в базу данных
Если же пользователь отказывается от сохранения редактируемых данных, то файл удаляется из временного хранилища либо автоматически, когда будет закрыта форма, с помощью которой он туда был помещен, либо «вручную», из встроенного языка. Процесс получения файла из информационной базы проще. Он выполняется в один этап, с помощью метода ПолучитьФайл(), рис. 8.339. Файл извлекается из реквизита типа на компьютер пользователя.
ХранилищеЗначения
и помещается
С помощью этого метода можно получить на клиентский компьютер данные не только из базы данных, но и из временного хранилища. При работе с файлами эта возможность имеет малое практическое значение. Зато она востребована, например, в тех случаях, когда временное Профессиональная разработка в системе «1С:Предприятие 8»
Программирование форм хранилище используется для передачи больших массивов данных между двумя формами на клиенте. Такой пример рассмотрен в разделе «Использование временного хранилища для передачи данных между формами», стр. 425.
Чтобы не запутаться в различных методах работы с файлами, все их можно представить в виде следующей иерархии (рис. 8.340).
Рис. 8.340. Методы работы с файлами Рис. 8.339. Извлечение файла из временного хранилища или из базы данных
Получение файла и сохранение его в базе данных
Расширенные возможности
В качестве примера рассмотрим задачу получения файла с клиентского компьютера и сохранения его в реквизите справочника.
Как уже говорилось раньше, в тонком клиенте расширенные возможности работы с файлами доступны всегда. В веб-клиенте для их использования нужно установить и подключить расширение работы с файлами. Здесь мы лишь перечислим эти возможности, так как их практическое использование, как правило, не вызывает трудностей. Установка и подключение расширения работы с файлами выполняются с помощью двух методов встроенного языка: ■■ ■■
УстановитьРасширениеРаботыСФайлами(), ПодключитьРасширениеРаботыСФайлами().
После этого в веб-клиенте становятся доступны методы экспорта/импорта файлов: ■■ ■■
ПоместитьФайлы(), ПолучитьФайлы().
Они аналогичны упоминавшимся ранее методам, но позволяют выполнять операции сразу над группой файлов. Также становятся доступны методы прямого доступа к локальной файловой системе клиентского компьютера: ■■ ■■ ■■ ■■ ■■
подробнее
Пример можно посмотреть в базе «Файлы и картинки», справочник Поставщики.
Пусть в конфигурации существует справочник Поставщики. Для каждого поставщика в базе данных должен храниться произвольный файл, содержащий договор с этим поставщиком. Сразу оговоримся, что рассматриваемый пример упрощен и произвольный файл мы будем хранить в одном из реквизитов самого справочника Поставщики. В реальной работе, как правило, так не поступают. Для хранения больших объемов бинарных данных (файлы, картинки) создаются отдельные объекты конфигурации (справочники или регистры сведений), связанные с данным объектом. Такой подход позволяет исключить обязательное считывание больших объемов информации при считывании самого объекта. Итак,
КопироватьФайл(), НайтиФайлы(), ПереместитьФайл(), СоздатьКаталог(), УдалитьФайлы().
Том 1
справочник Поставбудет содержать два реквизита: ФайлДоговора (для хранения двоичных данных) и ИмяФайлаДоговора (для хранения имени загруженного файла), рис. 8.341. щики
Рис. 8.341. Структура справочника «Поставщики»
353
Глава 8. Разработка форм Имя загруженного файла понадобится нам для того, чтобы иметь возможность в дальнейшем этот файл поместить обратно на компьютер пользователя. Форма элемента справочника Поставщики, помимо данных самого объекта, будет содержать два дополнительных реквизита: ИмяФайлаДоговора и СсылкаНаФайлВоВременномХранилище (рис. 8.342).
Если ПоместитьФайл(АдресВХранилище, , ВыбранноеИмяФайла, , УникальныйИдентификатор) Тогда Файл = Новый Файл(ВыбранноеИмяФайла); ИмяФайлаДоговора = Файл.Имя; СсылкаНаФайлВоВременномХранилище = АдресВХранилище; Модифицированность = Истина; КонецЕсли; КонецПроцедуры
Сначала создаются две служебные переменные АдресВХранилище и ВыбранноеИмяФайла, в которые будут возвращены ссылка на файл в хранилище и полное имя файла, выбранного на компьютере пользователя. Затем выполняется метод ПоместитьФайл(). Он располагается в условии Если потому, что в процессе выбора файла пользователь может, вообще говоря, отказаться от задуманной операции – загрузки файла. Поэтому модификация реквизитов формы выполняется только в том случае, когда операция помещения файла выполнена успешно. В этом случае короткое имя файла помещается в реквизит формы ИмяФайлаДоговора, а ссылка на этот файл во временном хранилище помещается в реквизит формы СсылкаНаФайлВоВременномХранилище. Рис. 8.342. Реквизиты формы элемента справочника «Поставщики»
Ссылка на временное хранилище запоминается в форме потому, что она необходима лишь на момент от загрузки файла до записи объекта в базу данных и не является частью прикладных данных объекта. ИмяФайлаДоговора запоминается в форме для того, чтобы не модифициро-
вать данные объекта до тех пор, пока не начнется запись объекта в базу данных. В принципе можно обойтись и без него, сохранять имя файла прямо в реквизит объекта, но тогда несколько сложнее станет проверка, выполняемая при сохранении файла на компьютер пользователя.
Для того чтобы из полного имени файла получить короткое имя, используется программный объект Файл (листинг 8.116). Листинг 8.116. Получение короткого имени файла
Файл = Новый Файл(ВыбранноеИмяФайла); ИмяФайлаДоговора = Файл.Имя;
Таким образом, после помещения файл окажется во временном хранилище, а в реквизитах формы будет ссылка на него и его имя (рис. 8.343).
Для загрузки файла с диска в информационную базу и для сохранения его на диск в форме созданы две локальные команды: ЗагрузитьСДиска и СохранитьНаДиск. Загрузка файла выполняется следующим образом (листинг 8.115). Листинг 8.115. Загрузка файла
&НаКлиенте Процедура ЗагрузитьСДиска(Команда) АдресВХранилище = ""; ВыбранноеИмяФайла = "";
354
Рис. 8.343. Файл во временном хранилище
Профессиональная разработка в системе «1С:Предприятие 8»
Программирование форм Примечательным здесь является то, что при помещении файла мы указали последний параметр метода ПоместитьФайл(), листинг 8.117. Листинг 8.117. Привязка файла к открытой форме
ПоместитьФайл(АдресВХранилище, , ВыбранноеИмяФайла, , УникальныйИдентификатор)
В качестве этого параметра мы передали уникальный идентификатор нашей открытой формы. Это значит, что файл во временном хранилище будет существовать до тех пор, пока мы не закроем форму. Тогда платформа автоматически удалит его из хранилища. Значит, если пользователь откажется от сохранения изменений, сделанных в форме, нам не нужно заботиться об удалении файла из временного хранилища – платформа это сделает сама.
Листинг 8.120. Помещение файла в реквизит объекта
ДвоичныеДанные = ПолучитьИзВременногоХранилища(СсылкаНаФайлВоВременномХранилище); ТекущийОбъект.ФайлДоговора = Новый ХранилищеЗначения(ДвоичныеДанные, Новый СжатиеДанных(9));
Таким образом, после выполнения этого обработчика мы будем иметь следующую картину (рис. 8.344).
А вот если пользователь решит сохранить сделанные изменения, тогда будут выполнены следующие действия. Сначала на сервере будет вызван обработчик события формы Перед записью на сервере (листинг 8.118). Листинг 8.118. Обработчик события «Перед записью на сервере»
&НаСервере Процедура ПередЗаписьюНаСервере(Отказ, ТекущийОбъект, ПараметрыЗаписи) // Получить файл из хранилища и поместить его в объект. Если ЭтоАдресВременногоХранилища(СсылкаНаФайлВоВременномХранилище) Тогда ДвоичныеДанные = ПолучитьИзВременногоХранилища( СсылкаНаФайлВоВременномХранилище); ТекущийОбъект.ФайлДоговора = Новый ХранилищеЗначения(ДвоичныеДанные, Новый СжатиеДанных(9)); ТекущийОбъект.ИмяФайлаДоговора = ИмяФайлаДоговора; КонецЕсли; КонецПроцедуры
В этом обработчике мы поместим файл из временного хранилища в реквизит записываемого объекта и в другой реквизит объекта поместим имя этого файла. Делать это мы будем не всегда (ведь пользователь может записать объект и не указывая файл договора), а только в том случае, когда реквизит формы действительно хранит ссылку на файл во временном хранилище (листинг 8.119). Листинг 8.119. Проверка того, что навигационная ссылка указывает на временное хранилище
Если ЭтоАдресВременногоХранилища(СсылкаНаФайлВоВременномХранилище) Тогда
В этом случае мы получим из временного хранилища двоичные данные и преобразуем их в объект ХранилищеЗначения, который и поместим в реквизит записываемого объекта (листинг 8.120). Том 1
Рис. 8.344. Файл в реквизите объекта
Затем платформа начнет запись объекта, и его данные будут помещены в базу данных (рис. 8.345).
Рис. 8.345. Запись данных объекта в базу данных
После этого, еще до окончания транзакции записи, на сервере будет вызван обработчик события формы При записи на сервере (листинг 8.121). Листинг 8.121. Обработчик события «При записи на сервере»
&НаСервере Процедура ПриЗаписиНаСервере(Отказ, ТекущийОбъект, ПараметрыЗаписи) // Удалить файл из временного хранилища. Если ЭтоАдресВременногоХранилища(СсылкаНаФайлВоВременномХранилище) Тогда УдалитьИзВременногоХранилища(СсылкаНаФайлВоВременномХранилище); КонецЕсли; КонецПроцедуры
355
Глава 8. Разработка форм В этом обработчике мы «наведем красоту». Так как данные объекта уже записаны в базу данных, полученный файл успешно сохранен, можно удалить из временного хранилища находящийся там файл. Для этого мы используем ссылку, сохраненную в реквизите формы (рис. 8.346).
Затем просто получаем файл на компьютер пользователя (листинг 8.124). Листинг 8.124. Получение файла на компьютер пользователя
ПолучитьФайл(СсылкаНаФайлВИБ, Объект.ИмяФайлаДоговора);
При выполнении этого метода будет открыт стандартный диалог операционной системы, который предложит либо открыть, либо сохранить получаемый файл (рис. 8.347).
Рис. 8.346. Удаление файла из временного хранилища
Теоретически можно это и не делать – платформа все равно автоматически удалит этот файл, когда мы закроем форму. Но в общем случае при интенсивной многопользовательской работе лучше освобождать ресурсы сервера сразу же после того, как необходимость в них исчезает. Процесс получения файла из информационной базы выглядит гораздо проще. Он целиком реализован в обработчике локальной команды формы СохранитьНаДиск (листинг 8.122). Листинг 8.122. Получение файла из информационной базы
&НаКлиенте Процедура СохранитьНаДиск(Команда) Если Объект.ИмяФайлаДоговора = "" Тогда Предупреждение("У поставщика нет сохраненного в базе договора"); Иначе СсылкаНаФайлВИБ = ПолучитьНавигационнуюСсылку(Объект.Ссылка, "ФайлДоговора"); ПолучитьФайл(СсылкаНаФайлВИБ, Объект.ИмяФайлаДоговора); КонецЕсли; КонецПроцедуры
Поскольку имя файла договора мы записываем в реквизит объекта только в момент записи, можно использовать его для определения того, есть ли в объекте сохраненный файл или нет. Чтобы получить файл из информационной базы, нужно иметь навигационную ссылку на этот файл. Навигационную ссылку мы получаем, указывая ссылку на объект и указывая имя реквизита объекта, в котором хранится файл (листинг 8.123). Листинг 8.123. Получение навигационной ссылки на реквизит объекта
Рис. 8.347. Диалог получения файла
Картинка товара в форме При работе с картинками используется тот же самый подход, который был описан выше. Отличие заключается только в том, что в предыдущем примере нам не нужно было никак отображать файл в форме элемента справочника Поставщики. А картинка, как правило, загружается в информационную базу именно для того, чтобы отображать ее в какой-либо форме. подробнее
Пример можно посмотреть в демонстрационной базе «Разработка форм, пример 12», справочник Товары.
Работу с картинками рассмотрим на примере справочника Товары и картинки товара. Ее нужно загрузить, отобразить в форме, сохранить в базе данных и иметь возможность получить из базы данных на клиентский компьютер. Снова сделаем оговорку. Рассматриваемый пример упрощен, и картинку мы будем хранить в одном из реквизитов самого справочника Товары. В реальной работе, как правило, так не поступают, а хранят картинки в отдельных объектах конфигурации, в справочниках или в регистрах сведений. Как и в предыдущем примере, справочник Товары будет содержать два реквизита: ФайлКартинки, чтобы хранить саму картинку, и ИмяФайлаКартинки, чтобы знать ее имя при выгрузке на клиентский компьютер (рис. 8.348).
СсылкаНаФайлВИБ = ПолучитьНавигационнуюСсылку(Объект.Ссылка, "ФайлДоговора");
356
Профессиональная разработка в системе «1С:Предприятие 8»
Программирование форм Загрузка картинки выполняется следующим образом (листинг 8.125). Листинг 8.125. Загрузка картинки
Рис. 8.348. Структура справочника «Товары»
Форма элемента справочника Товары также будет содержать два дополнительных реквизита: ИмяФайлаКартинки и СсылкаНаКартинку (рис. 8.349).
&НаКлиенте Процедура ЗагрузитьСДиска(Команда) АдресВХранилище = ""; ВыбранноеИмяФайла = ""; Если ПоместитьФайл(АдресВХранилище, , ВыбранноеИмяФайла, , УникальныйИдентификатор) Тогда Файл = Новый Файл(ВыбранноеИмяФайла); ИмяФайлаКартинки = Файл.Имя; СсылкаНаКартинку = АдресВХранилище; Модифицированность = Истина; КонецЕсли; КонецПроцедуры
Процедура полностью в листинге 8.115.
аналогична
той,
что
рассматривалась
Как только в реквизит формы мы поместим ссылку на картинку во временном хранилище (СсылкаНаКартинку = АдресВХранилище;), она отобразится в форме (рис. 8.350).
Рис. 8.349. Реквизиты формы справочника «Товары»
ИмяФайлаКартинки в форме нужно для того, чтобы не модифицировать данные объекта до того, как начнется запись в базу данных, а СсылкаНаКартинку будет содержать навигационную ссылку на картинку, находящуюся
во временном хранилище или в базе данных. Этот реквизит связан с полем формы, имеющим вид Поле картинки. Таким образом, платформа будет автоматически отображать в форме ту картинку, которая находится по ссылке, содержащейся в этом реквизите. Для загрузки картинки с диска в информационную базу и для сохранения ее на диск в форме созданы две локальные команды: ЗагрузитьСДиска и СохранитьНаДиск. Том 1
Рис. 8.350. Форма элемента справочника «Товары»
Таким образом, после помещения картинки она окажется во временном хранилище, а в реквизите формы будет ссылка на нее. Связанное с реквизитом поле картинки отобразит ее в форме (рис. 351).
357
Глава 8. Разработка форм Затем платформа начнет запись объекта, и его данные будут помещены в базу данных (рис. 8.353).
Рис. 8.351. Отображение картинки из временного хранилища
Когда пользователь решит сохранить сделанные изменения, на сервере будет вызван обработчик события формы Перед записью на сервере (листинг 8.126). Листинг 8.126. Обработчик события «Перед записью на сервере»
Рис. 8.353. Запись данных справочника в базу данных
После этого, еще до окончания транзакции записи, на сервере будет вызван обработчик события формы При записи на сервере (листинг 8.127).
&НаСервере Процедура ПередЗаписьюНаСервере(Отказ, ТекущийОбъект, ПараметрыЗаписи) // Получить файл из хранилища и поместить его в объект. Если ЭтоАдресВременногоХранилища(СсылкаНаКартинку) Тогда ДвоичныеДанные = ПолучитьИзВременногоХранилища(СсылкаНаКартинку); ТекущийОбъект.ФайлКартинки = Новый ХранилищеЗначения(ДвоичныеДанные, Новый СжатиеДанных(9)); ТекущийОбъект.ИмяФайлаКартинки = ИмяФайлаКартинки; КонецЕсли; КонецПроцедуры
Листинг 8.127. Обработчик события «При записи на сервере»
Этот обработчик также аналогичен тому, что рассматривался в листинге 8.118. Картинка из временного хранилища помещается в объект справочника, туда же помещается имя картинки из реквизита формы (рис. 8.352).
Здесь есть небольшое отличие от того, что мы делали при работе с файлами.
&НаСервере Процедура ПриЗаписиНаСервере(Отказ, ТекущийОбъект, ПараметрыЗаписи) // Удалить файл из временного хранилища. Если ЭтоАдресВременногоХранилища(СсылкаНаКартинку) Тогда УдалитьИзВременногоХранилища(СсылкаНаКартинку); СсылкаНаКартинку = ПолучитьНавигационнуюСсылку(ТекущийОбъект.Ссылка, "ФайлКартинки"); КонецЕсли; КонецПроцедуры
Как и раньше, мы удаляем картинку из временного хранилища, т. к. она нам больше не нужна, она уже сохранена в базе данных. Но так как форма, как и раньше, должна отображать картинку, в реквизит формы мы помещаем навигационную ссылку на картинку, которая теперь находится в базе данных. Для получения навигационной ссылки указываем ссылку на сам объект и имя его реквизита, в котором хранится картинка (листинг 8.128). Листинг 8.128. Получение навигационной ссылки на реквизит объекта
СсылкаНаКартинку = ПолучитьНавигационнуюСсылку(ТекущийОбъект.Ссылка, "ФайлКартинки"); Рис. 8.352. Помещение картинки в реквизит справочника
358
В результате мы будем иметь следующую картину (рис. 8.354).
Профессиональная разработка в системе «1С:Предприятие 8»
Программирование форм
Рис. 8.355. Диалог получения файла
Картинки, используемые для оформления Рис. 8.354. Отображение картинки из реквизита справочника
Теперь осталось сделать последнюю небольшую доработку. Если сейчас закрыть форму и снова открыть сохраненный элемент, мы не увидим картинки в форме, так как в реквизите формы нет ссылки на сохраненную в базе данных картинку. Поэтому создадим обработчик события формы При создании на сервере и в нем поместим в реквизит формы ссылку на картинку (листинг 8.129). Листинг 8.129. Обработчик события «При создании на сервере»
&НаСервере Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка) Если Объект.ИмяФайлаКартинки <> "" Тогда СсылкаНаКартинку = ПолучитьНавигационнуюСсылку(Объект.Ссылка, "ФайлКартинки"); КонецЕсли; КонецПроцедуры
Процесс получения картинки из информационной базы выглядит точно так же, как и в случае работы с файлами (листинг 8.130, рис. 8.355). Листинг 8.130. Получение картинки из информационной базы
&НаКлиенте Процедура СохранитьНаДиск(Команда) Если Объект.ИмяФайлаКартинки = "" Тогда Предупреждение("У товара нет сохраненной в базе картинки"); Иначе СсылкаНаФайлВИБ = ПолучитьНавигационнуюСсылку(Объект.Ссылка, "ФайлКартинки"); ПолучитьФайл(СсылкаНаФайлВИБ, Объект.ИмяФайлаКартинки); КонецЕсли; КонецПроцедуры
Том 1
Кроме картинок, являющихся данными и существующих в виде файлов, в формах могут использоваться картинки, являющиеся элементами оформления. Такие картинки хранятся либо в конфигурации, либо в библиотеке картинок, либо как общие картинки. Существует два способа использования таких картинок: ■■ во-первых, такую картинку можно поместить непосредственно в реквизит формы; ■■ во-вторых, картинку, являющуюся коллекцией, можно поместить в свойство элемента формы Поле, и тогда платформа будет отображать одну из имеющихся картинок коллекции. Здесь возможны два варианта: □□ когда поле связано с реквизитом типа Булево, в коллекции должно быть две картинки: одна из них будет отображаться, когда реквизит имеет значение Истина, другая – когда Ложь; □□ вторая возможность – связать поле с реквизитом типа Число. Тогда будет отображаться та картинка из коллекции, индекс которой содержится в реквизите. Рассмотрим перечисленные способы на примере. подробнее
Пример можно посмотреть в демонстрационной базе «Разработка форм, пример 12», обработка Формирование маршрутных листов.
В качестве «подопытного кролика» будем использовать форму гипотетической обработки ФормированиеМаршрутныхЛистов. В ней пользователь должен выбрать сначала тип автомобилей, для которых будут формироваться маршрутные листы: фуры или «газели». Чтобы тип выбранных автомобилей был хорошо заметен визуально, в левом углу формы мы выведем картинку, иллюстрирующую тот или иной тип автомобиля. Чтобы выполнить эту задачу, создадим в конфигурации две общие картинки: Грузовик и Газель (рис. 8.356).
359
Глава 8. Разработка форм
Рис. 8.358. Реквизит формы «Картинка»
Рис. 8.356. Общие картинки
Затем создадим реквизит формы обработки ТипАвтомобилей типа Число и свяжем его с полем, имеющим вид Поле переключателя (рис. 8.357).
Теперь для поля ТипАвтомобилей создадим обработчик события ПриИзменении(), в котором напишем следующий текст (листинг 8.131). Листинг 8.131. Обработчик события «При изменении»
&НаКлиенте Процедура ТипМашинПриИзменении(Элемент) Если ТипАвтомобилей = 1 Тогда Картинка = БиблиотекаКартинок.Газель; ИначеЕсли ТипАвтомобилей = 2 Тогда Картинка = БиблиотекаКартинок.Грузовик; КонецЕсли; КонецПроцедуры
В зависимости от выбранного значения переключателя мы подставляем в реквизит формы ту или иную картинку. Чтобы при открытии формы были выбраны значения переключателя и картинки, в обработчике события формы При создании на сервере напишем такой код (листинг 8.132). Листинг 8.132. Обработчик события «При создании на сервере» Рис. 8.357. Реквизит формы «ТипАвтомобилей»
Кроме этого, создадим реквизит формы Картинка типа и свяжем его с полем, имеющим вид Поле картинки (рис. 8.358).
360
Картинка
&НаСервере Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка) ТипАвтомобилей = 1; Картинка = БиблиотекаКартинок.Газель; КонецПроцедуры
Профессиональная разработка в системе «1С:Предприятие 8»
Программирование форм В результате после открытия формы она будет иметь следующий вид (рис. 8.359).
Рис. 8.361. Картинка «Внимание»
Если экспедитор требуется, будем показывать восклицательный знак. Если экспедитор не нужен, будем показывать пустую картинку. Затем создадим реквизит формы СписокАвтомобилей (ТаблицаЗначений) и ее колонки: Автомобиль (Строка) и НуженЭкспедитор (Булево), рис. 8.362. Рис. 8.359. Вид формы после открытия
Если изменить значение переключателя, то изменится и отображаемая в форме картинка (рис. 8.360).
Рис. 8.360. Вид формы после переключения типа автомобилей
Теперь займемся списком автомобилей. Кроме идентификатора автомобиля в этом списке указывается, нужен ли на данный автомобиль экспедитор или нет. Чтобы визуально быстро выделять автомобили, на которые нужен экспедитор, мы будем использовать пиктограмму, выводимую в первой колонке списка. Сначала добавим в общие картинки картинку Внимание. Она является коллекцией, состоящей из двух картинок: восклицательного знака и пустой картинки (рис. 8.361).
Рис. 8.362. Реквизиты «Автомобиль» и «НуженЭкспедитор»
Реквизит НуженЭкспедитор свяжем сразу с двумя полями таблицы формы. Во-первых, с полем СписокАвтомобилейНуженЭкспедитор, имеющим вид Поле флажка. В этом поле мы и будем устанавливать желаемое значение. Во-вторых, с полем СписокАвтомобилейКартинка, имеющим вид Поле картинки. В этом поле будет отображаться одна из двух пиктограмм. Чтобы поле СписокАвтомобилейКартинка «знало», где взять пиктограммы, в его свойстве КартинкаЗначений укажем созданную нами общую картинку Внимание (рис. 8.363).
Том 1
361
Глава 8. Разработка форм Для этого добавим в конфигурацию еще одну общую картинку Оповещения. Она также является коллекцией картинок (рис. 8.365).
Рис. 8.365. Картинка «Оповещения»
Первая картинка в коллекции – пустая, остальные символизируют определенный вид оповещения. Также добавим (рис. 8.366).
в
конфигурацию
перечисление
ВидыОповещений
Рис. 8.363. Свойство «Картинка значений»
В результате, если в реквизите НуженЭкспедитор будет значение Истина, отобразится первая картинка из коллекции. Если Ложь – вторая, пустая (рис. 8.364).
Рис. 8.366. Перечисление «ВидыОповещений»
После этого в таблицу значений в форме добавим два реквизита. Рис. 8.364. Отображение картинки в форме
Теперь рассмотрим последний способ работы с картинками. В списке автомобилей желательно также указывать, есть ли необходимость оповещать клиента о предстоящей доставке груза, и если есть – указывать конкретный способ оповещения: по телефону, по электронной почте и т. д. При этом хочется видеть визуальные отметки о том или ином виде оповещения.
362
Первый реквизит – ОповеститьКлиента (с типом перечисления ВидыОповещения). Свяжем его с полем таблицы СписокАвтомобилейОповеститьКлиента (рис. 8.367). В этом поле мы будем устанавливать нужное значение перечисления. Второй реквизит – НомерОповещения типа Число. Его свяжем с реквизитом таблицы СписокАвтомобилейКартинкаОповещения, имеющим вид Поле картинки. В этом поле будет отображаться одна из выбранных пиктограмм. В его свойстве КартинкаЗначений выберем нашу общую картинку Оповещения. Профессиональная разработка в системе «1С:Предприятие 8»
Программирование форм ДанныеСтроки.НомерОповещения = 5; ИначеЕсли ДанныеСтроки.ОповеститьКлиента.Пустая() Тогда ДанныеСтроки.НомерОповещения = 0; КонецЕсли; КонецПроцедуры
В результате, если значение перечисления не выбрано, будет отображаться пустая пиктограмма. Если выбрано – пиктограмма, соответствующая этому способу оповещения (рис. 8.368).
Рис. 8.367. Реквизиты «ОповеститьКлиента» и «НомерОповещения»
Для поля таблицы СписокАвтомобилейОповеститьКлиента создадим обработчик события ПриИзменении(), в котором, в зависимости от выбранного значения перечисления, будем заполнять реквизит НомерОповещения (листинг 8.133). Листинг 8.133. Обработчик события «При изменении»
&НаКлиенте Процедура СписокАвтомобилейОповеститьКлиентаПриИзменении(Элемент) ДанныеСтроки = Элементы.СписокАвтомобилей.ТекущиеДанные; Если ДанныеСтроки.ОповеститьКлиента = ПредопределенноеЗначение( "Перечисление.ВидыОповещений.Почта") Тогда ДанныеСтроки.НомерОповещения = 1; ИначеЕсли ДанныеСтроки.ОповеститьКлиента = ПредопределенноеЗначение( "Перечисление.ВидыОповещений.Телефон") Тогда ДанныеСтроки.НомерОповещения = 2; ИначеЕсли ДанныеСтроки.ОповеститьКлиента = ПредопределенноеЗначение( "Перечисление.ВидыОповещений.ЭлектроннаяПочта") Тогда ДанныеСтроки.НомерОповещения = 3; ИначеЕсли ДанныеСтроки.ОповеститьКлиента = ПредопределенноеЗначение( "Перечисление.ВидыОповещений.Интернет") Тогда ДанныеСтроки.НомерОповещения = 4; ИначеЕсли ДанныеСтроки.ОповеститьКлиента = ПредопределенноеЗначение( "Перечисление.ВидыОповещений.НеОповещать") Тогда
Том 1
Рис. 8.368. Отображение картинки в форме
Следует сделать небольшое замечание относительно пустых картинок (и картинок вообще), отображаемых в табличной части. Текущая строка списка подсвечивается голубым фоном. Кроме этого, к таблице может применяться условное оформление. Поэтому, чтобы пиктограммы хорошо выглядели на любом (не только белом) фоне, нужно делать их фон прозрачным. Особенно это важно для пустых пиктограмм. В противном случае в текущей строке они будут отображаться в виде белых прямоугольников, что некрасиво и вызывает у пользователя желание нажать на них мышью (рис. 8.369).
Рис. 8.369. Отображение картинки с непрозрачным фоном
363
Глава 8. Разработка форм Чтобы сделать пустую картинку прозрачной, нужно отредактировать ее цвет и установить для него свойство Прозрачность в значение 0 (рис. 8.370).
Один из возможных способов ввода такого значения в поле показан на рисунке. Нужно нажать кнопку выбора в поле ввода, платформа откроет форму выбора справочника Поставщики, в этой форме необходимо выделить нужного поставщика и нажать кнопку Выбрать. Ссылка на выбранного поставщика будет помещена в поле ввода. Однако можно использовать другой способ – ввод по строке. Не нажимая кнопку выбора, просто начать вводить в поле наименование поставщика. В момент паузы или по окончании ввода платформа автоматически сформирует список подходящих поставщиков, из которого можно будет выбрать нужного (рис. 8.372).
Рис. 8.370. Изменение прозрачности цвета
Ввод по строке «1С:Предприятие» поддерживает удобную возможность – ввод ссылочных значений в поля ввода путем набора текста прямо в этом поле. Ссылочные поля – это поля, значения которых являются ссылками на другие объекты базы данных. Например, в поле Поставщик может содержаться ссылка на какого-либо поставщика, который является одним из элементов справочника Поставщики (рис. 8.371).
Рис. 8.372. Ввод по строке
Если такой поставщик окажется один, платформа автоматически подставит ссылку на этого поставщика в редактируемое поле при переходе к другому элементу формы. Ввод по строке возможен благодаря тому, что для каждого объекта конфигурации, имеющего ссылочные значения, автоматически указываются поля, по которым осуществляется ввод по строке (рис. 8.373).
Рис. 8.373. Поля, используемые для ввода по строке
Рис. 8.371. Ссылочное поле «Поставщик»
364
Обычно для справочников в качестве таких полей используется Наименование и Код, то есть можно вводить в поле наименование элемента справочника или можно вводить его код. Профессиональная разработка в системе «1С:Предприятие 8»
Программирование форм Для других объектов конфигурации стандартно могут использоваться другие поля. Разработчик может изменить состав полей, по которым выполняется ввод по строке.
Последовательность событий при вводе по строке Рассмотрим, какие события вызываются платформой при вводе по строке (рис. 8.374). Рис. 8.375. Вызов событий «Автоподбор» и «Окончание ввода текста»
После обработки этого события платформа показывает рядом с полем ввода список выбора – список возможных значений, которые могут быть помещены в это поле. Пользователь выбирает одно из значений, после чего возникает событие поля – Обработка выбора. После обработки этого события платформа помещает выбранное значение в поле ввода и вызывает последнее событие поля – При изменении. Чаще всего при работе с вводом по строке разработчик решает две задачи:
Рис. 8.374. Последовательность событий при вводе по строке
Пользователь начинает вводить текст в поле. Дальше возможны варианты развития событий: ■■ в процессе ввода он делает паузу. В этом случае будет вызвано событие Автоподбор; ■■ находясь в поле ввода, в которое уже введена часть наименования, он нажимает стрелку вниз. Например, после паузы платформа показала список выбора, но пользователь случайно закрыл его. В этом случае также будет вызвано событие Автоподбор; ■■ в процессе ввода он не делает пауз и, введя часть наименования, переходит к следующему элементу формы, нажав Tab или Enter. В этом случае будет вызвано событие Окончание ввода текста (рис. 8.375). События Автоподбор и Окончание ввода текста – это клиентские события поля формы, вернее его расширения – расширения поля ввода. После обработки одного из этих событий платформа вызывает событие Обработка получения данных выбора. Это событие вызывается в модуле менеджера того объекта конфигурации, значение которого хранится в этом поле, в нашем случае это будет событие, обрабатываемое в модуле менеджера справочника Поставщики. Том 1
■■ сформировать список выбора по своим правилам; ■■ отказаться от выбора, сделанного пользователем, или подставить в поле собственное значение. Вторая задача довольно простая и решается в обработчике события Обработка выбора. ПОДРОБНЕЕ
Раздел «Событие «Обработка выбора», стр. 371.
А вот для решения первой задачи существует большое количество возможностей, которые мы сейчас и рассмотрим.
Формирование собственного списка выбора Как видно из приведенной выше схемы, в любом случае при вводе по строке вызываются два события: ■■ Автоподбор или Окончание ввода текста, ■■ Обработка получения данных выбора. Примечательным здесь является то, что первые события вызываются в форме, в то время как последнее событие вызывается в модуле менеджера прикладного объекта.
365
Глава 8. Разработка форм Из этого следует важное замечание: переопределять формирование списка выбора нужно прежде всего в обработчике Обработка получения данных выбора. Потому что это будет работать во всех случаях, когда в каком-либо поле, в какой-либо форме будет формироваться список выбора значений этого типа. Даже в тех формах, которые генерируются платформой автоматически и которые разработчик изменить не может. Более сложный случай – когда в одной или нескольких формах нужно иметь особенное формирование списка выбора, не такое, как в остальных местах. В этом случае нужно использовать обработчики событий этой (этих) формы: Автоподбор и Окончание ввода текста. В простейшем варианте в этих обработчиках должен быть написан одинаковый алгоритм. Самым сложным и специфическим является случай, когда в некоторой форме список выбора при паузе и при переходе к следующему элементу должен формироваться по разным алгоритмам. Тогда в каждом из обработчиков Автоподбор и Окончание ввода текста будет собственный алгоритм формирования списка выбора.
Событие «Обработка получения данных выбора» Итак, рассмотрим возможности, которые существуют в обработчике Обработка получения данных выбора.
– это булева переменная, на основе которой платформа определяет, что делать после выхода из этого обработчика. СтандартнаяОбработка
Если СтандартнаяОбработка равна Истина, то платформа самостоятельно сформирует список выбора, исходя из того, что указано в Параметрах. Если СтандартнаяОбработка равна Ложь, платформа не будет формировать список выбора самостоятельно, а покажет то, что находится в параметре ДанныеВыбора. Таким образом, у нас есть следующие возможности: ■■ изменить Параметры и сказать платформе, чтобы она сформировала список выбора; ■■ отказаться от стандартной обработки и самостоятельно сформировать список выбора. Сначала рассмотрим, каким образом можно модифицировать параметры. подробнее
Пример можно посмотреть в демонстрационной базе «Разработка форм, пример 13», документ Накладная, реквизит Товар табличной части.
Синтаксис описания этого обработчика выглядит следующим образом (листинг 8.134).
Допустим, есть документ Накладная, в табличной части которого необходимо подбирать товары. Причем для выбора должны предлагаться не все возможные товары, а только те, которые поставляет поставщик, указанный в этом документе, и те, которые не помечены на удаление.
Листинг 8.134. Объявление обработчика события «Обработка получения данных выбора»
Для этого у реквизита табличной части Товар заданы свойства Связи параметров выбора и Параметры выбора (рис. 8.376).
ОбработкаПолученияДанныхВыбора(ДанныеВыбора, Параметры, СтандартнаяОбработка)
– это переменная, в которую разработчик должен поместить собственный список выбора. При входе в обработчик этот параметр не содержит никаких значений, то есть через него нельзя получить доступ к списку выбора, который сформирует платформа. Просто потому, что этот список формируется уже после выхода из этого обработчика. Однако может возникнуть желание в этом обработчике получить список, формируемый платформой, и добавить в него (удалить) несколько элементов. Как это сделать – рассказано в разделе «Метод ПолучитьДанныеВыбора()», стр. 370. ДанныеВыбора
Переменная Параметры содержит набор параметров, которые платформа будет использовать для формирования списка выбора. Особенность заключается в том, что при формировании списка выбора платформа будет учитывать свойства Параметры выбора и Связи параметров выбора, заданные для соответствующего реквизита объекта конфигурации. Поэтому в параметрах могут содержаться какие-то отборы.
366
Рис. 8.376. Свойства «Связи параметров выбора» и «Параметры выбора»
Профессиональная разработка в системе «1С:Предприятие 8»
Программирование форм В связях параметров выбора указывается, что для выбора будут предлагаться только товары поставщика, указанного в документе. В параметрах выбора указывается, что кроме этого для выбора будут предлагаться только товары, не помеченные на удаление. В результате при наборе наименования товара в форме будет предложен следующий список товаров (рис. 8.377).
Рис. 8.379. Структура отборов
Добавим к ним еще одно условие, что товар не должен быть услугой, а стандартную обработку оставим в значении Истина, чтобы платформа сформировала список выбора самостоятельно (листинг 8.135). Листинг 8.135. Добавление условия отбора
Процедура ОбработкаПолученияДанныхВыбора(ДанныеВыбора, Параметры, СтандартнаяОбработка) Параметры.Отбор.Вставить("ВидТовара", Перечисления.ВидыТоваров.Товар); КонецПроцедуры
Рис. 8.377. Товары от поставщика «Поставщик 1», не помеченные на удаление
Если теперь выполнить те же самые операции, мы увидим, что для выбора предлагаются только элементы, являющиеся товарами (рис. 8.380).
Если мы посмотрим на все имеющиеся товары, то заметим, что подбор товаров произведен правильно (рис. 8.378).
Рис. 8.380. Товары, предлагаемые для выбора
Рис. 8.378. Полный список товаров
Допустим, нас не устраивает, что для выбора предлагаются те элементы справочника, которые являются услугами. Мы можем легко исправить это в обработчике события Обработка получения данных выбора в модуле менеджера справочника Товары. Благодаря свойствам Параметры выбора и Связи параметров выбора в этом обработчике структура параметров содержит следующие отборы (рис. 8.379). Том 1
Рассмотрим вторую ситуацию, когда мы полностью самостоятельно формируем список выбора, не используя стандартные возможности платформы. Здесь есть два случая. Список выбора может быть «простым» и «сложным». ■■ в простом случае это должен быть список значений, содержащий выбираемые значения (ссылки); ■■ в сложном случае это будет список значений, содержащий в качестве своих элементов структуры. Каждая такая структура содержит само выбираемое значение и некоторую дополнительную информацию об этом значении.
367
Глава 8. Разработка форм Сначала посмотрим, как можно сформировать простой список. подробнее
Пример можно посмотреть в демонстрационной базе «Разработка форм, пример 13», документ Накладная, реквизит Склад.
Затем создаем пустой список значений и, обходя результат запроса, заполняем список ссылками. В конце помещаем этот список в переменную ДанныеВыбора. В результате при вводе наименования склада мы будем иметь следующую ситуацию (рис. 8.381).
Допустим, в документе Накладная есть реквизит Склад. Тогда в модуле менеджера справочника Склады мы можем написать следующий обработчик (листинг 8.136). Листинг 8.136. Обработчик события «Обработка получения данных выбора»
Процедура ОбработкаПолученияДанныхВыбора(ДанныеВыбора, Параметры, СтандартнаяОбработка) СтандартнаяОбработка = Ложь; Запрос = Новый Запрос; Запрос.Текст = "ВЫБРАТЬ | Склады.Ссылка |ИЗ | Справочник.Склады КАК Склады |ГДЕ | Склады.Розничный = ЛОЖЬ | И Склады.Наименование ПОДОБНО &СтрокаПоиска";
Рис. 8.381. Склады, предлагаемые для выбора
Если посмотреть на список складов, мы увидим, что выбор произведен правильно, а фрагмент наименования склада может быть произвольным, не обязательно находящимся в начале наименования (рис. 8.382).
Запрос.УстановитьПараметр("СтрокаПоиска", "%" + Параметры.СтрокаПоиска + "%"); Результат = Запрос.Выполнить();
ВыборкаДетальныеЗаписи = Результат.Выбрать(); Список = Новый СписокЗначений; Пока ВыборкаДетальныеЗаписи.Следующий() Цикл Список.Добавить(ВыборкаДетальныеЗаписи.Ссылка); КонецЦикла; ДанныеВыбора = Список; КонецПроцедуры
В нем мы прежде всего отказываемся от стандартной обработки. Затем формируем запрос, который выберет нам все склады, не являющиеся розничными, и наименование которых содержит строку, введенную пользователем в поле ввода. Строку, введенную пользователем, мы получаем из структуры параметров, в ней она содержится отдельным элементом с ключом СтрокаПоиска (листинг 8.137). Листинг 8.137. Получение строки, введенной пользователем
Рис. 8.382. Полный список складов
Теперь рассмотрим, как формировать сложный список выбора. подробнее
Пример можно посмотреть в демонстрационной базе «Разработка форм, пример 13», документ Накладная, реквизит Поставщик. В модуле менеджера справочника Поставщики снять комментарии с варианта Пример 1.
Допустим, в документе Накладная есть реквизит Поставщик. Тогда в модуле менеджера справочника Поставщики мы можем написать следующий обработчик (листинг 8.138).
Запрос.УстановитьПараметр("СтрокаПоиска", "%" + Параметры.СтрокаПоиска + "%");
368
Профессиональная разработка в системе «1С:Предприятие 8»
Программирование форм Листинг 8.138. Обработчик события «Обработка получения данных выбора»
Процедура ОбработкаПолученияДанныхВыбора(ДанныеВыбора, Параметры, СтандартнаяОбработка) СтандартнаяОбработка = Ложь; Запрос = Новый Запрос; Запрос.Текст = "ВЫБРАТЬ | Поставщики.Ссылка, | Поставщики.ПометкаУдаления, | Поставщики.Ненадежный |ИЗ | Справочник.Поставщики КАК Поставщики |ГДЕ | Поставщики.Наименование ПОДОБНО &СтрокаПоиска";
После заполнения структуры добавляем ее в список значений, а после обхода всего результата запроса список помещаем в переменную ДанныеВыбора. В результате при вводе наименования поставщика список выбора будет выглядеть следующим образом (рис. 8.383).
Запрос.УстановитьПараметр("СтрокаПоиска", "%" + Параметры.СтрокаПоиска + "%"); Результат = Запрос.Выполнить();
ВыборкаДетальныеЗаписи = Результат.Выбрать(); Список = Новый СписокЗначений; Пока ВыборкаДетальныеЗаписи.Следующий() Цикл Структура = Новый Структура; Структура.Вставить("Значение", ВыборкаДетальныеЗаписи.Ссылка); Структура.Вставить("ПометкаУдаления", ВыборкаДетальныеЗаписи.ПометкаУдаления); Если ВыборкаДетальныеЗаписи.Ненадежный Тогда Структура.Вставить("Предупреждение", "Это ненадежный поставщик, его лучше не выбирать!"); КонецЕсли;
Рис. 8.383. Поставщики, предлагаемые для выбора
На примере имеющихся поставщиков мы сможем посмотреть все возможные варианты работы «сложного» списка выбора (рис. 8.384).
Список.Добавить(Структура); КонецЦикла; ДанныеВыбора = Список; КонецПроцедуры
Если выбрать Поставщик 1, мы не получим никаких предупреждений.
Здесь, как и раньше, отказываемся от стандартной обработки и запросом получаем нужные ссылки.
Если выбрать поставщика, помеченного на удаление (Поставщик11), мы получим стандартное предупреждение платформы (рис. 8.385).
Рис. 8.384. Полный список поставщиков
Затем создаем пустой список значений, а при каждом обходе результата запроса создаем структуру, в которую помещаем: ■■ само значение – в элемент с ключом Значение; ■■ признак пометки удаления – в элемент с ключом ПометкаУдаления. Если пользователь выберет поставщика, помеченного на удаление, платформа выдаст стандартное предупреждение; ■■ для тех поставщиков, которые являются ненадежными, мы добавляем в структуру элемент с ключом Предупреждение. Если пользователь выберет ненадежного поставщика, ему будет выдано добавленное нами предупреждение. Том 1
Рис. 8.385. Предупреждение о том, что выбранный элемент помечен на удаление
369
Глава 8. Разработка форм Если выбрать ненадежного поставщика, да еще и помеченного на удаление (Поставщик367), мы получим «свое» предупреждение (рис. 8.386).
Другой случай, когда поле ввода имеет ссылочный тип и при обработке события Обработка получения данных выбора в модуле менеджера объекта, еще до того, как платформа сформирует список выбора, необходимо получить этот список для модификации. Для таких особенных случаев в платформе существуют методы ПолучитьДанныеВыбора(). Эти методы полностью имитируют формирование списка выбора платформой, вплоть до вызова события Обработка получения данных выбора. Такой метод есть в глобальном контексте. В его параметре нужно указывать тип объекта, для которого он должен быть вызван. Такие методы есть у всех менеджеров прикладных объектов.
Рис. 8.386. Предупреждение о том, что выбран ненадежный поставщик
Таким образом, попутно мы убедились в следующем: если для выбираемого элемента указана и пометка удаления, и предупреждение, будет выведено предупреждение. Несколько слов о производительности. Событие Обработка получения данных выбора, обрабатываемое в модуле менеджера объекта, вызывается довольно часто. Перечислим еще раз: ■■ во-первых, при автоподборе, то есть когда возникает пауза при наборе текста в поле ввода; ■■ во-вторых, при вводе по строке, то есть когда в поле ввода уже введена какая-то строка и фокус ввода переходит на другой элемент формы; ■■ и, в-третьих (о чем не упоминалось в этом разделе), при быстром выборе, когда для выбора объекта используется не его основная форма выбора, а небольшой список, формируемый системой. Поэтому при написании обработчика Обработка получения данных выбора нужно особенно тщательно подходить к вопросу эффективности создаваемого кода.
Метод «ПолучитьДанныеВыбора()» В процессе работы с полем ввода могут возникнуть самые разные ситуации, связанные с обработкой ввода по строке или автоподбора. Как мы уже говорили, ввод по строке возможен только для ссылочных значений. Однако автоподбор и окончание ввода текста отрабатываются для любых типов в поле ввода. Поэтому, например, поле ввода может иметь строковый тип, но в обработчике события Автоподбор может анализироваться один или несколько справочников, из которых будет получаться список элементов, соответствующих введенной подстроке.
370
В использовании этих методов нет ничего сложного, за исключением того случая, когда этот метод вызывается в обработчике Обработка получения данных выбора. Если не предпринять специальных действий, это приведет к бесконечной рекурсии. Но от нее можно избавиться довольно простым способом. Рассмотрим это на примере. ПОДРОБНЕЕ
Пример можно посмотреть в демонстрационной базе «Разработка форм, пример 13», документ Накладная, реквизит Поставщик. В модуле менеджера справочника Поставщики снять комментарии с варианта Пример 2.
Рассмотрим следующий обработчик в модуле менеджера справочника Поставщики (листинг 8.139). Листинг 8.139. Обработчик события «Обработка получения данных выбора»
Процедура ОбработкаПолученияДанныхВыбора(ДанныеВыбора, Параметры, СтандартнаяОбработка) // Если это рекурсивный вызов, ничего не делать. Если НЕ Параметры.Свойство("Рекурсия") Тогда СтандартнаяОбработка = Ложь; // Получить стандартный список выбора. Параметры.Вставить("Рекурсия"); СтандартныйСписок = ПолучитьДанныеВыбора(Параметры); // Добавить к стандартному списку собственный элемент. ДополнительныйЭлемент = Справочники.Поставщики.НайтиПоКоду("000000003"); СтандартныйСписок.Добавить(ДополнительныйЭлемент); ДанныеВыбора = СтандартныйСписок; КонецЕсли; КонецПроцедуры
Профессиональная разработка в системе «1С:Предприятие 8»
Программирование форм Для защиты от рекурсии перед вызовом метода ПолучитьДанныеВыбора() в структуру параметров будем добавлять служебный параметр с ключом Рекурсия. Весь код, написанный в обработчике, будем выполнять только в том случае, если в параметрах отсутствует элемент Рекурсия, т. е. при первом «заходе» в этот обработчик (листинг 8.140). Листинг 8.140. Проверка на отсутствие рекурсии
Если НЕ Параметры.Свойство("Рекурсия") Тогда
При втором заходе в этот обработчик (когда платформа будет формировать стандартный список выбора) в параметрах уже будет присутствовать элемент Рекурсия. Таким образом, никакой код выполняться не будет (листинг 8.141). Листинг 8.141. Добавление элемента «Рекурсия» в данные выбора
Параметры.Вставить("Рекурсия"); СтандартныйСписок = ПолучитьДанныеВыбора(Параметры);
После получения стандартного списка мы добавляем в него еще одного поставщика, который нам очень нравится и, возможно, пригодится пользователю для выбора (листинг 8.142). Листинг 8.142. Добавление «собственного» поставщика
ДополнительныйЭлемент = Справочники.Поставщики.НайтиПоКоду("000000003"); СтандартныйСписок.Добавить(ДополнительныйЭлемент);
И в конце полученный список помещаем в переменную ДанныеВыбора. Так как в начале мы отказались от стандартной обработки, именно этот список и будет показан пользователю (рис. 8.387).
Событие «Обработка выбора» Это событие хорошо тем, что оно вызывается после того, как пользователь выбрал какое-то значение из предложенного списка, но еще до того, как это значение будет помещено в поле ввода. Поэтому в этом событии можно: ■■ отказаться от того выбора, который сделал пользователь (СтандартнаяОбработка = Ложь); ■■ поместить в поле ввода другое значение, не то, которое выбрал пользователь (параметр ВыбранноеЗначение). Первая ситуация может показаться на первый взгляд странной. Если пользователь может выбрать «что-то не то», то зачем тогда предлагать ему это выбирать? Нужно с самого начала предложить ему выбирать только из того, что «можно». Такой подход имеет право на жизнь и, наверное, может применяться в целом ряде случаев. Однако он имеет два недостатка. Первый недостаток, если можно так выразиться, «юзабильный». Например, пользователь начинает вводить в документ поставщика Стройтрест. Он точно знает, что такой поставщик существует в базе данных. Но программа не предлагает ему выбрать этого поставщика. Первое, о чем подумает пользователь, – что программа «сломалась», или что он неправильно пишет наименование. О том, что именно этого поставщика нельзя выбрать именно в этом документе, пользователь может не подумать совсем или догадается об этом только после долгих экспериментов. Поэтому логичнее поступать следующим образом: если пользователь хочет выбрать поставщика с таким наименованием, предоставить ему такую возможность. Но если по каким-то причинам этого поставщика нельзя использовать в этом документе, после выбора пользователя сообщить ему об этом и отказаться от выбора, сделанного пользователем. Такой сценарий, конечно, не является догмой, но в целом ряде случаев, когда для пользователя не является очевидным тот факт, что выбирать можно среди ограниченного множества элементов, этот сценарий вполне имеет право на жизнь. Другой недостаток изначального ограничения списка выбора может быть чисто технологическим. Например, для того чтобы выяснить, можно использовать этого поставщика или нет, требуется выполнить целый ряд сложных и непростых расчетов.
Рис. 8.387. Список поставщиков, предложенных для выбора
Том 1
Допустим, список выбора, формируемый для пользователя, будет содержать 49 элементов. Для всех них необходимо будет выполнить этот расчет. Это может занять значительное время. А в результате пользователь выберет один-единственный элемент из этих 49. В такой ситуации гораздо производительнее будет, ничего не рассчитывая, предоставить ему для выбора 49 элементов. А после того как он выберет
371
Глава 8. Разработка форм единственный элемент, только для него одного провести необходимые расчеты. И либо согласиться с выбором пользователя, либо отказаться от него. Что касается помещения в поле ввода значения другого типа, такая ситуация может возникнуть при имитации ввода по строке, выполняемого платформой. Например, когда поле ввода имеет строковый тип, список выбора формируется из элементов справочника, на основании выбора пользователя заполняется какая-то служебная информация, а в поле ввода помещается не ссылка, выбранная пользователем, а ее представление. Выполнить все эти действия как раз и можно в обработчике события Обработка выбора.
Событие «Начало выбора» Для того чтобы картина с формированием списка выбора для поля ввода была полной, следует упомянуть еще об одном событии – Начало выбора. Это событие возникает в поле ввода в момент нажатия кнопки выбора или клавиши F4 (рис. 8.388).
Можно отменить стандартную обработку, а в данные выбора поместить список значений, из которых будет выбирать пользователь. Тогда, даже если для реквизита не используется быстрый выбор, при наступлении события будет открыта не форма выбора, а список выбора, расположенный под полем ввода.
Программное изменение формы В «1С:Предприятии» реализован достаточно богатый механизм программного изменения формы, однако он не полностью позволяет реализовать те возможности, которые предоставляются средствами конфигурирования (см. раздел «Конструирование форм», стр. 233). Это обусловлено тем, что сама модель управляемого приложения ориентирована на работу со статическим, а не с динамическим описанием форм. Форма не рождается на клиенте. Форма рождается на сервере, она проходит несколько важных стадий предварительной обработки, прежде чем достичь глаз пользователя. Платформа содержит достаточно сложные механизмы многоуровневого кеширования различных частей формы, как на сервере, так и на клиенте. По этой причине возможность программного изменения формы является скорее опциональной, дополнительной. Она рассчитана на отдельные конкретные сценарии работы и не предполагает массового использования в большом количестве форм конфигурации или в часто используемых формах. Основным подходом при разработке прикладных решений должно являться визуальное конструирование форм в конфигураторе. А программное изменение форм рекомендуется использовать лишь в отдельных специфических сценариях работы.
Рис. 8.388. Событие «Начало выбора»
Стандартным действием платформы в этом случае является либо открытие формы выбора, либо открытие списка выбора (если для реквизита указан режим быстрого выбора). Если разработчик переопределяет формирование списка выбора при автоподборе и при окончании ввода текста, вполне возможно, что ему захочется формировать подобный список и при начале выбора. Такая возможность существует. Обработчик события Начало выбора имеет параметры ДанныеВыбора и СтандартнаяОбработка. Они используются таким же образом, как и в других рассмотренных обработчиках (листинг 8.143).
Такими сценариями могут быть, например, отображение в форме имеющихся типовых операций или характеристик объектов. То есть той информации, которая содержится в базе данных и структура которой неизвестна на этапе конфигурирования. Ее можно узнать только уже в процессе функционирования прикладного решения, в режиме 1С:Предприятие. Поэтому для ее отображения в форме и требуется ее программное изменение.
Общие подходы
Листинг 8.143. Объявление обработчика события «Начало выбора»
Встроенный язык позволяет добавлять, изменять и удалять реквизиты, команды и элементы формы. Особенность заключается в том, что программно удалить можно только то, что программно же и добавлено. Нельзя программно удалить элементы, реквизиты или команды, созданные в конфигураторе.
&НаКлиенте Процедура ПоставщикНачалоВыбора(Элемент, ДанныеВыбора, СтандартнаяОбработка)
При программном изменении формы нужно управлять «всей троицей» – реквизиты, команды и элементы. Например, чтобы разместить какие-то
372
Профессиональная разработка в системе «1С:Предприятие 8»
Программирование форм данные в форме, нужно создать реквизит, создать элемент, связать элемент с реквизитом. Для команды – создать команду, связать ее с имеющимся в модуле формы обработчиком, создать элемент, связать элемент с командой. Добавление и удаление реквизитов, команд и элементов формы возможно только на сервере. Поэтому алгоритмы модификации формы нужно размещать в серверных процедурах формы – в обработчиках событий формы на сервере или в контекстных серверных процедурах модуля формы.
Добавление поля Разберем пример с добавлением поля так, как мы делали бы его в конфигураторе, средствами визуального конструирования. Сначала мы добавим реквизит формы типа Строка (рис. 8.389).
Программное изменение формы возможно только «изнутри» формы, т. е. при нахождении в ее модуле. Нет возможности получить какую-либо форму, программно изменить ее и затем открыть. Потому что изменение формы возможно только на сервере, а открытие формы – только на клиенте. А встроенный язык не содержит методов, позволяющих разработчику принудительно передать форму с сервера на клиента. Механика добавления/удаления реквизитов формы принципиально отличается от механики работы с ее элементами и командами. Элементы и команды можно добавлять/удалять поодиночке, просто обращаясь к коллекциям этих элементов, используя методы Добавить() и Удалить(). Это относительно «безболезненные» операции для формы. Изменение состава реквизитов, напротив, является сложной и затратной операцией. Поэтому здесь используется следующий подход. Сначала разработчик создает два массива программных объектов, которые описывают реквизиты формы. Один массив – это те реквизиты, которые должны быть добавлены, а другой массив – это те реквизиты, которые нужно удалить. После этого «за один подход» выполняется модификация формы с помощью ее метода ИзменитьРеквизиты(), в который передаются оба этих массива. Сначала выполняется удаление реквизитов, затем – добавление. С добавлением реквизитов связана еще одна важная особенность. Можно добавить реквизит и установить его свойства. Но из встроенного языка нельзя назначить реквизит основным. Поэтому, например, полностью программно невозможно создать «настоящую» форму списка или объекта.
Рис. 8.389. Реквизит формы «РеквизитКомментарий»
После этого добавим элемент формы Поле, который в дальнейшем будет отображать значение реквизита (рис. 8.390).
Рис. 8.390. Поле «ПолеКомментарий»
Затем свяжем между собой элемент формы и реквизит формы (рис. 8.391).
Теперь в качестве примеров рассмотрим четыре случая программного изменения формы: ■■ ■■ ■■ ■■
добавление поля, добавление динамического списка, добавление колонки в таблицу, добавление команды.
Том 1
Рис. 8.391. Связь поля и реквизита
И в заключение для элемента формы назначим обработчик события При изменении, который заранее заготовлен в модуле нашей формы (рис. 8.392).
373
Глава 8. Разработка форм ОписаниеТиповДляРеквизита, , "Комментарий", Истина);
// тип // путь // заголовок // сохраняемые данные
ДобавляемыеРеквизиты = Новый Массив; ДобавляемыеРеквизиты.Добавить(НовыйРеквизит); ИзменитьРеквизиты(ДобавляемыеРеквизиты);
Рис. 8.392. Назначение обработчика события «При изменении»
Теперь все те же самые действия выполним программно, из встроенного языка. подробнее
Пример можно посмотреть в демонстрационной базе «Разработка форм, пример 14», общая форма Форма, команда Добавить поле. Это локальная команда этой формы.
Для изменения формы сразу же выполним контекстный вызов сервера, в котором и будем модифицировать форму (листинг 8.144). Листинг 8.144. Контекстный вызов сервера для модификации формы
&НаКлиенте Процедура ДобавитьПоле(Команда) ДобавитьПолеНаСервере(); КонецПроцедуры &НаСервере Процедура ДобавитьПолеНаСервере() …
В серверной процедуре сначала добавим реквизит формы РеквизитКомментарий (листинг 8.145). Листинг 8.145. Добавление реквизита формы
// Добавить реквизит. ТипыРеквизита = Новый Массив; ТипыРеквизита.Добавить(Тип("Строка")); ОписаниеТиповДляРеквизита = Новый ОписаниеТипов(ТипыРеквизита); НовыйРеквизит = Новый РеквизитФормы("РеквизитКомментарий", // имя
374
В этом фрагменте мы сначала создаем объект, описывающий тип добавляемого реквизита. Поскольку в общем случае реквизит может иметь составной тип, т. е. включать в себя сразу несколько типов, то для описания его типа используется объект ОписаниеТипов. Этот объект создается на основе массива, содержащего нужные типы. Наш реквизит будет иметь тип Строка, поэтому мы создаем массив ТипыРеквизита, содержащий единственный элемент. Затем на основании этого массива создаем описание типов – ОписаниеТиповДляРеквизита. Это описание типов мы используем при конструировании реквизита формы – НовыйРеквизитФормы(…). В параметрах конструктора мы указываем: ■■ имя реквизита – РеквизитКомментарий; ■■ тип этого реквизита – созданное нами описание типов ОписаниеТиповДляРеквизита; ■■ путь к реквизиту не указываем, поскольку добавляем реквизит первого уровня; ■■ заголовок реквизита – Комментарий, этот заголовок будет использоваться платформой для отображения в форме; ■■ последним параметром указываем, что этот реквизит содержит сохраняемые данные, т. е. при изменении этого реквизита будет автоматически устанавливаться модифицированность формы. В данном случае этот параметр мы используем исключительно в демонстрационных целях, чтобы показать, что такая возможность имеется. Благодаря этому в дальнейшем перед закрытием формы мы сможем анализировать ее модифицированность и предотвращать закрытие формы без сохранения измененных данных. После того как реквизит создан, мы добавляем его в массив и этот массив передаем в метод формы ИзменитьРеквизиты() первым параметром. То есть как те реквизиты, которые нужно добавить в форму. Теперь мы имеем состояние, аналогичное тому, которое было показано на рисунке 8.389. На втором этапе, как мы говорили выше, нужно создать элемент формы. Для этого мы используем следующий код (листинг 8.146).
Профессиональная разработка в системе «1С:Предприятие 8»
Программирование форм Листинг 8.146. Добавление элемента формы
// Добавить элемент формы и связать его с реквизитом. НовыйЭлемент = Элементы.Добавить("ПолеКомментарий", Тип("ПолеФормы"));
В результате мы на рисунке 8.390.
имеем
состояние,
которое
было
показано
Теперь мы связываем элемент формы и реквизит. Для этого в свойстве элемента ПутьКДанным мы указываем имя нашего реквизита (листинг 8.147). Листинг 8.147. Связь элемента с реквизитом
НовыйЭлемент.ПутьКДанным = "РеквизитКомментарий";
Теперь мы имеем состояние, которое было показано на рисунке 8.391. После того как элемент добавлен и связан с реквизитом, установим некоторые его свойства. Во-первых, укажем, что это не просто поле, а поле ввода, а во-вторых – отобразим в нем кнопку очистки (листинг 8.148).
Рис. 8.393. Поле ввода в форме
Добавление динамического списка Пример с добавлением динамического списка, если бы мы выполняли его средствами визуального конструирования, выглядел бы следующим образом. Сначала мы добавим реквизит формы типа (рис. 8.394).
ДинамическийСписок
Листинг 8.148. Установка свойств поля
НовыйЭлемент.Вид = ВидПоляФормы.ПолеВвода; НовыйЭлемент.КнопкаОчистки = Истина;
Теперь нам осталось выполнить последний шаг – назначить обработчик события для только что добавленного элемента формы (листинг 8.149). Листинг 8.149. Назначение обработчика события
// Установить обработчик события. НовыйЭлемент.УстановитьДействие("ПриИзменении", "ОбработчикПриИзмененииПоляКомментарий");
Здесь мы указываем имя события и имя процедуры, которая будет обрабатывать это событие. Эта процедура должна быть создана в модуле формы заранее, на этапе конфигурирования (листинг 8.150).
Рис. 8.394. Добавление реквизита формы
После этого для динамического списка зададим текст запроса и основную таблицу (рис. 8.395).
Листинг 8.150. Обработчик события «При изменении»
&НаКлиенте Процедура ОбработчикПриИзмененииПоляКомментарий(Элемент) Сообщение = Новый СообщениеПользователю; Сообщение.Текст = ЭтаФорма["РеквизитКомментарий"]; Сообщение.Сообщить(); КонецПроцедуры
После этого можно запустить систему в режиме 1С:Предприятие и посмотреть, как работает наша команда Добавить поле. В результате ее выполнения внизу формы появится поле ввода Комментарий. При изменении значения этого поля будет обрабатываться событие, и новое значение поля будет выводиться в окно сообщений (рис. 8.393). Том 1
Рис. 8.395. Установка текста запроса и основной таблицы
375
Глава 8. Разработка форм Затем добавим элемент формы Таблица (рис. 8.396).
Аналогичным образом создадим еще одну колонку таблицы Код и свяжем ее с колонкой динамического списка Код (рис. 8.399).
Рис. 8.396. Добавление таблицы формы
После этого свяжем между собой элемент формы и реквизит формы (рис. 8.397). Рис. 8.399. Добавление колонки «КолонкаКод» и ее связь с полем реквизита
Теперь эти же самые действия выполним программно, из встроенного языка. подробнее
Пример можно посмотреть в демонстрационной базе «Разработка форм, пример 14», общая форма Форма, команда Добавить динамический список. Это локальная команда этой формы. Рис. 8.397. Связь таблицы и реквизита
Теперь создадим колонку таблицы Наименование и свяжем ее с колонкой динамического списка Наименование (рис. 8.398).
Как и в предыдущем примере, модификацию формы будем выполнять в серверной контекстной процедуре. Сначала добавим реквизит формы РеквизитСписокТоваров (листинг 8.151). Листинг 8.151. Добавление реквизита формы
// Добавить реквизит "Динамический список". ТипыРеквизита = Новый Массив; ТипыРеквизита.Добавить(Тип("ДинамическийСписок")); ОписаниеТиповДляРеквизита = Новый ОписаниеТипов(ТипыРеквизита); НовыйРеквизит = Новый РеквизитФормы("РеквизитСписокТоваров", // имя ОписаниеТиповДляРеквизита, // тип , // путь "СписокТоваров", // заголовок Истина); // сохраняемые данные ДобавляемыеРеквизиты = Новый Массив; ДобавляемыеРеквизиты.Добавить(НовыйРеквизит); ИзменитьРеквизиты(ДобавляемыеРеквизиты);
Рис. 8.398. Добавление колонки «КолонкаНаименование» и ее связь с полем реквизита
376
Здесь все аналогично предыдущему примеру, за исключением типа добавляемого реквизита – ТипыРеквизита.Добавить(Тип("ДинамическийСписок")). Профессиональная разработка в системе «1С:Предприятие 8»
Программирование форм В результате мы имеем состояние, показанное на рисунке 8.394.
В результате мы имеем состояние, показанное на рисунке 8.399.
Теперь, после того как реквизит добавлен, можно задать текст запроса и основную таблицу динамического списка (листинг 8.152).
После этого можно запустить систему в режиме 1С:Предприятие и посмотреть, как работает наша команда Добавить динамический список.
Листинг 8.152. Установка текста запроса и основной таблицы
// Задать текст запроса и другие свойства динамического списка. РеквизитСписок = ЭтаФорма["РеквизитСписокТоваров"]; РеквизитСписок.ТекстЗапроса = "ВЫБРАТЬ Наименование, Код ИЗ Справочник.Товары"; РеквизитСписок.ОсновнаяТаблица = "Справочник.Товары";
В результате ее выполнения внизу формы появится полноценный список товаров, позволяющий добавлять, изменять и удалять товары (рис. 8.400).
В результате мы имеем состояние, показанное на рисунке 8.395. Теперь добавим элемент формы и свяжем его с данными. Снова все, как и в предыдущем примере. Отличается лишь тип добавляемого элемента (листинг 8.153). Листинг 8.153. Добавление элемента формы
// Добавить элемент формы и связать его с реквизитом. НовыйЭлемент = Элементы.Добавить("ЭлементСписокТоваров", Тип("ТаблицаФормы")); НовыйЭлемент.ПутьКДанным = "РеквизитСписокТоваров";
В результате мы имеем состояние, показанное на рисунке 8.397. Особенность работы с таблицей заключается в том, что при визуальном конструировании платформа предлагает автоматически создать колонки таблицы, если вы мышью перетаскиваете реквизит в дерево элементов формы. В нашем же случае необходимо это сделать самостоятельно. И не только создать колонки, но и связать их с данными (листинг 8.154). Листинг 8.154. Создание колонок и их связь с данными
Рис. 8.400. Динамический список в форме
Добавление колонки в таблицу Пример с добавлением колонки в существующую таблицу, если бы мы выполняли его средствами визуального конструирования, выглядел бы следующим образом. Сначала мы добавим подчиненный реквизит формы типа (рис. 8.401).
Строка
// Создать колонки и связать их с данными. НоваяКолонкаТаблицы = Элементы.Добавить("КолонкаНаименование", Тип("ПолеФормы"), НовыйЭлемент); НоваяКолонкаТаблицы.ПутьКДанным = "РеквизитСписокТоваров.Наименование"; НоваяКолонкаТаблицы = Элементы.Добавить("КолонкаКод", Тип("ПолеФормы"), НовыйЭлемент); НоваяКолонкаТаблицы.ПутьКДанным = "РеквизитСписокТоваров.Код";
Тут особенность заключается в том, что, во-первых, при добавлении колонки (поля формы) мы указываем его родителя третьим параметром метода Добавить(). НовыйЭлемент – это как раз та самая таблица, которую мы только что добавили в форму. Во-вторых, указывая путь к данным, мы указываем его полностью, от корня реквизитов. Сначала имя реквизита, являющегося динамическим списком, а потом через точку – имя одного из полей запроса, содержащегося в этом динамическом списке – РеквизитСписокТоваров.Наименование. Рис. 8.401. Добавление реквизита формы
Том 1
377
Глава 8. Разработка форм После этого добавим элемент формы Поле как подчиненный элемент существующей в форме таблицы (рис. 8.402).
Рис. 8.404. Назначение обработчика события
подробнее Рис. 8.402. Добавление элемента формы
Затем свяжем между собой элемент формы и реквизит формы (рис. 8.403).
Пример можно посмотреть в демонстрационной базе «Разработка форм, пример 14», общая форма Форма, команда Добавить колонку в таблицу. Это локальная команда этой формы.
Как и раньше, модификацию формы будем выполнять в серверной контекстной процедуре. Сначала добавим реквизит формы РеквизитКолонкаЗанятость (листинг 8.155). Листинг 8.155. Добавление реквизита формы
// Добавить реквизит. ТипыРеквизита = Новый Массив; ТипыРеквизита.Добавить(Тип("Строка")); ОписаниеТиповДляРеквизита = Новый ОписаниеТипов(ТипыРеквизита); НовыйРеквизит = Новый РеквизитФормы("РеквизитКолонкаЗанятость", ОписаниеТиповДляРеквизита, "РеквизитТаблицаЗначений", "Занятость", Истина);
Рис. 8.403. Связь элемента и реквизита
В заключение для элемента формы назначим обработчик события При изменении, который заранее заготовлен в модуле нашей формы (рис. 8.404). Теперь все те же самые действия выполним программно, из встроенного языка.
378
// имя // тип // путь // заголовок // сохраняемые данные
ДобавляемыеРеквизиты = Новый Массив; ДобавляемыеРеквизиты.Добавить(НовыйРеквизит); ИзменитьРеквизиты(ДобавляемыеРеквизиты);
Здесь особенность в том, что при добавлении реквизита мы указываем параметр Путь – РеквизитТаблицаЗначений. Поскольку добавляемый реквизит подчинен существующему в форме реквизиту, в этом параметре нужно указать полный путь от корня реквизитов до добавляемого нами реквизита, не включая имя самого добавляемого реквизита. Профессиональная разработка в системе «1С:Предприятие 8»
Программирование форм В результате мы имеем состояние, показанное на рисунке 8.401.
Добавление команды
После этого добавим элемент формы (листинг 8.156).
Последний пример, который мы рассмотрим, – это добавление команды. Если бы мы выполняли его в конфигураторе, это выглядело бы следующим образом.
Листинг 8.156. Добавление элемента формы
// Добавить элемент формы и связать его с реквизитом. НовыйЭлемент = Элементы.Добавить("КолонкаЗанятость", Тип("ПолеФормы"), Элементы.ЭлементТаблицаЗначений);
Сначала мы добавим команду формы НоваяКоманда (рис. 8.406).
Здесь та же особенность. При добавлении элемента мы указываем его родителя – элемент Таблица, существующий в форме Элементы.ЭлементТаблицаЗначений. В результате мы имеем состояние, показанное на рисунке 8.402. Теперь свяжем элемент формы с реквизитом формы и установим некоторые свойства элемента формы (листинг 8.157). Рис. 8.406. Добавление команды
Листинг 8.157. Связь элемента с реквизитом и установка свойств элемента
НовыйЭлемент.ПутьКДанным = "РеквизитТаблицаЗначений.РеквизитКолонкаЗанятость"; НовыйЭлемент.Вид = ВидПоляФормы.ПолеВвода; НовыйЭлемент.КнопкаОчистки = Истина;
Затем мы свяжем эту команду с обработчиком, который будет вызываться при исполнении этой команды (рис. 8.407).
В результате мы имеем состояние, показанное на рисунке 8.403. В заключение назначим обработчик события для только что добавленного элемента формы (листинг 8.158). Листинг 8.158. Назначение обработчика события
// Установить обработчик события. НовыйЭлемент.УстановитьДействие("ПриИзменении", "ОбработчикПриИзмененииКолонкиЗанятость");
В результате мы имеем состояние, показанное на рис. 8.404. После этого можно запустить систему в режиме 1С:Предприятие и посмотреть, как работает наша команда Добавить колонку в таблицу. В результате ее выполнения в существующей в форме таблице появится колонка Занятость. А когда мы изменим данные в этой колонке, новое значение поля будет выведено в окно сообщений – отработает назначенный нами обработчик При изменении (рис. 8.405).
Рис. 8.407. Назначение обработчика команды
Рис. 8.405. Дополнительная колонка в таблице значений
Рис. 8.408. Добавление кнопки в командную панель
Том 1
После этого добавим в командную панель формы кнопку (рис. 8.408).
379
Глава 8. Разработка форм И в заключение свяжем кнопку командной панели с той командой, которую мы добавили (рис. 8.409).
Здесь мы указываем родителя для добавляемой кнопки – существующую в форме командную панель Элементы.ФормаКоманднаяПанель. В результате мы имеем состояние, показанное на рисунке 8.408. Свяжем кнопку с командой и укажем, что кнопка будет являться кнопкой по умолчанию (она будет выделена среди других кнопок командной панели), листинг 8.162. Листинг 8.162. Связь кнопки с командой
НовыйЭлемент.ИмяКоманды = "НоваяКоманда"; НовыйЭлемент.КнопкаПоУмолчанию = Истина;
В результате мы имеем состояние, показанное на рисунке 8.409. Рис. 8.409. Связь кнопки с командой
Теперь все те же самые действия выполним программно, из встроенного языка. подробнее
После этого можно запустить систему в режиме 1С:Предприятие и посмотреть, как работает наша команда Добавить команду. В результате ее выполнения в командной панели формы появится кнопка Новая кнопка. А при нажатии этой кнопки в окно сообщений будет выведен отладочный текст (рис. 8.410).
Пример можно посмотреть в демонстрационной базе «Разработка форм, пример 14», общая форма Форма, команда Добавить команду. Это локальная команда этой формы.
Как и раньше, модификацию формы будем выполнять в серверной контекстной процедуре. Сначала добавим команду НоваяКоманда (листинг 8.159). Листинг 8.159. Добавление команды
// Добавить команду. НоваяКоманда = Команды.Добавить("НоваяКоманда");
В результате мы имеем состояние, показанное на рисунке 8.406. Назначим этой команде обработчик – процедуру, которая была создана в модуле формы заранее, на этапе конфигурирования (листинг 8.160). Листинг 8.160. Назначение обработчика команды
НоваяКоманда.Действие = "КомандаФормыДобавленнаяПрограммно";
В результате мы имеем состояние, показанное на рисунке 8.407. Добавим кнопку в командную панель формы (листинг 8.161). Листинг 8.161. Добавление кнопки в командную панель
// Добавить кнопку и связать ее с командой. НовыйЭлемент = Элементы.Добавить("КнопкаНоваяКоманда", Тип("КнопкаФормы"), Элементы.ФормаКоманднаяПанель);
380
Рис. 8.410. Кнопка в форме
Настройки пользователей Платформа «1С:Предприятие» предоставляет возможность сохранения разнообразных настроек, сделанных пользователем в процессе работы, и доступа к ним из встроенного языка. Это, например, размеры и положение открытых форм, настройки печати табличного документа, данные форм, значения реквизитов обработок и т. д. Большинство настроек пользователя стандартно хранятся в системных таблицах информационной базы, и разработчик имеет к ним доступ. Кроме этого, разработчик может переопределить хранение большинства настроек системы и уже в составе конфигурации реализовать собственный механизм хранения настроек и доступа пользователей к ним. Исключение составляют лишь настройки отбора, порядка и группировки динамических списков, которые платформа стандартно не сохраняет. Профессиональная разработка в системе «1С:Предприятие 8»
Программирование форм
Что такое настройка Что представляет собой одна настройка? Это некоторая совокупность сохраняемых данных (в общем случае произвольная), привязанная к чему-то в конфигурации и имеющая некоторое представление. Совокупность данных, которые сохраняются, называется настройки. Например, если речь идет об автоматическом сохранении данных формы, то настройками будут являться значения, введенные пользователем в поля формы. Или если речь идет о сохранении вариантов отчетов, то настройками будут являться доступные поля, пользовательские поля, условное оформление, структура отчета и другие данные, характеризующие конкретный вариант отчета. Как мы уже сказали, настройки (сохраняемые данные) обязательно привязаны к чему-то в конфигурации. А именно – к настраиваемому объекту и к пользователю информационной базы. Что является настраиваемым объектом, зависит от вида настройки. Например, в случае вариантов отчетов настраиваемым объектом является отчет, содержащийся в конфигурации. В случае с данными формы настраиваемым объектом является форма конфигурации и так далее. Для указания того, к какому объекту принадлежит эта настройка, используется ключ объекта – значение, однозначно идентифицирующее настраиваемый объект. Если настройка сохраняется в стандартном хранилище, то ключ объекта – строка. Например, для настройки варианта отчета ключом объекта может быть строка вида Отчет.ОстаткиТоваров, а для данных формы – строка вида Обработка.ВыгрузкаДанных.Форма.Форма. Подробнее
Документация «1С:Предприятие 8.2. Руководство разработчика», Приложение 4 «Перечень автоматически сохраняемых настроек».
Если настройка сохраняется в хранилище, созданном в конфигурации, то ключ объекта может быть произвольного типа. Понятно, что одну и ту же форму, один и тот же отчет разные пользователи могут настроить по-разному. Поэтому каждая настройка однозначно привязана еще и к пользователю информационной базы. Для этого используется строка – идентификатор пользователя. Если настройка сохраняется платформой автоматически, то в качестве идентификатора пользователя платформа использует имя пользователя. Например, МухинАВ. Том 1
Кроме этого многие настраиваемые объекты допускают существование нескольких настроек. Например, один пользователь для одного отчета может создать несколько вариантов, для одной формы этот же пользователь может сохранить несколько наборов ее параметров. Чтобы отличать одну настройку этого объекта и этого пользователя от другой, используется ключ настройки – значение, однозначно идентифицирующее данную настройку в разрезе ключа объекта и идентификатора пользователя. Если настройка сохраняется в стандартном хранилище, то в качестве ключа настройки платформа использует текстовую строку, представляющую собой уникальный идентификатор (UUID). Например, 57d67b45-3ec6-4ed2-82f9-8debcc89cb85. Если настройка сохраняется в хранилище, созданном в конфигурации, то ключ настройки может быть произвольного типа. Последней характеристикой настройки является ее представление – понятное пользователю наименование настройки. Сохраняя настройку, пользователь сам задает ее представление, а при выборе из существующих настроек представление позволяет ему отличить одну настройку от другой. В результате, например, одна настройка данных форм может выглядеть следующим образом: ■■ настройки – структура, содержащая имена реквизитов формы и значения, которые пользователь ввел в эти реквизиты; ■■ ключ объекта – Обработка.ВыгрузкаДанных.Форма.Форма; ■■ ключ настройки – 57d67b45-3ec6-4ed2-82f9-8debcc89cb85; ■■ идентификатор пользователя – МухинАВ; ■■ представление – Выгрузить данные за прошлый месяц.
Как хранятся настройки Набор системных таблиц, в которых платформа автоматически сохраняет различные настройки, называется стандартное хранилище настроек. Наряду со стандартным хранилищем настроек могут существовать хранилища настроек, созданные разработчиком в конфигурации. Всего платформа различает пять видов настроек, то есть пять видов информации, которая является настройками: ■■ ■■ ■■ ■■ ■■
варианты отчетов, пользовательские настройки отчетов, данные форм, общие настройки, системные настройки.
381
Глава 8. Разработка форм Все эти настройки могут храниться в стандартном хранилище. И в то же время для хранения всех видов настроек, кроме системных, можно назначить собственное хранилище, созданное в конфигурации. Для этого предназначен вид объектов конфигурации – Хранилища настроек. Они располагаются в ветке Общие дерева конфигурации (рис. 8.411).
В стандартном хранилище сохраняются только варианты отчета, созданные в режиме 1С:Предприятие. Варианты отчета, созданные в конфигураторе, сохраняются в самой схеме компоновки данных. То же самое относится и к пользовательским настройкам вариантов. Чтобы для примера посмотреть, как выглядят настройка варианта и пользовательская настройка отчета, можно создать отчет, например ОстаткиТоваров. В режиме 1С:Предприятие сохранить вариант отчета, сохранить пользовательскую настройку этого варианта, а затем выполнить следующий код (листинг 8.163). Подробнее
Этот пример можно посмотреть в демонстрационной конфигурации «Разработка форм», пример 15. Раздел «Как получить доступ к настройкам в системном хранилище», стр. 386. Листинг 8.163. Пример работы с настройками отчетов
Рис. 8.411. Хранилища настроек
Поскольку каждый из видов настроек имеет свои особенности, рассмотрим их по отдельности.
Варианты отчетов и пользовательские настройки отчетов О том, как настраиваются отчеты, рассказано в других разделах этой книги. Здесь пойдет речь только о том, как можно хранить эти настройки. Подробнее
Том 2, глава 16, разделы «Варианты отчетов», «Пользовательские настройки».
При сохранении в стандартное хранилище для настроек вариантов отчетов ключом объекта является полное имя отчета, например Отчет. ОстаткиТоваров. Для пользовательских настроек отчетов ключом объекта является полное имя отчета плюс ключ настройки варианта отчета, к которому относится данная пользовательская настройка. Например,
если
есть
вариант
отчета
с
ключом
настройки
57d67b45-3ec6-4ed2-82f9-8debcc89cb85, то для пользовательской настройки этого варианта отчета ключ объекта будет Отчет.ОстаткиТоваров/ 57d67b45-3ec6-4ed2-82f9-8debcc89cb85.
382
// Из системного хранилища получить ключ текущего варианта отчета. КлючТекущегоВарианта = ХранилищеСистемныхНастроек .Загрузить("Отчет.ОстаткиТоваров/КлючТекущегоВарианта"); // Из хранилища вариантов отчетов получить: // - список имеющихся вариантов отчета // - описание текущего варианта отчета // - сам вариант (настройки) отчета. СписокВариантов = ХранилищеВариантовОтчетов.ПолучитьСписок("Отчет.ОстаткиТоваров"); ОписаниеВарианта = ХранилищеВариантовОтчетов .ПолучитьОписание("Отчет.ОстаткиТоваров", КлючТекущегоВарианта); ВариантОтчета = ХранилищеВариантовОтчетов .Загрузить("Отчет.ОстаткиТоваров", КлючТекущегоВарианта); // Из системного хранилища получить ключ текущей пользовательской настройки варианта. КлючВариантаОтчета = "Отчет.ОстаткиТоваров/" + КлючТекущегоВарианта; КлючТекущейПользовательскойНастройки = ХранилищеСистемныхНастроек .Загрузить(КлючВариантаОтчета + "/КлючТекущихПользовательскихНастроек"); // Из хранилища пользовательских настроек отчетов получить: // - список имеющихся пользовательских настроек для этого варианта отчета // - описание текущей пользовательской настройки // - саму пользовательскую настройку (настройки) этого варианта отчета. СписокПользовательскихНастроек = ХранилищеПользовательскихНастроекОтчетов .ПолучитьСписок(КлючВариантаОтчета); ОписаниеПользовательскойНастройки = ХранилищеПользовательскихНастроекОтчетов .ПолучитьОписание(КлючВариантаОтчета, КлючТекущейПользовательскойНастройки); ПользовательскаяНастройка = ХранилищеПользовательскихНастроекОтчетов .Загрузить(КлючВариантаОтчета, КлючТекущейПользовательскойНастройки);
И для тех, и для других настроек разработчик может переопределить стандартное хранилище этих настроек в конфигурации как на уровне всей конфигурации, т. е. сразу для всех отчетов, так и на уровне отдельного отчета. Профессиональная разработка в системе «1С:Предприятие 8»
Программирование форм В первом случае используются свойства конфигурации Хранилище вариантов отчетов и Хранилище пользовательских настроек отчетов. Во втором случае используются свойства конкретного отчета Хранилище вариантов и Хранилище настроек. Подробнее
Том 2, глава 16, раздел «Хранилище вариантов и хранилище пользовательских настроек».
Данные форм Данные форм – это значения, установленные для тех или иных реквизитов формы. Данные формы удобно сохранять, например, для того, чтобы запомнить значения, с которыми запускалась некоторая обработка. Система может сохранять данные форм двумя способами: автоматически и вручную. Автоматическое сохранение данных формы в настройках выполняется при закрытии формы. При следующем открытии этой формы сохраненные данные будут восстановлены в соответствующих реквизитах формы. Автоматическое сохранение данных всегда выполняется в системное хранилище, и переназначить его в собственное хранилище нельзя. Стандартно автоматическое сохранение данных формы в настройках отключено. Чтобы его включить у конкретной формы, нужно установить свойство Автоматическое сохранение данных формы в настройках в значение Использовать (рис. 8.412).
Рис. 8.412. Свойство «Автоматическое сохранение данных формы в настройках»
После этого в списке реквизитов формы станет доступна колонка Сохранение, в которой нужно отметить те реквизиты формы, значения которых должны автоматически сохраняться. Чтобы сохранять/восстанавливать данные формы вручную, также нужно включить одно из свойств формы – СохранениеДанныхФормыВНастройках. Вручную данные формы можно сохранить/восстановить в любой момент работы с формой с помощью стандартных команд формы Сохранить параметры…, Восстановить параметры… Эти настройки стандартно также хранятся в системном хранилище, но разработчик может переназначить хранение этих настроек в собственное хранилище. Задать собственное хранилище для данных форм можно двумя способами. Во-первых, в свойствах конфигурации. Это будет работать для всех форм, которые есть в конфигурации. Для этого у конфигурации есть свойство Хранилище настроек данных форм (рис. 8.413). Рис. 8.413. Свойство «Хранилище настроек данных форм»
Том 1
383
Глава 8. Разработка форм Во-вторых, в свойствах конкретной формы. Это будет работать только для этой формы и только при ручном сохранении настроек. Для этого у формы есть свойства (рис. 8.414): ■■ Сохранение данных формы в настройках, ■■ Хранилище настроек.
Рис. 8.415. Алгоритм сохранения настроек данных формы
Чтобы для примера посмотреть, как выглядит настройка данных формы, можно создать обработку, например ВыгрузкаДанных. Создать у нее несколько реквизитов, разместить их в форме, у формы включить свойства СохранениеДанныхФормыВНастройках и Автоматическое сохранение данных формы в настройках, отметить все реквизиты. Затем в режиме 1С:Предприятие ввести данные в поля формы, сохранить параметры (Все действия – Сохранить параметры), ввести другие данные в поля формы и закрыть форму. Затем выполнить следующий код (листинг 8.164). Подробнее
Этот пример можно посмотреть в демонстрационной конфигурации «Разработка форм», пример 15. Раздел «Как получить доступ к настройкам в системном хранилище», стр. 386. Рис. 8.414. Свойства формы для назначения хранилища
Таким образом, когда система решает, куда сохранить настройки данных форм, она действует по следующему алгоритму (рис. 8.415): 1. Сначала смотрит свойства формы. Если в них указано какое-то хранилище, сохраняет в него. 2. Если в свойствах формы ничего не указано, платформа смотрит свойства конфигурации. Если в них указано какое-то хранилище, она сохраняет в него. 3. Если в свойствах конфигурации тоже ничего не указано, она сохраняет в стандартное хранилище (в системные таблицы информационной базы).
384
Листинг 8.164. Пример работы с настройками данных формы
// Из системного хранилища получить данные формы, сохраненные автоматически. ТекущаяНастройкаДанныхФормы = ХранилищеСистемныхНастроек .Загрузить("Обработка.ВыгрузкаДанных.Форма.Форма/ТекущиеДанные"); // Из системного хранилища получить ключ текущих настроек данных формы. КлючТекущихНастроекДанныхФормы = ХранилищеСистемныхНастроек .Загрузить("Обработка.ВыгрузкаДанных.Форма.Форма/КлючТекущихНастроекДанных"); // Из хранилища данных формы получить: // - список имеющихся настроек данных формы // - описание настройки данных формы // - сами данные (настройки) формы. СписокНастроекДанныхФормы = ХранилищеНастроекДанныхФорм .ПолучитьСписок("Обработка.ВыгрузкаДанных.Форма.Форма"); ОписаниеНастройкиДанныхФормы = ХранилищеНастроекДанныхФорм .ПолучитьОписание("Обработка.ВыгрузкаДанных.Форма.Форма",
Профессиональная разработка в системе «1С:Предприятие 8»
Программирование форм КлючТекущихНастроекДанныхФормы); НастройкаДанныхФормы = ХранилищеНастроекДанныхФорм .Загрузить("Обработка.ВыгрузкаДанных.Форма.Форма", КлючТекущихНастроекДанныхФормы);
Общие настройки Общие настройки разработчик может придумать сам. Под общими настройками понимаются произвольные настройки, относящиеся к конкретной конфигурации. Что это за настройки – должен определить сам разработчик, исходя из логики работы своего прикладного решения. Платформа самостоятельно не сохраняет никакие общие настройки. Но разработчик может сохранять всевозможные собственные настройки. Либо в стандартном хранилище, либо в хранилище, созданном в конфигурации. Для этого используются методы менеджера конкретного хранилища конфигурации Сохранить() и Загрузить(). Хранилище общих настроек можно получить с помощью одноименного свойства глобального контекста ХранилищеОбщихНастроек. Причем, если в свойствах конфигурации не указано специального хранилища для общих настроек, будет возвращен экземпляр менеджера стандартного хранилища, обслуживающий общие настройки. Если в свойстве конфигурации указано конкретное хранилище, будет возвращен менеджер этого хранилища (рис. 8.416).
Рис. 8.417. Свойство «Хранилище общих настроек» Листинг 8.165. Пример работы с общими настройками
// Задать представление первой настройки. ОписаниеПервойНастройки = Новый ОписаниеНастроек; ОписаниеПервойНастройки.Представление = "Представление первой настройки"; // Для примера – некоторый список значений. ДанныеНастройки = Новый Структура("Настройка11, Настройка12", 1, 2); // Сохранить первую настройку. // Пользователь не указан – настройка будет сохранена для текущего пользователя. ХранилищеОбщихНастроек.Сохранить("МойКлючОбъекта", "КлючНастройки1", ДанныеНастройки, ОписаниеПервойНастройки); Рис. 8.416. Алгоритм сохранения общих настроек
Для этого у конфигурации есть свойство Хранилище общих настроек (рис. 8.417). Попробовать работу с общими настройками можно на следующем примере (листинг 8.165). Подробнее
Этот пример можно посмотреть в демонстрационной конфигурации «Разработка форм», пример 15. Раздел «Как получить доступ к настройкам в системном хранилище», стр. 386.
Том 1
// Задать представление второй настройки. ОписаниеВторойНастройки = Новый ОписаниеНастроек; ОписаниеВторойНастройки.Представление = "Представление второй настройки"; // Для примера – хранилище значения. ДанныеНастройки = Новый ХранилищеЗначения("Некоторое значение"); // Сохранить вторую настройку. // Пользователь не указан – настройка будет сохранена для текущего пользователя. ХранилищеОбщихНастроек.Сохранить("МойКлючОбъекта", "КлючНастройки2", ДанныеНастройки, ОписаниеВторойНастройки); // Получить из хранилища общих настроек: // - список моих настроек // - описание каждой настройки // - сами настройки.
385
Глава 8. Разработка форм СписокОбщихНастроек = ХранилищеОбщихНастроек.ПолучитьСписок("МойКлючОбъекта"); ОписаниеНастройки1 = ХранилищеОбщихНастроек.ПолучитьОписание("МойКлючОбъекта", "КлючНастройки1"); ОписаниеНастройки2 = ХранилищеОбщихНастроек .ПолучитьОписание("МойКлючОбъекта", "КлючНастройки2"); Настройка1 = ХранилищеОбщихНастроек.Загрузить("МойКлючОбъекта", "КлючНастройки1"); Настройка2 = ХранилищеОбщихНастроек.Загрузить("МойКлючОбъекта", "КлючНастройки2");
Системные настройки Системные настройки – это настройки, которые требуются для работы системы вообще, безотносительно к конкретному прикладному решению. Например, это расположение и размеры открытых форм, настройки печати табличного документа, избранное, настройки глобального командного интерфейса, рабочего стола и так далее. Возможность переопределить хранение системных настроек отсутствует. Поэтому система всегда сохраняет их в стандартное хранилище (в системные таблицы информационной базы), рис. 8.418.
Листинг 8.166. Пример работы с системными настройками
// Настройка отображения формы: состав элементов, взаимное расположение и свойства элементов. // Сохраняется после изменения формы в режиме 1С:Предприятие (Все действия – Изменить форму). НастройкаОтображенияФормы = ХранилищеСистемныхНастроек .Загрузить("Обработка.ВыгрузкаДанных.Форма.Форма/НастройкиФормы");
// Размеры формы и элементов управления, положение разделителей и ширины колонок таблиц. РазмерыФормы = ХранилищеСистемныхНастроек .Загрузить("Обработка.ВыгрузкаДанных.Форма.Форма/НастройкиОкна"); // Избранное. Избранное = ХранилищеСистемныхНастроек.Загрузить("Общее/ИзбранноеРаботыПользователя"); // Настройка панели разделов // сохраняется после изменения панели разделов (Настройка панели разделов…). ПанельРазделов = ХранилищеСистемныхНастроек .Загрузить("Общее/ПанельРазделов/НастройкиКомандногоИнтерфейса"); // Настройка панели действий // сохраняется после изменения панели действий (Настройка панели действий…). ПанельДействий = ХранилищеСистемныхНастроек .Загрузить("Подсистема.Продажи/ПанельДействий/НастройкиКомандногоИнтерфейса"); // Настройка панели навигации // сохраняется после изменения панели навигации (Настройка панели навигации…). ПанельНавигации = ХранилищеСистемныхНастроек .Загрузить("Подсистема.Продажи/ПанельНавигации/НастройкиКомандногоИнтерфейса"); // Настройки рабочего стола (состав и расположение форм на рабочем столе) // сохраняются после изменения рабочего стола (Настройка рабочего стола…). РабочийСтол = ХранилищеСистемныхНастроек.Загрузить("Общее/НастройкиРабочегоСтола");
Рис. 8.418. Сохранение системных настроек
Значения системных настроек – это объекты без свойств и методов. Практический смысл их использования в основном заключается в обмене настройками между разными пользователями. Исключение составляет лишь избранное, в котором есть возможность работать с отдельными элементами избранного. Подробнее
Этот пример можно посмотреть в демонстрационной конфигурации «Разработка форм», пример 15. Раздел «Избранное», стр. 21.
Далее приведен пример получения различных системных настроек (листинг 8.166).
Как получить доступ к настройкам в системном хранилище При программной работе с настройками нужно использовать методы того хранилища, в котором находятся нужные нам настройки. В общем случае ситуация выглядит следующим образом: все настройки могут храниться в стандартном хранилище, или часть из них может храниться в хранилищах, созданных в конфигурации (рис. 8.419). Поэтому существуют методы глобального контекста, которые позволяют получить нужное хранилище, исходя из вида настроек, с которыми предполагается работать. Если вы хотите работать с системными настройками, то нужно использовать свойство глобального контекста ХранилищеСистемныхНастроек. Оно всегда возвращает менеджер стандартного хранилища (листинг 8.167). Листинг 8.167. Менеджер для работы с системными настройками
МенеджерСтандартногоХранилища = ХранилищеСистемныхНастроек;
386
Профессиональная разработка в системе «1С:Предприятие 8»
Программирование форм В случае, когда настройки хранятся в стандартном хранилище (за исключением общих настроек), используются зарезервированные ключи объектов, которые описаны в документации. Подробнее
Документация «1С:Предприятие 8.2. Руководство разработчика», Приложение 4 «Перечень автоматически сохраняемых настроек».
Если настройки хранятся в хранилищах, созданных в конфигурации, то предполагается, что ключи объектов либо совпадают с зарезервированными, либо описаны в документации к прикладному решению.
Когда нужно создавать собственные хранилища настроек Общий подход к работе с хранилищами настроек следующий. Рис. 8.419. Варианты хранения настроек
Если вы хотите работать с общими настройками, то нужно использовать свойство глобального контекста ХранилищеОбщихНастроек. Оно вернет либо менеджер стандартного хранилища, либо менеджер хранилища, созданного в конфигурации, если это хранилище указано в свойстве конфигурации ХранилищеОбщихНастроек (листинг 8.168). Листинг 8.168. Менеджер для работы с общими настройками
МенеджерХранилищаОбщихНастроек = ХранилищеОбщихНастроек;
С настройками вариантов отчета, данных форм и пользовательскими настройками отчетов сложнее. В принципе для них также существуют отдельные свойства глобального контекста: ХранилищеВариантовОтчетов, ХранилищеНастроекДанныхФорм и ХранилищеПользовательскихНастроекОтчетов. Эти свойства вернут либо менеджер стандартного хранилища, либо менеджер хранилища, созданного в конфигурации, если сохранение этого вида настроек переопределено в свойствах конфигурации. Однако если хранение этих видов настроек переопределено в конкретных отчетах или формах, то перечисленные свойства глобального контекста никак на это не отреагируют. В этом случае нужно использовать свойство глобального контекста ХранилищаНастроек и имя нужного хранилища, определенного в конфигурации (листинг 8.169). Листинг 8.169. Менеджер для работы с хранилищем, созданным в конфигурации
МенеджерМоегоХранилища = ХранилищаНастроек.МоеХранилище;
Для получения данных из хранилища или для сохранения данных в хранилище обязательно нужно знать ключ объекта, к которому относится настройка. Том 1
Предполагается, что в простых конфигурациях будет использоваться стандартный механизм хранения настроек в стандартном хранилище. Это не требует от разработчика какого-либо кодирования. А вот в сложных конфигурациях разработчик будет создавать собственные хранилища настроек и самостоятельно управлять сохранением и загрузкой пользовательских настроек. В каких ситуациях может понадобиться использовать собственное хранилище настроек? 1. Когда нужна особенная структура хранения настроек. Например, чтобы они были привязаны к подразделению. Чтобы у всех пользователей одного подразделения были одинаковые настройки. 2. Когда требуется обмен настройками в распределенной информационной базе, потому что стандартное хранилище не участвует в обмене в распределенной информационной базе. 3. Когда нужно легкое и/или особенное (нестандартное) администрирование настроек.
Как организовать собственное хранилище настроек Создание собственного хранилища конфигурации рассмотрим на небольшом примере. Он покажет сохранение настроек данных формы обработки в хранилище, созданном в конфигурации, и получение их из хранилища. Подробнее
Этот пример можно посмотреть в демонстрационной конфигурации «Разработка форм», пример 16.
387
Глава 8. Разработка форм Сначала добавим объект конфигурации киФорм.
Хранилище настроек – Настрой-
Перейдем к реквизитам формы и для всех реквизитов отметим, что их значения будут сохраняться.
Затем укажем это хранилище в свойстве конфигурации Хранилище настроек данных форм. Это будет означать, что данные любой формы можно будет сохранить в этом хранилище.
Для красоты, хотя можно этого и не делать, вынесем стандартные команды сохранения и восстановления параметров прямо в форму (рис. 8.420).
После этого добавим объект конфигурации, в котором собственно и будут храниться сами настройки. Можно использовать любой объект, который подходит для этого с точки зрения разработчика. Мы будем использовать справочник. Добавим справочник ХранилищеДанныхФорм с реквизитами: ■■ КлючОбъекта (тип Строка, длина 255); ■■ ДанныеФормы (тип ХранилищеЗначения). Реквизит для хранения пользователя, которому принадлежит настройка, мы не создаем. Все настройки данных форм будут у нас одинаковы для всех пользователей. Заметьте, мы создали хранилище, создали справочник, в котором будут храниться настройки. Но пока они никак между собой не связаны. То есть из свойств конфигурации известно, что данные формы будут храниться не в стандартном хранилище, а в каком-то другом, но где «физически» расположено это хранилище – пока не известно. Позже мы увидим, как устанавливается эта связь. Теперь добавим объект конфигурации Обработка. На примере формы этой обработки посмотрим, как работает сохранение данных формы в настройках. Обработку назовем ЗаполнитьСправочники. Она (теоретически) будет добавлять в выбранный справочник указанное количество элементов и задавать их наименование. Для этого у обработки будет четыре реквизита: ■■ Справочник (тип Строка, длина 10, переменная) – для указания имени заполняемого справочника; ■■ Наименование (тип Строка, длина 20, переменная) – для указания строки, с которой будет начинаться наименование добавляемых элементов; обработка будет автоматически добавлять к нему порядковый номер элемента; ■■ НачинатьСНомера (тип Число, длина 10) – порядковый номер, с которого начинается добавление номеров к наименованию элементов; ■■ КоличествоДобавляемыхЭлементов (тип Число, длина 10) – количество элементов, которые будут добавлены в справочник. Создадим форму этой обработки, и свойство формы Сохранение данных в настройках установим в значение Использовать список.
388
Рис. 8.420. Форма обработки «Заполнить справочники»
Теперь у хранилища настроек НастройкиФорм с помощью конструктора создадим две стандартные формы: форму загрузки настроек, форму сохранения настроек. Чтобы познакомиться с механикой сохранения и восстановления настроек в собственное хранилище, создадим у этих форм обработчики событий При создании на сервере, в которых напишем любой оператор, на который можно установить точку останова, например, а=4;. И установим на нем точку останова. Такой же текст напишем в обработчиках модуля менеджера хранилища настроек: ОбработкаЗагрузки, ОбработкаСохранения. Если теперь запустить отладочный сеанс «1С:Предприятия», то мы увидим, что при открытии обработки ЗаполнитьСправочники и выполнении команды Сохранить параметры… открывается форма сохранения нашего хранилища настроек, а при выполнении команды Восстановить параметры… открывается форма загрузки настроек. Больше пока ничего не происходит. Особенность работы с собственными хранилищами настроек как раз и заключается в том, что весь алгоритм сохранения настроек должен Профессиональная разработка в системе «1С:Предприятие 8»
Программирование форм быть написан на встроенном языке в основных формах сохранения и загрузки настроек хранилища. Именно он и будет определять, в каком именно объекте конфигурации будут «физически» храниться настройки. Кроме этого, при правильном написании будут вызываться также и обработчики из модуля менеджера хранилища. Итак, рассмотрим самый простой способ сохранения и загрузки данных формы. Сначала займемся сохранением. Когда система вызывает основную форму сохранения, она передает ей два стандартных параметра: КлючОбъекта и КлючТекущихНастроек. В случае сохранения данных формы ключ текущих настроек всегда будет иметь значение Неопределено, а вот КлючОбъекта будет строкой вида Обработка.ЗаполнитьСправочники.Форма.Форма.
То есть ключ объекта содержит полное имя формы, для которой сохраняются настройки, и тем самым однозначно идентифицирует эту форму среди остальных форм конфигурации. Для сохранения настройки нам нужно будет знать следующую информацию: ■■ ее ключ (ключ объекта); ■■ ее наименование, понятное пользователю (чтобы пользователь мог отличить одну настройку от другой); ■■ саму настройку, то есть сами значения сохраняемых реквизитов. В форме сохранения нам нужно узнать и обработать ключ объекта и наименование настройки. Саму же настройку мы получим в обработчике менеджера хранилища настройки. Поэтому создадим у формы сохранения два реквизита: КлючОбъекта и ИмяСохраняемойНастройки, оба типа Строка. КлючОбъекта – чтобы запомнить в нем ключ, переданный платформой в параметры формы, ИмяСохраняемойНастройки – чтобы запомнить имя
настройки, которое введет пользователь.
В обработчике события При создании на сервере запомним в реквизите КлючОбъекта тот ключ объекта, который платформа передаст нам в параметрах формы. Этот ключ понадобится нам в дальнейшем (листинг 8.170). Листинг 8.170. Сохранение ключа объекта
&НаСервере Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка) КлючОбъекта = Параметры.КлючОбъекта; КонецПроцедуры
Том 1
Теперь реквизит ИмяСохраняемойНастройки разместим в форме и создадим у формы команду Сохранить. В обработчике этой команды нужно подготовиться к сохранению настроек: создать в справочнике ХранилищеДанныхФорм новый элемент и указать ему тот ключ объекта, который мы имеем, чтобы в дальнейшем в обработчике модуля менеджера хранилища настроек записать в этот элемент справочника сохраняемые настройки. Естественно, сейчас мы рассматриваем упрощенный вариант и не программируем случай, когда пользователь сознательно или случайно перезаписывает настройки, уже существующие в справочнике. Итак, в обработчике нашей команды Сохранить вызываем серверную функцию, которая создает новый элемент в справочнике ХранилищеДанныхФорм, записывает в него имеющийся ключ объекта, имя настройки и возвращает код этого элемента справочника (листинг 8.171). Листинг 8.171. Создание элемента справочника для хранения настроек
&НаКлиенте Процедура Сохранить(Команда) КодНовогоЭлемента = СоздатьЭлементСправочника(КлючОбъекта, ИмяСохраняемойНастройки); КонецПроцедуры &НаСервереБезКонтекста Функция СоздатьЭлементСправочника(КлючОбъекта, ИмяСохраняемойНастройки) НовыйЭлемент = Справочники.ХранилищеДанныхФорм.СоздатьЭлемент(); НовыйЭлемент.Наименование = ИмяСохраняемойНастройки; НовыйЭлемент.КлючОбъекта = КлючОбъекта; НовыйЭлемент.Записать(); Возврат НовыйЭлемент.Код; КонецФункции
Теперь осталось только каким-то образом вызвать обработчик из модуля нашего хранилища настроек. Форма сохранения вызывается модально, и для того, чтобы вызвать обработчик из модуля хранилища настроек, используется возврат параметра при закрытии модальной формы. В качестве параметра возвращается объект ВыборНастроек, созданный конструктором (листинг 8.172). Листинг 8.172. Вызов обработчика из модуля хранилища настроек
&НаКлиенте Процедура Сохранить(Команда) КодНовогоЭлемента = СоздатьЭлементСправочника(КлючОбъекта, ИмяСохраняемойНастройки); Закрыть(Новый ВыборНастроек(КодНовогоЭлемента)); КонецПроцедуры
389
Глава 8. Разработка форм Если теперь запустить отладочный сеанс «1С:Предприятия», открыть обработку ЗаполнитьСправочники и выполнить команду Сохранить параметры…, указать имя, под которым будут сохранены данные, и нажать Сохранить, то мы увидим, что после закрытия формы сохранения вызывается обработчик ОбработкаСохранения в модуле нашего хранилища настроек. В этом обработчике нам собственно только останется записать настройки в созданный нами элемент справочника ХранилищеДанныхФорм. Настройки платформа передает нам в одноименном параметре этого обработчика (листинг 8.173). Листинг 8.173. Запись настроек в элемент справочника
Процедура ОбработкаСохранения(КлючОбъекта, КлючНастроек, Настройки, ОписаниеНастроек, Пользователь) ХранилищеДанныхФормСсылка = Справочники.ХранилищеДанныхФорм.НайтиПоКоду(КлючНастроек); ХранилищеДанныхФормОбъект = ХранилищеДанныхФормСсылка.ПолучитьОбъект(); ХранилищеДанныхФормОбъект.ДанныеФормы = Новый ХранилищеЗначения(Настройки, Новый СжатиеДанных()); ХранилищеДанныхФормОбъект.Записать(); КонецПроцедуры
Теперь займемся загрузкой настроек. Процесс загрузки настроек является противоположностью процессу их сохранения. Сначала нужно узнать, какую настройку загружать, а затем достать ее из хранилища настроек. Для этого в форме загрузки можно разместить список имеющихся сохраненных настроек, отобранных по нужному ключу объекта (полному имени формы). Для этого нужен реквизит формы (например СписокНастроек) типа ДинамическийСписок с произвольным запросом, например (листинг 8.174). Листинг 8.174. Запрос для динамического списка имеющихся настроек
ВЫБРАТЬ ХранилищеДанныхФорм.Код, ХранилищеДанныхФорм.Наименование ИЗ Справочник.ХранилищеДанныхФорм КАК ХранилищеДанныхФорм ГДЕ ХранилищеДанныхФорм.КлючОбъекта = &КлючОбъекта
В обработчике события При создании на сервере нужно передать в этот запрос имеющийся ключ объекта (листинг 8.175). Листинг 8.175. Передача параметра в запрос динамического списка
&НаСервере Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка) СписокНастроек.Параметры.УстановитьЗначениеПараметра("КлючОбъекта", Параметры.КлючОбъекта); КонецПроцедуры
390
После этого создадим в форме команду Загрузить, разместим ее в форме и напишем такой текст команды (листинг 8.176). Листинг 8.176. Вызов обработчика из модуля хранилища настроек
&НаКлиенте Процедура Загрузить(Команда) Закрыть(Новый ВыборНастроек(Элементы.СписокНастроек.ТекущиеДанные.Код)); КонецПроцедуры
Собственно, здесь при закрытии формы загрузки мы возвращаем в обработчик модуля менеджера хранилища код выбранного пользователем элемента справочника, хранящего настройки. А в самом обработчике ОбработкаЗагрузки модуля менеджера хранилища мы просто получаем настройки из элемента справочника и передаем их в параметр Настройки этого обработчика (листинг 8.177). Листинг 8.177. Получение настроек из элемента справочника
Процедура ОбработкаЗагрузки(КлючОбъекта, КлючНастроек, Настройки, ОписаниеНастроек, Пользователь) ХранилищеДанныхФормСсылка = Справочники.ХранилищеДанныхФорм.НайтиПоКоду(КлючНастроек); Настройки = ХранилищеДанныхФормСсылка.ДанныеФормы.Получить(); КонецПроцедуры
Вот так в простейшем случае выглядит интерактивное сохранение и загрузка настроек, когда используется хранилище, созданное в конфигурации. Если работа с настройками выполняется только программными средствами, то для этого используется менеджер конкретного хранилища настроек и его методы Сохранить() и Загрузить(). В результате вызываются соответственно обработчики событий ОбработкаСохранения и ОбработкаЗагрузки менеджера хранилища. В этом случае разработчику нужно самому позаботиться о том, чтобы сформировать и передать в эти методы ключ объекта, ключ настроек, настройки и другие необходимые параметры. Подробнее
Документация «1С:Предприятие 8.2. Руководство разработчика», глава 5 «Объекты конфигурации».
Профессиональная разработка в системе «1С:Предприятие 8»
Оптимизация клиент-серверного взаимодействия в формах
Оптимизация клиент-серверного взаимодействия в формах
Таким образом, разработчику при проектировании клиент-серверного взаимодействия в конфигурации нужно стремиться минимизировать количество вызовов сервера, которые он инициирует своим кодом.
Общие рекомендации по оптимизации клиент-серверного взаимодействия
Также разработчику нужно оптимизировать не только количество вызовов, но и объем передаваемых данных между клиентом и сервером (трафик). Неэффективность решения особенно будет заметна при работе через низкоскоростные каналы связи. Чтобы визуально оценить скорость работы на плохом канале связи, рекомендуется запускать клиентское приложение в режиме низкой скорости соединения (стр. 393), а в параметрах системы включать режим имитации задержек при вызове сервера (стр. 395).
Как уже говорилось при описании подхода к программированию форм, форма должна быть легкой, доступной в веб-клиенте и работать максимально быстро даже при использовании низкоскоростных каналов связи. Данные формы присутствуют как на клиенте, так и на сервере и автоматически синхронизируются при клиент-серверном взаимодействии. Передача данных между сервером и клиентом происходит во многих случаях: например, при открытии формы и записи данных платформа сама преобразовывает прикладные объекты в данные формы и обратно. При контекстных вызовах процедур модуля формы все изменения данных формы и ее элементов платформа передает на сервер и обратно т. д. Однако нужно понимать, что любое обращение на сервер – это непростой процесс. Платформа формирует обращение к серверу, передает его по каналу связи, выполняет какие-то действия на сервере, возвращает ответ по каналу связи… При работе тонкого клиента через GPRS каждый вызов сервера занимает примерно 1,5 секунды. Это, естественно, сказывается на быстродействии прикладного решения. Поэтому разработку управляемого приложения необходимо вести с контролем количества вызовов серверных процедур и функций из клиентского кода, а также объема передаваемых данных между клиентом и сервером (трафика). Общее количество серверных вызовов складывается: ■■ из обращений на сервер, которые выполняет платформа «1С:Предприятие»; ■■ вызовов, которые выполняются из клиентского кода конфигурации разработчиком. Если рассматривать источник этих вызовов, то существует несколько категорий серверных вызовов: ■■ вызовы, которые платформа делает в результате того, что пользователь совершает какие-то интерактивные действия. На это разработчик повлиять не может; ■■ вызовы, которые платформа также делает самостоятельно, но при выполнении определенных методов или свойств программного кода. На это разработчик может повлиять, если попробует использовать другие методы, свойства или изменить алгоритм; ■■ серверные вызовы, которые разработчик делает в явном виде в коде. Том 1
В связи с этим методика оптимизации клиент-серверного взаимодействия базируется на следующих общих рекомендациях: ■■ клиент и сервер рассматриваются как два взаимодействующих приложения; ■■ разработчик программирует в явном виде серверную и клиентскую части конфигурации; ■■ структура кода определяется логикой клиент-серверного взаимодействия, а не логикой того прикладного алгоритма, который реализует разработчик; ■■ клиентский код продумывается не как последовательность действий, которую нужно выполнить, а как сценарий передачи управления между клиентом и сервером; ■■ разработчик должен минимизировать частоту вызовов сервера и объем передаваемой между клиентом и сервером информации (трафик); ■■ нужно реализовывать алгоритмы так, чтобы было минимум кода на клиенте, но и минимум обращений к серверу. Приведенный выше и подробно рассмотренный далее (стр. 397) список рекомендаций – далеко не окончательный и не полный. Это скорее те рекомендации, которые очевидны уже прямо сейчас, в момент написания этой книги. Но для более полной картины требуется, конечно, накопление опыта по мере разработки прикладных решений на новой платформе. Важно понимать, что стремление оптимизировать код конфигурации должно быть в разумных пределах. Не нужно слепо следовать инструкциям и впадать в крайности. В погоне за оптимизацией можно сделать программный код совершенно нечитаемым. То есть за приемами оптимизации уже не будет видно собственно самой прикладной задачи, которая реализуется этим кодом. В этом случае поддержка такого кода станет очень сложным делом. Человек, который не принимал участия в написании этого кода, скорее всего, просто не станет раскапывать этот кладезь оптимизации. А сам разработчик через полгода – год тоже с большим трудом сможет разобраться в том, что же он написал…
391
Глава 8. Разработка форм Таким образом, нужно искать «золотую середину» между стройным читаемым кодом и его оптимизацией. Не нужно всегда бездумно стремиться только к одной лишь оптимизации.
Причем стандартно в этом окне будет показано только количество вызовов сервера (накопленное и текущее), а само окно показателей производительности будет плавно исчезать через 10 секунд, если курсор мыши не расположен над этим окном.
Инструменты, используемые при оптимизации клиент-серверного взаимодействия
При новых вызовах сервера в процессе работы «1С:Предприятия» это окно будет снова всплывать. Чтобы просто еще раз открыть окно показателей производительности, когда оно уже погасло, можно нажать кнопку Показатели производительности в информационной панели приложения.
В процессе отладки и работы конфигурации разработчику доступны следующие инструменты, которые он может использовать при оптимизации клиент-серверного взаимодействия: ■■ ■■ ■■ ■■
показатели производительности, режим низкой скорости соединения, режим имитации задержек при вызове сервера, отображение серверных вызовов в замерах производительности.
Рассмотрим каждый из них подробнее.
Значок в информационной панели приложения означает, что отображение показателей производительности включено. Включить/ выключить его можно как в настройках конфигуратора, так и в режиме 1С:Предприятие. При запуске сеанса «1С:Предприятия» из конфигуратора отображение показателей производительности по умолчанию включено. В этом можно убедиться, выполнив команду главного меню конфигуратора Сервис Параметры Запуск 1С:Предприятия Дополнительные (рис. 8.422).
Показатели производительности Показатели производительности прикладного решения позволяют разработчику оценить, насколько эффективно работает прикладное решение. Они отражают информацию о количестве текущих и накопленных вызовов сервера, длительности вызовов сервера, объеме принятых и отправленных данных (рис. 8.421).
Рис. 8.421. Окно показателей производительности в режиме «1С:Предприятие»
Текущие вызовы – это вызовы сервера с момента последнего действия пользователя. Накопленные вызовы – это вызовы сервера с момента запуска приложения или с момента обнуления накопленных показателей. Принято – это объем данных, принятых клиентом от сервера. Отправлено – это объем данных, отправленных с клиента на сервер. Запустив «1С:Предприятие» при включенном отображении показателей производительности, разработчик в реальном времени может увидеть и оценить количество и длительность серверных вызовов, а также объем переданных данных между клиентом и сервером. Анализ этих показателей позволит разработчику оптимизировать клиент-серверное взаимодействие в целях повышения эффективности работы прикладного решения. Окно показателей производительности будет стандартно всплывать в левом нижнем углу монитора при выполнении каких-либо действий, приводящих к вызову сервера в процессе работы «1С:Предприятия». Это окно можно мышью перетащить в любое другое место экрана.
392
Рис. 8.422. Настройка отображения показателей производительности в режиме «Конфигуратор»
В текущем сеансе «1С:Предприятия» можно включить отображение окна показателей производительности, выполнив команду главного меню Сервис Параметры и поставив флажок Отображать показатели производительности (рис. 8.423). Отображение показателей производительности также можно включить, запустив «1С:Предприятие» из командной строки с параметром /DisplayPerformance. Профессиональная разработка в системе «1С:Предприятие 8»
Оптимизация клиент-серверного взаимодействия в формах Подробнее
Документация «1С:Предприятие 8.2. Руководство разработчика», раздел 23.4.
Таким образом, чтобы оптимизировать разрабатываемое приложение, разработчику нужно запустить «1С:Предприятие» в режиме отладки из конфигуратора и проанализировать показатели производительности, отражающие клиент-серверное взаимодействие в процессе работы прикладного решения.
Режим низкой скорости соединения При оптимизации клиент-серверного взаимодействия бывает важно и интересно посмотреть, насколько эффективно прикладное решение будет работать при использовании низкоскоростных каналов связи. Рис. 8.423. Настройка отображения показателей производительности в режиме «1С:Предприятие»
Щелкнув правой кнопкой мыши на окне показателей производительности, можно выполнить различные команды контекстного меню: просмотреть историю текущих и накопленных вызовов сервера, обнулить накопленные показатели. Выбрав из контекстного меню пункт Настройка, можно настроить отображение различных показателей производительности – Объем отправленных данных, Объем принятых данных и т. д. (рис. 8.424).
Дело в том, что клиентский компьютер может быть подключен к серверу как по локальной сети, так и через Интернет. Связь с сервером через Интернет может устанавливаться не только через быстрые оптоволоконные каналы, но и через модемы, использующие такие протоколы доступа к данным, как GPRS и т. п. В этом случае администратору или пользователю «1С:Предприятия» нужно указать клиентскому приложению, что оно должно запуститься в режиме низкой скорости соединения. Режим низкой скорости соединения – это способ работы клиентского приложения, позволяющий ему функционировать на медленных каналах связи как можно эффективнее. При запуске в этом режиме платформа автоматически предпринимает шаги по оптимизации взаимодействия с сервером. Она отключает некоторую функциональность прикладного решения, например, не показывает рабочий стол и картинки разделов, объединяет и минимизирует вызовы сервера, дополнительно сжимает данные и т. д. Таким образом, даже на плохом канале связи, в режиме низкой скорости соединения «1С:Предприятие» будет обеспечивать приемлемую скорость работы пользователей. Заметим, что установка низкой скорости соединения имеет смысл только для тонкого клиента и веб-клиента, так как толстый клиент не умеет работать через Интернет.
Рис. 8.424. Настройка состава показателей производительности
Если снять флажок Скрывать окно показателей производительности автоматически в окне настройки, то окно показателей производительности будет постоянно висеть внизу экрана. Том 1
Задать низкую скорость соединения можно для всей информационной базы при ее создании или редактировании в списке информационных баз в стартовом окне «1С:Предприятия» (рис. 8.425). Также если в свойстве Скорость соединения информационной базы установлено Выбирать при запуске, то режим низкой скорости соединения может задать сам пользователь в диалоге выбора информационной базы (рис. 8.426).
393
Глава 8. Разработка форм Подробнее
Встроенная справка в режиме Конфигуратор – Справка
Содержание справки Запуск 1С:Предприятия 8 Общие параметры запуска, а также Параметры командной строки в режиме веб-клиента.
Для сеансов «1С:Предприятия», запускаемых из конфигуратора, тоже можно задать режим низкой скорости соединения. Для этого нужно выполнить команду главного меню Сервис Параметры Запуск 1С:Предприятия Основные и установить флажок Низкая скорость соединения (рис. 8.427).
Рис. 8.425. Установка скорости соединения в свойствах информационной базы
Рис. 8.426. Установка скорости соединения в диалоге выбора информационной базы
Кроме этого, при любых настройках информационной базы низкую скорость соединения можно указать с помощью параметра командной строки. Для запуска тонкого (листинг 8.178).
клиента
используется
параметр
/O
Low
Листинг 8.178. Установка низкой скорости соединения тонкого клиента в командной строке
HTTP,
Листинг 8.179. Установка низкой скорости соединения веб-клиента в командной строке
http://demo-ma.1c.ru/demo_ma?N=Administrator&O=Low
Режим низкой скорости соединения, как уже говорилось выше, сказывается на внешнем функционировании тонкого клиента и веб-клиента. Например, не отображается рабочий стол при старте приложения, не отображаются картинки разделов, автоматически не формируется список выбора при вводе по строке и т. д. Если в режиме 1С:Предприятие вызвать окно информации о программе (Справка О программе), то можно увидеть, на какой скорости соединения запущено приложение (рис. 8.428).
"C:\Program Files\1cv82\1cv8c.exe" /F D:\myBase /O Low
Для веб-клиента и тонкого клиента, подключаемого по протоколу используется параметр /O=Low (листинг 8.179).
Рис. 8.427. Установка скорости соединения в режиме «Конфигуратор»
Заметим, что режим низкой скорости соединения задается один раз при запуске клиентского приложения и не может быть изменен в процессе его работы. Подробнее
Документация «1С:Предприятие 8.2. Руководство разработчика», приложение 7, раздел 7.1.
394
Профессиональная разработка в системе «1С:Предприятие 8»
Оптимизация клиент-серверного взаимодействия в формах Режим имитации задержек при вызове сервера можно задать в параметрах конфигуратора, чтобы при запуске в режиме отладки приложение сразу работало в «плохих условиях». Для этого нужно выполнить команду главного меню Сервис Параметры Запуск 1С:Предприятия Основные и установить флажок Имитировать задержку при вызовах сервера (рис. 8.429).
Рис. 8.428. Окно информации о программе
Таким образом, чтобы визуально оценить, с какой скоростью будет работать прикладное решение у клиента на низкоскоростном канале связи, разработчику нужно подключиться к Интернету, например, через мобильный телефон, и запустить тонкого клиента в режиме низкой скорости соединения.
Имитация задержек при вызове сервера Однако разработчик может и не использовать специальные медленные соединения через Интернет, но при этом оценить реальную скорость работы его прикладного решения у клиента. Для этого предназначен режим имитации задержек при вызове сервера. При включении этого режима платформа (даже в файловом варианте на локальном компьютере) будет работать с теми временными задержками, с которыми работает реальный канал связи. Этот режим не нужно путать с режимом низкой скорости соединения. Режим низкой скорости соединения – это скорее инструмент пользователя. Пользователь устанавливает этот режим, чтобы приложение на медленных каналах связи работало как можно быстрее. Этот режим задается при запуске клиентского приложения и не может быть изменен в процессе его работы. Режим имитации задержек при вызове сервера – это инструмент разработчика, позволяющий ему превратить быстрый канал связи в медленный. Причем сделать это можно как при запуске приложения, так и в процессе его работы. При этом режим, в котором было запущено клиентское приложение, не изменится. Заметим, что включить режим имитации задержек при вызове сервера можно только для тонкого клиента и толстого клиента, запущенного в режиме управляемого приложения. Том 1
Рис. 8.429. Установка имитации задержек при вызове сервера в режиме «Конфигуратор»
При этом можно установить нужные временные задержки при вызове сервера и при передаче/получении данных с сервера. Платформа использует стандартные задержки, соответствующие мобильному интернет-соединению (через GPRS). Но разработчик может подобрать другие значения временных задержек, соответствующие характеристикам канала связи, используемым заказчиком. При запуске «1С:Предприятия» в режиме имитации задержек при вызове сервера в информационной панели приложения появится значок . В текущем рабочем сеансе также можно включить/выключить режим имитации задержек при вызове сервера. Для этого нужно выполнить команду главного меню «1С:Предприятия» Сервис Параметры и поставить флажок Имитировать задержку при вызовах сервера (рис. 8.430). Режим имитации задержек при вызове сервера также можно включить, запустив «1С:Предприятие» из командной строки с параметром /SimulateServerCallDelay. Подробнее
Документация «1С:Предприятие 8.2. Руководство разработчика», раздел 23.3.
395
Глава 8. Разработка форм
Рис. 8.430. Установка имитации задержек при вызове сервера в режиме «1С:Предприятие»
Таким образом, чтобы визуально оценить, с какой скоростью будет работать прикладное решение у клиента на низкоскоростном канале связи, разработчику нужно запустить тонкий клиент в режиме низкой скорости соединения и установить режим имитации задержек при вызове сервера (при этом не нужно использовать специальные медленные каналы связи, можно это сделать даже в файловом варианте на локальном компьютере).
Отображение серверных вызовов в замерах производительности Замер производительности позволяет оценить скорость работы всей конфигурации или любой ее части в процессе отладки. При этом измеряется частота и скорость выполнения отдельных участков кода, указывается, где выполнялся код – на сервере или на клиенте, помечаются строки кода, приведшие к вызову сервера. Для того чтобы выполнить замер производительности какого-либо участка конфигурации, нужно запустить «1С:Предприятие» из конфигуратора в режиме отладки, дойти в ходе выполнения приложения до интересующего участка, перейти в режим Конфигуратор и выполнить команду главного меню Отладка Замер производительности. Затем вернуться в режим 1С:Предприятие, продолжить выполнение приложения, а когда замер производительности больше не нужен – повторно выполнить команду Отладка Замер производительности из конфигуратора. После этого в конфигураторе откроется окно с результатами замера производительности (рис. 8.431). Эти результаты можно сохранить в файл для их дальнейшего анализа с помощью команд Файл Сохранить и Файл Сохранить как. Файл результатов имеет расширение *.pff.
396
Рис. 8.431. Окно результатов замера производительности
В окне результатов замера производительности, в колонке Обр. сервером (Обработка сервером), показываются серверные вызовы, которые выполняются платформой и/или производятся из клиентского кода: ■■ вызовы сервера методами объектов встроенного языка, вызовы процедур и функций, исполнение которых происходит на сервере, отображаются с помощью значка ; ■■ вызовы клиентских процедур и функций, в которых тем или иным способом происходил вызов сервера, отображаются с помощью значка . В окне результатов замера производительности показывается, где исполнялся код на встроенном языке в клиент-серверной информационной базе – на клиенте или на сервере: ■■ строки кода на встроенном языке, исполнение которых происходило на клиенте, отображаются в колонке Клиент с помощью значка ; ■■ строки кода на встроенном языке, исполнение которых происходило на сервере, отображаются в колонке Сервер с помощью значка . По любой колонке окна результатов замера производительности возможна сортировка: для этого достаточно щелкнуть мышью в соответствующей колонке. В окне результатов замера производительности существует возможность фильтрации информации результатов замера. Такая возможность реализована в виде двух флажков (Клиент и Сервер) в правой нижней части окна результатов замера. По умолчанию поставлены оба флажка, то есть в результатах замера присутствует информация о ходе исполнения кода на встроенном языке, как на клиенте, так и на сервере. Профессиональная разработка в системе «1С:Предприятие 8»
Оптимизация клиент-серверного взаимодействия в формах Подробнее
Документация «1С:Предприятие 8.2. Руководство разработчика», раздел 23.2.
Анализ замеров производительности в процессе разработки может дать дополнительную информацию, детализирующую данные показателей производительности. Совместное использование этих двух инструментов позволит выявить узкие места в приложении даже без наличия большой тестовой базы и без выполнения нагрузочного тестирования.
Примеры оптимизации клиент-серверного взаимодействия Объединение нескольких вызовов сервера в один
Рис. 8.433. Заполнение колонок табличной части в приходной накладной
Выбор товара происходит на клиенте, но на клиенте, имея ссылку на товар, нельзя получить значения реквизитов этой ссылки, например Артикул. Чтобы его получить, нужно «пойти» с этой ссылкой на сервер, там прочитать из базы данных значение артикула и передать его обратно на клиента.
В процессе работы формы часто бывает нужно получить дополнительную информацию об объекте, на который ссылается поле реквизита, и отразить ее в форме. Как это сделать наиболее эффективно? Рассмотрим пример.
Рассмотрим возможные варианты решения этой задачи.
Предположим, в конфигурации существует справочник Товары. В нем для каждого товара хранится его артикул, единица измерения и цена. Для приходования товаров существует документ ПриходнаяНакладная, в табличную часть которого подбираются товары (рис. 8.432).
Как уже говорилось выше, возможности ссылки на клиенте сильно ограничены. Чтобы воспользоваться полными возможностями ссылки, можно, например, создать универсальную функцию ПолучитьРеквизитИзБазыДанных(Ссылка, ИмяРеквизита), поместить ее в общем модуле, исполняющемся на сервере, и использовать ее всякий раз, когда потребуется получить реквизит какого-нибудь объекта.
Первый вариант решения
Поскольку процедура универсальная, мы будем использовать ее в разных формах, поэтому поместим ее не в какой-то одной форме, а в общем модуле, чтобы все формы могли ею пользоваться. Итак, создадим общий модуль конфигурации РаботаСОбъектами. По умолчанию у него установлен флажок Сервер, значит, экземпляры этого модуля будут скомпилированы на стороне сервера. Установим у него флажок Вызов сервера, чтобы экспортируемые процедуры и функции этого модуля можно было вызывать с клиента (рис. 8.434). Рис. 8.432. Выбор товара в приходной накладной
Хочется, чтобы пользователь, выбрав товар, видел в документе не только ссылку, но и сразу же артикул, единицу измерения и цену выбранного товара (рис. 8.433). Таким образом, в тот момент, когда пользователь выбирает товар в колонке Товар, ссылающейся на справочник Товары, в другие колонки табличной части документа Артикул, ЕдИзм и Цена нужно записать артикул, единицу измерения и цену этого товара, хранящиеся в справочнике. Том 1
Рис. 8.434. Свойства модуля «РаботаСОбъектами»
397
Глава 8. Разработка форм Поместим в этом модуле функцию для получения реквизита объекта по его ссылке (листинг 8.180). Листинг 8.180. Функция «ПолучитьРеквизитИзБазыДанных()»
Функция ПолучитьРеквизитИзБазыДанных(Ссылка, ИмяРеквизита) Экспорт Возврат Ссылка[ИмяРеквизита]; КонецФункции
Чтобы обеспечить заполнение колонок табличной части приходной накладной при выборе товара, создадим форму документа и обработчик события ПриИзменении() для поля формы Товар, содержащегося в таблице формы Товары (листинг 8.181). Листинг 8.181. Процедура «ТоварыТоварПриИзменении()»
Рис. 8.435. Заполнение колонок табличной части в приходной накладной
&НаКлиенте Процедура ТоварыТоварПриИзменении(Элемент)
Сразу после выбора товара посмотрим на показатели производительности (рис. 8.436).
ДанныеТекущейСтроки = Элементы.Товары.ТекущиеДанные; ВыбранныйТовар = ДанныеТекущейСтроки.Товар; ДанныеТекущейСтроки.Артикул = РаботаСОбъектами. ПолучитьРеквизитИзБазыДанных(ВыбранныйТовар, "Артикул"); ДанныеТекущейСтроки.ЕдИзм = РаботаСОбъектами. ПолучитьРеквизитИзБазыДанных(ВыбранныйТовар, "ЕдиницаИзмерения"); ДанныеТекущейСтроки.Цена = РаботаСОбъектами. ПолучитьРеквизитИзБазыДанных(ВыбранныйТовар, "Цена"); КонецПроцедуры
В этом обработчике мы получаем доступ к данным текущей строки таблицы формы в переменной ДанныеТекущейСтроки. Чтобы получить значение, содержащееся в конкретном поле текущей строки, нужно через точку указать имя этого поля (.Товар). Так мы получаем ссылку на выбранный товар и вместе с именем нужного реквизита передаем ее в функцию ПолучитьРеквизитИзБазыДанных(), которая возвращает нам значение этого реквизита. Подробнее
Этот пример можно посмотреть в демонстрационной конфигурации «Разработка форм, пример 17 (вар. 1)».
Посмотрим теперь, какие серверные вызовы будут происходить в режиме 1С:Предприятие в результате. Для этого запустим «1С:Предприятие», откроем приходную накладную и сделаем выбор из справочника товаров в колонке Товар. После этого колонки табличной части Артикул, ЕдИзм и Цена будут автоматически заполнены соответствующими значениями из справочника Товары (рис. 8.435).
398
Рис. 8.436. Окно показателей производительности
Там будет показано число вызовов сервера, в общем случае их будет три или больше. Больше трех вызовов может быть при первом выполнении этого действия, так как платформа выполняет запрос к информационной базе и кеширование необходимых данных. При втором и последующем выборе товара произойдет три вызова сервера. Как мы уже говорили выше, когда платформа самостоятельно обращается к серверу, на это мы повлиять не можем. Поэтому подробно исследовать, почему серверных вызовов больше трех, мы не будем. Но три серверных вызова – это «наши вызовы», которые мы породили своим кодом. Рассмотрим подробнее, откуда они взялись. Так происходит потому, что в результате использования универсальной функции ПолучитьРеквизитИзБазыДанных() будет происходить обращение на сервер столько раз, сколько понадобится получить реквизитов объекта. Таким образом, при выборе товара в строке табличной части документа произошло три вызова сервера, так как нам понадобилось узнать значение трех реквизитов выбранного товара.
Второй вариант решения На самом деле нет необходимости три раза «дергать» сервер. Ведь мы точно знаем, что каждый раз при добавлении нового товара нам понадобятся все три его реквизита. А значит, все их можно получить за один серверный вызов. Это будет более эффективным решением. В данном случае универсальность выбранного нами решения нужно принести в жертву эффективности работы конкретной формы в конкретной Профессиональная разработка в системе «1С:Предприятие 8»
Оптимизация клиент-серверного взаимодействия в формах ситуации. В данной ситуации прежде всего нас должна заботить не универсальность, а прикладная логика работы формы. Универсальность сама по себе хороша, но не в данном случае. То есть нет одного решения на все времена. В каждой форме нужно думать заново.
РеквизитыТовара = ПолучитьРеквизитыТовара(ВыбранныйТовар); ДанныеТекущейСтроки.Артикул = РеквизитыТовара.Артикул; ДанныеТекущейСтроки.ЕдИзм = РеквизитыТовара.ЕдиницаИзмерения; ДанныеТекущейСтроки.Цена = РеквизитыТовара.Цена;
Для реализации этого решения в обработчике события ПриИзменении поля Товар табличной части документа ПриходнаяНакладная нужно вызвать функцию, возвращающую в виде структуры сразу все нужные нам реквизиты выбранного элемента. Поэтому в модуле формы документа поместим функцию ПолучитьРеквизитыТовара(), выполняющуюся на сервере без контекста формы (листинг 8.182).
КонецПроцедуры
Листинг 8.182. Функция «ПолучитьРеквизитыТовара()»
Подробнее
&НаСервереБезКонтекста Функция ПолучитьРеквизитыТовара(Ссылка) РеквизитыТовара = Новый Структура; РеквизитыТовара.Вставить("Артикул", Ссылка.Артикул); РеквизитыТовара.Вставить("ЕдиницаИзмерения", Ссылка.ЕдиницаИзмерения); РеквизитыТовара.Вставить("Цена", Ссылка.Цена); Возврат РеквизитыТовара; КонецФункции
В этом обработчике мы передаем ссылку на выбранный товар в функцию ПолучитьРеквизитыТовара(), которая возвращает в виде структуры реквизиты товара, и присваиваем значение полей возвращенной структуры колонкам табличной части Артикул, ЕдИзм и Цена.
Этот пример можно посмотреть в демонстрационной конфигурации «Разработка форм, пример 17 (вар. 2)».
Запустим «1С:Предприятие», откроем приходную накладную и сделаем выбор из справочника товаров в колонке Товар табличной части документа. После этого колонки табличной части Артикул, ЕдИзм и Цена будут автоматически заполнены соответствующими значениями из справочника Товары (рис. 8.437).
В этой функции мы создаем структуру и заполняем ее поля Артикул, ЕдиницаИзмерения и Цена значениями соответствующих реквизитов справочника Товары, полученных по ссылке на элемент справочника. Единственное значение данных формы, которое нам понадобится в этой функции, – это ссылка на элемент справочника, его мы передаем в параметре Ссылка. Поэтому мы выполняем внеконтекстный серверный вызов (директива компиляции &НаСервереБезКонтекста), который будет работать значительно быстрее, чем вызов сервера с контекстом формы (директива компиляции &НаСервере). Подробнее этот вопрос будет рассмотрен в следующем примере (стр. 400). Как видите, функция будет совершенно не универсальная, зато форма будет работать быстро за счет минимизации серверных вызовов. То есть вместо трех вызовов сервера, как раньше, будет происходить всего один серверный вызов. Теперь изменим обработчик события ПриИзменении() поля Товар табличной части документа ПриходнаяНакладная следующим образом (листинг 8.183). Листинг 8.183. Процедура «ТоварыТоварПриИзменении()»
&НаКлиенте Процедура ТоварыТоварПриИзменении(Элемент)
ДанныеТекущейСтроки = Элементы.Товары.ТекущиеДанные; ВыбранныйТовар = ДанныеТекущейСтроки.Товар;
Том 1
Рис. 8.437. Заполнение колонок табличной части в приходной накладной
Как мы видим, функциональность прикладного решения будет такой же, как и в первом случае, но производительность будет втрое выше, так как при выборе товара в одной строке табличной части документа будет произведено только одно обращение к серверу (рис. 8.438). Рис. 8.438. Окно показателей производительности
Заметим, что здесь так же, как и в предыдущем варианте, при первом выборе товара может быть лишний серверный вызов за счет кеширования формой данных в списке выбора.
399
Глава 8. Разработка форм Таким образом, мы видим реальный выигрыш в производительности прикладного решения по сравнению с предыдущим вариантом.
Резюме
Однако заметьте, что мы получали реквизиты товара по его ссылке. Это очень удобная возможность платформы, но приводящая к загрузке всего объекта в память, что не всегда нужно. Допустим, нам нужно получить только три реквизита товара, а всего их – пятьдесят. Поэтому эффективнее использовать запрос для получения реквизитов товара.
Поэтому нужно стараться получить всю необходимую информацию за один вызов сервера.
В связи с этим изменим функцию для получения реквизитов товара в модуле формы следующим образом (листинг 8.184). Листинг 8.184. Функция «ПолучитьРеквизитыТовара()»
&НаСервереБезКонтекста Функция ПолучитьРеквизитыТовара(ТоварСсылка) РеквизитыТовара = Новый Структура; Запрос = Новый Запрос; Запрос.Текст = "ВЫБРАТЬ | Товары.Артикул, | Товары.ЕдиницаИзмерения, | Товары.Цена |ИЗ | Справочник.Товары КАК Товары |ГДЕ | Товары.Ссылка = &Ссылка"; Запрос.УстановитьПараметр("Ссылка", ТоварСсылка); Выборка = Запрос.Выполнить().Выбрать(); Если Выборка.Следующий() Тогда Артикул = Выборка.Артикул; ЕдиницаИзмерения = Выборка.ЕдиницаИзмерения; Цена = Выборка.Цена; Иначе Артикул = 0; ЕдиницаИзмерения = 0; Цена = 0; КонецЕсли; РеквизитыТовара.Вставить("Артикул", Артикул); РеквизитыТовара.Вставить("ЕдиницаИзмерения", ЕдиницаИзмерения); РеквизитыТовара.Вставить("Цена", Цена); Возврат РеквизитыТовара; КонецФункции
В этой функции мы заполняем поля структуры реквизитов товара значениями соответствующих реквизитов, полученных при помощи запроса из справочника Товары. В запросе мы устанавливаем параметр Ссылка, равный переданной в функцию ссылке на элемент справочника (ТоварСсылка).
400
В процессе работы прикладного решения любое обращение на сервер сказывается на его производительности.
Не нужно создавать универсальные процедуры для обхода клиентсерверной логики, например, ПолучитьРеквизитИзБазыДанных(Ссылка, ИмяРеквизита) и вызывать их всякий раз, когда понадобятся какие-либо реквизиты объекта. Таким образом, из показанных вариантов решения задачи более эффективным будет второй вариант за счет меньшего количества серверных вызовов. Заметим, что объединять в один серверный вызов нужно логически связанные действия, иначе может возникнуть желание вообще все сделать за один вызов сервера, даже то, что логически между собой не связано.
Использование внеконтекстных серверных процедур в модуле формы Серверные процедуры и функции могут исполняться с передачей контекста формы на сервер (директива компиляции &НаСервере) и без (директива компиляции &НаСервереБезКонтекста). При контекстных серверных вызовах процедур в модуле формы форма передает свои данные (реквизиты) и элементы на сервер и обратно. Данные формы становятся доступны на сервере, но нужно понимать, что передача контекста формы на сервер – это целый непростой процесс. Ведь контекст формы сначала, на клиенте, нужно подготовить к передаче, упаковать, а потом на сервере создать специальную среду, в которой будет исполняться код, развернуть весь полученный контекст, инициализировать им эту среду и т. д. После выполнения процедуры измененные данные снова «поедут» на клиента, если их нужно отображать в форме. На все это, естественно, тратится время и ресурсы системы. Однако использование контекстных серверных процедур необходимо, когда нужно, например, поменять данные во всей табличной части или когда нужно при этом поработать с тем объектом, который отображается в форме, выполнить его экспортируемый метод и т. п. Во внеконтекстных серверных процедурах недоступен контекст формы. Это значит, что при вызове этих процедур не происходит передача данных формы на сервер и обратно. Соответственно, производительность прикладного решения при использовании внеконтекстных серверных процедур будет выше. Профессиональная разработка в системе «1С:Предприятие 8»
Оптимизация клиент-серверного взаимодействия в формах Так что же использовать в том или ином случае – внеконтекстные или контекстные серверные процедуры? Решение зависит от конкретной задачи. Рассмотрим пример. Предположим, в периодическом регистре сведений Цены содержатся розничные цены товаров из справочника Товары. Для расходования товаров существует документ РасходнаяНакладная, в табличную часть которого подбираются товары. Хочется, чтобы пользователь, выбрав товар, видел в документе не только ссылку, но и сразу же цену выбранного товара из регистра сведений, актуальную на дату документа (рис. 8.439).
В этом обработчике мы вызываем контекстную серверную процедуру РозничнаяЦена(). Эту процедуру мы поместим в модуле формы документа (листинг 8.186). Листинг 8.186. Процедура «РозничнаяЦена()»
&НаСервере Процедура РозничнаяЦена()
Идентификатор = Элементы.Товары.ТекущаяСтрока; ДанныеТекущейСтроки = Объект.Товары.НайтиПоИдентификатору(Идентификатор); Отбор = Новый Структура; Отбор.Вставить("Товар", ДанныеТекущейСтроки.Товар); ЗначенияРесурсов = РегистрыСведений.Цены.ПолучитьПоследнее(Объект.Дата, Отбор); ДанныеТекущейСтроки.Цена = ЗначенияРесурсов.Цена;
КонецПроцедуры
Рис. 8.439. Подстановка актуальной цены товара в расходную накладную
Таким образом, в тот момент, когда пользователь выбирает товар в колонке Товар, ссылающейся на справочник Товары, колонку Цена табличной части документа РасходнаяНакладная нужно заполнить актуальной ценой товара из регистра сведений. Рассмотрим возможные варианты решения этой задачи.
Первый вариант решения Чтобы обеспечить подстановку актуальной цены в расходную накладную при выборе товара, мы будем «уходить» на сервер, там определять цену товара, подставлять ее в документ и просто возвращаться обратно на клиента. Ведь получить доступ к базе данных мы можем только на сервере – поэтому сразу же сделаем все, что нам нужно, прямо на сервере. Для этого создадим форму документа и обработчик события ПриИзменении() для поля формы Товар, содержащегося в таблице формы Товары (листинг 8.185). Листинг 8.185. Процедура «ТоварыТоварПриИзменении()»
&НаКлиенте Процедура ТоварыТоварПриИзменении(Элемент) РозничнаяЦена(); КонецПроцедуры
Том 1
В этой процедуре мы получаем Идентификатор текущей строки таблицы формы. По этому идентификатору находим эту строку в объекте ДанныеФормыКоллекция, содержащем табличную часть документа – Объект.Товары. Таким образом, мы получаем доступ к данным текущей строки таблицы формы в переменной ДанныеТекущейСтроки и через точку от нее можем обращаться к значению колонок таблицы. Затем мы создаем структуру Отбор, содержащую отбор по измерению регистра Товар, и устанавливаем его равным ссылке на выбранный товар (ДанныеТекущейСтроки.Товар). Затем мы выполняем метод менеджера регистра сведений Цены ПолучитьПоследнее() и присваиваем значение ресурса Цена наиболее поздней записи регистра на дату документа (Объект.Дата) для выбранного товара (Отбор) соответствующей колонке таблицы формы. Заметьте, что значения реквизитов документа (Объект.Дата, Объект.Товары) и свойства элементов формы (Элементы.Товары.ТекущаяСтрока) доступны на сервере, так как при использовании директивы компиляции &НаСервере в процедуру передается весь контекст формы. Подробнее
Этот пример можно посмотреть в демонстрационной конфигурации «Разработка форм, пример 18 (вар. 1)».
Запустим «1С:Предприятие», откроем расходную накладную, добавим запись в табличную часть документа и сделаем выбор из справочника товаров в колонке Товар. После этого колонка табличной части Цена автоматически заполнится последней ценой из регистра сведений, актуальной на дату документа для выбранного товара (рис. 8.440).
401
Глава 8. Разработка форм решение будет работать быстрее. И если раньше мы подставляли цену в документ на сервере, то теперь мы будем делать это на клиенте. Именно для этого действия сервер совершенно не нужен, это можно прекрасно сделать прямо на клиенте. Для этого изменим обработчик события ПриИзменении() поля Товар табличной части документа РасходнаяНакладная следующим образом (листинг 8.187). Листинг 8.187. Процедура «ТоварыТоварПриИзменении()»
&НаКлиенте Процедура ТоварыТоварПриИзменении(Элемент) Рис. 8.440. Подстановка актуальной цены товара в расходную накладную
В результате использования процедуры РозничнаяЦена() для подстановки цены в документ будет происходить одно обращение на сервер (рис. 8.441).
Рис. 8.441. Окно показателей производительности
Заметим, что при первом выборе товара может быть лишний серверный вызов за счет автоматического кеширования формой данных в списке выбора. Но мы не будем исследовать эту ситуацию, так как этот вызов делается платформой, а нас интересуют вызовы, инициированные разработчиком.
Второй вариант решения Один вызов сервера, происходящий при подстановке цены товара, неизбежен и оправдан. Но обратите внимание на объем передаваемых на сервер и обратно данных, указанный на рисунке (чтобы его увидеть, нужно включить соответствующие опции в окне настройки показателей производительности). Можно ли его уменьшить? Конечно! Действительно, зачем «гонять» весь контекст формы туда и обратно, когда нам нужна всего лишь одна цена товара? На самом деле в функции для получения актуальной цены РозничнаяЦена(), кроме ссылки на выбранный товар, используется только один реквизит документа РасходнаяНакладная – Дата. Вместо того чтобы передавать весь контекст формы на сервер, можно передать эти значения в функцию в качестве параметров. Описание функции в модуле формы мы предварим директивой компиляции &НаСервереБезКонтекста. Таким образом, мы не будем передавать данные формы на сервер, и наше прикладное
402
ДанныеТекущейСтроки = Элементы.Товары.ТекущиеДанные; ДанныеТекущейСтроки.Цена = РозничнаяЦена(ДанныеТекущейСтроки.Товар, Объект.Дата);
КонецПроцедуры
В этом обработчике мы получаем доступ к данным текущей строки таблицы формы в переменной ДанныеТекущейСтроки и через точку от нее можем обращаться к значению колонок таблицы. Ссылку на выбранный товар (ДанныеТекущейСтроки.Товар) и дату документа (Объект.Дата) мы передаем в функцию для получения актуальной цены РозничнаяЦена() и присваиваем возвращенное значение колонке табличной части Цена. В модуле формы документа поместим функцию РозничнаяЦена(), выполняющуюся на сервере без контекста формы (листинг 8.188). Листинг 8.188. Функция «РозничнаяЦена()»
&НаСервереБезКонтекста Функция РозничнаяЦена(ВыбранныйТовар, АктуальнаяДата) Отбор = Новый Структура; Отбор.Вставить("Товар", ВыбранныйТовар); ЗначенияРесурсов = РегистрыСведений.Цены.ПолучитьПоследнее(АктуальнаяДата, Отбор); Возврат ЗначенияРесурсов.Цена; КонецФункции
В этой функции мы создаем структуру Отбор, содержащую отбор по измерению регистра Товар, и устанавливаем его равным ссылке на выбранный товар. Затем при помощи метода ПолучитьПоследнее() мы возвращаем актуальную цену выбранного товара. подробнее
Этот пример можно посмотреть в демонстрационной конфигурации «Разработка форм, пример 18 (вар. 2)».
Запустим «1С:Предприятие», откроем расходную накладную и сделаем выбор из справочника товаров в колонке Товар табличной части документа. После этого колонка табличной части Цена автоматически заполнится Профессиональная разработка в системе «1С:Предприятие 8»
Оптимизация клиент-серверного взаимодействия в формах последней ценой из регистра сведений, актуальной на дату документа для выбранного товара (рис. 8.442).
Итак, объединим два параметра, передаваемых в функцию для получения актуальной цены в структуру, и передадим ее целиком, как структуру параметров (листинг 8.189, 8.190). Листинг 8.189. Процедура «ТоварыТоварПриИзменении()»
&НаКлиенте Процедура ТоварыТоварПриИзменении(Элемент) ДанныеТекущейСтроки = Элементы.Товары.ТекущиеДанные; Отбор = Новый Структура("Товар", ДанныеТекущейСтроки.Товар); ПараметрыФункции = Новый Структура("Отбор, АктуальнаяДата", Отбор, Объект.Дата); ДанныеТекущейСтроки.Цена = РозничнаяЦена(ПараметрыФункции); КонецПроцедуры Листинг 8.190. Функция «РозничнаяЦена()»
Рис. 8.442. Подстановка актуальной цены товара в расходную накладную
Как мы видим, функциональность прикладного решения будет такой же, как и в первом случае, но объем передаваемых на сервер данных будет значительно меньше (вместо 2399 + 1730 байт), так как при вызове функции РозничнаяЦена() мы использовали внеконтекстный серверный вызов и не передавали все данные формы на сервер (рис. 8.443).
&НаСервереБезКонтекста Функция РозничнаяЦена(ПараметрыФункции) ЗначенияРесурсов = РегистрыСведений.Цены.ПолучитьПоследнее(ПараметрыФункции .АктуальнаяДата, ПараметрыФункции.Отбор); Возврат ЗначенияРесурсов.Цена; КонецФункции
Обратите внимание, если мы сравним объем передаваемых данных, то оказывается, что он больше, чем когда мы передавали параметры в функцию по отдельности (рис. 8.444).
Рис. 8.443. Окно показателей производительности
Заметим, что здесь, так же как и в предыдущем варианте, при первом выборе товара может быть лишний серверный вызов за счет автоматического кеширования формой данных в списке выбора. Но, с другой стороны, использование процедур с параметрами тоже может иметь свои недостатки. Слишком большое количество параметров в процедуре может снижать производительность. «Слишком большое» – понятие относительное, конкретные числовые оценки дать нельзя. Но, например, если есть выбор – передать 100 параметров или передать всего 2 параметра, то, конечно же, нужно передавать 2 параметра, а не 100. Поэтому разработчику всегда нужно искать компромисс между здравым смыслом («читабельностью» программы) и оптимизацией. В связи с этим можно на клиенте формировать структуру параметров, передаваемых в функцию, и затем передавать ее целиком, одним параметром. В данном конкретном случае мы передаем всего два параметра. Это нормально – можно передавать их по отдельности, и нет необходимости сокращать их количество. Но на этом примере мы покажем, как в принципе можно это сделать. Например, сгруппировать логически связанные между собой параметры в один, который является структурой. Том 1
Рис. 8.444. Окно показателей производительности
Получается, что для данного примера это действительно ненужная «оптимизация». Как мы и говорили, два параметра в этом примере – это хорошо, и мы даже получили увеличение объема передаваемых данных, когда упаковали их в одну структуру. Но когда параметров слишком много, ситуация может быть обратной. Поэтому в каждой ситуации нужно думать, как лучше поступить, и упаковка параметров в один должна быть логически понятна и объяснима.
Резюме Применение внеконтекстных процедур позволяет значительно уменьшить объем передаваемых данных (трафик) между клиентом и сервером и уменьшить нагрузку на систему. Поэтому, где возможно, нужно использовать внеконтекстные серверные процедуры, а если требуется передавать туда какие-то данные формы, то можно одно-два значения передать в качестве параметров.
403
Глава 8. Разработка форм Не нужно без необходимости использовать контекстные серверные процедуры, если в них не требуется использовать и изменять большинство реквизитов формы.
Таким образом, в тот момент, когда пользователь изменит поле ЦенаУслуги документа ОказаниеУслуги, поля Вознаграждение и Сумма нужно рассчитать по описанному выше алгоритму.
Таким образом, из показанных вариантов решения задачи более эффективным будет второй вариант за счет использования внеконтекстного серверного вызова.
Рассмотрим возможные варианты решения этой задачи.
Использование клиентских процедур для небольших расчетов данных формы В процессе разработки конфигурации часто возникает вопрос: «Где выполнять пересчет данных формы – на клиенте или на сервере?». Однозначного ответа тут нет. С одной стороны, на клиенте должно быть минимум кода, потому что такова идеология управляемого приложения. Клиентского кода по определению не должно быть много. Основной подход заключается в том, что на клиенте должен исполняться только тот код, который управляет формой и отображением данных в ней. Все расчеты должны выполняться на сервере. С другой стороны, нужно избегать лишних обращений на сервер. И хотя процесс вычислений произойдет на сервере значительно быстрее, но сам вызов сервера, да еще с контекстом формы, снизит производительность прикладного решения. Решение зависит от конкретной задачи. Рассмотрим пример. Предположим, в форме документа об оказании услуг содержится цена услуги, процент вознаграждения и сумма услуги. При изменении цены услуги нужно рассчитать сумму услуги, равной цене услуги, плюс процент вознаграждения. Процент вознаграждения устанавливается в зависимости от цены услуги (рис. 8.445).
Первый вариант решения Чтобы обеспечить перерасчет суммы услуги при изменении цены, мы сразу пойдем на сервер (ведь расчеты нужно делать на сервере), там рассчитаем вознаграждение и сумму услуги и поместим их в форму. Затем вернемся на клиента с готовой формой. Для этого создадим форму документа ОказаниеУслуги и обработчик события ПриИзменении() для поля формы ЦенаУслуги (листинг 8.191). Листинг 8.191. Процедура «ЦенаУслугиПриИзменении()»
&НаКлиенте Процедура ЦенаУслугиПриИзменении(Элемент)
РасчетСуммыУслуги();
КонецПроцедуры
В этом обработчике мы вызываем процедуру РасчетСуммыУслуги(), исполняющуюся на сервере (листинг 8.192). Листинг 8.192. Процедура «РасчетСуммыУслуги()»
&НаСервере Процедура РасчетСуммыУслуги() Если Объект.ЦенаУслуги > 1000 Тогда Объект.Вознаграждение = 10; Иначе Объект.Вознаграждение = 5; КонецЕсли; Объект.Сумма = Объект.ЦенаУслуги + Объект.ЦенаУслуги * Объект.Вознаграждение/100; КонецПроцедуры
В процедуру расчета передается контекст формы, так как в ней изменяются реквизиты объекта Вознаграждение и Сумма. Отключим для соответствующих полей формы свойство Доступность, так как они рассчитываются при изменении поля ЦенаУслуги. подробнее Рис. 8.445. Пересчет данных в документе при изменении цены услуги
404
Этот пример можно посмотреть в демонстрационной конфигурации «Разработка форм, пример 19 (вар. 1)».
Профессиональная разработка в системе «1С:Предприятие 8»
Оптимизация клиент-серверного взаимодействия в формах Запустим «1С:Предприятие», откроем документ об оказании услуг, выберем услугу и внесем цену услуги. После этого поля Вознаграждение и Сумма автоматически пересчитаются по заданному нами алгоритму (рис. 8.446).
Листинг 8.193. Процедура «ЦенаУслугиПриИзменении()»
&НаКлиенте Процедура ЦенаУслугиПриИзменении(Элемент) Если Объект.ЦенаУслуги > 1000 Тогда Объект.Вознаграждение = 10; Иначе Объект.Вознаграждение = 5; КонецЕсли; Объект.Сумма = Объект.ЦенаУслуги + Объект.ЦенаУслуги * Объект.Вознаграждение/100; КонецПроцедуры подробнее
Этот пример можно посмотреть в демонстрационной конфигурации «Разработка форм, пример 19 (вар. 2)». Рис. 8.446. Пересчет данных в документе при изменении цены услуги
В результате будет сделано одно обращение на сервер, кроме того, этот вызов будет контекстным (рис. 8.447).
Запустим «1С:Предприятие», откроем документ об оказании услуг, выберем услугу и внесем цену услуги. После этого поля Вознаграждение и Сумма автоматически пересчитаются по заданному нами алгоритму.
Рис. 8.447. Окно показателей производительности
Как мы видим, функциональность прикладного решения будет такой же, как и в первом случае, но производительность будет выше, так как мы выполнили перерасчет данных документа на клиенте, без обращения к серверу. Окно показателей производительности не появится (или будет пустым), так как вызовов сервера не было вообще.
Второй вариант решения
Резюме
Чтобы оценить правильность своих действий, можно проанализировать, что же было сделано. Ход рассуждений может быть примерно таким:
Таким образом, если в процедуре пересчета требуется массированная обработка данных формы (стр. 406) или если в ней используются свойства и методы объектов, недоступных на клиенте, то выполнять пересчет данных формы нужно на сервере. Для этого необходимо поместить код в контекстную серверную процедуру модуля формы. Или поместить код в процедуру модуля объекта и вызывать этот метод объекта, предварительно конвертировав данные формы в объект (стр. 432).
■■ «Контекстный вызов. А он нужен? Можно было обойтись внеконтекстным вызовом?». ■■ «Внеконтекстный вызов. А он нужен? Вообще тут нужен вызов сервера? Есть что-то, что нельзя сделать на клиенте?». ■■ «Если это делать на клиенте, это сложные вычисления? Сложнее, чем если бы их делали на сервере?». На самом деле обращения на сервер для пересчета данных формы могло бы и не быть. Как мы увидим ниже, более эффективно этот расчет будет работать на клиенте. Поскольку все данные для пересчета доступны на клиенте (это поля основного реквизита формы Объект – ЦенаУслуги, Вознаграждение и Сумма), то нет смысла лишний раз обращаться на сервер. Код пересчета – небольшой, и он быстро выполнится из клиентской процедуры при изменении цены услуги. Для этого изменим обработчик события ПриИзменении() поля ЦенаУслуги документа ОказаниеУслуги следующим образом (листинг 8.193). Том 1
Если в расчете участвует немного данных формы и все эти данные уже есть на клиенте, то лучше это делать в клиентской процедуре модуля формы. Клиентский код должен максимально быстро сделать что-то на клиенте, без обращения к серверу. Он не должен содержать большой объем бизнеслогики. Например, быстро пересчитать сумму по количеству и цене или рассчитать значение какого-то реквизита на основе другого и т. п. Поэтому не нужно без необходимости использовать контекстные серверные процедуры для небольших расчетов данных формы. Таким образом, из показанных вариантов решения задачи более эффективным будет второй вариант за счет пересчета данных формы на клиенте, без обращения к серверу.
405
Глава 8. Разработка форм
Использование контекстных серверных процедур для пересчета данных коллекций форм Теперь рассмотрим пример, когда пересчет данных формы более эффективно выполнять на сервере. Мы уже говорили в предыдущем примере, что на сервере вычисления необходимо выполнять, когда на клиенте нет нужных типов данных, или когда используется сложный алгоритм расчета, содержащий много кода, или когда требуется обратиться к объекту, содержащемуся в форме, напрямую. Однако в данном примере будет рассмотрен другой вопрос – где наиболее эффективно выполнять пересчет большого количества строк табличной части – на сервере или на клиенте? С одной стороны, на серверный контекстный вызов платформа тратит время и ресурсы. Желательно бы этого избегать. С другой стороны, на клиенте присутствуют не все строки коллекций форм (табличных частей, таблиц значений), а только их видимая часть. Остальные «дочитываются» с сервера динамически, по мере того как пользователь прокручивает таблицу. Или по мере того как разработчик перебирает коллекцию данных в реквизите формы из встроенного языка. Таким образом, при массовом пересчете на клиенте все строки табличной части будут получены с сервера на клиента, и все вернутся обратно при следующем контекстном вызове сервера. Посмотрим, какое решение более оптимально. Рассмотрим пример. Предположим, в табличной части расходной накладной содержатся товары и их цены. При нажатии кнопки Пересчет цен, расположенной в форме документа, должно производиться повышение цен товаров на 10 % и пересчет сумм продажи товаров как произведения их количества и цены (рис. 8.448).
Первый вариант решения Чтобы обеспечить пересчет цен товаров в табличной части расходной накладной, не будем вызывать сервер. Пересчитаем все цены на клиенте, ведь все необходимые данные на нем есть и обращаться к серверу вроде бы незачем. Для этого создадим форму документа и ее команду ПересчетЦен. Перетащим команду в командную панель таблицы формы Товары. Обработчик события нажатия кнопки Пересчет цен заполним следующим образом (листинг 8.194). Листинг 8.194. Обработчик события нажатия кнопки «Пересчет цен»
&НаКлиенте Процедура ПересчетЦен(Команда) Для Каждого ТекСтрокаТовары Из Объект.Товары Цикл ТекСтрокаТовары.Цена = ТекСтрокаТовары.Цена * 1.1; ТекСтрокаТовары.Сумма = ТекСтрокаТовары.Количество * ТекСтрокаТовары.Цена; КонецЦикла; КонецПроцедуры
В этом обработчике мы в цикле обходим табличную часть документа и пересчитываем цены и суммы товаров. подробнее
Этот пример можно посмотреть в демонстрационной конфигурации «Разработка форм, пример 20 (вар. 1)».
Запустим «1С:Предприятие», откроем документ РасходнаяНакладная № 2 (он содержит 1 000 позиций товаров) и нажмем кнопку Пересчет цен. После этого цены и суммы товаров пересчитаются по заданному нами алгоритму (рис. 8.448). Пересчет всех строк табличной части произойдет непосредственно на клиенте. Но при нажатии кнопки Пересчет цен произойдет двадцать восемь вызовов сервера (рис. 8.449).
Рис. 8.449. Окно показателей производительности
Рис. 8.448. Пересчет цен товаров в расходной накладной
Рассмотрим возможные варианты решения этой задачи.
406
Так происходит потому, что при открытии формы на клиента передается 35 строк табличной части, и затем, по мере программного обращения, остальные строки «дочитываются» с сервера порциями по 35 строк (1015 = 28 * 35 + 35). В процессе пересчета все недостающие (965) строки «приедут» с сервера на клиент. При следующем контекстном вызове все измененные данные, то есть все 1000 строк, «поедут» обратно на сервер (рис. 8.450). Профессиональная разработка в системе «1С:Предприятие 8»
Оптимизация клиент-серверного взаимодействия в формах
Рис. 8.452. Схема передачи данных между клиентом и сервером
Рассмотрим подробнее, сколько вызовов сервера при этом произойдет и какой будет объем передаваемых данных между клиентом и сервером. Мы специально рассматриваем пример документа с большой табличной частью, так как на нем лучше сравнивать показатели производительности (табл. 8.1). Таблица 8.1. Показатели производительности Текущие вызовы
Открытие формы 2 Пересчет табличной части 28 Контекстный серверный вызов 1
Отправлено
Принято
1801 11327 205518
14865 161774 991
При открытии формы 2 вызова сервера происходят при открытии формы в первый раз, при следующем открытии – 1 вызов. Объем принятых данных отражает ситуацию, когда на клиент «приезжает» форма и «видимые» 35 строк табличной части.
Рис. 8.450. Схема программного взаимодействия сервера и клиента
Например, сделаем команду Вызов сервера, из нее вызовем после пересчета цен пустую серверную контекстную процедуру и посмотрим на показатели производительности (рис. 8.451).
Рис. 8.451. Окно показателей производительности
Для наглядности рассмотрим схему передачи данных между клиентом и сервером (рис. 8.452).
Том 1
При пересчете табличной части 28 вызовов сервера тратятся на «дочитывание» строк табличной части документа на клиента порциями по 35 строк. Объем принятых данных отражает ситуацию, когда табличная часть «доехала» в форму документа на клиента. Объем отправленных данных отражает ситуацию, когда форма сообщает серверу, какие строки и в каком порядке получить. При следующем контекстном вызове объем отправленных данных отражает ситуацию, когда все 1000 измененных строк табличной части «уезжают» на сервер. Таким образом, объем принятой информации 14 865 а объем отправленной – 205 518 байтов.
+ 161 774 = 176 639,
Если сравнить объем принятых и переданных данных, то получится, что форма и 1 000 строк, переданные на клиента, меньше,
407
Глава 8. Разработка форм чем 1 000 строк, переданных с клиента на сервер. Это действительно так, потому что обратно передаются не только строки но и служебная информация о том, что строка изменена. Таким образом, в первом случае 161 774 байта информации передается на клиента и 205 518 байтов передается на сервер. Как видите, объем передаваемых данных будет довольно большим (161 774 + 205 518 = 367 292 байта). На самом деле, как будет показано ниже, более эффективно этот расчет будет работать на сервере.
После этого цены и суммы товаров пересчитаются по заданному нами алгоритму. Посмотрим на схему программного взаимодействия клиента и сервера в этом случае (рис. 8.453).
Второй вариант решения Форма всегда создается на сервере, а не на клиенте. Таким образом, при открытии формы все данные для пересчета уже есть на сервере. Поэтому лучше выполнять пересчет строк табличной части на сервере, а не на клиенте, так как строки для пересчета не будут передаваться на клиента. Поэтому в данном решении мы сразу «уйдем» на сервер вместе с контекстом формы и там все пересчитаем. И затем вернемся на клиента. Для этого изменим обработчик события нажатия кнопки Пересчет цен документа РасходнаяНакладная следующим образом (листинг 8.195). Листинг 8.195. Обработчик события нажатия кнопки «Пересчет цен»
&НаКлиенте Процедура ПересчетЦен(Команда) ПересчетЦенНаСервере(); КонецПроцедуры
В этом обработчике мы вызываем серверную контекстную процедуру ПересчетЦенНаСервере(). Поместим ее в модуле формы (листинг 8.196). Листинг 8.196. Процедура «ПересчетЦенНаСервере()»
&НаСервере Процедура ПересчетЦенНаСервере() Для Каждого ТекСтрокаТовары Из Объект.Товары Цикл ТекСтрокаТовары.Цена = ТекСтрокаТовары.Цена * 1.1; ТекСтрокаТовары.Сумма = ТекСтрокаТовары.Количество * ТекСтрокаТовары.Цена; КонецЦикла; КонецПроцедуры подробнее
Этот пример можно посмотреть в демонстрационной конфигурации «Разработка форм, пример 20 (вар. 2)».
Запустим «1С:Предприятие», откроем документ РасходнаяНакладная № 2 (он содержит 1 000 позиций товаров) и нажмем кнопку Пересчет цен.
408
Рис. 8.453. Схема программного взаимодействия сервера и клиента
Функциональность прикладного решения будет такой же, как и в первом случае, но производительность будет выше, хотя мы и выполнили контекстный серверный вызов. Посмотрим теперь на показатели производительности при нажатии кнопки Пересчет цен (рис. 8.454).
Рис. 8.454. Окно показателей производительности
Для наглядности рассмотрим схему передачи данных между клиентом и сервером (первый вариант решения для сравнения приведен слева), рис. 8.455. Рассмотрим подробнее, сколько вызовов сервера при этом произойдет и какой будет объем передаваемых данных между клиентом и сервером. Мы специально рассматриваем пример документа с большой табличной частью, так как на нем лучше сравнивать показатели производительности (табл. 8.2). Таблица 8.2. Показатели производительности
Пересчет табличной части на сервере и возврат на клиента
Текущие вызовы Отправлено
Принято
1
204 863
1 666
При пересчете табличной части на сервере объем принятых данных отражает ситуацию, когда все 1000 измененных строк табличной части «приезжают» на клиента. Таким образом, во втором варианте передается 204 863 байта информации против 367 292 байтов в первом. Заметим, что мы здесь сравниваем только объем передаваемых данных, инициируемый разработчиком. Профессиональная разработка в системе «1С:Предприятие 8»
Оптимизация клиент-серверного взаимодействия в формах Параметры формы представляют собой структуру, каждый элемент которой описывает один параметр формы. Эта структура передается в метод ОткрытьФорму() вторым параметром, и в результате форма открывается за один серверный вызов в нужном состоянии. Другим способом является получение формы методом ПолучитьФорму(). Используя возвращенное этим методом значение объекта УправляемаяФорма, можно обращаться к ее свойствам и методам, а также к свойствам и методам ее элементов, чтобы подготовить форму к открытию в нужном состоянии. И затем открыть форму методом Открыть(). Какой же способ наиболее эффективен? Рассмотрим пример. Предположим, в конфигурации существует иерархический справочник Товары и документ ПриходнаяНакладная с табличной частью Товары, содержащей перечень приходуемых товаров. При нажатии кнопки Подбор, расположенной в форме документа, должен производиться подбор товаров в табличную часть приходной накладной. При этом форма выбора из справочника Товары должна открываться в режиме множественного выбора, и иерархический список товаров должен быть представлен в виде дерева (рис. 8.456). Рис. 8.455. Схема передачи данных между клиентом и сервером
Резюме Все данные формы изначально доступны на сервере при ее открытии. В частности, присутствуют все строки табличных частей, а на клиенте – только их видимая часть. Поэтому изменять данные коллекций форм (табличные части, таблицы значений) лучше на сервере. Если же аналогичные действия выполнять на клиенте, то все данные коллекций форм будут переданы на клиента, хотя они не требуются для отображения в форме. Таким образом, из показанных вариантов решения задачи более эффективным будет второй вариант за счет того, что данные табличной части изменяются на сервере, а значит, не происходит ненужная предварительная передача всей табличной части на клиента.
Управление открываемой формой путем передачи параметров Часто бывает нужно открыть форму не интерактивно, а из встроенного языка. Как правило, при этом в зависимости от различных условий форма должна иметь тот или иной вид. Чтобы открыть форму, используются методы глобального контекста ОткрытьФорму() или ОткрытьФормуМодально(). При этом в форму передаются параметры – стандартные или созданные разработчиком. Они используются для того, чтобы открыть форму в некотором нужном состоянии. Том 1
Рис. 8.456. Подбор товаров в табличную часть приходной накладной
Заметим, что если форма выбора всегда должна открываться в заданном виде, то можно задать свойства формы в конфигураторе и ничего не программировать. Однако форма выбора может открываться из разных мест конфигурации, и ее внешний вид может зависеть от различных условий. В таком случае нужно программно формировать внешний вид формы при ее открытии. Последний случай мы сейчас рассмотрим и изучим, как всегда, возможные варианты решения этой задачи.
409
Глава 8. Разработка форм
Первый вариант решения В данном решении мы получим форму на клиенте, установим нужные свойства этой формы и затем откроем ее. Чтобы обеспечить подбор товаров в табличную часть приходной накладной, создадим форму документа и ее команду Подбор. Перетащим команду в командную панель таблицы формы Товары. Обработчик события нажатия кнопки Подбор заполним следующим образом (листинг 8.197). Листинг 8.197. Обработчик события нажатия кнопки «Подбор»
&НаКлиенте Процедура Подбор(Команда) ФормаВыбора = ПолучитьФорму("Справочник.Товары.ФормаВыбора", , Элементы.Товары); ФормаВыбора.Элементы.Список.МножественныйВыбор = Истина; ФормаВыбора.Элементы.Список.Отображение = ОтображениеТаблицы.Дерево; ФормаВыбора.Открыть(); КонецПроцедуры
В этом обработчике мы получаем основную форму выбора справочника Товары как подчиненную таблице Товары формы документа ПриходнаяНакладная. Таким образом, переменная ФормаВыбора будет содержать объект УправляемаяФорма. Используя коллекцию элементов (Элементы) этой формы, мы устанавливаем свойство МножественныйВыбор таблицы формы Список в значение Истина и свойство Отображение в значение системного перечисления ОтображениеТаблицы.Дерево. Тем самым мы добьемся того, что форма, отражающая иерархический список товаров, будет открываться в режиме множественного выбора и таблица списка будет представлена в виде дерева. И затем мы открываем форму выбора методом Открыть(). При выборе из формы выбора справочника выбранное значение будет передано в обработчик события ОбработкаВыбора таблицы формы Товары приходной накладной, так как она является владельцем открытой формы выбора. Причем при множественном выборе форма возвращает не один элемент, а массив элементов.
В этом обработчике мы организуем цикл обхода массива переданных элементов (ВыбранноеЗначение). И в этом цикле добавим новую строку в табличную часть документа (Объект.Товары) и присвоим ее полю Товар значение очередного элемента массива выбранных товаров. подробнее
Этот пример можно посмотреть в демонстрационной конфигурации «Разработка форм, пример 21 (вар. 1)».
Запустим «1С:Предприятие», откроем приходную накладную и нажмем кнопку Подбор. После этого форма выбора из справочника товаров будет открыта в режиме множественного выбора, и иерархический список товаров будет представлен в виде дерева. При нажатии кнопки Выбрать выделенные записи из справочника товаров будут добавлены в табличную часть приходной накладной (рис. 8.456). Если мы посмотрим на показатели производительности, то увидим, что при открытии формы выбора в процедуре Подбор() произойдут два вызова сервера (рис. 8.457).
Рис. 8.457. Окно показателей производительности
Заметим, что при первом открытии формы могут быть лишние серверные вызовы за счет кеширования платформой необходимой информации о форме. Но мы будем изучать стандартную ситуацию, когда при открытии формы происходит один вызов сервера. Для наглядности рассмотрим схему программного взаимодействия клиента и сервера (рис. 8.458).
Поэтому создадим обработчик события ОбработкаВыбора таблицы формы Товары и заполним его следующим образом (листинг 8.198). Листинг 8.198. Обработчик события «ОбработкаВыбора» таблицы «Товары»
&НаКлиенте Процедура ТоварыОбработкаВыбора(Элемент, ВыбранноеЗначение, СтандартнаяОбработка) Для Каждого ВыбранныйЭлемент Из ВыбранноеЗначение Цикл НоваяСтрока = Объект.Товары.Добавить(); НоваяСтрока.Товар = ВыбранныйЭлемент; КонецЦикла;
Рис. 8.458. Схема программного взаимодействия сервера и клиента
КонецПроцедуры
Ниже мы покажем, как этого избежать.
410
Один вызов происходит при выполнении метода оправдан, так как его делает сама платформа.
ПолучитьФорму(),
и он
А вот второго вызова, который происходит при изменении свойства Отображение таблицы формы Список, могло бы и не быть.
Профессиональная разработка в системе «1С:Предприятие 8»
Оптимизация клиент-серверного взаимодействия в формах
Второй вариант решения На
самом
деле более эффективно открывать форму методом при этом передавая в нее параметры. Параметры будут доступны в обработчике события формы выбора ПриСозданииНаСервере, где и нужно управлять состоянием формы при ее открытии. ОткрытьФорму(),
Для этого изменим обработчик события нажатия кнопки Подбор документа ПриходнаяНакладная следующим образом (листинг 8.199). Листинг 8.199. Обработчик события нажатия кнопки «Подбор»
&НаКлиенте Процедура Подбор(Команда) ПараметрыФормы = Новый Структура; ПараметрыФормы.Вставить("МножественныйВыбор", Истина); ПараметрыФормы.Вставить("РежимОтображения", "Дерево"); ОткрытьФорму("Справочник.Товары.ФормаВыбора", ПараметрыФормы, Элементы.Товары); КонецПроцедуры
В этом обработчике мы создаем структуру ПараметрыФормы и добавляем в нее элементы МножественныйВыбор со значением Истина и РежимОтображения со значением Дерево. Причем МножественныйВыбор – это стандартный параметр, поставляемый расширением управляемой формы для динамического списка, который при открытии формы выбора устанавливает соответствующее свойство для таблицы динамического списка. Это платформа делает автоматически. А параметр РежимОтображения мы создаем сами, чтобы передать в обработчик события ПриСозданииНаСервере режим отображения таблицы динамического списка в виде дерева. Затем мы открываем основную форму выбора справочника Товары как подчиненную таблице Товары формы документа ПриходнаяНакладная методом ОткрытьФорму(), который производит одно обращение к серверу.
В этом обработчике мы анализируем значение параметра РежимОтображения и в соответствии с ним устанавливаем свойство Отображение таблицы формы Список в значение системного перечисления ОтображениеТаблицы.Дерево. подробнее
Этот пример можно посмотреть в демонстрационной конфигурации «Разработка форм, пример 21 (вар. 2)».
Запустим «1С:Предприятие», откроем приходную накладную и нажмем кнопку Подбор. После этого форма выбора из справочника товаров будет открыта в режиме множественного выбора, и иерархический список товаров будет представлен в виде дерева. При нажатии кнопки Выбрать выделенные записи из справочника товаров будут добавлены в табличную часть приходной накладной. Как мы видим, функциональность прикладного решения будет такой же, как и в первом случае, но производительность будет выше, так как для открытия формы выбора при помощи метода ОткрытьФорму() потребовался только один вызов сервера (рис. 8.459).
Рис. 8.459. Окно показателей производительности
Заметим, что при первом открытии формы могут быть лишние серверные вызовы за счет кеширования платформой необходимой информации о форме.
Резюме Чтобы открыть форму в некотором нужном состоянии, рекомендуется использовать методы ОткрытьФорму() или ОткрытьФормуМодально() и при этом передавать в них параметры. Форма будет открыта за один серверный вызов.
Для анализа параметра РежимОтображения создаем форму выбора справочника Товары и обработчик события формы ПриСозданииНаСервере. Заполняем его следующим образом (листинг 8.200).
Не рекомендуется открывать форму с помощью метода ПолучитьФорму() и затем обращаться к ее свойствам и методам, так как изменение свойств и методов формы на клиенте может привести к лишним обращениям на сервер.
Листинг 8.200. Обработчик события «ПриСозданииНаСервере»
Кроме того, программный код будет выглядеть при этом менее стройным и читаемым. Он может вообще перестать работать, если, например, в форме переименовали какой-то реквизит, к которому обращались снаружи.
&НаСервере Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка) Если Параметры.РежимОтображения = "Дерево" Тогда Элементы.Список.Отображение = ОтображениеТаблицы.Дерево; КонецЕсли; КонецПроцедуры
Том 1
Таким образом, из показанных вариантов решения задачи более эффективным будет второй вариант за счет открытия формы с передачей в нее параметров за один серверный вызов.
411
Глава 8. Разработка форм
Реализация функциональности в клиентских и серверных обработчиках событий формы в зависимости от их назначения Для реализации функциональности форм разработчик может использовать клиентские и серверные обработчики событий формы. Но делать это нужно правильно и по назначению. Например, при интерактивном или программном создании формы с существующими в информационной базе данными вызывается серверное событие ПриЧтенииНаСервере. Затем для всех форм вызывается серверное событие ПриСозданииНаСервере. В обработчиках этих двух событий можно и нужно подготавливать форму к работе. Затем вызывается клиентское событие формы ПриОткрытии, в обработчике которого можно выполнять действия, доступные только на клиенте, например, общение с пользователем. Часто бывает нужно задать функциональность формы сразу при ее открытии, например, заполнить какие-то реквизиты формы или установить какие-то свойства ее элементов и т. п. В обработчике какого же события – ПриСозданииНаСервере, ПриЧтенииНаСервере или ПриОткрытии – это нужно делать? Рассмотрим пример. Предположим, в периодическом регистре сведений Цены содержатся розничные цены товаров из справочника Товары. При открытии формы уже существующего товара в поле Розничная цена должна подставляться цена из регистра сведений, и это поле должно быть недоступно для редактирования. При открытии формы нового товара поле Розничная цена должно быть недоступно (рис. 8.460).
Для этого создадим форму элемента справочника Товары. Создадим реквизит формы РозничнаяЦена типа Число и перетащим его в дерево элементов формы. Затем создадим обработчик события формы ПриОткрытии и заполним его следующим образом (листинг 8.201). Листинг 8.201. Обработчик события «ПриОткрытии»
&НаКлиенте Процедура ПриОткрытии(Отказ) Если Параметры.Ключ.Пустая() Тогда Элементы.РозничнаяЦена.Видимость = Ложь; Иначе РозничнаяЦена = РозничнаяЦена(Объект.Ссылка); Элементы.РозничнаяЦена.Доступность = Ложь; КонецЕсли; КонецПроцедуры
В этом обработчике мы анализируем значение параметра формы Ключ. Если ссылка, содержащаяся в нем, пустая, то, значит, создается новый элемент, и мы устанавливаем для поля формы РозничнаяЦена свойство Видимость в значение Ложь. В противном случае – товар уже создан. Мы узнаем его цену на текущую дату из регистра сведений и присваиваем ее реквизиту РозничнаяЦена. Также мы устанавливаем для поля формы РозничнаяЦена свойство Доступность в значение Ложь. Теперь поместим в модуль формы функцию для получения актуальной цены товара из регистра сведений, выполняющуюся на сервере без контекста формы (листинг 8.202). Листинг 8.202. Функция «РозничнаяЦена()»
Рис. 8.460. Форма редактирования существующего товара
Рассмотрим возможные варианты решения этой задачи.
Первый вариант решения Чтобы обеспечить нужную функциональность формы при ее открытии, все действия будем выполнять в обработчике события ПриОткрытии. Подходящее название, зачем задумываться о назначении других обработчиков? «При открытии» – название события говорит само за себя, значит, в нем все и сделаем.
412
&НаСервереБезКонтекста Функция РозничнаяЦена(ТоварСсылка) Отбор = Новый Структура; Отбор.Вставить("Товар", ТоварСсылка); ЗначенияРесурсов = РегистрыСведений.Цены.ПолучитьПоследнее(, Отбор); Возврат ЗначенияРесурсов.Цена; КонецФункции
В этой функции мы создаем структуру Отбор, содержащую отбор по измерению регистра Товар, и устанавливаем его равным ссылке на товар, переданной в функцию. Затем при помощи метода ПолучитьПоследнее() мы возвращаем последнюю на текущую дату цену товара. подробнее
Этот пример можно посмотреть в демонстрационной конфигурации «Разработка форм, пример 22 (вар. 1)».
Профессиональная разработка в системе «1С:Предприятие 8»
Оптимизация клиент-серверного взаимодействия в формах Запустим «1С:Предприятие» и откроем форму редактирования одного из товаров. В открывшейся форме поле Розничная цена автоматически заполнится последней ценой этого товара из регистра сведений, при этом поле Розничная цена будет недоступно для редактирования (рис. 8.460). В случае создания нового товара поле Розничная цена будет невидимо. Однако в обоих случаях (и для нового, и для уже существующего товара) при открытии формы редактирования будут сделаны два обращения на сервер (рис. 8.461).
Рис. 8.461. Окно показателей производительности
Заметим, что при первом открытии формы могут быть лишние серверные вызовы за счет кеширования платформой необходимой информации о форме. Но мы будем изучать стандартную ситуацию, когда при открытии формы происходит один вызов сервера. Для наглядности рассмотрим схему программного взаимодействия клиента и сервера (рис. 8.462).
Второй вариант решения На самом деле когда открывается форма с существующими в информационной базе данными, вызывается серверное событие ПриЧтенииНаСервере. В обработчике этого события, в параметре ТекущийОбъект, нам доступен прикладной объект, содержащийся в форме, со всей его функциональностью. Таким образом, здесь мы можем подготовить данные формы, зависящие от данных объекта, к открытию. Затем вызывается серверное событие формы ПриСозданииНаСервере. Это событие не зависит от того, какие данные форма отображает, и вызывается при открытии у всех форм. Именно в обработчике этого события нужно полностью подготавливать саму форму, ее внешнее представление, к открытию. Для подготовки данных формы лучше использовать событие ПриЧтенииНаСервере. Таким образом, к моменту передачи формы на клиента и возникновению события ПриОткрытии вся подготовительная работа по открытию формы будет уже сделана. Останется только выполнить какое-то общение с пользователем (Предупреждение, Вопрос и т. п.), если это нужно. В данном решении мы используем обработчик события ПриЧтенииНаСервере. Это событие вызывается только для существующих объектов, при создании новых оно не вызывается. Поэтому для реализации нужной функциональности формы мы можем стандартно сконфигурировать поле РозничнаяЦена невидимым и недоступным, а в этом обработчике просто включать его видимость без какого-либо программного анализа, новый это элемент или нет. Итак, создадим обработчик события формы элемента справочника Товары ПриЧтенииНаСервере и переместим в него код из функции РозничнаяЦена(), листинг 8.203. Листинг 8.203. Обработчик события «ПриЧтенииНаСервере»
Рис. 8.462. Схема программного взаимодействия сервера и клиента
Один вызов происходит при открытии формы элемента справочника, и его делает сама платформа. А вот второго вызова, который происходит при изменении свойства Видимость поля Розничная цена для нового товара или при подстановке цены из регистра сведений для существующего товара, могло бы и не быть. Этот лишний серверный вызов произошел с клиента, из обработчика события ПриОткрытии. Ниже мы покажем, как этого избежать.
Том 1
&НаСервере Процедура ПриЧтенииНаСервере(ТекущийОбъект) Отбор = Новый Структура; Отбор.Вставить("Товар", ТекущийОбъект.Ссылка); ЗначенияРесурсов = РегистрыСведений.Цены.ПолучитьПоследнее(, Отбор); РозничнаяЦена = ЗначенияРесурсов.Цена; Элементы.РозничнаяЦена.Видимость = Истина; КонецПроцедуры
Отключим свойства Доступность и Видимость для поля РозничнаяЦена. Поскольку обработчик ПриЧтенииНаСервере будет отрабатывать только для существующих объектов, то для новых товаров поле РозничнаяЦена будет невидимым, а для существующих товаров мы заполняем его последней ценой текущего товара из регистра сведений и устанавливаем
413
Глава 8. Разработка форм его видимость, недоступным для редактирования оно будет в любом случае.
Использование стандартных полей запроса в динамических списках на клиенте
подробнее
Формы списка объектов конфигурации построены с помощью динамического списка. Динамический список формируется путем запроса к основной таблице, указанной в соответствующем свойстве реквизита типа ДинамическийСписок, или путем произвольного запроса к базе данных.
Этот пример можно посмотреть в демонстрационной конфигурации «Разработка форм, пример 22 (вар. 2)».
Как мы видим, функциональность прикладного решения будет такой же, как и в первом случае, но производительность будет выше, так как не будет лишних вызовов сервера с клиента. В результате та же функциональность формы будет реализована за один серверный вызов (рис. 8.463).
Рис. 8.463. Окно показателей производительности
Заметим, что при первом открытии формы могут быть лишние серверные вызовы за счет кеширования платформой необходимой информации о форме.
Обычно далеко не все поля динамического списка используются для отображения в форме. Например, в форме списка справочника это поля Код и Наименование плюс реквизиты, созданные разработчиком. В запросе на сервере из таблицы справочника могут быть выбраны и переданы на клиента и другие его стандартные реквизиты. Например, для иерархического справочника это поля Ссылка, ЭтоГруппа, Родитель, Предопределенный и т. п. Особенность в том, что запросом выбираются и передаются на клиента значения только тех реквизитов, в свойствах которых стоит отметка Использовать всегда, или они отображаются в форме (рис. 8.464).
Резюме Для реализации функциональности форм разработчик должен правильно и по назначению использовать клиентские и серверные обработчики событий формы. Большая часть кода должна быть реализована в серверных обработчиках событий формы. Например, форма должна быть максимально подготовлена для открытия в обработчиках ПриЧтенииНаСервере и ПриСозданииНаСервере, а в обработчике ПриОткрытии нужно выполнять только действия, недоступные на сервере – Предупреждение, Вопрос и т. п. При открытии формы настоятельно не рекомендуется выполнять обращения к серверу из кода модуля формы в обработчиках клиентских событий формы, таких как ПриОткрытии и ПриПовторномОткрытии. При необходимости обращения из них к серверным данным следует размещать эти данные в реквизитах формы, в обработчике события ПриСозданииНаСервере. Таким образом, из показанных вариантов решения задачи более эффективным будет второй вариант за счет реализации функциональности формы в обработчике события ПриЧтенииНаСервере.
Рис. 8.464. Форма списка иерархического справочника
Таким образом, при помощи свойства полей динамического списка Использовать всегда можно получить значения реквизитов объекта на клиенте, не обращаясь лишний раз к серверу. А можно «пойти» на сервер и получить эти реквизиты по ссылке на объект, используя свойство таблицы динамического списка ТекущаяСтрока. Какой же способ наиболее эффективен? Рассмотрим этот вопрос на примере открытия текущего элемента из формы списка иерархического справочника.
414
Профессиональная разработка в системе «1С:Предприятие 8»
Оптимизация клиент-серверного взаимодействия в формах Предположим, в конфигурации существует иерархический справочник Товары. При открытии формы элемента справочника из формы списка нужно проанализировать, является ли выбранный элемент группой, и в зависимости от этого открывать форму группы или форму элемента справочника. Рассмотрим возможные варианты решения этой задачи.
Первый вариант решения В данном решении мы будем получать ссылку на текущий элемент, отображаемый в списке, затем «пойдем» с ней на сервер, чтобы из информационной базы узнать, является элемент группой или нет. В зависимости от этого, вернувшись на клиента, будем открывать либо форму элемента, либо форму группы. Чтобы программно открывать форму элемента, создадим форму списка справочника Товары и ее команду ОткрытьТовар. Перетащим команду в командную панель формы. Обработчик события нажатия кнопки Открыть товар заполним следующим образом (листинг 8.204). Листинг 8.204. Обработчик события нажатия кнопки «Открыть товар»
&НаКлиенте Процедура ОткрытьТовар(Команда) СсылкаНаЭлементСправочника = Элементы.Список.ТекущаяСтрока; ПараметрыФормы = Новый Структура("Ключ", СсылкаНаЭлементСправочника);
подробнее
Этот пример можно посмотреть в демонстрационной конфигурации «Разработка форм, пример 23 (вар. 1)».
Запустим «1С:Предприятие», выделим группу в форме списка товаров и нажмем кнопку Открыть товар. В результате будет открыта форма группы справочника товаров. Затем выделим элемент справочника и нажмем кнопку Открыть товар. В результате будет открыта форма элемента справочника товаров. Однако в обоих случаях при открытии формы будут сделаны два обращения на сервер (рис. 8.465). Рис. 8.465. Окно показателей производительности
Заметим, что при первом открытии формы могут быть лишние серверные вызовы за счет кеширования платформой необходимой информации о форме. Но мы будем изучать стандартную ситуацию, когда при открытии формы происходит один вызов сервера. Для наглядности рассмотрим схему программного взаимодействия клиента и сервера (рис. 8.466).
Если ЕслиЭтоГруппа(СсылкаНаЭлементСправочника) Тогда ОткрытьФорму("Справочник.Товары.ФормаГруппы", ПараметрыФормы); Иначе ОткрытьФорму("Справочник.Товары.ФормаОбъекта", ПараметрыФормы); КонецЕсли; КонецПроцедуры
В этом обработчике, используя свойство ТекущаяСтрока таблицы формы Список, отражающей данные динамического списка, мы получаем ссылку на текущий элемент справочника. Значение ссылки мы присваиваем параметру формы Ключ. И в зависимости от того, является ли данный элемент группой, открываем форму группы или форму элемента справочника с этим параметром. Для определения, является ли элемент справочника группой по переданной ссылке, поместим в модуле формы функцию, исполняющуюся на сервере без контекста формы (листинг 8.205). Листинг 8.205. Функция «ЕслиЭтоГруппа»
НаСервереБезКонтекста Функция ЕслиЭтоГруппа(Ссылка) Возврат Ссылка.ЭтоГруппа; КонецФункции
Том 1
Рис. 8.466. Схема программного взаимодействия сервера и клиента
Второй вызов происходит при открытии формы элемента или группы справочника, и его делает сама платформа. А вот первого вызова, который происходит при определении, является ли текущий элемент группой, могло бы и не быть. Ниже мы покажем, как этого избежать.
Второй вариант решения В данном решении мы не будем специально «ходить» на сервер и определять, является ли текущий элемент группой или нет, потому что эти данные уже есть в динамическом списке. Просто сделаем так, чтобы они присутствовали в нем, даже несмотря на то, что они не отображаются в форме. Тогда все, что нам нужно знать об этом элементе, мы сможем выяснить прямо на клиенте, без вызова сервера.
415
Глава 8. Разработка форм Установим флажок Использовать всегда для поля ЭтоГруппа в свойствах основного реквизита формы Список (см. рис. 8.464). Это значит, что данные этого поля будут передаваться на клиента, даже несмотря на то, что в форме они нигде не отображаются. Такая возможность сделана как раз на случай только программного использования этих данных.
всегда», вместо того чтобы обращаться на сервер за этими значениями.
Теперь изменим обработчик события нажатия кнопки Открыть товар следующим образом (листинг 8.206).
Тут есть один интересный момент. Заметьте, что в этой ситуации можно было бы использовать метод ОткрытьЗначение(Элементы.Список.ТекущаяСтрока) – он один заменяет собой весь код выше (см. листинг 8.206). Но в этом случае для иерархического справочника будет каждый раз происходить лишнее обращение к серверу для определения, является ли открываемый элемент группой или нет. Но если это будет не иерархический справочник, а обычный, или другой объект конфигурации, документ например, этого обращения не будет.
Листинг 8.206. Обработчик события нажатия кнопки «Открыть товар»
&НаКлиенте Процедура ОткрытьТовар(Команда) СсылкаНаЭлементСправочника = Элементы.Список.ТекущаяСтрока; ПараметрыФормы = Новый Структура("Ключ", СсылкаНаЭлементСправочника);
Таким образом, из показанных вариантов решения задачи более эффективным будет второй вариант за счет получения реквизитов динамического списка на клиенте без обращения к серверу.
Если Элементы.Список.ТекущиеДанные.ЭтоГруппа Тогда ОткрытьФорму("Справочник.Товары.ФормаГруппы", ПараметрыФормы); Иначе ОткрытьФорму("Справочник.Товары.ФормаОбъекта", ПараметрыФормы); КонецЕсли;
Этот пример хорошо иллюстрирует то, что нет «рецептов на все времена», и каждый раз нужно думать и анализировать, как решить конкретную задачу наиболее эффективно.
КонецПроцедуры
Использование стандартного параметра формы отчета для автоматического формирования отчета при его открытии
В этом обработчике для определения, является ли элемент справочника группой, мы используем свойство ТекущиеДанные таблицы формы Список, отражающей данные динамического списка. И затем через точку от него обращаемся к полю ЭтоГруппа текущей строки этой таблицы. подробнее
Этот пример можно посмотреть в демонстрационной конфигурации «Разработка форм, пример 23 (вар. 2)».
Поскольку значение этого поля уже доступно на клиенте, нам не понадобится лишний раз обращаться на сервер. В результате та же функциональность будет реализована за один серверный вызов, и производительность прикладного решения будет выше (рис. 8.467). Рис. 8.467. Окно показателей производительности
Заметим, что при первом открытии формы могут быть лишние серверные вызовы за счет кеширования платформой необходимой информации о форме.
Резюме В формах списка объектов конфигурации, построенных с помощью динамического списка, часто бывает нужно использовать значения стандартных реквизитов текущего объекта списка. Для этого нужно получать значения стандартных реквизитов объекта в динамических списках на клиенте, устанавливая флажок «Использовать
416
Пользователю часто может понадобиться сформировать отчет сразу при его открытии. Эту очень удобную возможность предоставляет платформа «1С:Предприятие». Для этого можно использовать параметр СформироватьПриОткрытии, поставляемый расширением формы для отчета, и передавать его в форму при открытии. Или же можно установить этот параметр в значение Истина в обработчике события формы ПриСозданииНаСервере. Казалось бы, можно сформировать отчет и в обработчике события формы ПриОткрытии методом СкомпоноватьРезультат(), доступном в модуле формы на клиенте. Но посмотрим, какое решение будет наиболее эффективным. Предположим, в конфигурации существует отчет РеестрОказанныхУслуг, выводящий список существующих в информационной базе документов ОказаниеУслуги. При открытии формы отчета список документов должен формироваться автоматически, без нажатия кнопки Сформировать. Для примера взят самый простой отчет, но он, тем не менее, позволит рассмотреть возможные варианты решения этой задачи.
Первый вариант решения Чтобы программно сформировать отчет РеестрОказанныхУслуг при открытии, в форме отчета, в обработчике ПриОткрытии вызовем автоматическое формирование отчета. Профессиональная разработка в системе «1С:Предприятие 8»
Оптимизация клиент-серверного взаимодействия в формах Для этого создадим форму отчета и обработчик события формы ПриОткрытии и заполним его следующим образом (листинг 8.207).
мации о форме. Но мы будем изучать стандартную ситуацию, когда при открытии формы происходит один вызов сервера.
Листинг 8.207. Обработчик события «ПриОткрытии»
Для наглядности рассмотрим схему программного взаимодействия клиента и сервера (рис. 8.470).
&НаКлиенте Процедура ПриОткрытии(Отказ) СкомпоноватьРезультат(); КонецПроцедуры
В этом обработчике при открытии формы на клиенте отчет формируется методом СкомпоноватьРезультат(), поставляемым расширением формы для отчета. подробнее
Этот пример можно посмотреть в демонстрационной конфигурации «Разработка форм, пример 24 (вар. 1)».
Запустим «1С:Предприятие» и откроем отчет РеестрОказанныхУслуг из панели действий приложения (рис. 8.468).
Рис. 8.470. Схема программного взаимодействия сервера и клиента
Один вызов происходит при открытии формы отчета, и его делает сама платформа. А вот второго вызова, который происходит при выполнении метода СкомпоноватьРезультат(), можно избежать. Ниже мы покажем, как это сделать.
Второй вариант решения На самом деле можно выполнить открытие формы отчета и его формирование за один серверный вызов. Для этого нужно установить параметр формы СформироватьПриОткрытии в значение Истина в обработчике события формы ПриСозданииНаСервере. Итак, создадим обработчик события формы отчета РеестрОказанныхУслуг – ПриСозданииНаСервере и заполним его следующим образом (листинг 8.208). Рис. 8.468. Формирование отчета при его открытии
Листинг 8.208. Обработчик события «ПриСозданииНаСервере»
Отчет будет сформирован сразу при открытии формы. Вроде бы все хорошо, но в данном случае при открытии формы отчета будут сделаны два обращения на сервер (рис. 8.469).
&НаСервере Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка) Параметры.СформироватьПриОткрытии = Истина; КонецПроцедуры
А обработчик события ПриОткрытии удалим. Рис. 8.469. Окно показателей производительности
Заметим, что при первом открытии формы могут быть лишние серверные вызовы за счет кеширования платформой необходимой инфорТом 1
подробнее
Этот пример можно посмотреть в демонстрационной конфигурации «Разработка форм, пример 24 (вар. 2)».
417
Глава 8. Разработка форм Запустим «1С:Предприятие» и откроем отчет РеестрОказанныхУслуг из панели действий приложения. Как мы видим, функциональность прикладного решения будет такой же, как и в первом случае, но производительность будет выше, так как для открытия формы отчета и его формирования потребовался только один вызов сервера (рис. 8.471).
Запустим «1С:Предприятие» и откроем отчет РеестрОказанныхУслуг из панели навигации приложения (рис. 8.472).
Рис. 8.471. Окно показателей производительности
Заметим, что при первом открытии формы могут быть лишние серверные вызовы за счет кеширования платформой необходимой информации о форме.
Третий вариант решения Для формирования отчета в первых двух случаях мы использовали стандартную команду открытия формы отчета, автоматически помещаемую платформой в панель действий приложения. При этом отчет в обоих случаях будет формироваться всегда при открытии с помощью этой стандартной команды. Теперь покажем вариант программного открытия формы отчета с параметром СформироватьПриОткрытии. Для этого создадим общую команду СписокОказанныхУслуг и поместим ее в группу Панель навигации.Важное. В модуле команды напишем следующий код (листинг 8.209). Листинг 8.209. Модуль команды «СписокОказанныхУслуг»
&НаКлиенте Процедура ОбработкаКоманды(ПараметрКоманды, ПараметрыВыполненияКоманды) ПараметрыФормы = Новый Структура("СформироватьПриОткрытии", Истина); ОткрытьФорму("Отчет.РеестрОказанныхУслуг.Форма", ПараметрыФормы); КонецПроцедуры
В этом обработчике мы создаем структуру ПараметрыФормы и добавляем в нее элемент СформироватьПриОткрытии со значением Истина. Затем мы открываем форму отчета РеестрОказанныхУслуг с этим параметром. А форму отчета РеестрОказанныхУслуг можно теперь вообще удалить, поскольку она больше не нужна. А также уберем видимость у стандартной команды открытия формы отчета в командном интерфейсе рабочего стола конфигурации. подробнее
Этот пример можно посмотреть в демонстрационной конфигурации «Разработка форм, пример 24 (вар. 3)».
418
Рис. 8.472. Формирование отчета при его открытии
Отчет будет сформирован сразу при открытии формы за один серверный вызов. Заметим, что при первом открытии формы могут быть лишние серверные вызовы за счет кеширования платформой необходимой информации о форме.
Резюме Платформа «1С:Предприятие» предоставляет очень удобную возможность формировать отчет, построенный с помощью системы компоновки данных, сразу при его открытии. Для этого нужно использовать параметр СформироватьПриОткрытии, поставляемый расширением формы для отчета, и передавать его в форму при открытии. Или же можно установить параметр формы СформироватьПриОткрытии в значение Истина в обработчике события формы ПриСозданииНаСервере. При открытии формы отчета настоятельно не рекомендуется выполнять обращения к серверу, например формировать отчет, из кода модуля формы в обработчиках клиентских событий формы, таких как ПриОткрытии и ПриПовторномОткрытии. Это потребует лишнего обращения к серверу и будет неэффективно. Таким образом, из показанных вариантов решения задачи более эффективными будут второй и третий варианты за счет использования параметра формы отчета СформироватьПриОткрытии и формирования отчета сразу при открытии за один серверный вызов. Профессиональная разработка в системе «1С:Предприятие 8»
Оптимизация клиент-серверного взаимодействия в формах
Изменение свойств элементов формы, не требующих обращения к серверу Для реализации той или иной функциональности формы часто бывает нужно изменять свойства ее элементов в зависимости от конкретных действий пользователя. Делать это приходится на клиенте, например, при изменении значений каких-либо элементов формы, то есть в обработчике событий ПриИзменении. При этом изменение некоторых свойств приводит к пересчету местоположения элементов формы, так как внешний вид формы автоматически формируется платформой на основе ее декларативного описания, заданного разработчиком. Первоначальная подготовка внешнего вида формы происходит на сервере. Если свойства, влияющие на расположение элементов формы, меняются программно (например, свойство Видимость), форма должна полностью «пересчитать» расположение полей. Это выполняется на сервере и требует определенных затрат времени. Поэтому, может быть, более эффективно использовать свойства элементов формы, изменение которых не приводит к обращениям на сервер. Например, вместо свойства Видимость можно использовать свойство Доступность. Рассмотрим пример. Предположим, в форме документа об оказании услуг содержится цена услуги, флажок скидки, сумма скидки и сумма услуги. При изменении цены услуги нужно рассчитать сумму услуги, равной цене услуги за вычетом суммы скидки. Поле СуммаСкидки должно быть доступно для изменения только в случае установки в поле флажка Скидка (рис. 8.473).
Первый вариант решения Чтобы обеспечить перерасчет суммы услуги при изменении ее цены и скидки, создадим форму документа ОказаниеУслуги и обработчик события ПриИзменении для поля формы ЦенаУслуги (листинг 8.210). Листинг 8.210. Процедура «ЦенаУслугиПриИзменении()»
&НаКлиенте Процедура ЦенаУслугиПриИзменении(Элемент) Объект.СуммаУслуги = Объект.ЦенаУслуги – Объект.СуммаСкидки; КонецПроцедуры
Аналогичные действия выполним в обработчике события для поля формы СуммаСкидки (листинг 8.211).
ПриИзменении
Листинг 8.211. Процедура «СуммаСкидкиПриИзменении()»
&НаКлиенте Процедура СуммаСкидкиПриИзменении(Элемент) Объект.СуммаУслуги = Объект.ЦенаУслуги – Объект.СуммаСкидки; КонецПроцедуры
Алгоритм пересчета суммы услуги мы выполняем на клиенте, так как он небольшой и быстро выполняется из клиентской процедуры при изменении цены услуги и суммы скидки. Здесь нет ничего принципиально нового, так как этот вопрос мы уже рассматривали во втором варианте третьего примера (стр. 405). Включим для поля формы СуммаУслуги свойство ТолькоПросмотр, так как оно является расчетным. Теперь нам нужно обеспечить доступность для изменения поля СуммаСкидки в зависимости от отметки в поле Скидка. Можно сделать поле СуммаСкидки невидимым, если поле Скидка не отмечено. Для этого создадим обработчик события ПриИзменении для поля формы Скидка (листинг 8.212). Листинг 8.212. Процедура «СкидкаПриИзменении()»
Рис. 8.473. Пересчет данных в документе при изменении цены услуги
Таким образом, в тот момент, когда пользователь изменит поле ЦенаУслуги или поле СуммаСкидки документа ОказаниеУслуги, поле СуммаУслуги нужно рассчитать по описанному выше алгоритму. Рассмотрим возможные варианты решения этой задачи. Том 1
&НаКлиенте Процедура СкидкаПриИзменении(Элемент) Если Объект.Скидка Тогда Элементы.СуммаСкидки.Видимость = Истина; Иначе Объект.СуммаСкидки = 0; Элементы.СуммаСкидки.Видимость = Ложь; Объект.СуммаУслуги = Объект.ЦенаУслуги – Объект.СуммаСкидки; КонецЕсли; КонецПроцедуры
419
Глава 8. Разработка форм В этом обработчике мы анализируем значение реквизита Скидка типа Булево и в зависимости от него устанавливаем свойство Видимость поля формы СуммаСкидки. Затем мы производим пересчет суммы услуги в соответствии с заданным алгоритмом. Этот пересчет, как мы знаем, не требует обращения к серверу. А вот при изменении свойства Видимость на клиенте произойдет лишний вызов сервера, что, конечно, нежелательно.
при изменении видимости элементов формы происходит один вызов сервера. Для наглядности рассмотрим схему программного взаимодействия клиента и сервера (рис. 8.475).
И в заключение установим видимость поля СуммаСкидки в зависимости от отметки в поле Скидка в обработчике события формы ПриСозданииНаСервере (листинг 8.213). Листинг 8.213. Обработчик события «ПриСозданииНаСервере»
&НаСервере Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка) Если Объект.Скидка Тогда Элементы.СуммаСкидки.Видимость = Истина; Иначе Элементы.СуммаСкидки.Видимость = Ложь; КонецЕсли; КонецПроцедуры подробнее
Этот пример можно посмотреть в демонстрационной конфигурации «Разработка форм, пример 25 (вар. 1)».
Запустим «1С:Предприятие», создадим документ об оказании услуги, выберем услугу, клиента и внесем цену услуги. Первоначально поле СуммаСкидки не видно в форме, но после отметки в поле Скидка оно становится видимым и доступным для изменения. Внесем сумму скидки. После этого поле СуммаУслуги автоматически пересчитается по заданному нами алгоритму (см. рис. 8.473). При снятии отметки в поле Скидка поле СуммаСкидки обнуляется и становится невидимым. После этого поле СуммаУслуги снова пересчитывается. В результате изменение свойства Видимость на клиенте приведет к пересчету местоположения элементов формы, которое происходит на сервере. В итоге будет сделано одно лишнее обращение на сервер, которое понизит производительность прикладного решения (рис. 8.474).
Рис. 8.474. Окно показателей производительности
Заметим, что при первом изменении видимости элементов формы могут быть лишние серверные вызовы за счет кеширования платформой необходимой информации. Но мы будем изучать стандартную ситуацию, когда
420
Рис. 8.475. Схема программного взаимодействия сервера и клиента
Второй вариант решения На самом деле можно обойтись без вызова сервера, если использовать для поля СуммаСкидки свойство Доступность вместо свойства Видимость. Для этого изменим обработчик события Скидка (листинг 8.214).
ПриИзменении
поля формы
Листинг 8.214. Процедура «СкидкаПриИзменении()»
&НаКлиенте Процедура СкидкаПриИзменении(Элемент) Если Объект.Скидка Тогда Элементы.СуммаСкидки.Доступность = Истина; Иначе Объект.СуммаСкидки = 0; Элементы.СуммаСкидки.Доступность = Ложь; Объект.СуммаУслуги = Объект.ЦенаУслуги – Объект.СуммаСкидки; КонецЕсли; КонецПроцедуры
В этом обработчике мы анализируем значение реквизита Скидка типа Булево и в зависимости от него устанавливаем свойство Доступность поля формы СуммаСкидки. Затем мы производим пересчет суммы услуги в соответствии с заданным алгоритмом. И в заключение установим доступность поля СуммаСкидки в зависимости от отметки в поле Скидка в обработчике события формы ПриСозданииНаСервере (листинг 8.215).
Профессиональная разработка в системе «1С:Предприятие 8»
Оптимизация клиент-серверного взаимодействия в формах Листинг 8.215. Обработчик события «ПриСозданииНаСервере»
&НаСервере Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка) Если Объект.Скидка Тогда Элементы.СуммаСкидки.Доступность = Истина; Иначе Элементы.СуммаСкидки.Доступность = Ложь; КонецЕсли; КонецПроцедуры подробнее
Этот пример можно посмотреть в демонстрационной конфигурации «Разработка форм, пример 25 (вар. 2)».
Запись данных объекта в единой транзакции за один серверный вызов В процессе работы прикладного решения значения реквизитов объекта могут меняться не только интерактивно, но и программно. При этом запись данных объекта в информационную базу должна выполняться в единой транзакции за один серверный вызов. Рассмотрим этот вопрос на примере работы с файлами и картинками. Предположим, в форме элемента справочника Товары содержится поле, отражающее картинку товара. При нажатии кнопки Загрузить картинку, расположенной в форме документа, должен открываться диалог выбора файла картинки. Выбранная картинка должна быть отображена в форме элемента и записана в соответствующий реквизит объекта (рис. 8.476).
Запустим «1С:Предприятие», создадим документ об оказании услуги, выберем услугу, клиента и внесем цену услуги. Первоначально поле СуммаСкидки недоступно для редактирования, но после отметки в поле Скидка мы можем внести сумму скидки. После этого поле СуммаУслуги автоматически пересчитается по заданному нами алгоритму. При снятии отметки в поле Скидка поле СуммаСкидки обнуляется и становится недоступным. После этого поле СуммаУслуги снова пересчитывается. Как мы видим, функциональность прикладного решения будет практически такой же, как и в первом случае, но производительность будет выше, так как изменение свойства Доступность на клиенте не приведет к обращению на сервер. Окно показателей производительности не появится (или будет пустым), так как вызовов сервера не было вообще.
Резюме Таким образом, если логика интерактивной работы формы требует изменения ее внешнего вида, это приводит к лишним вызовам сервера с клиента и, соответственно, к снижению производительности прикладного решения. Поэтому если прикладная логика позволяет не скрывать элементы, то лучше их не скрывать, а делать недоступными, потому что изменение свойства Видимость приводит к перестроению формы и, соответственно, к лишним вызовам сервера. Вместо него лучше использовать свойство Доступность. Рекомендуется не использовать формы, меняющие состав и положение элементов. И вообще, если есть такая возможность, лучше не использовать свойства и методы встроенного языка, приводящие к вызову сервера (это указано в синтакс-помощнике). Таким образом, из показанных вариантов решения задачи более эффективным будет второй вариант за счет использования свойства поля формы Доступность вместо свойства Видимость. В результате изменение этого свойства на клиенте не потребовало обращения к серверу. Том 1
Рис. 8.476. Выбор картинки в форме товара
Сначала пользователь должен выбрать картинку товара. Единственный способ работы с файлами пользователя – интерактивно выбрать картинку и поместить ее во временное хранилище на сервере. Затем получить ее из временного хранилища и записать в базу данных, например, в реквизит объекта. В форме картинка отображается автоматически по навигационной ссылке на временное хранилище или на реквизит объекта, содержащий эту картинку. Когда же нужно записывать картинку из временного хранилища в соответствующий реквизит объекта? Можно записать картинку сразу после выбора, но более эффективно записать ее тогда, когда пользователь захочет сохранить объект. Рассмотрим возможные варианты решения этой задачи.
421
Глава 8. Разработка форм
Первый вариант решения В данном решении запишем картинку в базу данных сразу же после ее выбора. Итак, создадим форму элемента справочника Товары. Добавим в форму реквизит АдресКартинки (тип Строка), в котором будет храниться навигационная ссылка на реквизит справочника ДанныеФайлаКартинки. Перетащим реквизит АдресКартинки в дерево элементов формы. Установим свойства элемента: Вид – Поле картинки и ПоложениеЗаголовка – Нет. Создадим команду формы ЗагрузитьКартинку и поместим ее в командную панель формы. При нажатии этой кнопки будет выполняться выбор файла картинки с диска, запись данных картинки в реквизит справочника ДанныеФайлаКартинки и отображение картинки в форме (рис. 8.477).
КонецЕсли; АдресКартинки = ПолучитьНавигационнуюСсылку(Объект.Ссылка, "ДанныеФайлаКартинки"); КонецПроцедуры
В этом обработчике реквизиту АдресКартинки присваивается пустое значение и затем методом глобального контекста ПоместитьФайл() открывается диалог выбора файла картинки с диска. В результате выбора имя выбранного файла сохраняется в реквизите справочника ИмяФайла, и данные файла картинки помещаются во временное хранилище. Адрес данных в этом хранилище сохраняется в реквизите формы АдресКартинки. Затем в процедуре ПоместитьФайлКартинки() выполняется запись данных картинки в реквизит справочника ДанныеФайлаКартинки. И затем с помощью метода ПолучитьНавигационнуюСсылку() реквизиту АдресКартинки присваивается навигационная ссылка на реквизит ДанныеФайлаКартинки, и картинка отображается в форме. В первом параметре метода ПолучитьНавигационнуюСсылку() передается ссылка на объект Объект.Ссылка, а во втором – имя реквизита. Контекстную серверную процедуру ПоместитьФайлКартинки() заполним следующим образом (листинг 8.217). Листинг 8.217. Процедура «ПоместитьФайлКартинки()»
&НаСервере Процедура ПоместитьФайлКартинки() ЭлементСправочника = РеквизитФормыВЗначение("Объект"); ДвоичныеДанные = ПолучитьИзВременногоХранилища(АдресКартинки); ЭлементСправочника.ДанныеФайлаКартинки = Новый ХранилищеЗначения(ДвоичныеДанные, Новый СжатиеДанных()); ЭлементСправочника.Записать(); УдалитьИзВременногоХранилища(АдресКартинки); ЗначениеВРеквизитФормы(ЭлементСправочника, "Объект"); КонецПроцедуры
Рис. 8.477. Форма элемента справочника «Товары»
Обработчик события нажатия кнопки Загрузить картинку заполним следующим образом (листинг 8.216). Листинг 8.216. Обработчик события нажатия кнопки «Загрузить картинку»
&НаКлиенте Процедура ЗагрузитьКартинку(Команда) Перем ВыбранноеИмя; АдресКартинки = ""; Если ПоместитьФайл(АдресКартинки, "", ВыбранноеИмя, Истина) Тогда Объект.ИмяФайла = ВыбранноеИмя; ПоместитьФайлКартинки();
422
Чтобы мы могли записать объект, в этой процедуре значение основного реквизита формы Объект преобразуется в значение объекта – элемента справочника. Затем в переменной ДвоичныеДанные сохраняются данные, полученные из временного хранилища по адресу АдресКартинки. Затем создается объект ХранилищеЗначения, в него помещается значение переменной ДвоичныеДанные, и значение объекта ХранилищеЗначения сохраняется в реквизите справочника ДанныеФайлаКартинки. Затем данные объекта – элемента справочника записываются, временное хранилище очищается, и значение измененного объекта преобразовывается обратно в значение основного реквизита формы. Теперь осталось обеспечить чтение картинки при чтении данных уже существующего объекта. Для этого создадим обработчик события формы ПриЧтенииНаСервере и заполним его следующим образом (листинг 8.218). Профессиональная разработка в системе «1С:Предприятие 8»
Оптимизация клиент-серверного взаимодействия в формах Листинг 8.218. Обработчик события «ПриЧтенииНаСервере»
&НаСервере Процедура ПриЧтенииНаСервере(ТекущийОбъект) АдресКартинки = ПолучитьНавигационнуюСсылку(ТекущийОбъект.Ссылка, "ДанныеФайлаКартинки"); КонецПроцедуры подробнее
Этот пример можно посмотреть в демонстрационной конфигурации «Разработка форм, пример 26 (вар. 1)».
Запустим «1С:Предприятие» и откроем форму элемента справочника Товары. Если у товара уже была выбрана картинка, она отразится в форме. Нажмем кнопку Загрузить картинку и изменим картинку товара. Выбранная картинка отобразится в поле картинки товара и будет записана в реквизит объекта ДанныеФайлаКартинки (рис. 8.476). Таким образом, мы добились нужной функциональности формы, но посмотрим теперь на показатели производительности. В результате из обработчика события нажатия кнопки Загрузить картинку (см. листинг 8.216) будет сделано целых пять вызовов сервера (рис. 8.478)!
этим методом, сразу же помещается в реквизит формы АдресКартинки. Это приводит к тому, что форма обновляется, чтобы отобразить картинку по этой ссылке. Если в вызове метода ПоместитьФайл() вместо АдресКартинки использовать другую произвольную переменную, а не реквизит формы, то произойдет только один серверный вызов. Один вызов сервера будет сделан при записи картинки объекта при вызове серверной процедуры ПоместитьФайлКартинки(). Этого вызова можно избежать, если не записывать картинку сразу при выборе, а хранить данные картинки во временном хранилище до тех пор, пока объект не записан. И еще два вызова произойдут при выполнении метода ПолучитьНавигационнуюСсылку(). Этот метод выполняет обращение к серверу при получении ссылки на реквизит. Здесь один серверный вызов происходит при получении навигационной ссылки, а второй вызов – потому, что она сразу же присваивается реквизиту формы АдресКартинки. Этих вызовов также можно избежать, если использовать навигационную ссылку на временное хранилище для отображения картинки в форме до тех пор, пока объект не записан.
Второй вариант решения Итак, устраним описанные выше ошибки. Для этого изменим обработчик события нажатия кнопки Загрузить картинку следующим образом (листинг 8.219). Листинг 8.219. Обработчик события нажатия кнопки «Загрузить картинку»
Рис. 8.478. Окно показателей производительности
Для наглядности рассмотрим схему программного взаимодействия клиента и сервера (рис. 8.479).
Рис. 8.479. Схема программного взаимодействия сервера и клиента
Два вызова сервера произойдут при выполнении метода ПоместитьФайл(), и эти вызовы оправданы, так как их делает платформа. Один раз сервер вызывается при исполнении метода ПоместитьФайл(), так как он передает картинку с клиентского компьютера во временное хранилище, а второй вызов происходит потому, что навигационная ссылка, возвращенная Том 1
&НаКлиенте Процедура ЗагрузитьКартинку(Команда) Перем ВыбранноеИмя, АдресВременногоХранилища; Если ПоместитьФайл(АдресВременногоХранилища, "", ВыбранноеИмя, Истина, УникальныйИдентификатор) Тогда Объект.ИмяФайла = ВыбранноеИмя; АдресКартинки = АдресВременногоХранилища; Модифицированность = Истина; КонецЕсли; КонецПроцедуры
В этом обработчике методом ПоместитьФайл() открывается диалог выбора файла картинки с диска. В результате выбора имя выбранного файла ВыбранноеИмя сохраняется в реквизите справочника ИмяФайла, и данные файла картинки помещаются во временное хранилище. Параметр УникальныйИдентификатор связывает эти данные хранилища с нашей формой. Когда форма будет закрыта, данные из хранилища будут автоматически удалены. Адрес данных в этом хранилище сохраняется в переменной АдресВременногоХранилища. В случае успешного выбора файла картинки ее значение присваивается реквизиту АдресКартинки. Таким образом, реквизит будет содержать
423
Глава 8. Разработка форм навигационную ссылку на данные файла картинки во временном хранилище, и картинка отобразится в форме. Свойству формы Модифицированность присваивается значение Истина, чтобы указать, что форма уже модифицирована, так как мы выбрали картинку товара. Как мы уже говорили, при выборе картинки данные еще не записаны в объект базы данных. Возможно, пользователь и не станет сохранять данные. В этом случае мы закроем форму, и данные временного хранилища, связанные с этой формой, будут автоматически уничтожены. Но если пользователь решит записать данные формы, то тогда нам нужно будет взять картинку из временного хранилища и сохранить ее в базе данных. Для этого создадим обработчик события формы ПередЗаписьюНаСервере и заполним его следующим образом (листинг 8.220). Листинг 8.220. Обработчик события «ПередЗаписьюНаСервере»
&НаСервере Процедура ПередЗаписьюНаСервере(Отказ, ТекущийОбъект, ПараметрыЗаписи) Если ЭтоАдресВременногоХранилища(АдресКартинки) Тогда ДвоичныеДанные = ПолучитьИзВременногоХранилища(АдресКартинки); ТекущийОбъект.ДанныеФайлаКартинки = Новый ХранилищеЗначения(ДвоичныеДанные, Новый СжатиеДанных()); КонецЕсли; КонецПроцедуры
Это событие выполняется непосредственно перед записью объекта из формы, когда пользователь нажал Записать или Записать и закрыть. В этой процедуре мы сохраняем значение картинки в случае, если у нас есть ссылка на временное хранилище. В переменной ДвоичныеДанные сохраняются данные, полученные из временного хранилища по адресу АдресКартинки. Затем создается объект ХранилищеЗначения, в него помещается значение переменной ДвоичныеДанные, и значение объекта ХранилищеЗначения сохраняется в реквизите справочника ДанныеФайлаКартинки. После записи картинки в объект нужно очистить временное хранилище и установить для реквизита формы АдресКартинки новую навигационную ссылку на реквизит объекта, хранящий данные картинки. Для этого создадим обработчик события формы ПриЗаписиНаСервере и заполним его следующим образом (листинг 8.221). Листинг 8.221. Обработчик события «ПриЗаписиНаСервере»
&НаСервере Процедура ПриЗаписиНаСервере(Отказ, ТекущийОбъект, ПараметрыЗаписи) Если ЭтоАдресВременногоХранилища(АдресКартинки) Тогда УдалитьИзВременногоХранилища(АдресКартинки); КонецЕсли; АдресКартинки = ПолучитьНавигационнуюСсылку(ТекущийОбъект.Ссылка, "ДанныеФайлаКартинки"); КонецПроцедуры
424
Это событие выполняется после записи данных объекта, но еще до окончания транзакции записи. Так что если по каким-то причинам объект не был записан в базу, в форме останется все по-прежнему, и реквизит АдресКартинки будет указывать на временное хранилище, в котором будет находиться картинка объекта. Процедуру ПоместитьФайлКартинки() теперь можно удалить из модуля формы, так как она больше не нужна. подробнее
Этот пример можно посмотреть в демонстрационной конфигурации «Разработка форм, пример 26 (вар. 2)».
Запустим «1С:Предприятие» и откроем форму элемента справочника Товары. Если у товара уже была выбрана картинка, она отразится в форме. Нажмем кнопку Загрузить картинку и изменим картинку товара. Выбранная картинка отобразится в поле картинки товара и будет записана в реквизит объекта ДанныеФайлаКартинки в тот момент, когда пользователь решит записать товар. Как мы видим, функциональность прикладного решения будет практически такой же, как и в первом случае. Посмотрим теперь на показатели производительности. В результате из обработчика события нажатия кнопки Загрузить картинку (см. листинг 8.219) будут сделаны два вызова сервера (рис. 8.480). Рис. 8.480. Окно показателей производительности
Эти вызовы произойдут при выполнении метода оправданы, так как их делает платформа.
ПоместитьФайл(),
и они
Посмотрим теперь, сколько вызовов сервера будет сделано при записи элемента справочника. Ведь именно в этот момент картинка окажется в базе данных. В форме товара нажмем кнопку Записать (рис. 8.481). Рис. 8.481. Окно показателей производительности
При первом нажатии произойдут три серверных вызова, и затем – два вызова, если мы, не закрывая формы, снова и снова нажимаем кнопку Записать. Первый вызов происходит, когда устанавливается объектная блокировка на записываемые данные. Второй контекстный вызов сервера выполняется платформой, чтобы записать данные, отображаемые в форме. Третий – при обновлении динамического списка, открытого в основном окне программы. При последующих нажатиях кнопки Записать выполняются последние два вызова. Блокировка устанавливается только один раз и будет снята при закрытии формы. Профессиональная разработка в системе «1С:Предприятие 8»
Оптимизация клиент-серверного взаимодействия в формах Таким образом, видно, что при записи выполняются «обычные» вызовы сервера, которые платформа сделала бы в любом случае. То есть на запись картинки товара мы не потратили дополнительных вызовов сервера. В результате мы избавились от трех лишних вызовов сервера, которые были у нас в первом случае при вызове методов ПоместитьФайлКартинки() и ПолучитьНавигационнуюСсылку().
Резюме Запись объектов конфигурации в информационную базу должна производиться не когда придется, а в нужный момент, и не должна понижать эффективность прикладного решения. Действия, логически объединенные в одну транзакцию (например, запись реквизитов объекта), нужно выполнять в одном серверном вызове. Это обеспечит согласованность данных объекта и избавит от лишних вызовов сервера. При выборе картинки объекта, пока объект не записан пользователем, загруженные картинки должны быть во временном хранилище. Как только объект записывается, нужно переносить картинки из временного хранилища в реквизит и записывать синхронно с объектом (в одной транзакции).
С одной стороны, при передаче данных через клиента мы минимизируем вызовы сервера. Но объем передаваемых данных может быть при этом довольно большим. Кроме того, поскольку на клиенте присутствуют не все данные коллекций форм, а только их видимая часть (см. пример 4 на стр. 406), то данные при передаче будут постепенно «дочитываться» с сервера. С другой стороны, этого можно избежать, передавая данные через временное хранилище, минуя клиента, хотя для этого и потребуются дополнительные вызовы сервера. Посмотрим, какое решение оптимальнее. Рассмотрим пример. Предположим, в табличную часть документа РасходнаяНакладная подбираются товары из справочника Товары. При нажатии кнопки Подбор, расположенной в форме документа, должна открываться форма подбора, в которую передаются строки табличной части документа. После того как пользователь произведет подбор товаров из справочника и закроет форму подбора, отобранные товары передаются обратно в табличную часть расходной накладной (рис. 8.482).
Что плохого, если записывать картинку в базу сразу, после ее выбора? При этом будут произведены лишние вызовы сервера, ведь нет уверенности, что именно эта картинка и окажется в объекте в результате действий пользователя. Пользователь может вообще отказаться от записи объекта в базу данных. Также тут есть вопрос согласованности данных. Картинку записали, а объект – «не смогли». В результате данные могут быть несогласованными. То есть такие изменения должны выполняться в одной транзакции, за один серверный вызов. Поэтому не нужно записывать картинку в базу данных сразу при ее выборе, а делать это нужно непосредственно перед записью самого объекта в базу данных. Таким образом, из показанных вариантов решения задачи более эффективным будет второй вариант за счет записи картинки объекта синхронно с самим объектом в одной транзакции за один серверный вызов.
Использование временного хранилища для передачи данных между формами В процессе работы прикладного решения часто бывает нужно передавать данные из одной формы в другую. Примером такого обмена данными между формами является передача табличной части из формы документа в форму подбора и обратно. Можно передавать данные через клиента в параметре типа ДанныеФормыКоллекция, а можно использовать для этого временное хранилище, работа с которым будет происходить на сервере. Том 1
Рис. 8.482. Подбор товаров в табличную часть расходной накладной
Рассмотрим возможные варианты решения этой задачи.
425
Глава 8. Разработка форм
Первый вариант решения Итак, создадим форму документа РасходнаяНакладная. Создадим команду формы Подбор и перетащим ее в командную панель таблицы формы Товары. Обработчик события нажатия кнопки Подбор заполним следующим образом (листинг 8.222). Листинг 8.222. Обработчик события нажатия кнопки «Подбор»
&НаКлиенте Процедура Подбор(Команда) ПараметрыПодбора = Новый Структура("ТчТоваровДокумента", Объект.Товары); ФормаПодбора = ОткрытьФорму("Документ.РасходнаяНакладная.Форма.ФормаПодбора", ПараметрыПодбора, ЭтаФорма); КонецПроцедуры
В этом обработчике мы создаем структуру ПараметрыФормы и добавляем в нее элемент ТчТоваровДокумента, который содержит табличную часть документа (Объект.Товары). Затем мы открываем форму подбора документа ФормаПодбора с параметром типа ДанныеФормыКоллекция как подчиненную форме документа. Теперь создадим форму документа с именем ФормаПодбора с основным реквизитом СписокТоваров типа ДинамическийСписок, отражающим данные справочника Товары. Затем создадим реквизит формы ОтобранныеТовары типа ТаблицаЗначений (с колонками Товар типа СправочникСсылка.Товары и Количество типа Число), который будет содержать список отобранных товаров и их количество. Перетащим реквизиты СписокТоваров и ОтобранныеТовары в форму, а также зададим свойства этих таблиц формы: Заголовок, ПоложениеЗаголовка – Верх, ПоложениеКоманднойПанели – Нет. Зададим также свойство формы Заголовок и выключим свойство Автозаголовок. Чтобы обеспечить заполнение реквизита ОтобранныеТовары данными табличной части расходной накладной, создадим обработчик события формы ПриСозданииНаСервере и заполним его следующим образом (листинг 8.223). Листинг 8.223. Обработчик события «ПриСозданииНаСервере»
&НаСервере Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка) ТчТоваровДокумента = Параметры.ТчТоваровДокумента; Для Каждого ТоварТч Из ТчТоваровДокумента Цикл Элемент = ОтобранныеТовары.Добавить(); Элемент.Товар = ТоварТч.Товар; Элемент.Количество = ТоварТч.Количество; КонецЦикла; КонецПроцедуры
426
В этом обработчике мы в цикле обходим коллекцию данных, содержащуюся в параметре формы ТчТоваровДокумента, и заполняем таблицу значений ОтобранныеТовары элементами этой коллекции. Таким образом, список отобранных товаров при открытии формы подбора будет заполнен данными табличной части расходной накладной. Затем реализуем возможность добавления товаров из списка товаров в таблицу отобранных товаров. Для этого создадим обработчик события ВыборЗначения у таблицы формы СписокТоваров и включим у этой таблицы свойство РежимВыбора (листинг 8.224). Листинг 8.224. Обработчик события «ВыборЗначения» таблицы формы «СписокТоваров»
&НаКлиенте Процедура СписокТоваровВыборЗначения(Элемент, Значение, СтандартнаяОбработка) СтандартнаяОбработка = Ложь; ДобавитьТовар(Значение); КонецПроцедуры
В модуле формы поместим процедуру ДобавитьТовар(), в которой выполняется добавление товаров из списка товаров в таблицу отобранных товаров. Но заметим, что эта процедура не имеет отношения к передаче данных между формами (листинг 8.225). Листинг 8.225. Процедура «ДобавитьТовар()»
&НаКлиенте Процедура ДобавитьТовар(Товар) Элемент = ОтобранныеТовары.Вставить(0); Элемент.Товар = Товар; Элемент.Количество = 1; Элементы.ОтобранныеТовары.ТекущаяСтрока = Элемент.ПолучитьИдентификатор(); КонецПроцедуры
Затем, при нажатии кнопки ОК, форма подбора должна закрываться, и список отобранных товаров должен передаваться обратно в табличную часть расходной накладной. Для этого создадим команду формы подбора ОК и перетащим ее в командную панель формы. Отключим свойство командной панели Автозаполнение и установим свойство ГоризонтальноеПоложение – Право. Также перетащим в командную панель формы команду Отмена из списка стандартных команд формы. Обработчик события нажатия кнопки ОК заполним следующим образом (листинг 8.226). Профессиональная разработка в системе «1С:Предприятие 8»
Оптимизация клиент-серверного взаимодействия в формах Листинг 8.226. Обработчик события нажатия кнопки «ОК»
&НаКлиенте Процедура ОК(Команда)
ВладелецФормы.ОбработатьПодбор(ОтобранныеТовары); Закрыть();
КонецПроцедуры
В этом обработчике, перед тем как закрыть форму подбора, мы вызываем экспортируемую процедуру ОбработатьПодбор() владельца формы, то есть формы объекта – документа РасходнаяНакладная, и передаем в нее список отобранных товаров (листинг 8.227). Листинг 8.227. Процедура «ОбработатьПодбор()»
&НаКлиенте Процедура ОбработатьПодбор(ОтобранныеТовары) Экспорт Объект.Товары.Очистить(); Для Каждого ТоварТч Из ОтобранныеТовары Цикл Элемент = Объект.Товары.Добавить(); Элемент.Товар = ТоварТч.Товар; Элемент.Количество = ТоварТч.Количество; КонецЦикла; Модифицированность = Истина; КонецПроцедуры
Таблица 8.3. Показатели производительности Текущие вызовы
Отправлено
Принято
29
189 303
153 302
Мы видим, что сервер вызывается 29 раз. Один вызов происходит, чтобы открыть форму подбора, и 28 вызовов сервера тратятся на «дочитывание» строк табличной части в форму документа на клиента порциями по 35 строк. Объем принятых данных отражает ситуацию, когда табличная часть «доехала» в форму документа на клиента, так как с клиента мы «отправляем» Объект.Товары в параметрах открываемой формы. Объем отправленных данных отражает ситуацию, когда вся табличная часть с клиента «уехала» на сервер, так как она передается в параметре метода ОткрытьФорму(). Для наглядности рассмотрим схему передачи данных между клиентом и сервером (рис. 8.483).
В этой процедуре, помещенной в модуле формы документа, мы очищаем табличную часть документа, затем в цикле обходим коллекцию данных, содержащуюся в параметре ОтобранныеТовары, и заполняем табличную часть документа элементами этой коллекции. И затем свойство формы Модифицированность устанавливаем в значение Истина, так как мы изменили табличную часть документа. Таким образом, табличная часть расходной накладной при закрытии формы подбора по кнопке ОК будет заполнена списком отобранных товаров. подробнее
Этот пример можно посмотреть в демонстрационной конфигурации «Разработка форм, пример 27 (вар. 1)».
Запустим
«1С:Предприятие», откроем документ Расходная накладная № 3 (он содержит 1000 позиций товаров) и нажмем кнопку Подбор. После этого откроется форма подбора, в которую будут переданы строки табличной части документа.
Посмотрим, сколько вызовов сервера при этом произойдет и какой будет объем передаваемых данных между клиентом и сервером. Мы специально рассматриваем пример документа с большой табличной частью, так как на нем лучше сравнивать показатели производительности (табл. 8.3). Том 1
Рис. 8.483. Схема передачи данных между клиентом и сервером
427
Глава 8. Разработка форм После того как пользователь произведет подбор товаров из справочника (в нашем примере выбран всего один товар) и закроет форму подбора, отобранные товары и их количество будут переданы обратно в табличную часть расходной накладной (рис. 8.482).
Для наглядности рассмотрим схему программного взаимодействия клиента и сервера (рис. 8.485).
Посмотрим теперь на показатели производительности (табл. 8.4). Таблица 8.4. Показатели производительности Текущие вызовы
Отправлено
Принято
28
11 271
97 690
28 вызовов сервера тратятся на «дочитывание» строк таблицы значений ОтобранныеТовары в форму подбора на клиента порциями по 35 строк. Объем принятых данных отражает ситуацию, когда таблица ОтобранныеТовары «доехала» в форму подбора на клиента, так как с клиента мы вызываем процедуру ОбработатьПодбор(), в которую передаем эту таблицу в качестве параметра. Для наглядности рассмотрим схему передачи данных между клиентом и сервером (рис. 8.484). Рис. 8.485. Схема программного взаимодействия сервера и клиента
Как мы видим, при открытии формы подбора платформа делает вызов сервера. Заметим, что при первом открытии формы могут быть лишние серверные вызовы за счет кеширования платформой необходимой информации о форме. Но мы будем изучать стандартную ситуацию, когда при открытии формы происходит один вызов сервера. Рис. 8.484. Схема передачи данных между клиентом и сервером
Может возникнуть вопрос: «Почему в первой таблице, когда в форму документа дочитывалась табличная часть, было передано 153 302, а тут, когда те же данные дочитываются в форму подбора, передано всего 97 690? Дело в том, что в первой таблице дочитывалась именно табличная часть. Во второй таблице дочитывалась не табличная часть, а таблица значений. Таблица значений устроена проще, чем табличная часть, поэтому она сериализуется лучше (объем данных меньше). Кроме этого, в первом примере табличная часть содержит три колонки, а таблица значений во втором случае содержит всего две колонки. За счет этого во втором случае и получается меньший объем принятых данных. В результате мы добились нужной функциональности формы, но при большом массиве передаваемых данных такой вариант обмена данными между формами будет неоптимальным.
428
При этом в форму подбора передается параметр ТчТоваровДокумента, содержащий данные табличной части формы объекта. Все строки табличной части сначала «приедут» с сервера, так как на клиенте присутствует только видимая часть этих строк (см. пример 4 на стр. 406). Затем все они «поедут» на сервер при открытии формы подбора. При передаче отобранных товаров обратно в форму документа в параметре процедуры ОбработатьПодбор() все данные таблицы значений ОтобранныеТовары формы подбора будут «дочитаны» с сервера на клиента. Таким образом, количество вызов сервера будет расти пропорционально количеству строк табличной части, так как строки «дочитываются» порциями по 35 строк, а также потенциально большой объем данных будет передаваться с сервера на клиента и обратно, что нехорошо, особенно в случае медленного соединения. Рассмотрим теперь другой вариант. Профессиональная разработка в системе «1С:Предприятие 8»
Оптимизация клиент-серверного взаимодействия в формах
Второй вариант решения На самом деле более эффективно передавать данные между формами через временное хранилище, работа с которым будет происходить на сервере. Ведь основная масса строк табличной части находится на сервере, а не на клиенте, и поэтому логично было бы передать их другой форме прямо с сервера, не «таская» их на клиента. Для этого перед открытием формы подбора нужно сначала записать данные табличной части документа во временное хранилище, а в форме подбора прочитать его и загрузить в список отобранных товаров. Изменим обработчик события нажатия кнопки Подбор следующим образом (листинг 8.228). Листинг 8.228. Обработчик события нажатия кнопки «Подбор»
&НаКлиенте Процедура Подбор(Команда) АдресТоваровВХранилище = ПоместитьТоварыВХранилище(); ПараметрыПодбора = Новый Структура("АдресТоваровДокумента", АдресТоваровВХранилище); ФормаПодбора = ОткрытьФорму("Документ.РасходнаяНакладная.Форма.ФормаПодбора", ПараметрыПодбора, ЭтаФорма); КонецПроцедуры
В этом обработчике в функции ПоместитьТоварыВХранилище() мы помещаем данные, выгруженные из табличной части документа, во временное хранилище. Эта функция возвращает адрес данных в хранилище – АдресТоваровВХранилище. Затем открываем форму подбора с параметром АдресТоваровДокумента, содержащим этот адрес.
Теперь создадим в форме подбора строковой реквизит АдресТоваровДокумента для хранения адреса товаров в хранилище. Заполнять его будем в обработчике события формы ПриСозданииНаСервере (листинг 8.231). Листинг 8.231. Обработчик события «ПриСозданииНаСервере»
&НаСервере Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
АдресТоваровДокумента = Параметры.АдресТоваровДокумента; ОтобранныеТовары.Загрузить(ПолучитьИзВременногоХранилища(АдресТоваровДокумента));
КонецПроцедуры
В этом обработчике мы сохраняем в реквизите АдресТоваровДокумента адрес товаров во временном хранилище, получаем из хранилища данные по этому адресу и загружаем их в таблицу значений ОтобранныеТовары. Таким образом, список отобранных товаров при открытии формы подбора будет заполнен данными табличной части расходной накладной. Теперь при закрытии формы подбора по нажатии кнопки ОК нужно записать список отобранных товаров во временное хранилище, а в форме документа прочитать его и загрузить обратно в табличную часть. Изменим обработчик события нажатия кнопки ОК следующим образом (листинг 8.232). Листинг 8.232. Обработчик события нажатия кнопки «ОК»
&НаКлиенте Процедура ОК(Команда)
Поместим в модуле формы документа функцию ПоместитьТоварыВХранилище(), выполняющуюся на сервере с контекстом формы (листинг 8.229).
Листинг 8.229. Функция «ПоместитьТоварыВХранилище()»
КонецПроцедуры
&НаСервере Функция ПоместитьТоварыВХранилище() Возврат ПоместитьВоВременноеХранилище(Объект.Товары.Выгрузить(, "Товар,Количество"), УникальныйИдентификатор); КонецФункции
Поместим в модуле формы подбора процедуру ЗаписатьПодборВХранилище(), выполняющуюся на сервере с контекстом формы, для записи данных таблицы значений ОтобранныеТовары во временное хранилище по адресу АдресТоваровДокумента (листинг 8.233).
В самом начале модуля формы документа мы определяем клиентскую переменную АдресТоваровВХранилище, чтобы потом получить по этому адресу список отобранных товаров из формы подбора (листинг 8.230).
&НаСервере Процедура ЗаписатьПодборВХранилище() ПоместитьВоВременноеХранилище(ОтобранныеТовары.Выгрузить(), АдресТоваровДокумента); КонецПроцедуры
Листинг 8.230. Определение переменной «АдресТоваровВХранилище»
ЗаписатьПодборВХранилище(); ВладелецФормы.ОбработатьПодбор(); Закрыть();
Листинг 8.233. Процедура «ЗаписатьПодборВХранилище()»
&НаКлиенте Перем АдресТоваровВХранилище;
Том 1
429
Глава 8. Разработка форм Процедуру ОбработатьПодбор() владельца формы, то есть формы объекта – документа РасходнаяНакладная, изменим следующим образом (листинг 8.234). Листинг 8.234. Процедура «ОбработатьПодбор()»
&НаКлиенте Процедура ОбработатьПодбор() Экспорт ПолучитьТоварыИзХранилища(АдресТоваровВХранилище); Модифицированность = Истина; КонецПроцедуры
Поместим в модуле формы документа процедуру ПолучитьТоварыИзХранилища(), выполняющуюся на сервере с контекстом формы, для чтения данных из временного хранилища. В процедуру мы передаем адрес этих данных в хранилище, хранящийся в клиентской переменной АдресТоваровВХранилище (листинг 8.235).
Таблица 8.5. Показатели производительности Текущие вызовы
Отправлено Принято
2
2 353
12 536
Мы видим, что сервер вызывается 2 раза. Один вызов происходит при записи данных табличной части в хранилище, а второй – при открытии формы подбора методом ОткрытьФорму(). Объем принятых данных отражает ситуацию, когда на клиента «приезжает» форма и видимые 35 строк табличной части. Для наглядности рассмотрим схему передачи данных между клиентом и сервером (первый вариант решения для сравнения приведен слева), рис. 8.486.
Листинг 8.235. Процедура «ПолучитьТоварыИзХранилища()»
&НаСервере Процедура ПолучитьТоварыИзХранилища(АдресТоваровВХранилище) Объект.Товары.Загрузить(ПолучитьИзВременногоХранилища(АдресТоваровВХранилище)); КонецПроцедуры
В этой процедуре мы получаем товары из временного хранилища по адресу АдресТоваровВХранилище и загружаем их в табличную часть документа. Таким образом, табличная часть расходной накладной при закрытии формы подбора по кнопке ОК будет заполнена списком отобранных товаров. подробнее
Этот пример можно посмотреть в демонстрационной конфигурации «Разработка форм, пример 27 (вар. 2)».
Запустим «1С:Предприятие», откроем документ Расходная накладная № 3 (он содержит 1000 позиций товаров) и нажмем кнопку Подбор. После этого строки табличной части документа будут помещены во временное хранилище. Затем откроется форма подбора. При ее открытии данные из хранилища будут прочитаны и загружены в список отобранных товаров. Посмотрим, сколько вызовов сервера при этом произойдет и какой будет объем передаваемых данных между клиентом и сервером. Мы специально рассматриваем пример документа с большой табличной частью, так как на нем лучше сравнивать показатели производительности (табл. 8.5).
430
Рис. 8.486. Схема передачи данных между клиентом и сервером
После того как пользователь произведет подбор товаров из справочника (в нашем примере выбран всего один товар) и закроет форму подбора, отобранные товары и их количество будут помещены во временное хранилище. В форме документа в процедуре ОбработатьПодбор() данные из хранилища будут прочитаны и загружены обратно в табличную часть. Посмотрим теперь на показатели производительности (табл. 8.6). Профессиональная разработка в системе «1С:Предприятие 8»
Оптимизация клиент-серверного взаимодействия в формах Таблица 8.6. Показатели производительности Текущие вызовы Отправлено
Принято
2
182 538
5 196
во временное хранилище, а второй вызов – собственно при открытии формы подбора.
Здесь один вызов сервера тратится на помещение таблицы значений ОтобранныеТовары из формы подбора в хранилище, а второй – на чтение этих данных из хранилища в форме документа. Объем принятых данных отражает ситуацию, когда вся табличная часть «приезжает» в форму документа на клиента, так как мы ее заново загрузили на сервере из временного хранилища. Для наглядности рассмотрим схему передачи данных между клиентом и сервером (первый вариант решения для сравнения приведен слева), рис. 8.487.
Рис. 8.488. Схема программного взаимодействия сервера и клиента
Заметим, что при первом открытии формы могут быть лишние серверные вызовы за счет кеширования платформой необходимой информации о форме. При закрытии формы подбора из процедуры ОК() один вызов сервера произойдет при записи списка отобранных товаров во временное хранилище, а второй вызов – из процедуры формы документа ОбработатьПодбор() при чтении отобранных товаров из временного хранилища и загрузке их в табличную часть документа. Рис. 8.487. Схема передачи данных между клиентом и сервером
Объем принятых данных близок к аналогичным показателям в первом варианте. И действительно, все будет похоже. Здесь мы получаем всю табличную часть с сервера, и это занимает 182 538. А в первом примере мы, наоборот, передавали всю табличную часть на сервер (рис. 8.483). И там это заняло 189 303. В принципе значения одинаковые, разница объясняется разными направлениями движения данных (может использоваться разная степень сжатия данных) и нюансами кеширования. Для наглядности рассмотрим схему программного взаимодействия клиента и сервера (рис. 8.488). При открытии формы подбора из процедуры Подбор() один вызов сервера произойдет при записи списка товаров табличной части документа
Том 1
Итого 4 контекстных вызова сервера вместо 57 (в первом варианте)! По объему передаваемых данных в первом случае получается: 153 302 + 189 303 + 97 690 = 440 295. Во втором случае получается: 12 536
+ 182 538 = 195 074.
То есть разница в объеме передаваемых данных больше чем в два раза! Что показательно, в первом случае количество серверных вызовов будет увеличиваться пропорционально увеличению табличной части, а во втором варианте количество серверных вызовов будет постоянным, независимо от объема табличной части. Это тоже важный момент. Таким образом, мы видим, что при большом массиве передаваемых данных такой вариант обмена данными между формами будет оптимальнее.
431
Глава 8. Разработка форм
Резюме При оптимизации клиент-серверного взаимодействия нужно стремиться не только минимизировать вызовы сервера, но и следить за объемом передаваемых данных между сервером и клиентом. Если можно лишний раз не передавать данные между клиентом и сервером, лучше их не передавать. При передаче данных между формой объекта и формой подбора рекомендуется использовать временное хранилище, чтение и запись которого должны выполняться на сервере. Потенциально большой массив данных не рекомендуется передавать в качестве параметра формы подбора. Таким образом, из показанных вариантов решения задачи более эффективным будет второй вариант за счет передачи данных между формами, минуя клиент, через временное хранилище.
Реализация пересчета данных объекта в модуле объекта или в модуле формы в зависимости от логики объекта Для реализации той или иной функциональности объектов конфигурации часто бывает нужно выполнить пересчет данных объекта, содержащегося в форме. Сделать это можно как в контекстной серверной процедуре модуля формы, так и в экспортируемой процедуре модуля объекта. В первом случае производится пересчет непосредственно данных формы, без получения объекта, а при записи объекта из формы эти данные конвертируются в объект и записываются. Во втором случае предварительно нужно получить объект, преобразовав данные формы в объект, произвести пересчет и выполнить обратное преобразование объекта в данные формы. На это требуется дополнительное время, но зато процедура, инкапсулированная в объекте, может вызываться из других мест конфигурации, как отдельный метод этого объекта. Когда же нужно помещать процедуру пересчета данных объекта в модуле формы, а когда в модуле объекта? Однозначного ответа тут нет. Решение зависит от конкретной задачи. Рассмотрим пример. Предположим, в конфигурации существует справочник Клиенты. В нем для каждого клиента хранится процент скидки, предоставляемый ему при оказании услуг. В форме документа об оказании услуг содержится услуга, цена услуги, клиент, которому она оказывается, сумма скидки и сумма услуги. При выборе клиента нужно выяснить, предоставляется ли ему скидка, и рассчитать сумму скидки как процент от цены услуги. При этом сумма услуги рассчитывается как цена услуги за вычетом суммы скидки (рис. 8.489).
432
Рис. 8.489. Пересчет данных в документе при изменении клиента
Таким образом, в тот момент, когда пользователь изменит поле Клиент или поле ЦенаУслуги документа ОказаниеУслуги, поля СуммаСкидки и СуммаУслуги нужно рассчитать по описанному выше алгоритму. Рассмотрим возможные варианты решения этой задачи.
Первый вариант решения В данном решении поместим процедуру для начисления скидки клиенту в модуле формы документа ОказаниеУслуги. Чтобы обеспечить перерасчет суммы скидки и суммы услуги при изменении ее цены и выборе клиента, создадим форму документа ОказаниеУслуги и обработчик события ПриИзменении для поля формы Клиент, ссылающегося на справочник Клиенты (листинг 8.236). Листинг 8.236. Процедура «КлиентПриИзменении()»
&НаКлиенте Процедура КлиентПриИзменении(Элемент) НачислитьСкидку(); КонецПроцедуры
В этом обработчике мы вызываем контекстную серверную процедуру для начисления скидки клиенту, расположенную в модуле формы (листинг 8.237). Листинг 8.237. Процедура «НачислитьСкидку()»
&НаСервере Процедура НачислитьСкидку() Объект.СуммаСкидки = Объект.ЦенаУслуги * Объект.Клиент.Скидка / 100; Объект.СуммаУслуги = Объект.ЦенаУслуги – Объект.СуммаСкидки; КонецПроцедуры
Профессиональная разработка в системе «1С:Предприятие 8»
Оптимизация клиент-серверного взаимодействия в формах В этой процедуре мы получаем значение реквизита Скидка по ссылке на текущий элемент справочника Клиенты (Объект.Клиент). Как показывалось во втором варианте первого примера (стр. 398), более эффективно получать значение реквизита запросом, а не через точку от ссылки, но мы для упрощения сейчас сделаем так. И затем пересчитываем поля СуммаСкидки и СуммаУслуги документа ОказаниеУслуги по заданному алгоритму. Теперь обеспечим пересчет суммы услуги при изменении цены услуги. Для этого создадим обработчик события ПриИзменении для поля формы ЦенаУслуги (листинг 8.238). Листинг 8.238. Процедура «ЦенаУслугиПриИзменении()»
&НаКлиенте Процедура ЦенаУслугиПриИзменении(Элемент) Объект.СуммаУслуги = Объект.ЦенаУслуги – Объект.СуммаСкидки; КонецПроцедуры
Включим для полей формы СуммаСкидки и СуммаУслуги свойство ТолькоПросмотр, так как они являются расчетными. подробнее
Этот пример можно посмотреть в демонстрационной конфигурации «Разработка форм, пример 28 (вар. 1)».
Запустим «1С:Предприятие», создадим документ об оказании услуги, выберем услугу и внесем цену услуги. При этом сумма услуги становится равной цене услуги. Затем выберем клиента. После этого, если в списке клиентов указан процент скидки, предоставляемой клиенту, сумма скидки рассчитывается как этот процент от цены услуги. При этом сумма услуги рассчитывается как цена услуги за вычетом суммы скидки (рис. 8.489). Посмотрим теперь на показатели производительности. При выборе клиента произойдет один вызов сервера (рис. 8.490).
Рис. 8.490. Окно показателей производительности
Этот вызов происходит при выполнении контекстной серверной процедуры НачислитьСкидку(). Заметим, что при первом выборе клиента может быть лишний серверный вызов за счет кеширования платформой необходимой информации в списке выбора. Но мы будем изучать стандартную ситуацию, когда при выборе происходит один вызов сервера. Том 1
Итак, мы поместили процедуру для начисления скидки клиенту в модуле формы документа ОказаниеУслуги. После записи или проведения документа из формы пересчитанные данные формы будут преобразованы в объект и записаны. Таким образом, в данном решении мы посчитали процедуру начисления скидки «частным» делом этой формы. Снаружи данная функциональность формы не видна.
Второй вариант решения На самом деле может быть более логично поместить процедуру для начисления скидки клиенту в модуле объекта. Потому что начисление скидки – это часть прикладной логики самого документа ОказаниеУслуги. Изменим процедуру НачислитьСкидку() в модуле формы документа следующим образом (листинг 8.239). Листинг 8.239. Процедура «НачислитьСкидку()»
&НаСервере Процедура НачислитьСкидку() Документ = РеквизитФормыВЗначение("Объект"); Документ.НачислитьСкидкуКлиенту(); ЗначениеВРеквизитФормы(Документ, "Объект"); КонецПроцедуры
В этой процедуре мы сначала получаем объект, отображающийся в форме. Для этого преобразуем основной реквизит формы в объект – документ ОказаниеУслуги. Затем выполняем экспортируемый метод объекта НачислитьСкидкуКлиенту() и выполняем обратное преобразование объекта в реквизит формы Объект. Затем откроем модуль объекта и поместим в нем процедуру для начисления скидки клиенту (листинг 8.240). Листинг 8.240. Процедура «НачислитьСкидкуКлиенту()»
Процедура НачислитьСкидкуКлиенту() Экспорт СуммаСкидки = ЦенаУслуги * Клиент.Скидка / 100; СуммаУслуги = ЦенаУслуги – СуммаСкидки; КонецПроцедуры
В этой процедуре мы реализуем тот же алгоритм пересчета, что и в предыдущем варианте, но только пересчитываем не данные формы, а данные самого объекта. Эти изменения после преобразования объекта в основной реквизит формы отобразятся в форме документа. подробнее
Этот пример можно посмотреть в демонстрационной конфигурации «Разработка форм, пример 28 (вар. 2)».
433
Глава 8. Разработка форм Запустим «1С:Предприятие», создадим документ об оказании услуги, выберем услугу и внесем цену услуги. При этом сумма услуги становится равной цене услуги. Затем выберем клиента. После этого, если в списке клиентов указан процент скидки, предоставляемой клиенту, сумма скидки рассчитывается как этот процент от цены услуги. При этом сумма услуги рассчитывается как цена услуги за вычетом суммы скидки. Посмотрим теперь на показатели производительности. При выборе клиента произойдет один вызов сервера (рис. 8.491).
Рис. 8.491. Окно показателей производительности
Этот вызов происходит при выполнении контекстной серверной процедуры модуля формы НачислитьСкидку(), а из нее вызывается экспортируемый метод документа НачислитьСкидкуКлиенту().
Листинг 8.242. Процедура «НачислитьСкидкуНаСервере»
&НаСервереБезКонтекста Процедура НачислитьСкидкуНаСервере(СсылкаНаДокумент) Документ = СсылкаНаДокумент.ПолучитьОбъект(); Документ.НачислитьСкидкуКлиенту(); Документ.Записать(); КонецПроцедуры
В этой процедуре по переданной ссылке на документ мы получаем объект, выполняем экспортируемый метод объекта НачислитьСкидкуКлиенту() и записываем документ. Запустим «1С:Предприятие», откроем список клиентов и изменим процент скидки, предоставляемой какому-либо клиенту. Затем откроем список документов об оказании услуг, выделим документ для данного клиента и нажмем кнопку Начислить скидку. Сумма скидки и сумма услуги в документе пересчитаются по заданному алгоритму (рис. 8.492).
Заметим, что здесь, так же как и в предыдущем варианте, при первом выборе клиента может быть лишний серверный вызов за счет кеширования платформой необходимой информации в списке выбора. Итак, мы поместили процедуру для начисления скидки клиенту в модуле объекта. Тем самым мы предоставили доступ к данному методу документа ОказаниеУслуги из других мест конфигурации – форм, обработок и т. д. Таким образом, в данном решении мы посчитали процедуру начисления скидки частью прикладной логики объекта. Данная функциональность документа доступна, например, из формы списка документов об оказании услуг. То есть мы можем изменить клиенту процент скидки, затем выделить документ об оказании услуги и пересчитать по нему скидку, не открывая документа. Для этого создадим форму списка документа ОказаниеУслуги и ее команду НачислитьСкидку. Перетащим команду в командную панель формы. Обработчик события нажатия кнопки Начислить скидку заполним следующим образом (листинг 8.241). Листинг 8.241. Обработчик события нажатия кнопки «Начислить скидку»
&НаКлиенте Процедура НачислитьСкидку(Команда) НачислитьСкидкуНаСервере(Элементы.Список.ТекущаяСтрока); КонецПроцедуры
В этом обработчике мы вызываем внеконтекстную серверную процедуру модуля формы НачислитьСкидкуНаСервере() и передаем в нее ссылку на текущий документ (листинг 8.242).
434
Рис. 8.492. Начисление скидки клиенту из формы списка документов
Можно организовать начисление скидки для документов в цикле и т. д.
Резюме Пересчитывать данные объекта можно как в контекстной серверной процедуре модуля формы объекта, так и в экспортируемой процедуре модуля объекта. Когда процедура пересчета является частью прикладной логики объекта, то нужно реализовывать процедуру в модуле объекта как его экспортируемый метод. Когда процедура пересчета отражает функциональность конкретной формы, то можно реализовывать ее в модуле этой формы. Таким образом, из показанных вариантов решения задачи более эффективным будет второй вариант за счет реализации пересчета данных в экспортируемом методе объекта. Этот метод будет доступен из других мест конфигурации форм, обработок и т. д. Профессиональная разработка в системе «1С:Предприятие 8»
Задачи хранения информации
Глава 9. Хранение информации Задачи хранения информации При создании любых решений в области автоматизации практически всегда приходится решать задачи хранения информации. При этом поднимаются вопросы собственно предназначения хранимой информации и многочисленные технологические вопросы. К технологическим вопросам можно отнести те, которые приходится решать для достижения оптимального соотношения таких показателей, как объем, надежность, функциональность, быстродействие. Причем на всех этапах жизненного цикла информации: запись информации, хранение информации, получение информации, удаление информации. При создании бизнес-приложений сложность решений этих задач обусловлена наличием противоречий между: ■■ необходимостью обеспечения удобства представления логики взаимодействия сущностей в информационной модели; ■■ необходимостью хранения больших объемов информации; ■■ повышенными требованиями к широкой функциональности и высокой производительности доступа к этим данным. Например, чем больше объем, тем в общем случае сложнее с обеспечением скорости доступа к информации (рис. 9.1).
Например, хранение информации о происходящих в жизни автоматизируемого предприятия событиях в виде набора неструктурированных текстов – идеальное решение с точки зрения простоты и скорости регистрации. Однако последующая обработка этой информации для составления каких бы то ни было аналитических отчетов в таком случае будет сопряжена с колоссальными временными затратами. Потому что как для решения задачи поиска информации обо всех продажах предприятия, так и для поиска информации о продажах одному покупателю необходимо будет пересмотреть данные всех текстов. И чем больше функциональных возможностей потребуется на этапе получения информации, тем дольше будут работать соответствующие обработки, зачастую по нескольку раз просматривая одну и ту же информацию, но уже с разными целями. Объектно-реляционная парадигма системы «1С:Предприятие» позволяет решить проблему соотношения удобства представления и манипулирования объектами, отражающими прикладные сущности, с должной надежностью и эффективностью обработки больших объемов информации этих объектов в базе данных. Объекты и процессы прикладной области отражаются в решении посредством объектов конфигурации. Таким образом, объекты конфигурации обеспечивают удобство манипулирования данными, характеризующими прикладные объекты и процессы. Но сами данные объектов хранятся в реляционной базе данных (в виде таблиц, полей, индексов), при этом обеспечиваются вопросы оптимального быстродействия при больших объемах информации (рис. 9.2).
Рис. 9.1. Схема противоречий между требованиями к хранимой информации
И в результате очевидные прямые решения одних вопросов ухудшают возможности решения других. Том 1
Рис. 9.2. Схема представления и манипулирования данными в системе «1С:Предприятие»
435
Глава 9. Хранение информации В системе «1С:Предприятие» все возможные к применению в решениях прикладные объекты прототипированы. Каждый прототип отвечает за отражение в прикладном решении определенной совокупности объектов или процессов прикладной области, имеющих схожие поведенческие характеристики и схожую роль в общей картине решения. Примерами прототипов являются справочники, документы, регистры различных видов и так далее. В рамках средств платформы для каждого прототипа уже предопределены: ■■ оптимальная для большинства задач структура хранения информации в реляционной базе данных; ■■ набор средств встроенного языка для манипулирования этой информацией; ■■ методы, свойства, события и типовые для решаемых задач операции; ■■ способы отображения и редактирования; ■■ средства регулирования прав доступа и т. д.
■■ обеспечения обмена информацией и взаимодействия между созданными объектами. Обеспечение же всей остальной необходимой функциональности берет на себя платформа. Но и в этих вопросах, при необходимости, у разработчиков достаточно широкие возможности «подправить» поведение программы. В частности, при решении задач, связанных с вводом и получением информации для последующего анализа. Например, при отображении динамических списков система считывает из базы данных содержимое только видимых полей и полей, необходимых «для технологических нужд». Если же разработчику необходимо сделать так, чтобы данные некоего поля не отображаясь, тем не менее, считывались из базы данных вместе с остальными, он может этого добиться. Итак, вернемся к общим вопросам, связанным с обеспечением эффективного хранения информации. Прежде всего, они не являются самоцелью. К выбору прототипов объектов для использования в рамках решения необходимо подходить с точки зрения обеспечения целей автоматизации и областей применимости прототипов. А вот если одинаковая функциональность может быть достигнута различными альтернативными с точки зрения организации хранения информации путями, то выбор оптимального варианта построения конфигурации как раз и будет определяться оптимальностью решения вопросов хранения информации. Причем разработчику необходимо решать эти вопросы в комплексе. Потому что все объекты будут тесно связаны между собой логическими, информационными, интерфейсными и прочими связями в интересах преследования общих целей автоматизации. В общем виде взаимосвязь и предназначение объектов, относящихся к соответствующим прототипам, могут быть описаны следующим образом (рис. 9.4).
Рис. 9.3. Пример представления и манипулирования данными
Таким образом, облегчается работа разработчика конкретного прикладного решения. С точки зрения эффективного хранения информации вместо решения задач «низкого» уровня он занят решением вопросов: ■■ выбора нужного прототипа; ■■ создания в рамках прототипов объектов с наиболее подходящим составом для отражения прикладных сущностей;
436
Рис. 9.4. Взаимосвязь различных групп объектов
Профессиональная разработка в системе «1С:Предприятие 8»
Задачи хранения информации Если требуется хранить в базе данных информацию, которая изменяется достаточно редко и работа с которой строится по принципу «ввели один раз, но используется много раз», то для хранения такой информации наиболее удобны объекты из блока Условно-постоянная информация. То есть справочники, перечисления, константы, планы видов характеристик – при решении практически любых задач. Планы счетов, планы видов расчетов и т. п. – при решении специфичных задач, сопряженных с использованием принципа «двойной записи», использованием механизмов сложных периодических расчетов и т. д. Если требуется хранить информацию о происходящих в жизни автоматизируемого предприятия действиях (событиях и выполняемых операциях), то есть информацию, для которой важна привязка ко времени, то наиболее удобно использовать Документы. На схеме к этой же группе относятся и другие объекты, которые используются для решения вопросов дополнительной функциональности системы при обслуживании этой информации: ■■ журналы – средства визуального группирования информации разных документов; ■■ последовательности – средства логического группирования информации разных документов; ■■ нумераторы – средства группирования разных документов для ведения единой нумерации. Если требуется хранить информацию о состоянии показателей, учитываемых в системе, то более удобны для решения этих задач объекты из группы регистры. Причем показатели могут иметь привязку ко времени или не иметь ее, быть наиболее общими или достаточно специфичными, предназначенными к использованию в специальных моделях учета (те же «двойная запись», «сложные периодические расчеты» и т. д.). Чаще всего модель обмена информацией между объектами вышеописанных прототипов обслуживает следующую модель автоматизации бизнес-решений: ■■ требуемые аналитические и информационные материалы о различных аспектах состояния дел на автоматизируемом предприятии получаются пользователями посредством отчетов и обработок (объектов, специально предназначенных для обеспечения вывода информации в удобном для пользователя виде); ■■ для обеспечения максимального быстродействия формирования отчетной информации о состоянии учитываемых в системе показателей алгоритмы представления этой информации берут ее в уже
Том 1
готовом или почти готовом виде, с последующей «дообработкой», из регистров; ■■ стандартная методика использования регистров заключается в том, что изменение состояния учитываемых показателей в регистрах производится не произвольным образом, а при наличии «документального подтверждения». То есть информация регистров вторична, она заполняется на основании данных документов. Ведь именно документы, как правило, служат для обеспечения регистрации происходящих в жизни автоматизируемого предприятия событий. В то же время платформа не ограничивает разработчика жесткими рамками стандартной методики и позволяет изменять данные регистров и другими произвольными способами, например, напрямую из процедур встроенного языка; ■■ однозначность толкования вводимой в документы информации обеспечивается заполнением документов посредством выбора элементов объектов хранения условно-постоянной информации, отражающих объекты прикладной области. Однако, как уже было замечено выше, разработчик не обязан слепо следовать предлагаемой логике. В ситуациях, когда это окажется оправданным, можно применять приемы, упрощающие или даже полностью отвергающие ее. Например, в платформе «1С:Предприятие» есть возможности и средства прямого интерактивного ввода информации в регистры, формирования отчетов на основании данных первичных документов, заполнения справочников посредством обработок и так далее. Более того, рассмотрение и оценка возможных вариантов выбора прототипов и объектов будут производиться фактически каждый раз заново, для данной конкретной ситуации данного конкретного решения. Потому что даже в рамках преследования одинаковых целей автоматизации, но для разных условий функционирования, эффективная композиция структуры объектов в рамках решения может оказаться разной. Например, ситуации для предприятия, заключающего в течение года сто сделок по десять миллионов рублей, и для предприятия, заключающего в год десять миллионов сделок по сто рублей, с точки зрения оптимизации хранения информации различаются. Поэтому цель данного раздела не навязать единственно верную структурную технологию решения задач хранения информации (тем более что такой не существует), а показать возможности решения вопросов хранения информации. И зачастую – в сравнении плюсов и минусов альтернативных вариантов использования для этих решений различных видов объектов системы «1С:Предприятие».
437
Глава 9. Хранение информации
Варианты подходов к решению задач хранения информации
к объектам базы данных (то есть при неудачном стечении обстоятельств при обращении к картинке может выясниться, что она удалена или модифицирована пользователем).
Хранение информации, общей для информационной базы
Использование макетов
При решении вопросов хранения общей информации есть возможности организовать решения в рамках работы с конфигурацией или с базой данных.
Использование общих картинок Например, картинки с логотипами юридических лиц компании могут храниться в составе общих картинок конфигурации, а могут в составе реквизитов справочника (например, справочника Организации), рис. 9.5.
Если предпочтение отдается хранению информации на уровне конфигурации, то кроме картинок возможно использование макетов – общих макетов и макетов объектов конфигурации. При этом могут быть использованы следующие виды макетов: ■■ ■■ ■■ ■■ ■■ ■■ ■■ ■■ ■■
макет текстового документа, макет табличного документа, макет двоичных данных, макет Active document, макет HTML-документа, макет географической схемы, макет графической схемы, макет схемы компоновки данных, макет оформления компоновки данных.
Чаще всего макеты используются для хранения данных шаблонов нужных типов. Например, когда в конфигурации нужно хранить «красивый» шаблон приглашения, разработанный в Microsoft Word, с целью его автоматического заполнения при выполнении соответствующей задачи работы пользователя (рис. 9.6).
Рис. 9.5. Пример хранения картинок в составе конфигурации
С точки зрения надежности хранения информации успешность обращения к картинке в первом случае «гарантируется» неизменностью конфигурации, во втором – мерами разграничения прав доступа пользователей
438
Рис. 9.6. Пример хранения макета Active document
Профессиональная разработка в системе «1С:Предприятие 8»
Варианты подходов к решению задач хранения информации При этом можно загружать макеты из файлов, а можно создавать пустые макеты нужного вида (рис. 9.7).
Хранение единичных значений условно-постоянной информации Зачастую при решении задач необходимо реализовывать хранение данных неких единичных значений, которые меняются крайне редко.
Использование констант Константы – классические объекты для хранения таких данных. Добавлять новые константы или удалять старые можно только в режиме Конфигуратор, но вот заполнение и модификация значений обычно производятся пользователями (если не ограничен доступ). При решении прикладных задач посредством констант обычно запоминаются общие для всей информационной базы значения. Можно привести примеры таких констант, как ОсновнаяБазоваяВалюта или ОсновнаяОрганизация. Рис. 9.7. Создание макета
Но, кроме того, могут использоваться, например, макеты специального типа (макет схемы компоновки данных) для хранения схемы компоновки данных отчета. В ней описываются источники данных для отчета, связи между ними, параметры получения данных отчета и его настройки: структура отчета, список полей, отбор, сортировка, условное оформление и др. (рис. 9.8).
Также в константах могут храниться значения по умолчанию для поддержания работы алгоритмов, критичных к пустым значениям. Такими константами являются, например, константы НачалоРабочегоДня, ОкончаниеРабочегоДня. Кроме этого, благодаря тому, что значения, хранящиеся в константе, общие для всех, с помощью констант можно организовать информирование пользовательских сеансов работы с программой. Например, пользователь с административными правами имеет право устанавливать для булевой константы ЗавершениеРаботыПользователей значение Истина. А соответствующая обработка ожидания проверяет значение этой константы и, в случае необходимости, завершает пользовательский сеанс. Подробнее
Пример данного механизма реализован в составе демонстрационной конфигурации «Хранение информации», которая находится на прилагаемом компакт-диске.
Необходимая функциональность реализуется в рамках модуля управляемого приложения (листинг 9.1). Листинг 9.1. Фрагмент модуля управляемого приложения
Перем ЗавершитьРаботу; Процедура ПриНачалеРаботыСистемы() Рис. 9.8. Хранение схемы компоновки данных отчета в макете
Том 1
КонтрольРежимаЗавершенияРаботыПользователей(); ПодключитьОбработчикОжидания("КонтрольРежимаЗавершенияРаботыПользователей", 180);
КонецПроцедуры
439
Глава 9. Хранение информации Процедура КонтрольРежимаЗавершенияРаботыПользователей() Экспорт // Определить текущее значение константы. Завершение = ХранениеИнформации.ЗавершитьРаботуПользователей(); Если Завершение Тогда Если ЗавершитьРаботу Тогда
// Завершить работу окончательно. ЗавершитьРаботуСистемы();
Иначе // Предупредить пользователя и приготовиться // завершить работу в следующий раз. ТекстПредупреждения = "Работа системы будет автоматически завершена через 3 минуты!"; Предупреждение(ТекстПредупреждения, 30, "Завершение работы"); ЗавершитьРаботу = Истина;
Рис. 9.9. Структура регистра «УчетнаяПолитика»
КонецЕсли; КонецЕсли;
Обратите внимание: в данном регистре не подразумевалось использование измерений, а значит, разрезов учета значений ресурсов. То есть данные регистра могут использоваться как общие для всей базы данных.
КонецПроцедуры
Подробнее
//----------------// Выполнить начальную инициацию флага завершения работы. ЗавершитьРаботу = Ложь;
Функция для получения значения константы ЗавершениеРаботыПользователей располагается в общем модуле ХранениеИнформации, исполняющемся на сервере (в свойствах модуля должен быть установлен флажок ВызовСервера), листинг 9.2.
Раздел «Хранение информации в регистрах сведений», стр. 455.
Использование перечислений Если необходимо хранить уже не единичные значения, а некие конечные наборы значений, и при этом не подразумевается их модификация пользователями, то для решения задач возможно применение перечислений.
Листинг 9.2. Функция общего модуля «ХранениеИнформации»
Все операции по добавлению, изменению, удалению значений перечислений производятся только в режиме работы Конфигуратор.
Функция ЗавершитьРаботуПользователей() Экспорт Возврат Константы.ЗавершениеРаботыПользователей.Получить();
Само же хранение информации перечислений реализуется в соответствующих таблицах базы данных (по одной для каждого перечисления), рис. 9.10.
КонецФункции
Использование регистров сведений В случае, когда необходимо хранить информацию общую для базы данных, но используемую для отдельных направлений учета или отдельных подсистем конфигурации, может оказаться оправданным хранение единичных условно-постоянных значений не посредством констант, а посредством ресурсов регистра сведений. Рассмотрим, например, непериодический независимый регистр сведений УчетнаяПолитика (рис. 9.9). Возможности пользователей по модификации значений будут определяться средствами разграничения прав доступа.
440
Рис. 9.10. Хранение значений перечислений
Профессиональная разработка в системе «1С:Предприятие 8»
Варианты подходов к решению задач хранения информации Обращение для чтения этой информации возможно как средствами табличной модели (запросы), так и объектными методами. Если, например, в ходе обработки необходимо использовать заранее известное значение перечисления, то его можно получить, указав его имя через точку после имени перечисления (в данном примере используется объектная модель доступа к данным), листинг 9.3. Листинг 9.3. Пример получения значения перечисления
ЗаполняемоеЗначениеВидаКонтрагента = Перечисления.ВидыКонтрагентов.ЧастноеЛицо;
Еще раз подчеркнем: при использовании такого кода разработчик уверен, что данное значение перечисления не может быть удалено или изменено пользователем, поскольку модификация этих данных возможна только в режиме Конфигуратор. Кроме того, многие «типовые операции», связанные с использованием перечислений, уже реализованы средствами платформы. Например, в ходе некой обработки нужно предложить пользователю выбрать значение перечисления ВидыКонтрагентов. Задача может быть решена следующим образом (в данном примере используется табличная модель доступа к данным), листинг 9.4, 9.5.
Пока Выборка.Следующий() Цикл
// Заполнить значения списка. СписокЗначенийПеречисления.Добавить(Выборка.Значение, Выборка. ПредставлениеЗначения); КонецЦикла; Возврат СписокЗначенийПеречисления; КонецФункции
Краткий комментарий: в функции ПолучитьЗначенияПеречисления(), выполняющейся на сервере, запросом из таблицы перечисления ВидыКонтрагентов считываются значения и представления для каждой записи. В цикле выборки из результата запроса заполняются значения и представления списка значений СписокЗначенийПеречисления. Этот список возвращается в обработчик команды, в котором пользователю предлагается выбрать значение из списка СписокЗначенийПеречисления. Однако если бы выбор значения перечисления нужен был для заполнения поля, имеющего визуальное представление (например, в форме контрагента), то данный код писать не пришлось бы вообще. Достаточно было бы установить соответствующий тип значения поля ввода (ПеречислениеСсылка.ВидыКонтрагентов), рис. 9.11.
Листинг 9.4. Обработчик команды для организации интерактивного выбора значения перечисления
&НаКлиенте Процедура ВыбратьЗначениеПеречисления(Команда) СписокЗначенийПеречисления = ПолучитьЗначенияПеречисления(); // Предложить пользователю выбрать значение. ВыбранноеЗначение = СписокЗначенийПеречисления. ВыбратьЭлемент("Выберите вид контрагента"); КонецПроцедуры Листинг 9.5. Получение списка значений перечисления
&НаСервереБезКонтекста Функция ПолучитьЗначенияПеречисления() СписокЗначенийПеречисления = Новый СписокЗначений;
// Прочитать значения перечисления из базы данных. Запрос = Новый Запрос; Запрос.Текст = " |ВЫБРАТЬ | ВидыКонтрагентов.Ссылка КАК Значение, | ПРЕДСТАВЛЕНИЕ(ВидыКонтрагентов.Ссылка) КАК ПредставлениеЗначения |ИЗ | Перечисление.ВидыКонтрагентов КАК ВидыКонтрагентов"; Результат = Запрос.Выполнить(); Выборка = Результат.Выбрать();
Том 1
Рис. 9.11. Тип значения поля ввода
Дальнейшая функциональность была бы реализована платформой автоматически (рис. 9.12).
441
Глава 9. Хранение информации К предопределенному элементу справочника можно обратиться, указав его имя через точку после имени справочника (например, Справочники.ВидыСобытий.Семинар).
Рис. 9.12. Выбор значения перечисления в поле ввода
Использование предопределенных элементов Если требуется сочетать гарантии наличия информации с гибкими возможностями модификации этой информации, интересные возможности предоставляет использование предопределенных элементов справочников, планов видов характеристик, планов счетов и т. п. Благодаря тому, что добавление и удаление предопределенных элементов возможны только в режиме работы Конфигуратор, разработчик может быть уверен в их сохранности при любых действиях пользователей. Кроме этого, каждый предопределенный элемент обладает уникальным именем, что позволяет создавать алгоритмы, использующие, например, предопределенные виды контактной информации, предопределенные вычеты НДФЛ, предопределенные счета налогового учета и так далее. Таким образом, предопределенные элементы не «обезличены» для конфигурации, и конфигурация имеет возможность отличить один предопределенный элемент от другого (рис. 9.13).
Например, если при создании документа Событие необходимо заполнить значение реквизита ВидСобытия (тип значения: СправочникСсылка.ВидыСобытий) предопределенным элементом справочника, это может выглядеть так (листинги 9.6, 9.7). Листинг 9.6. Обработчик команды для создания события с предопределенным элементом справочника
&НаКлиенте Процедура СоздатьСобытиеСеминар(Команда) СсылкаНаДокумент = СоздатьНовоеСобытие(ДатаПроведения); ОткрытьЗначение(СсылкаНаДокумент); КонецПроцедуры Листинг 9.7. Пример использования предопределенного элемента справочника
&НаСервереБезКонтекста Функция СоздатьНовоеСобытие(ДатаПроведения)
// Создать новый документ. НовоеСобытие = Документы.Событие.СоздатьДокумент(); // Заполнить поля. НовоеСобытие.Дата = ДатаПроведения; // Заполнить значением предопределенного элемента. НовоеСобытие.ВидСобытия = Справочники.ВидыСобытий.Семинар; // ... // Записать документ. НовоеСобытие.Записать(); Возврат НовоеСобытие.Ссылка;
КонецФункции
Однако обращение к менеджерам объектов (например, Справочники.<Имя справочника>) на клиенте недоступно. Для получения ссылки на предопределенное значение на клиенте следует использовать метод глобального контекста ПредопределенноеЗначение() (например, ПредопределенноеЗначение("Справочник.ВидыСобытий.Семинар") ). Например, требуется открыть форму предопределенного элемента справочника. Это можно сделать с помощью следующего кода (листинг 9.8). Листинг 9.8. Обработчик команды для открытия формы предопределенного элемента справочника
&НаКлиенте Процедура СоздатьСобытиеСеминар(Команда) ВидСобытия = ПредопределенноеЗначение("Справочник.ВидыСобытий.Семинар"); ОткрытьЗначение(ВидСобытия); Рис. 9.13. Пример предопределенного элемента справочника
442
КонецПроцедуры
Профессиональная разработка в системе «1С:Предприятие 8»
Варианты подходов к решению задач хранения информации При работе с объектами встроенного языка предопределенные элементы отличаются от «обычных» лишь значением свойства Предопределенный (у обычных – Ложь, у предопределенных – Истина). Работа пользователя с предопределенными элементами, по сравнению с обычными, ограничивается лишь невозможностью удалить их. Все остальные способы модификации предопределенных элементов следует ограничивать правами доступа или с помощью прикладных алгоритмов. Это означает, что пользователь при необходимости может изменить наименование предопределенного элемента, код, пометить на удаление и т. д. При этом для системы этот предопределенный элемент остается тем же самым предопределенным элементом, т. к. его внутренний идентификатор не меняется.
Хранение информации объектных и необъектных сущностей При выборе прототипов объектов для хранения информации одним из типичных вопросов, возникающих при неочевидных случаях, является выбор между объектными и необъектными данными. Например, между регистром сведений и справочником.
Например, как определились выше, состав сотрудников предприятия целесообразно хранить посредством объекта конфигурации Справочник (рис. 9.14).
Рис. 9.14. Таблица справочника «Сотрудники»
Однако если взглянуть на проблему шире, может оказаться, что на самом деле тут смешиваются две сущности: ■■ «Физические лица» как отражение реальных людей, с которыми предстоит иметь дело в рамках решения; ■■ «Сотрудники подразделений предприятия», причем один и тот же человек может быть сотрудником нескольких подразделений предприятия, выполняя в них различные задачи (должности, круг обязанностей и проч.). Причем вторая сущность как объект нигде не фигурирует, просто нужно помнить «кто есть кто». Тогда хранение сотрудников подразделений может быть реализовано посредством регистра сведений (рис. 9.15).
К объектным данным относятся данные справочников, документов, планов видов характеристик, планов счетов, планов видов расчета, бизнеспроцессов, задач, планов обмена. К необъектным данным относятся данные регистров сведений, регистров накопления, регистров бухгалтерии, регистров расчета, перерасчетов, последовательностей и констант. В рамках текущей темы ограничимся лишь вопросами выбора этих данных для различных задач хранения информации. Для принятия решения рекомендуется обращать внимание на природу данных предметной области. Если они обладают некоей «самостью», несмотря на смену значений отдельных свойств этого объекта, то предпочтение следует отдавать определению этих данных как объектных. Например, сотрудник может сменить фамилию, имя, паспорт, цвет глаз и т. д., однако при этом он останется все тем же сотрудником. Таким образом, мы рассмотрели типичный пример идентификации сотрудников предприятия как данных объектных и подлежащих учету посредством справочника. Однако следует учитывать, что выбор вида объекта конфигурации не должен производиться для каждой сущности отдельно. Необходимо анализировать наличие и остальных сущностей в комплексе всей прикладной задачи. Причем желательно не только на текущий момент, но и с учетом развития задачи в будущем. Том 1
Рис. 9.15. Связь таблицы справочника и таблицы регистра сведений
Если аналогичным образом рассматривать хранение данных о сотрудниках и их трудовых договорах, то можно также выделить две сущности: ■■ «Физическое лицо»; ■■ «Сотрудник – трудовой договор» как отражение юридических отношений данного лица с организацией, имеющее при этом объектную природу, поскольку впоследствии ссылка на трудовой договор будет фигурировать во многих документах и регламентированных отчетах. В этом случае для хранения данных следует использовать два справочника, один из которых (справочник ТрудовыеДоговораСотрудников) будет подчинен другому (справочник ФизическиеЛица), рис. 9.16.
443
Глава 9. Хранение информации
Рис. 9.16. Связь таблиц справочников
Таким образом, выбор каждого из вариантов хранения информации определяется тем, какую сущность предметной области будет отражать тот или иной объект. При этом разработчикам рекомендуется также и имя объекта определять так, чтобы оно максимально отражало описываемую сущность. Это позволит впоследствии обеспечить правильное восприятие и использование объекта.
Хранение информации в самих объектах или в других объектах Необходимо помнить, что любой объект – это единая сущность с точки зрения манипулирования данными. То есть при любых операциях с объектом (чтение, запись, модификация) происходит обращение к информации базы данных, касающейся всего объекта. Например, справочник ДоговорыКонтрагентов имеет подчиненные объекты: два реквизита (ДатаПоставки и ВидДоговора) и табличную часть Спецификация. В свою очередь, в состав табличной части тоже входит ряд реквизитов (рис. 9.17).
□□ Предопределенный; □□ Родитель; □□ Владелец; □□ ЭтоГруппа; □□ ДатаПоставки; □□ ВидДоговора; ■■ информация табличной части Спецификация – в отдельной таблице, содержащей следующие поля: □□ Ссылка (значение этого поля равно значению поля Ссылка основной таблицы справочника); □□ НомерСтроки; □□ Номенклатура; □□ Количество; □□ Цена; □□ Сумма. Любое обращение к объекту документа приведет к тому, что из базы данных будет считана информация, соответствующая данному объекту, из обеих таблиц. При этом не важно, как именно выполнялось обращение: посредством метода ПолучитьОбъект() из ссылки (листинг 9.9) или при открытии формы, основным реквизитом которой является объект договора (рис. 9.18). Листинг 9.9. Пример получения объекта справочника из ссылки
ОбъектДоговора = СсылкаНаДоговор.ПолучитьОбъект();
Рис. 9.17. Структура справочника «ДоговорыКонтрагентов»
Хранение этой информации в базе данных будет реализовано системой следующим образом: ■■ в основной таблице справочника будет храниться информация в следующих полях: □□ Ссылка; □□ Код; □□ Наименование; □□ Пометка удаления;
444
Рис. 9.18. Открытие формы объекта, отображающей табличную часть
В последнем случае, кстати, не важно, будут отображаться на форме данные табличной части элемента или нет (рис. 9.19).
Профессиональная разработка в системе «1С:Предприятие 8»
Варианты подходов к решению задач хранения информации
Рис. 9.19. Открытие формы объекта, в которой табличная часть не отображается
Рис. 9.20. Открытие формы объекта
Объект в любом случае считывается целиком, поскольку при открытии формы платформа также создает объект справочника, обеспечивая тем самым целостность изменений, вносимых в данные объекта как интерактивно, так и программно, в модуле формы.
Однако при необходимости выполнить такое обращение это будет легко сделать, например, с помощью запроса (листинг 9.10).
Данную особенность нужно иметь в виду для сущностей, при работе с которыми часто необходим доступ именно к объектам, а не ссылкам (например, объекты, которые часто модифицируются пользователями). При чтении объекта или его модификации данные будут считываться и записываться по объекту целиком. Таким образом, чем меньше этих данных будет, тем быстрее будут выполняться операции, меньше будет продолжительность блокировок и т. д.
Запрос = Новый Запрос; Запрос.Текст = "ВЫБРАТЬ | СпецификацииДоговоров.Код, | СпецификацииДоговоров.Наименование, | СпецификацииДоговоров.Номенклатура, | СпецификацииДоговоров.Количество, | СпецификацииДоговоров.Цена, | СпецификацииДоговоров.Сумма |ИЗ | Справочник.СпецификацииДоговоров КАК СпецификацииДоговоров |ГДЕ | СпецификацииДоговоров.Владелец = &Владелец";
Из этого можно сделать вывод, что информацию, которую предполагается хранить в объектах, следует анализировать на предмет разделения на активно используемую и неактивно используемую. Активно используемую информацию можно хранить в реквизитах самого объекта или его табличных частей. Неактивно используемую информацию об объекте можно хранить не в самом объекте, а посредством других информационных структур. Однако при этом придется самостоятельно заботиться о поддержании целостности изменений при модификации данных объекта. Для вышеприведенного примера, если информацию спецификаций можно считать «неактивно используемой», ее хранение можно организовать посредством, например, регистра сведений СпецификацииДоговоров или подчиненного справочника СпецификацииДоговоров. И в том и в другом случае при считывании объекта договора обращение к информации спецификации выполняться не будет (рис. 9.20).
Том 1
Листинг 9.10. Пример получения данных подчиненного справочника запросом
Запрос.УстановитьПараметр("Владелец", Договор); Результат = Запрос.Выполнить(); Выборка = Результат.Выбрать(); Пока Выборка.Следующий() Цикл // Выполнить действия с информацией строки спецификации. // ... КонецЦикла;
В этом случае из базы данных будет считана лишь нужная информация спецификаций, относящаяся к договору, ссылка на который содержится в переменной Договор. Обратиться к данным подчиненного справочника можно и с помощью объектной модели работы с данными (листинг 9.11).
445
Глава 9. Хранение информации Листинг 9.11. Получение данных подчиненного справочника с помощью объектной модели работы с данными
СсылкаНаВладельца = Договор; Выборка = Справочники.СпецификацииДоговоров.Выбрать( , СсылкаНаВладельца); Пока Выборка.Следующий() Цикл // Выполнить действия с информацией строки спецификации. // ... КонецЦикла;
В этом случае, в отличие от табличной модели работы с данными, будут считаны целиком объекты элементов подчиненного справочника. При выборе того или иного варианта хранения, кроме разницы между «хранением необъектных данных» и «хранением объектных данных» (рассмотренной в разделе «Хранение информации объектных и необъектных сущностей» на стр. 443), можно еще учесть требования к уникальности информации, накладываемые используемыми объектами системы «1С:Предприятие». Если необходимо обеспечить жесткую уникальность понятия «номенклатурная позиция спецификации договора» (то есть одна и та же номенклатурная позиция не может быть указана более одного раза в спецификации одного договора), тогда предпочтительнее вариант с использованием регистра сведений. Он как раз позволяет хранить только уникальную с точки зрения ключевых полей информацию (в данном случае – измерений Договор и Номенклатура). Для подчиненного же справочника таких ограничений по уникальности нет. Если необходимо хранить информацию в виде простой таблицы, то вариант с использованием подчиненного справочника будет предпочтительнее. Аналогична цепочка рассуждений, если в ходе решения некоей прикладной задачи на этапе конфигурирования для объекта необходимо ввести много признаков или особых свойств. Одно дело, если эти свойства и признаки касаются всех элементов данной сущности и активно используются при работе с объектами, им соответствующими. Тогда информацию данных свойств уместно хранить в виде реквизитов объекта. Например, реквизит Услуга булевого типа для справочника Номенклатура. Очень многие прикладные механизмы, работающие с элементами справочника Номенклатура, должны быстро различать ситуации работы с услугами или материальными номенклатурными позициями. Другое дело, если этот признак касается лишь некоторых элементов и используется лишь в отдельных механизмах. Тогда для хранения этой информации нерационально использовать реквизиты, а можно использовать другие объекты.
446
Например, информацию о том, какие из физических лиц являются пользователями, уместнее хранить в отдельном справочнике (с реквизитом ФизЛицо) или в соответствующем регистре сведений. Кроме того, возможна ситуация, когда необходимо, чтобы новые признаки и характеристики могли вводиться не только на этапе конфигурирования (разработчиками), но и в режиме работы «1С:Предприятие» пользователями. Для реализации этой возможности удобна организация хранения информации с использованием объекта План видов характеристик. Подробнее
Раздел «Использование плана видов характеристик для хранения видов характеристик», стр. 483.
В ситуации, когда требуется с помощью специальных свойств выделить только один элемент, использование реквизитов объектов вообще является неверным. Например, введение булевого реквизита БазоваяВалюта в состав справочника Валюты нерационально, как с точки зрения хранения информации (поле будет существовать для всех элементов, хотя значение Истина с прикладной точки зрения уместно только у одного элемента), так и с точки зрения быстродействия. Для корректного разрешения подобных ситуаций уместно считать элементы, обладающие такими специальными свойствами, данными, общими для всей базы данных, и организовывать хранение информации об этом посредством констант или регистров сведений. Так же осторожно нужно подходить к использованию строковых реквизитов неограниченной длины. Крайне не рекомендуется использовать их для хранения информации, объем которой может быть достаточно большим или непрогнозируемым. Примером такого некорректного использования реквизита может служить сохранение в реквизите значения, получаемого функцией ЗначениеВСтрокуВнутр() (например, для таблицы значений, содержащей большое количество строк). Не рекомендуется хранить в реквизитах активно используемых объектов картинки и образы файлов (использование полей типа ХранилищеЗначения), если заранее известно, что размер их будет велик. Для сохранения подобной информации следует использовать альтернативные методы.
Хранение иерархической информации Иерархическими принято считать структуры, у которых четко прослеживаются отношения «один ко многим». Например, «один руководитель – много подчиненных» (рис. 9.21). Кроме того, уровней иерархии может быть больше одного: «один руководитель, в подчинении которого находятся руководители подразделений, в подчинении которых находятся подчиненные» – пример трехуровневой иерархической структуры (рис. 9.22). Ну а в общем случае уровней может быть значительно больше. Профессиональная разработка в системе «1С:Предприятие 8»
Варианты подходов к решению задач хранения информации тель означает, что данный сотрудник непосредственно подчинен именно
Рис. 9.21. Пример одноуровневой иерархии
этому руководителю (а в информации по этому руководителю будет указано, кому он, в свою очередь, подчинен). В строке, отражающей информацию по директору, поле Руководитель пустое. Это значит, что в данной схеме у директора нет руководителей. Еще говорят «директор находится на корневом уровне иерархии». Данный прием применяется при хранении иерархической информации объектов прикладной области на уровне объектов базы данных системы «1С:Предприятие». То есть «нижестоящие» элементы должны помнить ссылку на «вышестоящие» элементы иерархии.
Рис. 9.22. Пример многоуровневой иерархии
Необходимо отметить, что в прикладных задачах в любом случае используется не бесконечное количество уровней иерархии. Например, хотя и говорят, что бюрократия бесконечна, но, составляя организационноштатную структуру любой организации, всегда приходим к конечному количеству уровней подчинения, ответственности и т. д. В данном разделе мы не будем обсуждать достоинства и недостатки использования иерархических структур в области их применения. Сосредоточимся на возможностях организации хранения иерархической информации средствами системы «1С:Предприятие». Для «экономного» хранения информации об иерархичности хранимых данных достаточно, если каждый из нижестоящих элементов будет помнить ссылку на непосредственно стоящий над ним элемент. Таким образом, информацию об иерархии можно хранить не только в виде схем, но и в виде таблиц. Например, информация о вышеприведенной схеме может храниться так, как показано в табл. 9.1. Таблица 9.1. Пример хранения иерархической информации Сотрудник
Руководитель
Директор Руководитель отдела закупок Менеджер по закупкам Товаровед Руководитель отдела продаж Менеджер по продажам Продавец Секретарь
Директор Руководитель отдела закупок Руководитель отдела закупок Директор Руководитель отдела продаж Руководитель отдела продаж Директор
Каждая строка таблицы содержит информацию по одной персоне. Для каждой строки таблицы упоминание некой персоны в поле РуководиТом 1
Однако это не значит, что разработчик в каждом отдельно взятом случае должен «доводить» выполнение этого приема до уровня таблиц базы данных. В типовых ситуациях эту работу берет на себя сама платформа. Разберем, что же это за ситуации. При разработке бизнес-решений разработчику чаще всего приходится иметь дело с иерархическими структурами при организации хранения условно-постоянной информации (справочники, планы видов характеристик), реже – при работе с регистрацией событий. В отношении хранения условно-постоянной информации учтены следующие ситуации: ■■ иерархия объектных данных одной сущности (рассматривается в разделе «Хранение иерархии данных одной сущности» на стр. 448); ■■ иерархия объектных данных разных сущностей (рассматривается в разделе «Хранение иерархии данных разных сущностей» на стр. 452); ■■ хранение иерархии необъектных данных внутри объекта (рассматривается в разделе «Хранение подчиненных данных в составе объекта» на стр. 450); ■■ хранение иерархии необъектных данных вне объекта (рассматривается в разделе «Хранение подчиненных данных вне объекта» на стр. 452). В остальных же случаях или для реализации ситуаций иерархии событий разработчик всегда может реализовать свою иерархическую схему посредством добавления реквизита к «подчиненным» объектам, значением которого должна являться ссылка на объект-владелец. Например, в рамках некоторого договора был оформлен документ ЗаказПокупателя. На основании документа ЗаказПокупателя был введен документ РеализацияТоваров. На основании документа РеализацияТоваров были введены документы СчетФактура и ПриходныйКассовыйОрдер. Впоследствии часть товара была возвращена, то есть на основании документа РеализацияТоваров был введен документ ВозвратТоваровОтПокупателя. Аналогичная цепочка документов может быть оформлена в отношении другого документа ЗаказПокупателя (рис. 9.23).
447
Глава 9. Хранение информации пользователи программы, и являются примерами данных объектного типа. Как информация об этой иерархии может быть отражена средствами платформы «1С:Предприятие»? Для этого при разработке следует произвести настройку свойств объекта конфигурации – справочника Пользователи, касающихся иерархии справочника. А именно: справочник – Иерархический, вид иерархии – Иерархия элементов (то есть нижестоящие элементы справочника иерархически подчиняются вышестоящим – именно элементам справочника), количество уровней иерархии ограничено – только три (рис. 9.25).
Рис. 9.23. Структура документов, введенных на основании
Необходимо хранить информацию о том, что все эти документы находятся в иерархии конкретного договора с покупателем. Решается данная задача включением в состав всех объектов, которые могут подчиняться договору, реквизита, например, Основание, ссылающегося на данный договор. подробнее
Этот пример более широко (в отношении вопросов ввода на основании, отображения иерархии подчинения договору) рассмотрен в разделе «Ввод на основании» (стр. 524) и приведен в составе демонстрационной конфигурации «Хранение информации», которая находится на прилагаемом компакт-диске.
Хранение иерархии данных одной сущности Выше (см. табл. 9.1) обсуждалась схема организационно-штатной структуры компании (рис. 9.24).
Рис. 9.25. Настройка иерархии справочника «Пользователи»
Дальнейшую работу возьмет на себя платформа. В состав основной таблицы справочника Пользователи будет добавлено поле Родитель для хранения в записях иерархически подчиненных элементов ссылок на элементы, которым они непосредственно иерархически подчиняются. Обращение к этому предопределенному полю будет возможно посредством соответствующих объектов встроенного языка для манипулирования данными справочника или посредством запросов. Кроме того, при записи и модификации данных в справочнике Пользователи платформа будет отслеживать ограничение по количеству уровней иерархии, не позволяя реализовать попытки их превышения, выдавая соответствующие предупреждения.
Рис. 9.24. Организационно-штатная структура компании
Допустим, при проектировании принято решение, что персоналии, отраженные в схеме, относятся к одной сущности прикладной области –
448
Помимо этого, в расширения соответствующих форм и элементов форм будут включены средства, облегчающие решение задач отображения информации справочника в иерархическом виде. Например, возможность отображения списка справочника в виде дерева или иерархического списка (рис. 9.26). Профессиональная разработка в системе «1С:Предприятие 8»
Варианты подходов к решению задач хранения информации Каждый реквизит объекта справочника или плана вида характеристик, если используется иерархия групп и элементов, может иметь следующие значения свойства Использование: Рис. 9.26. Отображение справочника «Пользователи» в виде иерархического списка
Подробнее
Пример реализации подобной схемы приведен в демонстрационной конфигурации «Хранение информации» (справочник Пользователи), которая находится на прилагаемом компакт-диске.
Рассмотренный выше пример касался случая иерархии элементов. Однако могут встречаться задачи, когда иерархия используется лишь для логического упорядочивания хранения и отображения данных объектных сущностей.
■■ Для элемента, ■■ Для группы, ■■ Для группы и элемента. Это позволяет легче решать задачи, для которых необходимо выделять свойства, присущие нужным уровням иерархии. Например, значение реквизита ОтветственныйМенеджер присуще только группам справочника Контрагенты. Считается, что все элементы нижестоящих уровней данной группы закреплены за этим менеджером (рис. 9.28). В этом случае для реквизита ОтветственныйМенеджер значение свойства Использование указывается – Для группы.
Например, данные справочника Номенклатура удобнее представлять в виде упорядочивания по товарным группам (рис. 9.27).
Рис. 9.28. Группы и элементы справочника «Контрагенты»
Рис. 9.27. Отображение справочника «Номенклатура» в виде дерева
Обратите внимание: каждый конечный элемент обладает конкретной закупочной ценой. Однако говорить о значении закупочной цены родителя этих элементов – нонсенс с прикладной точки зрения. Таким образом, свойства элементов и свойства их родителей отличаются друг от друга. Для реализации решений подобных задач используется вид иерархии Иерархия групп и элементов. С точки зрения хранения данных в базе данных для двух видов иерархии большой разницы нет, но для прикладной и интерфейсной функциональности возможности отличаются сильно. Том 1
Выгоды использования такого решения проявятся, например, при решении задачи «перезакрепления» контрагентов за другим менеджером. Чтобы «перезакрепить» все элементы, входящие в группу, не обязательно будет указывать каждому контрагенту его нового ответственного менеджера, достаточно лишь указать другое значение реквизита ОтветственныйМенеджер для этой группы. С другой стороны, реквизит ОтветственныйМенеджер можно сделать используемым и группами, и элементами. Тогда предложенная выше схема закрепления сможет учитывать ситуации, когда контрагент находится в группе, закрепленной за одним менеджером, но сам закреплен за другим менеджером.
449
Глава 9. Хранение информации Для интерфейсных задач при использовании данного вида иерархии платформа опять же берет на себя решения большинства вопросов различного поведения групп и элементов:
будет создавать реквизиты с типом значения СправочникСсылка.Руководители, но нельзя будет создать реквизиты, ссылающиеся на строки табличной части ПодчиненныеРядовыеСотрудники.
■■ «разделение» форм на основную форму элемента и основную форму группы для операций заполнения и просмотра данных объектов; ■■ «разделение» на форму выбора и форму выбора группы для реализации операций выбора; ■■ определение того, в каких ситуациях правомерен выбор групп, а в каких нет (по умолчанию, например, реквизиты документов интерактивно могут заполняться только значениями элементов); ■■ использование отбора динамического списка, содержащего таблицу справочника (ЭтоГруппа = Истина/Ложь), позволяющего просматривать (в зависимости от необходимости) только элементы, только группы или элементы и группы; ■■ и так далее.
Хранение подчиненных данных в составе объекта Практически все объекты системы «1С:Предприятие», предназначенные для хранения данных объектных сущностей (справочники, документы, планы видов характеристик, планы видов расчета и т. д.), имеют возможность хранить свою информацию не только в виде значений реквизитов, но и в составе подчиненных табличных частей. ПРИМЕЧАНИЕ
Подобным образом также может решаться задача хранения информации «один ко многим», рассмотренная ранее в разделе «Хранение иерархической информации» на стр. 446.
В качестве примера возьмем все ту же организационно-штатную структуру компании (см. рис. 9.24). Допустим, на ее основе необходимо реализовать хранение информации об объектной сущности «Руководители». Решение может быть реализовано в виде справочника Руководители так, чтобы руководители были элементами справочника, а рядовые сотрудники указывались в строках табличной части ПодчиненныеРядовыеСотрудники как ссылки на элементы справочника ФизическиеЛица (рис. 9.29). В результате в системе будет реализовано хранение информации об объектных сущностях – «Руководителях», с указанием подчиненных в качестве их описания. Однако необходимо иметь в виду, что информация строк подчиненной табличной части не имеет своей объектной сущности. То есть при данном способе хранения информации нельзя будет сослаться ни на одного «рядового подчиненного некоего руководителя». В составе документов можно
450
Рис. 9.29. Схема хранения данных справочника «Руководители»
Для задач, когда ссылка на такие сведения смысла не имеет, хранение множества подчиненных данных, характеризующих данный объект, внутри самого объекта может быть весьма удобным. Классическим примером являются документы с такими табличными частями, как ПоступлениеТоваров, Состав, Событие, СторонниеЛица и т. д. Схемы, когда подчиненная информация сама имеет иерархический вид, также могут быть реализованы внутри объекта, если это покажется удобным. Например, при оформлении заказа покупателя необходимо дать возможность пользователю вводить не только информацию о том, какие номенклатурные позиции, в каком количестве и по какой цене желает приобрести покупатель, но и еще произвольное количество дополнительных пожеланий по любой номенклатурной позиции в свободной форме, с возможностью отметки, насколько эти пожелания действительно важны. Представление информации в этом случае может быть отображено следующей таблицей (табл. 9.2). Таблица 9.2. Схема представления информации Заказ
Заказ № 3 от 12.02.10
Номенклатура
Количество Цена Сумма
Лазерный принтер 2 Canon LBP-810
200
400
Телефон LG W7200
30
300
10
Пожелания
Белого цвета Дополнительно упаковать в гофротару Без гарнитуры Доставку приурочить к 8 марта Цвет любой, только не черный
Профессиональная разработка в системе «1С:Предприятие 8»
Варианты подходов к решению задач хранения информации Поскольку речь идет о регистрации события Заказ покупателя, то для хранения информации логично использовать объект – документ ЗаказПокупателя. Таким образом, получаем три уровня иерархии: ■■ документ, ■■ указание номенклатурных позиций документа с количественносуммовыми характеристиками, ■■ указание дополнительных пожеланий к номенклатурным позициям. Реализация хранения этой информации может быть организована следующим образом. Для хранения информации о заказанных товарах с количественно-суммовыми характеристиками можно использовать табличную часть Состав. Но дополнительные пожелания будет неудобно хранить в рамках этой табличной части. Как показано в таблице выше, к одной номенклатурной позиции может предъявляться более одного требования и форма информации этих требований более «свободная», нежели указание цены, количества и суммы. В этом случае для хранения информации о дополнительных пожеланиях покупателя, если эту информацию нужно хранить внутри объекта, можно использовать еще одну табличную часть ДополнительныеТребования. Реквизитами табличной части ДополнительныеТребования будут Требование, Важно и Номенклатура (рис. 9.30). Соответствие с информацией табличной части Состав будет организованно именно по номенклатурным позициям.
Рис. 9.31. Форма документа «ЗаказПокупателя»
Поскольку для выполнения операций заполнения дополнительных требований пользователь сначала должен будет открыть соответствующую закладку, у многостраничной группы Страницы обработчик события смены страницы реализован в виде следующей процедуры (листинг 9.12). Листинг 9.12. Обработчик события «ПриСменеСтраницы»
&НаКлиенте Процедура СтраницыПриСменеСтраницы(Элемент, ТекущаяСтраница) // Проверить, активизирована ли закладка // "Дополнительные требования". Если ТекущаяСтраница.Имя = "ГруппаДополнительныеТребования" Тогда // Заполнить список выбора у колонки "Номенклатура" таблицы // формы "Дополнительные требования" списком номенклатурных // позиций, использованных в табличной части "Состав". ПолучитьСоставНоменклатуры(); КонецЕсли; КонецПроцедуры
Рис. 9.30. Структура документа «ЗаказПокупателя»
Дополнительный сервис для пользователя может касаться вопроса подбора номенклатурных позиций в табличную часть ДополнительныеТребования только из перечисленных в табличной части Состав. Подробнее
В демонстрационной конфигурации «Хранение информации», которая находится на прилагаемом компакт-диске, в форме документа ЗаказПокупателя приведен один из вариантов решения этой задачи.
В форме документа расположена многостраничная группа с двумя закладками – Состав и Дополнительные требования (рис. 9.31). Том 1
В процедуре обработки события ПриСменеСтраницы, если имя текущей страницы – ГруппаДополнительныеТребования, вызывается серверная процедура ПолучитьСоставНоменклатуры(), в которой происходит заполнение списка выбора у колонки Номенклатура таблицы формы ДополнительныеТребования списком номенклатурных позиций, использованных в табличной части Состав (листинг 9.13). Листинг 9.13. Процедура «ПолучитьСоставНоменклатуры()»
&НаСервере Процедура ПолучитьСоставНоменклатуры() // Очистить список выбора у колонки "Номенклатура" таблицы формы // "Дополнительные требования". Элементы.ДополнительныеТребованияНоменклатура.СписокВыбора.Очистить();
451
Глава 9. Хранение информации // Выгрузить список номенклатурных позиций, использованных в // табличной части "Состав", в таблицу значений. ТЗСоставНоменклатуры = Объект.Состав.Выгрузить(, "Номенклатура"); Для Каждого СтрокаТЗ ИЗ ТЗСоставНоменклатуры Цикл Элементы.ДополнительныеТребованияНоменклатура. СписокВыбора.Добавить(СтрокаТЗ.Номенклатура); КонецЦикла КонецПроцедуры
В ситуациях же, когда поддержание однозначности связей «один ко многим» критично, разработчику необходимо будет решать этот вопрос. Для этого следует либо дополнительно обеспечивать уникальность значений реквизитов или комбинаций значений реквизитов в самом объекте, либо «выносить» хранение этой информации в другие объекты, специально предназначенные для обеспечения уникальности комбинаций значений сущностей, – регистры сведений.
Таким образом, возможности выбора номенклатурных позиций на странице ДополнительныеТребования будут ограничены списком номенклатурных позиций, использованных в табличной части Состав. Для этого необходимо включить свойство РежимВыбораИзСписка у колонки Номенклатура таблицы формы ДополнительныеТребования (рис. 9.32).
Хранение иерархии данных разных сущностей Допустим, необходимо организовать хранение информации по предыдущей трудовой деятельности каждого сотрудника компании. Сами сотрудники признаны сущностями объектного типа, и для хранения их информации в рамках решения создан справочник Сотрудники. Как решить задачу? С одной стороны, данная информация непосредственно связана с сотрудником и могла бы быть реализована посредством включения табличной части ТрудоваяДеятельность в состав объектов справочника Сотрудники. Но к выбору такого варианта нужно подходить осторожно. Как обсуждалось в разделе «Хранение подчиненных данных в составе объекта» (см. стр. 450), подчиненные табличные части предназначены для учета только необъектных сущностей, то есть при таком решении в других объектах системы невозможно будет использовать поля или реквизиты, соответствующие понятию «место предыдущей работы конкретного сотрудника». Если же необходимость в такой объектной сущности есть или может появиться, то решение видится в использовании подчиненного справочника ТрудоваяДеятельность. В его элементах можно хранить информацию о должности, месте работы, дате начала деятельности, дате окончания деятельности по каждому эпизоду предыдущей работы сотрудника.
Рис. 9.32. Свойства колонки «Номенклатура» таблицы формы «ДополнительныеТребования»
Необходимо заметить, что в данном примере иерархических данных не реализована связь «один ко многим» в чистом виде. Ведь информация «номенклатурная позиция заказа покупателя» не относится к объектным данным. В общем случае одна и та же номенклатурная позиция может быть указана сколько угодно раз в табличном поле Состав. И значит, невозможно установить, к какой именно строке состава (с этой номенклатурной позицией) относятся пожелания покупателя, описанные в табличной части ДополнительныеТребования. Однако в постановке задачи это и не требовалось. То есть либо такие ситуации не критичны для логики работы разрабатываемого решения, либо пользователь сам может описать, что имелось в виду, в строковом реквизите Требование.
452
Впоследствии эта сущность может быть использована, например, для организации структуры регистра накопления СтажРаботы или для заполнения реквизитов соответствующих документов.
Хранение подчиненных данных вне объекта Для хранения необъектных данных, соответствующих определенным комбинациям значений измерений, предназначены регистры сведений. Подробнее
Раздел «Хранение информации в регистрах сведений», стр. 455.
Рассмотрим пример. В торговой компании покупатели закреплены за менеджерами, их обслуживающими. Сами менеджеры компании, в свою очередь, относятся к тому или иному департаменту. Необходимо иметь представление, кто за кем закреплен на каждый момент времени. Профессиональная разработка в системе «1С:Предприятие 8»
Варианты подходов к решению задач хранения информации В данном случае вариант хранения информации в регистре сведений предпочтителен тем, что автоматически будет обеспечена уникальность значений измерений. То есть в регистре ЗакреплениеПокупателей невозможно будет создать две записи с одним и тем же покупателем (соответственно, невозможно одного покупателя закрепить за несколькими менеджерами). Аналогично в отношении регистра ЗакреплениеМенеджеров. Кроме того, регистры сведений позволяют хранить не только статические варианты иерархических структур, но и изменяющиеся во времени. Если указанные регистры сведений сделать периодическими, то впоследствии можно будет легко хранить динамику картины отношений. То есть отражать в системе все изменения, касающиеся закреплений (например, менеджер со всей своей клиентской базой передан другому департаменту). И так же легко получать информацию о состоянии модели закреплений на любой момент времени.
Хранение информации, имеющей привязку ко времени Практически все объекты, поддерживающие возможность добавления новых полей (значений, реквизитов), могут работать с данными типа Дата. Но зачастую предметом хранения является не информация о датах, а другая информация, которая просто должна храниться в привязке ко времени. Например, необходимо помнить, начиная с какого момента времени для таких-то номенклатурных позиций действуют такие-то цены. Информацию, хранящуюся в привязке ко времени, чаще всего разделяют на содержащую объектные данные, необъектные данные.
Использование документов
Также для ситуаций, когда в готовое (и эксплуатируемое) решение приходится вводить новые сущности, добавление новых измерений к регистру сведений позволяет легко решать задачи усложнения «взаимоотношений» данных.
В задачах хранения объектных данных, привязанных ко времени, речь обычно идет о регистрации неких событий и всего, что с ними связано, например, в хозяйственной жизни предприятия. Чаще всего для хранения такой информации выбираются объекты Документ.
Например, начиная с какого-то момента, закрепление покупателей за менеджерами продолжает оставаться однозначным, но только в рамках конкретных проектов. То есть в основном проекте Торговля за обслуживание некоего покупателя по-прежнему отвечает тот же менеджер, но в проекте Информационное сопровождение – совсем другой (да еще и из другого департамента).
В нашем примере (с хранением информации о ценах), если необходимо в привязке ко времени фиксировать, как (и вследствие какого события) произошло изменение цен, для хранения этой информации можно использовать документ ИзменениеЦенКомпании (рис. 9.33).
С точки зрения классификации ситуации хранения данных такое изменение «революционно», отдельные его части можно даже рассматривать как переход от схемы «один ко многим» к схеме «многие ко многим». Однако сама реализация подобного «поворота событий» очень проста. В состав регистра ЗакреплениеПокупателей достаточно добавить измерение Проект. И поскольку система обеспечивает в регистре сведений уникальность комбинаций значений измерений, задача уже фактически решена. Остается лишь согласовать с пользователями, будет ли в регистре сведений ЗакреплениеПокупателей пустая ссылка на проект (для старых данных) с прикладной точки зрения восприниматься проектом основной деятельности предприятия – Торговля, либо необходимо произвести соответствующую обработку для заполнения этих данных. Так же легко в состав регистра сведений может быть введена дополнительная информация, характеризующая конкретные комбинации значений измерений. Это реализуется посредством добавления ресурсов. Например, для регистра ЗакреплениеПокупателей могут быть введены такие ресурсы, как Лояльность, ЧастотаКонтактов, СуммаКвотыПродаж и так далее. Для регистра ЗакреплениеМенеджеров могут быть введены такие ресурсы, как БазовыйОклад, ПроцентПремии, Эффективность и тому подобное. Том 1
Рис. 9.33. Документ «ИзменениеЦенКомпании»
В пользу такого решения говорит функциональность объектов документов, поддерживаемая на уровне платформы «1С:Предприятие»: ■■ ■■ ■■ ■■ ■■
заполнение, запись, проведение, формирование движений по регистрам, расположение на оси времени,
453
Глава 9. Хранение информации ■■ пометка на удаление, ■■ удаление.
в одном решении и обеспечивать каждый свою функциональность. И даже более того, помогают друг другу.
Кроме этого, положительным моментом является возможность решения (средствами платформы) вопросов отображения списков документов, группирования разных видов документов в единой хронологии для общего отображения или для общей обработки и так далее. Подробнее
Глава 10 «Документы и последовательности», стр. 495.
Использование периодических регистров сведений Как рассуждали выше, в разделе «Задачи хранения информации» на стр. 435, для решения учетных и аналитических задач кроме учета событий важно, чтобы система в определенных ситуациях учитывала показатели, которые изменяются или при обработке вышеуказанных событий, или вследствие других действий пользователя. Возможно, в нашем примере будет необходимо быстро получить ответ, для какого товара в такой-то момент времени действует такая-то цена. Получение этой информации из документов может оказаться неудобным или длительным по времени, потому что данные разных документов могут противоречить друг другу и для определения истины разработчику придется прописать некие алгоритмы. Использование периодических регистров сведений позволяет в данной ситуации (и подобных ей) достаточно быстро создать решение, большую часть функциональности которого поддерживает сама платформа (рис. 9.34).
Рис. 9.34. Структура регистра накопления «ЦеныНоменклатуры»
Например, получение информации об актуальных значениях цен на некоторый момент времени (рис. 9.35). Подробнее
Раздел «Хранение информации в регистрах сведений», стр. 455.
При этом хотелось бы заметить, что в рассмотренном нами примере оба варианта (и использование документов, и использование периодических регистров сведений) для хранения данных, имеющих привязку ко времени, не противоречат друг другу. Они могут «мирно уживаться»
454
Рис. 9.35. Схема получения актуальных цен
Подробнее
Данный пример полностью приведен в составе демонстрационной конфигурации «Хранение информации», которая находится на прилагаемом компакт-диске.
Использование объекта «ХранилищеЗначения» При решении вопросов хранения информации желательно различать информацию, обеспечивающую основную бизнес-логику решения и другую, вспомогательную информацию. Данные основной бизнес-логики активно используются в учетных и аналитических механизмах. Для них важны такие вопросы, как индексирование, упорядочивание в запросах и выборках, суммирование, поиск и т. п. Вопросам обеспечения хранения этих данных, по сути, посвящена большая часть данной главы. Данные же вспомогательной информации нужно просто хранить. Все возможное манипулирование этой информацией сводится к операциям записи и чтения. Вопросам организации хранения такой информации посвящен текущий раздел. Итак, платформа системы «1С:Предприятие» предоставляет возможность хранения некоторой вспомогательной информации в базе данных посредством полей типа ХранилищеЗначения. Особенностью использования таких полей является то, что база данных «не обязана ничего знать» о природе хранимой там информации. Это могут быть картинки, файлы, таблицы, данные примитивных типов, да что угодно. База данных отвечает лишь за хранение этой информации, не обеспечивая больше никакой функциональности. При этом еще говорят, что тип значения ХранилищеЗначения позволяет хранить значения различных типов в сериализованном виде, то есть в виде, который позволяет записывать данные и восстанавливать их. Профессиональная разработка в системе «1С:Предприятие 8»
Хранение информации в регистрах сведений ПРИМЕЧАНИЕ
Для всех объектов, чьи данные сериализуются, в описании встроенного языка данная возможность указывается отметкой «Сериализуется».
Важной особенностью хранилища значений является возможность хранения данных в сжатом виде. Это позволяет существенно сократить размеры базы данных при необходимости хранения больших объемов информации. С прикладной точки зрения в полях типа ХранилищеЗначения можно хранить, например, значения каких-то вспомогательных настроек пользователей, фотографии, изображения, образы файлов и так далее. Например, фотографии сотрудников или файлы с аудиозаписью важных переговоров (то есть данные типа Картинка или ДвоичныеДанные). При этом, хотя в системе не существует явного ограничения на размер данных, хранящихся в полях типа ХранилищеЗначения, следует все-таки осмотрительно подходить к решению, что именно требуется хранить в базе данных. Большой объем хранимой вспомогательной информации может привести к тому, что административные операции (например, создание резервной копии базы данных) выполняются медленно из-за большого объема базы данных. А большой объем обусловлен не требованиями обеспечения основной бизнес-логики, а тем, что кто-то из сотрудников решил хранить в базе данных любимые фильмы. Особенно аккуратно нужно относиться к возможности использования полей типа ХранилищеЗначения в составе объектов (например, справочников, документов), активно использующихся при реализации основной бизнес-логики. Ведь данные объектов считываются целиком при обращении к ним. Поэтому, например, вопрос хранения тех же фотографий лучше решать не в составе справочника Сотрудники, а в отдельном подчиненном справочнике или регистре сведений. Тогда будет сохранена возможность идентификации соответствия изображений сотрудникам, к которым они относятся. И в то же время при использовании объектов справочника Сотрудники для решения других задач выполняемые операции не будут замедляться из-за необходимости считывания из базы данных больших объемов информации.
■■ периодичность, ■■ подчинение записей регистратору. Разберем использование этой функциональности на примерах.
Уникальность записей регистра сведений Одним из основных показаний для использования именно регистров сведений для хранения данных является то, что регистры сведений обеспечивают уникальность хранимой информации для конкретных комбинаций значений разрезов ее хранения. То есть набор значений разрезов является уникальным ключом каждой записи регистра. Сама информация в регистре хранится в виде значений ресурсов. А разрезы хранения информации реализуются посредством измерений регистра. Рассмотрим следующий пример. Для хранения значения метода списания себестоимости, действующего на автоматизируемом предприятии, может использоваться непериодический регистр сведений УчетнаяПолитикаПредприятия. В случае отсутствия измерений (разрезов хранения информации) состав регистра будет выглядеть следующим образом (рис. 9.36).
Рис. 9.36. Структура регистра «УчетнаяПолитикаПредприятия»
В таком регистре можно хранить только одно значение метода списания себестоимости (табл. 9.3). Таблица 9.3. Значение, хранимое в регистре МетодСписанияСебестоимости
FIFO
Хранение информации в регистрах сведений Удобным средством для реализации задач хранения информации необъектных данных, развернутой в некоторых разрезах, является использование регистров сведений. Для решения таких задач регистры сведений обладают функциональностью, которая включает в себя: ■■ уникальность записей в разрезах ключей записей, Том 1
Запись другого значения в данный регистр обязательно должна сопровождаться замещением предыдущего (табл. 9.4). Два значения одновременно храниться не могут. Таблица 9.4. Значение, хранимое в регистре МетодСписанияСебестоимости
Средневзвешенный
455
Глава 9. Хранение информации Это соответствует требованиям прикладной области. Ведь действительно, если для решения ряда учетных задач потребуется получать значение используемого на предприятии метода списания себестоимости, то важно, чтобы он был одним и тем же. Если же автоматизируемое предприятие, например, представляет собой ряд самостоятельных юридических лиц (организаций), то для хранения информации об учетной политике каждой организации в рассмотренный регистр сведений можно ввести измерение Организация (рис. 9.37). В результате данные в регистре смогут храниться в разрезе организаций.
Количество используемых в составе регистра сведений измерений и ресурсов определяется задачами, которые решаются посредством этого регистра. Например, если стоит задача хранения информации о «персональных» для покупателей ценах на товары, она может быть решена посредством регистра сведений со следующим составом (рис. 9.39).
Рис. 9.39. Структура регистра сведений Рис. 9.37. Структура регистра «УчетнаяПолитикаПредприятия»
По каждой конкретной организации в регистре сможет присутствовать только одна запись. Значение метода списания себестоимости в этой записи будет «персональным» для этой организации. И ключом этой записи будет значение организации (табл. 9.5). Таблица 9.5. Пример хранения данных в регистре «УчетнаяПолитикаПредприятия» Организация
МетодСписанияСебестоимости
ООО «АвтоматикаСвязьПроект» ООО «Информационные системы» ООО «Мультимедиа Плюс»
FIFO Средневзвешенный Средневзвешенный
Однако впоследствии любые расширения этой задачи не приводят к необходимости серьезной структурной перестройки в вопросах организации хранения информации и достаточно легко реализуются. Например, если впоследствии необходимо будет ввести понятие «Договор», когда по одному договору с покупателем на товары одни цены, а по другому могут быть совсем другие. Или если по каждой поставляемой номенклатурной позиции понадобится хранить не просто информацию о ценах продажи, но и учет сезонной скидки, условия доставки, процент предоплаты, срок отсрочки платежа и т. д. Все эти требования могут быть реализованы в рамках все того же регистра за счет добавления соответствующих ресурсов и измерений (рис. 9.40).
Таким образом, важно понимать, что регистр сведений не является простой таблицей для хранения произвольной информации. Требование уникальности записей по ключевым полям обязательно. И оно отслеживается системой автоматически, при любых попытках модификации данных или модификации состава регистра сведений. Если в вышеприведенном примере после заполнения данных регистра информацией об организациях попытаться удалить измерение Организация из регистра как объекта конфигурации, то система не позволит внести эти изменения в конфигурацию базы данных (рис. 9.38).
Рис. 9.40. Структура регистра сведений
Важно лишь то, что в данном случае «ключом уникальности» записей регистра будет уже номенклатурная позиция конкретного договора с покупателем. ВНИМАНИЕ!
Рис. 9.38. Сообщения при реорганизации базы данных
456
Хотелось бы обратить внимание на то, что возможность расширения функциональности регистра за счет добавления новых ресурсов не является обязательной к использованию. В некоторых случаях лучше добавлять не ресурсы, а новые регистры сведений. Подробно этот вопрос рассматривается в разделе «Проектирование структуры регистров сведений» на стр. 479.
Профессиональная разработка в системе «1С:Предприятие 8»
Хранение информации в регистрах сведений
Периодические регистры сведений Одной из возможностей регистра сведений является хранение данных не только в разрезе указанных измерений, но и в хронологическом разрезе. Разработчик может создавать периодические регистры сведений, указывая минимальную периодичность хранения данных. Например, для реализации хранения информации в регистре сведений УчетнаяПолитикаПредприятия не только в разрезе организаций, но и в разрезе лет (в действительности учетная политика предприятия принимается сроком на год), в состав объекта конфигурации можно внести следующее изменение – указать периодичность хранения информации регистра В пределах года (рис. 9.41).
Таким образом, в регистре сведений можно хранить не просто статические данные, но и историю изменений этих данных. При такой организации хранения информации появляются возможности: ■■ получения информации, актуальной на тот или иной временной момент; ■■ получения информации о значениях данных, вступающих в силу после некоего временного момента; ■■ получения картины динамики изменения данных за некоторый период; ■■ решения других прикладных задач, связанных с хранением информации в привязке ко времени. Например, периодический регистр сведений ПерсонифицированныйПрайс сможет не только хранить информацию о том, какова цена на определенную номенклатуру сейчас (или была в прошлом), но и о том, как она будет изменяться в будущем (если эти изменения будут заранее планироваться). Подробнее
Раздел «Получение данных из периодических регистров сведений», стр. 473.
Подчинение записей регистратору В ряде прикладных задач возникает необходимость обеспечения обоснования хранимой в регистрах сведений информации наличием документов, зарегистрировавших изменения этой информации.
Рис. 9.41. Периодичность регистра сведений
В результате в структуру хранения данных регистра будет добавлено поле Период. Причем оно будет включено в состав ключа записей регистра. То есть, по сути, является еще одним разрезом хранения информации.
Например, изменение отпускных цен компании может производиться только определенным кругом лиц, и каждое такое изменение должно сопровождаться оформлением соответствующего документа. То есть данные регистра сведений должны четко «помнить», в связи с каким именно документом они там оказались (рис. 9.42).
Теперь в регистре УчетнаяПолитикаПредприятия (см. рис. 9.37) смогут храниться, например, такие данные (табл. 9.6). Таблица 9.6. Пример хранения данных в регистре «УчетнаяПолитикаПредприятия» Период
Организация
МетодСписанияСебестоимости
2009 г. 2009 г. 2009 г. 2010 г. 2010 г.
ООО «АвтоматикаСвязь Проект» ООО «Информационные системы» ООО «Мультимедиа Плюс» ООО «АвтоматикаСвязь Проект» ООО «Мультимедиа Плюс»
FIFO Средневзвешенный Средневзвешенный Средневзвешенный LIFO
Том 1
Рис. 9.42. Хранение данных в регистре сведений, подчиненном регистратору
457
Глава 9. Хранение информации Чаще всего при этом необходимо обеспечивать гранулярность записи или модификации данных регистра сведений. В качестве такой «гранулы» используется набор записей, подчиненных документу-регистратору. Например, при проведении документа-регистратора его набор записей целиком перезаписывается. Для того чтобы разработчику не пришлось решать массу вопросов обеспечения данной функциональности собственными силами, он может воспользоваться штатными возможностями платформы. Для этого достаточно установить значение Подчинение регистратору свойству Режим записи регистра сведений как объекта конфигурации (рис. 9.43).
Рис. 9.44. Регистраторы регистра сведений
Это можно сделать как при редактировании самого регистра как объекта конфигурации, так и при редактировании документа-регистратора как объекта конфигурации. Рис. 9.43. Свойства регистра сведений «ЦеныНоменклатуры»
С точки зрения хранения данных в регистре установка значения Подчинение регистратору свойства Режим записи приводит к включению в состав регистра полей Регистратор, НомерСтроки и Активность. ПРИМЕЧАНИЕ
Обратите внимание на то, что поле Активность по умолчанию не включается в форму списка, сгенерированную платформой. Поэтому если вы захотите увидеть, какие новые поля появились у регистра, и для этого откроете форму списка, то вы не увидите там поля Активность. Но при необходимости его можно добавить вручную в форму списка.
Далее требуется указать, какие именно документы могут быть регистраторами записей регистра (рис. 9.44).
458
Благодаря этому облегчается труд разработчика, которому необходимо сформировать или модифицировать набор (наборы) записей регистра (регистров), подчиненных некоему документу. Подробнее
Раздел «Создание, изменение, удаление записей регистра сведений», стр. 462.
Платформа во многих механизмах будет сама использовать обращение к данным свойствам объектов конфигурации. Поэтому при удалении документов или отмене проведения (если свойство Удаление движений установлено в значение, отличное от Не удалять) система производит поиск движений этого документа в таблицах всех регистров, для которых данный документ может быть регистратором, и удаляет их. Профессиональная разработка в системе «1С:Предприятие 8»
Хранение информации в регистрах сведений Хотелось бы обратить внимание, что поле Регистратор обеспечивает привязку к документу, но не всегда входит в разряд ключевых полей. Для того чтобы поле Регистратор стало ключевым, необходимо для такого регистра сведений (с режимом записи Подчинение регистратору) установить для свойства Периодичность значение По позиции регистратора. С прикладной точки зрения это означает возможность хранения в регистре сведений данных с привязкой к временной оси с дробностью до момента времени. То есть фактически каждый регистратор может делать движения по любым комбинациям измерений (при этом не будет конфликтовать по поводу уникальности с другими документами). А значения ресурсов можно получать не только на определенный период, но и на момент времени документа (рис. 9.45).
Хронология записей регистра сведений с периодичностью По позиции регистратора внутри секунды однозначна с точки зрения чтения информации, но не управляема разработчиком с точки зрения записи информации. Например, при отображении движений регистра внутри секунды они упорядочиваются системой по ссылкам на регистраторы, то есть по внутренним идентификаторам документов. И такой порядок неизменен при любом обращении на чтение информации, однако нет возможности произвольно изменить его (внутри секунды).
Структура регистра сведений В состав регистра сведений как объекта конфигурации включаются: ■■ измерения, ■■ ресурсы, ■■ реквизиты. Как уже было рассмотрено выше, в разделе «Уникальность записей регистра сведений» на стр. 455: ■■ ресурсы хранят данные регистра, то есть ту информацию, ради хранения которой регистр, собственно, создавался и с которой работает функциональность регистра; ■■ измерения используются для обеспечения разрезов хранения этой информации.
Рис. 9.45. Получение значений ресурсов на момент времени документа
Однако необходимо понимать, что с точки зрения решения реальных бизнес-задач точность записи хронологии изменений информации больше секунды вряд ли требуется. Таким образом, исходя из области применения, если требуется поместить действия двух событий в определенном хронологическом порядке, то их нужно помещать в разные периоды. То есть если записи движений формируются так, что поле Период заполняется значением Дата документа, то нужно менять дату документа (рис. 9.46).
Рис. 9.46. Запись движений документов с точностью до даты
Том 1
Кроме того, для ситуаций, когда необходимо кроме данных хранить дополнительную информацию собственно о записях регистра, возможно использование реквизитов. Хотелось бы особо отметить, что деление информации регистра на реквизиты и ресурсы – элемент общего подхода. И хотя технологически хранение информации ресурсов и реквизитов регистра сведений существенно не различается, правильное отнесение разработчиком данных к ресурсам или реквизитам позволяет впоследствии быстро отличить, что является «функцией» регистра, а что просто комментирует запись. Строго говоря, это один из ключевых моментов организации разработки в «1С:Предприятии» – деление структуры метаданных по ролям, исполняемым конкретными объектами в прикладном решении, а не только по их технологическому устройству. Например, регистр сведений ЦеныНоменклатуры хранит информацию о ценах в разрезах номенклатурных позиций и типов цен. Эта информация впоследствии используется для работы механизмов ценообразования. Но, кроме того, для вопросов контроля над изменением цен в составе регистра есть реквизит Ответственный, в котором для каждой записи регистра указывается ссылка на пользователя, ответственного за ввод данной записи (рис. 9.47).
459
Глава 9. Хранение информации
Рис. 9.47. Структура регистра сведений «ЦеныНоменклатуры»
Далее, как было рассмотрено выше, регистры сведений могут иметь режим записи Подчинение регистратору, вследствие чего в состав таблиц регистра добавляется поле Регистратор. И регистр сведений может быть периодическим, вследствие чего в состав его таблиц добавляется поле Период (рис. 9.48).
■■ Регистратор – содержит ссылку на документ, которому подчинена данная запись. Это поле существует только для регистров с режимом записи Подчинение регистратору; ■■ НомерСтроки – уникальный номер данной записи в наборе записей регистра, подчиненных документу, указанному в поле Регистратор. Это поле существует только для регистров с режимом записи Подчинение регистратору; ■■ Активность – имеет тип Булево. Содержит признак влияния записи на получение информации из регистра. Записи, для которых значение данного свойства установлено в Ложь, не будут учитываться при получении «первых» или «последних» записей регистра, а также при получении сведений на определенный момент времени. Это поле существует только для регистров с режимом записи Подчинение регистратору; ■■ Ключ – короткий ключ записи регистра. Поле присутствует у непериодических регистров, имеющих хотя бы одно измерение; ■■ <Измерение> – содержит значение измерения. Количество таких полей равно количеству измерений, определенных для регистра как объекта конфигурации; ■■ <Ресурс> – значение ресурса. Количество таких полей равно количеству ресурсов, определенных для регистра как объекта конфигурации; ■■ <Реквизит> – значение реквизита. Количество таких полей равно количеству реквизитов, определенных для регистра как объекта конфигурации. Таким образом, для регистра ЦеныНоменклатуры с режимом записи Подчинение регистратору и периодичностью По позиции регистратора пример заполнения таблицы базы данных будет следующим (темным фоном выделены ключевые поля записей), табл. 9.7. Теперь рассмотрим непериодический регистр сведений Сотрудники с независимым режимом записи (рис. 9.49).
Рис. 9.48. Основные свойства регистра сведений «ЦеныНоменклатуры»
Данные каждого регистра сведений хранятся в отдельной таблице базы данных. Каждая такая таблица имеет следующий состав колонок: ■■ Период – дата записи. Определяет положение данной записи на временной оси. Это поле существует только для периодических регистров;
460
Рис. 9.49. Структура регистра «Сотрудники»
Таблица регистра Сотрудники, хранящая информацию в базе данных, может быть заполнена следующим образом (темным фоном выделены ключевые поля записей), табл. 9.8.
Профессиональная разработка в системе «1С:Предприятие 8»
Хранение информации в регистрах сведений
Ответственный
истина
Пульт PX Оптовая
2
истина
Пульт PX Мелкооптовая 170,00 Семенов
3
истина
Пульт PX Розничная
200,00 Семенов
4
истина
Пульт VH Оптовая
100,00 Семенов
5
истина
Пульт VH Мелкооптовая 90,00
1
истина
Пульт PX Оптовая
Цена
Номенклатура
1
ТипЦены
Активность
Изменение цен компании 000000001 от 16.04.2010 21:54:41 Изменение цен 16.04.2010 компании 000000001 21:54:41 от 16.04.2010 21:54:41 Изменение цен 16.04.2010 компании 000000001 21:54:41 от 16.04.2010 21:54:41 Изменение цен 16.04.2010 компании000000001 21:54:41 от 16.04.2010 21:54:41 Изменение цен 16.04.2010 компании 000000001 21:54:41 от 16.04.2010 21:54:41 Изменение цен 18.04.2010 компании 000000002 20:49:26 от 18.04.2010 20:49:26 Изменение цен 18.04.2010 компании 000000002 20:49:26 от 18.04.2010 20:49:26 Изменение цен 18.04.2010 компании 000000002 20:49:26 от 18.04.2010 20:49:26 Изменение цен 18.04.2010 компании 000000002 20:49:26 от 18.04.2010 20:49:26 16.04.2010 21:54:41
Номер строки
Регистратор
Период
Таблица 9.7. Пример заполнения регистра сведений «ЦеныНоменклатуры»
150,00 Семенов
Семенов
170,00 Иванов
2
истина
Пульт PX Мелкооптовая 190,00 Иванов
3
истина
Пульт PX Розничная
4
истина
Пульт VH Мелкооптовая 100,00 Иванов
220,00 Иванов
Таблица 9.8. Пример заполнения регистра сведений «Сотрудники» Физическое лицо
Подразделение
Должность
Иванов Иван Сергеевич Семенов Сергей Петрович Семенов Сергей Петрович Петровский Семен Иванович Петровская Ирина Ивановна
Отдел продаж Отдел продаж Отдел закупок Руководство компании Бухгалтерия
Руководитель Менеджер Руководитель Руководитель Бухгалтер
Конечно же, функциональность регистра сведений с независимым режимом записи и регистра сведений с режимом записи Подчинение регистратору различается. Также различается функциональность использования периодических и непериодических регистров сведений.
Поэтому для поддержания должного быстродействия при обращении к данным информационной базы для таблиц регистров сведений в зависимости от вида регистра создаются, например, следующие индексы: ■■ для регистра сведений с периодичностью По позиции регистратора: □□ Период + Регистратор + НомерСтроки; □□ Регистратор + НомерСтроки; □□ Измерение1 + [Измерение2 + …] + Период + Регистратор + НомерСтроки – если для данного регистра есть хоть одно измерение. В данный индекс включаются все измерения в том порядке, в котором они заданы в составе регистра как объекта конфигурации, поле Период, поле Регистратор и поле НомерСтроки; □□ Измерение + Период + Регистратор + НомерСтроки – если для данного измерения свойство Индексировать установлено в значение Индексировать; □□ Ресурс + Период + Регистратор + НомерСтроки – если для данного ресурса свойство Индексировать установлено в значение Индексировать; □□ Реквизит + Период + Регистратор + НомерСтроки – если для данного реквизита свойство Индексировать установлено в значение Индексировать; ■■ для непериодического регистра сведений: □□ Измерение1 + [Измерение2 +…] – если для данного регистра есть хоть одно измерение. В данный индекс включаются все измерения в том порядке, в котором они заданы в составе регистра как объекта конфигурации; □□ ИзмерениеN + Измерение1 + [Измерение2 +…] – если для измерения ИзмерениеN задано свойство Индексировать или свойство Ведущее, и при этом это не первое и не единственное измерение. В данный индекс включаются ИзмерениеN и затем все остальные измерения в том порядке, в котором они заданы в составе регистра как объекта конфигурации; □□ Реквизит + Измерение1 + [Измерение2 +…] – если для данного реквизита свойство Индексировать установлено в значение Индексировать. В данный индекс включается поле Реквизит и затем все измерения в том порядке, в котором они заданы в составе регистра как объекта конфигурации; □□ Ресурс + Измерение1 + [Измерение2 +…] – если для данного ресурса свойство Индексировать установлено в значение Индексировать. В данный индекс включается поле Ресурс и затем все измерения в том порядке, в котором они заданы в составе регистра как объекта конфигурации; □□ Ключ. Использование индексов позволяет сократить время выполнения операций с данными регистра.
Том 1
461
Глава 9. Хранение информации
462
Цена
Ответственный
3
истина Пульт PX Розничная
200,00
Семенов
4
истина Пульт VH Оптовая
100,00
Семенов
5
истина Пульт VH Мелкооптовая 90,00
Семенов
1
истина Пульт PX Оптовая
170,00
Иванов
2
истина Пульт PX Мелкооптовая 190,00
Иванов
3
истина Пульт PX Розничная
220,00
Иванов
4
истина Пульт VH Мелкооптовая 100,00
Иванов
ТипЦены
Семенов
Номенклатура
Регистратор
истина Пульт PX Мелкооптовая 170,00
Таблица 9.10. Пример заполнения регистра сведений «ЦеныНоменклатуры»
Изменение цен 16.04.2010 компании 000000001 1 21:54:41 от 16.04.2010 21:54:41 Изменение цен 16.04.2010 компании 000000001 2 21:54:41 от 16.04.2010 21:54:41
Ответственный
Разным фоном в таблице выделены наборы записей. Согласно постулату об уникальности записей по значениям ключевых полей невозможно, например, записать одновременно две записи с одинаковыми значениями полей Номенклатура, ТипЦены, Период, Регистратор (табл. 9.10).
2
Цена
Поясним эти положения на примерах. Для регистра сведений ЦеныНоменклатуры с режимом записи Подчинение регистратору ключевыми полями являются Период, Регистратор, Номенклатура, ТипЦены. Гранулой обмена информации с базой данных является набор записей, подчиненных одному регистратору (табл. 9.9).
Семенов
истина Пульт PX Оптовая
150,00
Семенов
истина Пульт PX Оптовая
155,00
Петров
ТипЦены
■■ все записи в регистрах уникальны с точки зрения комбинации значений в ключевых полях; ■■ добавление, изменение, удаление информации в регистрах производятся «гранулами», представляющими собой наборы записей.
150,00
Номенклатура
Для понимания работы механизмов формирования или модификации записей в таблице регистра сведений необходимо прежде всего исходить из следующих положений:
Активность
В общем случае в таблицу регистра сведений записи могут вводиться пользователем вручную, генерироваться в процессе выполнения обработок либо при поведении документов.
Номер строки
Создание, изменение, удаление записей регистра сведений
истина Пульт PX Оптовая
Активность
Приложение «Хранение данных», раздел «Индексы таблиц базы данных».
1
Номер строки
Подробнее
Изменение цен 16.04.2010 компании 000000001 21:54:41 от 16.04.2010 21:54:41 Изменение цен 16.04.2010 компании 000000001 21:54:41 от 16.04.2010 21:54:41 Изменение цен 16.04.2010 компании 000000001 21:54:41 от 16.04.2010 21:54:41 Изменение цен 16.04.2010 компании 000000001 21:54:41 от 16.04.2010 21:54:41 Изменение цен 16.04.2010 компании 000000001 21:54:41 от 16.04.2010 21:54:41 Изменение цен 18.04.2010 компании 000000002 20:49:26 от 18.04.2010 20:49:26 Изменение цен 18.04.2010 компании 000000002 20:49:26 от 18.04.2010 20:49:26 Изменение цен 18.04.2010 компании 000000002 20:49:26 от 18.04.2010 20:49:26 Изменение цен 18.04.2010 компании 000000002 20:49:26 от 18.04.2010 20:49:26
Регистратор
Также необходимо иметь в виду, что, например, SQL Server накладывает определенное ограничение – не более 16 полей в индексе. Поэтому работа с регистрами, имеющими очень большое количество измерений, может быть неэффективна по скорости из-за невозможности использования индексов.
Период
Измерения, к значениям которых необходим быстрый доступ (например, при реализации отборов), следует располагать первыми, далее – в порядке убывания «популярности в отборах». Таким образом будет обеспечиваться возможность эффективного применения индексов при реализации задач чтения информации из таблицы регистра.
Таблица 9.9. Пример заполнения регистра сведений «ЦеныНоменклатуры»
Период
Вышеприведенное описание структуры индексов позволяет утверждать, что в общем случае порядок расстановки измерений регистра сведений имеет важное значение.
Профессиональная разработка в системе «1С:Предприятие 8»
Хранение информации в регистрах сведений При подобной попытке система выдаст соответствующее предупреждение и не выполнит запись. Это обосновывается требованиями прикладной области, поскольку невозможно одновременно установить для одного и того же товара две разные оптовые цены. В то же время положение о «гранулярности» модификации информации регистра облегчает реализацию операций удаления или модификации данных. Потому что с прикладной точки зрения: ■■ удаление документа Изменение цен компании № 1 должно повлечь за собой удаление всех записей регистра, подчиненных данному документу; ■■ изменение в данных документа при его перепроведении должно повлечь создание нового набора записей (движений документа), который должен полностью заместить старые записи регистра, подчиненные этому документу. Приемы добавления, удаления и модификации движений регистров с режимом записи Подчинение регистратору универсальны. То есть они одинаковы что для подчиненных регистров сведений, что для других видов регистров (накопления, бухгалтерии, расчетов).
Рис. 9.50. Свойство «Основной отбор»
ПРИМЕЧАНИЕ
Нужно помнить о различии ключей записей регистров накопления и регистров сведений. В регистре накопления номер строки входит в ключ записи, поэтому одним документом можно писать одинаковые значения в разные записи. В регистре сведений номер записи не входит в ключ, поэтому одинаковые значения измерений и даты одним документом писать нельзя! Подробно примеры подобных действий описаны в разделах «Свойство «Движения» объекта документа», стр. 552 и «Запись набора записей регистра без использования свойства «Движения»», стр. 560.
В отношении регистров сведений с независимым режимом записи гранулами обмена с базой данных будут наборы записей с установленными отборами по значениям ключевых полей регистра. Кроме того, для некоторых прикладных задач может понадобиться реализация обмена информацией независимых регистров сведений в рамках распределенных баз данных. В таких ситуациях в гранулы обмена между базами данных будут включаться комбинации значений измерений с установленным свойством Основной отбор. Также в основной отбор может включаться поле Период для периодических регистров (рис. 9.50). Например, в состав демонстрационной конфигурации «Хранение информации», которая находится на прилагаемом компакт-диске, входит ПерсонифицированныйПрайс – регистр сведений с независимым режимом записи и периодичностью В пределах дня (рис. 9.51). Том 1
Рис. 9.51. Структура регистра сведений «ПерсонифицированныйПрайс»
С прикладной точки зрения посредством этого регистра руководство компании может указывать информацию об исключительных условиях ценообразования для отдельных покупателей. Причем режим редактирования позволяет заполнять данные этого регистра и вручную, и программно (например, посредством обработки РаспоряжениеНаУстановкуЦенПокупателя). Ключевыми полями для этого регистра будут Период, Покупатель, Номенклатура. Поэтому гранулой модификации может считаться любая комбинация значений этих полей. Например, если для решения некой задачи нам необходимо устанавливать или менять на определенный период для определенного покупателя цены на все номенклатурные позиции сразу, гранулами модификации будут наборы записей, соответствующие комбинациям значений полей Период, Покупатель. Таким образом, данные, хранимые в регистре, можно представить следующим образом (серым фоном в таблице выделены ключевые поля), табл. 9.11.
463
Глава 9. Хранение информации Текст процедуры, вызываемой обработчиком нажатия кнопки Выполнить, представлен в листинге 9.14.
Таблица 9.11. Пример заполнения данными регистра сведений «ПерсонифицированныйПрайс» Период
Гранула «10.04.2009 – 10.04.2009 Компания "Риона"» Гранула «13.09.2009 – 13.09.2009 ЦветМетМаш» 11.01.2010 Гранула «11.01.2010 – 11.01.2010 Компания "Риона"» 11.01.2010 Гранула «10.04.2010 – 10.04.2010 Ялта-Лтд»
Покупатель
Номенклатура
Цена
Компания "Риона"
Монитор 17' Philips 107S20
300,00
&НаКлиенте Процедура ВыполнитьЗаписьВРегистр(Команда)
ЦветМетМаш
Пульт VH
120,00
Компания "Риона" Компания "Риона" Компания "Риона"
Монитор 17' Philips 107S20 Монитор 19' Hitachi CM715ET Монитор LCD 22' M8537ZM/A
290,00 290,00 350,00
КонецПроцедуры
Ялта-Лтд
Мышь 3D-Sensor
4,00
В результате такого гранулирования данные каждой гранулы, то есть наборы записей, соответствующие каждой грануле, можно удалять или замещать целиком. Именно это и реализуется посредством обработки РаспоряжениеНаУстановкуЦенПокупателя, входящей в состав демонстрационной конфигурации «Хранение информации», которая находится на прилагаемом компактдиске. В форме обработки посредством полей ввода пользователь заполняет реквизиты формы ВыбранныйПокупатель и ДатаУстановки. А посредством таблицы Товары, находящейся в форме обработки, можно ввести информацию о том, какие цены, для каких номенклатурных позиций нужно назначить выбранному покупателю на дату установки (рис. 9.52).
Листинг 9.14. Обработчик события нажатия кнопки «Выполнить»
НепосредственнаяЗаписьВРегистр();
Из этого обработчика вызывается серверная процедура наяЗаписьВРегистр(), листинг 9.15.
Непосредствен-
Листинг 9.15. Процедура «НепосредственнаяЗаписьВРегистр»
&НаСервере Процедура НепосредственнаяЗаписьВРегистр() // Создать набор записей, соответствующий грануле // "Период – Покупатель". НаборЗаписей = РегистрыСведений.ПерсонифицированныйПрайс.СоздатьНаборЗаписей(); НаборЗаписей.Отбор.Период.Установить(ДатаУстановки); НаборЗаписей.Отбор.Покупатель.Установить(ВыбранныйПокупатель); // Добавить записи в созданный набор записей. Для Каждого СтрокаТовара Из Товары Цикл НоваяЗапись = НаборЗаписей.Добавить(); НоваяЗапись.Период = ДатаУстановки; НоваяЗапись.Покупатель = ВыбранныйПокупатель; НоваяЗапись.Номенклатура = СтрокаТовара.Номенклатура; НоваяЗапись.Цена = СтрокаТовара.Цена; КонецЦикла;
// Записать набор записей с замещением старого, // соответствующего той же грануле. НаборЗаписей.Записать();
КонецПроцедуры
В процедуре сначала создается набор записей с установкой значений отбора по ключевым полям, то есть по полю Период и по измерению Покупатель. Далее в цикле перебора строк таблицы Товары происходит заполнение записей в созданном наборе записей. После этого сформированный набор записей записывается с замещением старого набора записей регистра, соответствующего той же грануле (у параметра Замещать метода набора записей Записать() значение по умолчанию – Истина). Рис. 9.52. Форма обработки «РаспоряжениеНаУстановкуЦенПокупателя»
464
В результате выполнения обработки (исходные данные см. рис. 9.52) таблица регистра будет содержать следующие данные (табл. 9.12).
Профессиональная разработка в системе «1С:Предприятие 8»
Хранение информации в регистрах сведений Таблица 9.12. Данные регистра сведений «ПерсонифицированныйПрайс» Период
Гранула «10.04.2010 – 10.04.2009 Компания "Риона"» Гранула «13.09.2009 – 13.09.2009 ЦветМетМаш» 11.01.2010 Гранула «11.01.2010 – Компания "Риона"» 11.01.2010 Гранула «10.04.2010 – Ялта-Лтд»
10.04.2010
Покупатель
Компания "Риона"
Номенклатура
Монитор 17' Philips 107S20
Таблица 9.13. Запись с дублирующими значениями ключевых полей Цена
300,00
ЦветМетМаш
Пульт VH
120,00
Компания "Риона"
Монитор 17' Philips 107S20 Монитор 15' LG Studioworks 575N
295,00
Мышь 3D-Sensor
4,00
Компания "Риона" Ялта-Лтд
300,00
Как видите, информация, соответствующая грануле «11.01.2010 – Компания "Риона"», заместилась согласно данным таблицы Товары формы обработки. Необходимо иметь в виду, что для независимого регистра сведений подобное «гранулирование» умозрительное, виртуальное. То есть посредством него можем получить совершенно любой набор записей (главное, чтобы отбор устанавливался по всем ключевым полям или ни по одному из них, и только на равенство). Но не всегда можно будет записать любой набор, т. к. если в отбор включены не все ключевые поля и выполняется добавление, то можно пересечься с существующими значениями ключевых полей. Конечно, выполнение записи набора записей с замещением просто очистит старые записи, с которыми пересекаемся. Но иногда на практике возникают задачи, когда необходимо запретить такое замещение. Допустим, в рассмотренном нами примере обработка РаспоряжениеНаУстановкуЦенПокупателя не должна позволять устанавливать новые цены для покупателя на определенный период по тем номенклатурным позициям, по которым цены уже были установлены ранее. Такое требование достаточно легко реализуемо. Достаточно лишь в той же процедуре установить значение Ложь параметру Замещать метода Записать() набора записей регистра (листинг 9.16). Листинг 9.16. Фрагмент кода
// Записать набор записей с замещением старого, // соответствующего той же грануле. НаборЗаписей.Записать(Ложь);
При попытке выполнения обработки для условий, отображенных выше (см. рис. 9.52), система выдаст предупреждение о том, что запись с такими ключевыми полями уже существует (табл. 9.13), и запись нового набора записей не состоится. Том 1
Период
Покупатель
Номенклатура
11.01.2010
Компания "Риона"
Монитор 17' Philips 107S20
Для ситуаций, когда необходимо замещать все записи независимого регистра сведений новым набором записей, гранулой можно считать весь регистр. Для этого достаточно вообще не устанавливать отбор. То есть для этого в обработке, подобной вышеприведенной, не нужно указывать установки отборов (листинг 9.17). Листинг 9.17. Пример записи набора записей без установки отбора
&НаСервере Процедура НепосредственнаяЗаписьВРегистр() // Создать набор записей. НаборЗаписей = РегистрыСведений.ПерсонифицированныйПрайс.СоздатьНаборЗаписей(); // Добавить записи в созданный набор записей. Для Каждого СтрокаТовара Из Товары Цикл НоваяЗапись = НаборЗаписей.Добавить(); НоваяЗапись.Период = ДатаУстановки; НоваяЗапись.Покупатель = ВыбранныйПокупатель; НоваяЗапись.Номенклатура = СтрокаТовара.Номенклатура; НоваяЗапись.Цена = СтрокаТовара.Цена; КонецЦикла;
// Записать набор записей с замещением старого, соответствующего // той же грануле. НаборЗаписей.Записать();
КонецПроцедуры
Тогда при записи нового набора записей с замещением будут замещены все записи регистра. Для некоторых задач необходимо, чтобы таблица независимого регистра сведений просто полностью очищалась. Такого результата легко добиться следующим образом (листинг 9.18). Листинг 9.18. Пример очистки регистра сведений
НаборЗаписей = РегистрыСведений.ПерсонифицированныйПрайс.СоздатьНаборЗаписей(); НаборЗаписей.Записать();
В некоторых задачах бывает необходимо модифицировать записи, соответствующие неким сложным условиям, причем модификации будут подвергаться и значения ключевых полей. Например, в регистре ПерсонифицированныйПрайс нужно повысить на 20 % цены на все номенклатурные позиции, входящие в группы, в названиях которых упоминаются слово «принтеры», если они стоят меньше 300, и переопределить их на некоего выделенного покупателя. То есть для остальных покупателей таких цен больше быть не должно.
465
Глава 9. Хранение информации подробнее
Пример реализации такой задачи с использованием объекта МенеджерЗаписи регистра сведений приведен в обработке ДействияСДаннымиРегистраСведений демонстрационной конфигурации «Хранение информации», которая находится на прилагаемом компакт-диске.
Рассмотрим этот пример (листинг 9.19). Листинг 9.19. Обработчик события нажатия кнопки «Переопределить на выбранного покупателя цены»
&НаКлиенте Процедура ПовыситьЦены(Команда) ПереопределитьЦеныВРегистре(ВыделенныйПокупатель); КонецПроцедуры
Из обработчика события нажатия кнопки Переопределить на выбранного покупателя цены вызывается серверная процедура ПереопределитьЦеныВРегистре(), листинг 9.20. Листинг 9.20. Процедура «ПереопределитьЦеныВРегистре»
&НаСервереБезКонтекста Процедура ПереопределитьЦеныВРегистре(ВыделенныйПокупатель) // Подготовить менеджер записи. Запись = РегистрыСведений.ПерсонифицированныйПрайс.СоздатьМенеджерЗаписи(); // Получить данные записей, соответствующих условиям. Запрос = Новый Запрос; Запрос.Текст = " |ВЫБРАТЬ | ПерсонифицированныйПрайс.Период, | ПерсонифицированныйПрайс.Покупатель, | ПерсонифицированныйПрайс.Номенклатура, | ПерсонифицированныйПрайс.Цена |ИЗ | РегистрСведений.ПерсонифицированныйПрайс | КАК ПерсонифицированныйПрайс |ГДЕ | ПерсонифицированныйПрайс.Номенклатура.Наименование | ПОДОБНО ""%принтер%"" | И ПерсонифицированныйПрайс.Цена < 300"; Результат = Запрос.Выполнить(); Выборка = Результат.Выбрать(); Пока Выборка.Следующий() Цикл // Установить ключевые поля менеджера записи. Запись.Период = Выборка.Период; Запись.Покупатель = Выборка.Покупатель; Запись.Номенклатура = Выборка.Номенклатура; // Прочитать запись из базы данных. Запись.Прочитать();
466
// Убедиться, что запись все еще есть в базе данных. Если Запись.Выбран() Тогда // Переопределить покупателя. Запись.Покупатель = ВыделенныйПокупатель;
// Установить новую цену. Запись.Цена = Выборка.Цена * 1.2;
// Записать модифицированную запись в базу данных. Запись.Записать(); КонецЕсли; КонецЦикла; КонецПроцедуры
Краткий комментарий: сначала готовится объект манипулирования данными одной записи регистра сведений – менеджер записи. Далее посредством запроса из основной таблицы регистра получаются записи, соответствующие условиям. Обратите внимание: условие по наименованию позволяет получить значения, в которых в любом месте наименования встречается сочетание символов «принтер». В цикле перебора выборки результата запроса устанавливаются значения ключевых полей менеджера записи и производится чтение записи из базы данных. Далее изменяется значение покупателя в записи, а цена в нее устанавливается как увеличенное на 20 % значение цены из выборки. После этого методом Записать() менеджера записи производится непосредственная запись в таблицу базы данных с замещением. Хотелось бы отметить, что в данном примере было рассмотрено использование менеджера записи для программной работы, но объект РегистрСведенийМенеджерЗаписи.<имя> предназначен еще и для обеспечения интерактивной работы с записью регистра сведений. Обязательное условие – регистру сведений в конфигурации должен быть установлен режим записи Независимый (рис. 9.53). Обратите внимание: на схеме отображено, что непосредственные операции обмена информацией с базой данных менеджер записи реализует посредством все тех же объектов манипулирования данными – наборов записей регистра. Их два. Один набор записей – пустой. Он используется для удаления записи со старыми ключевыми значениями. А второй набор записей содержит одну запись – ту, которую нужно записать в регистр. При необходимости у разработчика есть возможность «вмешиваться» в процесс модификации данных регистра посредством использования обработчиков событий. В случае записи новой записи (то есть записи с такими ключевыми полями еще не было) из формы записи регистра сведений последовательность, с которой задействованы обработчики событий, следующая (рис. 9.54). Профессиональная разработка в системе «1С:Предприятие 8»
Хранение информации в регистрах сведений Обратите внимание: ряд событий, выделенных темным фоном, выполняется в одной транзакции. Вследствие этого, если в рамках любого из обработчиков этих событий установить параметру Отказ значение Истина, транзакция будет отменена. То есть новая запись не запишется, да и любые другие изменения в базе данных не выполнятся (ведь в рамках этих обработчиков событий разработчик мог пытаться менять что-то еще). Это важно с точки зрения обеспечения непротиворечивости изменений в информации объектов, связанных единой прикладной задачей. В случае модификации уже существующей записи регистра посредством менеджера записи могут быть изменены значения ключевых полей. А значит, запись набора с новыми ключевыми полями сама по себе не заместит «старый» набор. Поэтому здесь система работает в два этапа: сначала удаляет «старый» набор записей (состоящий из одной «старой» записи), потом уже записывает «новый» (состоящий из «новой» записи), рис. 9.55.
Рис. 9.53. Схема использования менеджера записи регистра сведений
Рис. 9.54. Последовательность событий, вызываемая при записи из формы новой записи регистра сведений
Том 1
Рис. 9.55. Последовательность событий, вызываемая при записи из формы существующей записи регистра сведений
467
Глава 9. Хранение информации Как видно на схеме, удаление «старого» набора записей производится посредством записи пустого набора записей. При этом получается, что обработчики событий (ПередЗаписью и ПриЗаписи) модуля набора записей будут вызываться дважды. Итак, подробно рассмотрены возможности работы посредством менеджера записи. Однако нужно заметить, что и с набором записей также возможна работа в интерактивном режиме (рис. 9.56).
Краткий комментарий: сначала создается структура отбора ЗначениеОтбора со значениями реквизитов формы ВыбранныйПокупатель и ДатаУстановки, затем она добавляется в структуру параметров формы ПараметрыФормы. Эти параметры передаются в форму набора записей регистра сведений ПерсонифицированныйПрайс, и форма открывается с отбором по полям регистра Период и Покупатель, указанным в форме обработки РаспоряжениеНаУстановкуЦенПокупателя. Заметим, что поскольку форма набора записей не является основной формой регистра сведений, она должна быть заранее создана в конфигураторе. Реализацию дальнейших действий пользователя можно доверить самой платформе, поскольку расширения формы набора записей реализуют всю основную функциональность, которая может потребоваться при модификации данных регистра (рис. 9.57).
Рис. 9.56. Схема использования набора записей регистра сведений
подробнее
Пример организации интерактивного ввода приведен в обработке РаспоряжениеНаУстановкуЦенПокупателя, на закладке Посредством формы набора записей. Эта обработка входит в состав демонстрационной конфигурации «Хранение информации», которая находится на прилагаемом компакт-диске.
Рассмотрим этот пример. Пользователь заполняет посредством соответствующих полей ввода реквизиты формы ВыбранныйПокупатель и ДатаУстановки. Далее по нажатии кнопки Открыть форму набора записей форма набора записей регистра сведений открывается с отбором по значениям этих реквизитов (листинг 9.21). Листинг 9.21. Обработчик события нажатия кнопки «Открыть форму набора записей»
&НаКлиенте Процедура ОткрытьФормуНабораЗаписей(Команда) // Открыть форму набора записей с отбором по покупателю и дате // установки цен. ЗначениеОтбора = Новый Структура("Покупатель, Период", ВыбранныйПокупатель, ДатаУстановки); ПараметрыФормы = Новый Структура("Отбор", ЗначениеОтбора); ОткрытьФорму("РегистрСведений.ПерсонифицированныйПрайс.Форма. ФормаНабораЗаписей", ПараметрыФормы) КонецПроцедуры
468
Рис. 9.57. Использование формы обработки «РаспоряжениеНаУстановкуЦенПокупателя»
Если разработчику необходимо изменить эту функциональность, то это возможно сделать за счет использования соответствующих обработчиков событий (рис. 9.58). При работе с формой набора записей регистра сведений порядок, в котором задействованы обработчики событий, не различается для записи нового набора записей и для записи уже существовавшего, но модифицированного набора записей.
Профессиональная разработка в системе «1С:Предприятие 8»
Хранение информации в регистрах сведений Для того чтобы не допустить записи подобной информации в регистр, можно, конечно, выполнять соответствующую проверку в обработчике события ПередЗаписью. Однако, поскольку подобная задача в практике может встречаться не раз, данная проверка добавлена к функциональности платформы. Для того чтобы задействовать ее автоматически, достаточно лишь установить свойство Запрет незаполненных значений у измерения Номенклатура (рис. 9.59).
Рис. 9.58. Последовательность событий при записи в форме набора записей регистра сведений
Дополнительная функциональность при создании и удалении записей регистра сведений Кроме рассмотренных выше основных вопросов организации заполнения и модификации информации регистров сведений хотелось бы еще разобрать ряд вспомогательных, но не менее важных вопросов для организации решения некоторых прикладных задач. Так, для ряда задач важно не допустить записи данных с пустыми значениями разрезов учета.
Рис. 9.59. Свойства измерения «Номенклатура»
Хотелось бы обратить внимание, что данная проверка выполняется именно в момент попытки записи данных в регистр. Если, например, сначала свойство установлено не было и регистр уже заполнился данными записей (среди которых встречаются и записи с пустыми значениями номенклатуры), а потом в конфигурации данное свойство установили, то при реструктуризации базы данных это действие никак не отрабатывается. Запрет касается именно момента и только момента записи данных в регистр. В отношении поля Период для периодических регистров сведений и в отношении поля Регистратор регистра сведений с подчиненным режимом записи подобная проверка выполняется всегда (рис. 9.60).
В рассмотренном выше примере регистра сведений ПерсонифицированныйПрайс с прикладной точки зрения удивительна, например, следующая запись (табл. 9.14). Трактовать ее данные не предоставляется возможным. Таблица 9.14. Пример записи в регистре сведений «ПерсонифицированныйПрайс» Период
Покупатель
20.04.2010 Компания "Риона"
Том 1
Номенклатура
Цена
300,00
Рис. 9.60. Сообщение об ошибке при попытке записи «пустого значения» поля «Период»
469
Глава 9. Хранение информации Другая особенность связана с удалением информации из базы данных. Платформа «1С:Предприятие» допускает непосредственное удаление объектов без контроля ссылочной целостности. Если в результате такой операции будут удалены, например, элементы справочника Номенклатура, ссылки на которые использованы в записях регистра сведений, то информация регистра сведений с прикладной точки зрения может стать некорректной (табл. 9.15). Таблица 9.15. Пример ссылки на отсутствующий объект базы данных Период
Покупатель
Номенклатура
Цена
20.04.2010
Компания "Риона"
<Объект не найден>
300,00
Если разработчик хочет, чтобы подобные ситуации корректно отрабатывались средствами самой платформы, то достаточно для измерения Номенклатура при конфигурировании установить свойство Ведущее. В результате при удалении элемента справочника платформа автоматически удалит все записи регистра сведений, связанные с этим элементом. Кроме того, если для измерения регистра сведений установлено свойство Ведущее, то платформа автоматически поместит команду перехода к списку записей регистра в группу Перейти, в панель навигации формы объекта, соответствующего типу измерения (рис. 9.61). Данная функциональность опять же облегчает быструю разработку прикладных решений.
Получение данных из регистров сведений Только хранение информации как таковое вряд ли требуется при решении прикладных задач. Конечно же, при необходимости всегда подразумевается возможность получения хранимой информации. Можно выделить два больших круга задач, касающихся получения информации из регистров сведений: ■■ получение информации о записях регистра для технологических целей (обычно касающихся именно хранения этой информации); ■■ получение информации «функции» регистра (обычно для решения вопросов, ради которых регистр создавали). Таким образом, например, из рассмотренного выше регистра ПерсонифицированныйПрайс, хранящего цены продажи в разрезах покупателей и номенклатурных позиций, может понадобиться получить информацию для проведения операций манипулирования с этими ценами. Например, повысить на отдельные товары цены на определенный процент. А может понадобиться проведение сравнительного анализа: насколько персональные цены в среднем ниже общефирменных, и как это влияет на вал продаж по отдельным номенклатурным позициям.
Получение данных из непериодических регистров сведений В случае работы с регистрами сведений, у которых отсутствует привязка данных ко времени (непериодические регистры), решение задач обоих типов выполняется непосредственным обращением к записям таблицы базы данных, отвечающей за хранение информации регистра. В зависимости от сложности условий отборов, применяемых при этом, от необходимости соединения информации регистра с информацией других источников, от необходимости использования механизма динамического чтения данных используют или объектную модель представления информации (чтение посредством методов объектов, отвечающих за манипулирование данных регистров), или табличную модель представления информации (обращение к данным посредством запросов, написанных на языке запросов «1С:Предприятия»).
Рис. 9.61. Автоматическое формирование команды перехода к подчиненной информации в группе «Перейти» в панели навигации формы элемента справочника «Номенклатура»
И тот и другой способ обращения выполняется впоследствии за счет одних и тех же запросов СУБД к таблице регистра сведений. Однако, исходя из функциональных возможностей, можно различить ситуации, когда уместнее применять работу с той или иной моделью. Объектная модель обычно применяется: ■■ для чтения данных с простейшими отборами (обязательно только на равенство значению; более того, применяя метод Выбрать(), отбор можно строить только по одному полю);
470
Профессиональная разработка в системе «1С:Предприятие 8»
Хранение информации в регистрах сведений ■■ в случае необходимости применения механизма динамического чтения данных. Посредством этого механизма чтение данных осуществляется по блокам, а не целиком сразу всех; ■■ табличная модель применима во всех случаях, когда не требуется использование механизма динамического чтения данных. Таким образом, посредством запросов можно выбирать данные с отборами какой угодно сложности (как по измерениям, так и по любым другим полям или по подчиненным полям полей записей регистра). Кроме того, при необходимости в том же запросе информацию регистра можно тут же соединять с информацией других источников и/или выполнять дополнительную обработку полученных данных. Рассмотрим несколько примеров, приведенных в обработке ДействияСДаннымиРегистраСведений, в демонстрационной конфигурации «Хранение информации», которая находится на прилагаемом компакт-диске. Для непериодического независимого регистра сведений Сотрудники, все поля которого – ссылки на элементы соответствующих справочников (рис. 9.62), задача перебора всех записей регистра может быть решена так, как показано в листинге 9.22.
Рис. 9.62. Структура регистра «Сотрудники» Листинг 9.22. Пример перебора всех записей регистра
ВыборкаЗаписей = РегистрыСведений.Сотрудники.Выбрать(); Пока ВыборкаЗаписей.Следующий() Цикл // Выполнить действие с очередной записью. // ... КонецЦикла;
Хотелось бы отметить, что по умолчанию дополнительное упорядочивание записей при работе с выборкой не производится (табл. 9.16). Таблица 9.16. Пример результата работы с выборкой Физическое лицо
Иванов Иван Сергеевич Семенов Сергей Петрович Семенов Сергей Петрович Петровский Семен Иванович Петровская Ирина Ивановна
Подразделение
Отдел продаж Отдел продаж Отдел закупок Руководство компании Бухгалтерия
Должность
Руководитель Менеджер Руководитель Руководитель Бухгалтер
В таблице 9.16 по сотруднику «Семенов» видно, что ссылка на отдел продаж указана раньше ссылки на отдел закупок. Хотя порядок мог быть и каким-то другим. Том 1
Теперь рассмотрим задачу получения должности определенного физического лица в определенном подразделении. Это пример задачи на функцию регистра сведений. В качестве параметров передаем значения физического лица и подразделения, в качестве результата функции ожидаем значение должности (листинг 9.23). Листинг 9.23. Пример получения должности физического лица
// Подготовить структуру отбора по измерениям. СтруктураОтбора = Новый Структура; СтруктураОтбора.Вставить("ФизическоеЛицо", ПроверяемоеЛицо); СтруктураОтбора.Вставить("Подразделение", ВыбранноеПодразделение); // Получить структуру с данными ресурсов записи. СтруктураРесурсов = РегистрыСведений.Сотрудники.Получить(СтруктураОтбора); // Сообщить занимаемую должность. Должность = СтруктураРесурсов.Должность; Сообщение = Новый СообщениеПользователю; Если Должность.Пустая() Тогда Сообщение.Текст = "В этом подразделении не работает"; Иначе Сообщение.Текст = Должность.Наименование; КонецЕсли; Сообщение.Сообщить();
Обратите внимание: для метода Получить() обязательна передача параметра, содержащего структуру отбора значений по всем измерениям непериодического регистра. Результатом применения метода является структура, в которой для каждого элемента ключом будет название ресурса регистра, а значением – значение ресурса из найденной записи регистра. Следующая задача – проверить, работает ли в компании определенное физическое лицо. И если работает, выполнить некоторые действия с записью по этому сотруднику. Допустим, ссылка на проверяемое физическое лицо будет в переменной ПроверяемоеЛицо. Тогда решение можно реализовать следующим образом (листинг 9.24). Листинг 9.24. Пример проверки наличия записи по физическому лицу в регистре сведений
// Подготовить структуру отбора по измерению "ФизическоеЛицо". СтруктураОтбора = Новый Структура("ФизическоеЛицо", ПроверяемоеЛицо); // Получить выборку с отбором. ВыборкаЗаписей = РегистрыСведений.Сотрудники.Выбрать(СтруктураОтбора); // Выполнить действия. Пока ВыборкаЗаписей.Следующий() Цикл // Выполнить действия с записью. // ... КонецЦикла;
471
Глава 9. Хранение информации В данном примере применялся отбор по значению измерения регистра. Вообще в качестве полей для отбора могут использоваться измерения или реквизиты регистра, для которых в конфигураторе установлен признак индексирования в значение Индексировать или установлен признак Ведущее. Но необходимо помнить, что отбор при этом возможен только на равенство и только по одному полю. Рассмотренные задачи также могли быть решены и посредством соответствующих запросов. Рассмотрим ряд задач, когда применение запросов более уместно, нежели применение объектной модели. Доступ к информации таблицы регистра в базе данных осуществляется посредством основной таблицы регистра сведений. ПРИМЕЧАНИЕ
Состав ее полей соответствует составу полей таблицы регистра сведений в базе данных (можно посмотреть в разделе «Структура регистра сведений», стр. 459).
Допустим, требуется сообщить наименования физических лиц, упомянутых в записях регистра сведений Сотрудники. Условие – в наименовании должностей этих лиц должно быть слово «Руководитель». Эта задача может быть решена следующим образом (листинг 9.25). Листинг 9.25. Пример получения физических лиц, в наименовании должностей которых присутствует слово «Руководитель»
// Получить перечень нужных физических лиц. Запрос = Новый Запрос; Запрос.Текст = "ВЫБРАТЬ РАЗЛИЧНЫЕ | Сотрудники.ФизическоеЛицо.Наименование КАК ФизЛицо |ИЗ | РегистрСведений.Сотрудники КАК Сотрудники |ГДЕ | Сотрудники.Должность.Наименование ПОДОБНО ""%Руководитель%"""; // Перебрать и сообщить полученный список. Результат = Запрос.Выполнить(); Выборка = Результат.Выбрать(); Пока Выборка.Следующий() Цикл Сообщение = Новый СообщениеПользователю; Сообщение.Текст = Выборка.ФизЛицо; Сообщение.Сообщить(); КонецЦикла;
Краткий комментарий: в запросе выбираем неповторяющиеся наименования всех физических лиц из таблицы регистра, если наименования должностей в этих записях содержат набор символов «Руководитель»
472
(в любом месте наименования). Далее выборка результата запроса перебирается, и в цикле сообщается полученная информация. Попытка решения этой задачи посредством выборки была бы грубой методической ошибкой: ■■ во-первых, выборка не может строиться с отбором по значениям ресурсов. То есть перебирать пришлось бы все записи регистра; ■■ во-вторых, условие отбора устанавливается не по значению поля Должность, а по наличию в наименовании этой должности сочетания символов «Руководитель». То есть такая проверка в цикле перебора записей регистра привела бы к необходимости применения запроса СУБД к таблице данных справочника Должности. И это на каждом шаге цикла! ■■ в-третьих, сообщать нужно наименования физических лиц. То есть при выполнении условия проверки для каждой подходящей записи регистра системе пришлось бы еще обращаться посредством запроса СУБД к таблице справочника ФизическиеЛица для считывания наименования элемента, соответствующего нужной ссылке. Таким образом, решение посредством объектной модели привело бы к многочисленным обращениям к таблицам базы данных (на каждом шаге цикла перебора всех записей регистра). Решение же посредством запроса будет реализовано системой за счет левых соединений таблиц регистра и двух справочников, но за одно обращение к базе данных. Не говоря уже о том, что выборка результата запроса будет меньше выборки всех записей регистра. Следующая задача – сообщить, сколько подразделений компании задействовано в регистре Сотрудники. Эта задача может быть решена посредством следующего запроса (листинг 9.26). Листинг 9.26. Пример получения количества задействованных подразделений
// Установить исходно, что подразделений нет. КоличествоПодразделений = 0; // Посчитать количество "непустых" подразделений в записях регистра. Запрос = Новый Запрос; Запрос.Текст = "ВЫБРАТЬ | КОЛИЧЕСТВО(РАЗЛИЧНЫЕ Сотрудники.Подразделение) | КАК КоличествоПодразделений |ИЗ | РегистрСведений.Сотрудники КАК Сотрудники |ГДЕ | Сотрудники.Подразделение <> &ПустоеПодразделение"; Запрос.УстановитьПараметр("ПустоеПодразделение", Справочники.Подразделения.ПустаяСсылка()); Результат = Запрос.Выполнить(); Выборка = Результат.Выбрать(); Если Выборка.Следующий() Тогда КоличествоПодразделений = Выборка.КоличествоПодразделений; КонецЕсли;
Профессиональная разработка в системе «1С:Предприятие 8»
Хранение информации в регистрах сведений // Сообщить полученные результаты. Сообщение = Новый СообщениеПользователю; Сообщение.Текст = Строка(КоличествоПодразделений); Сообщение.Сообщить();
В данном случае применен запрос, вычисляющий количество упоминаний различных подразделений в соответствующем поле записей регистра. При этом записи с незаполненным полем Подразделение не учитываются. Если выборка запроса будет непустой (есть записи), то исходное нулевое количество подразделений заменяется на определенное в запросе. В данном случае продемонстрирована возможность применения агрегатных функций (КОЛИЧЕСТВО()) при чтении информации регистра запросом. Следующая задача – получить список «внутренних совместителей» с предоставлением информации, в каких отделах, на каких должностях они работают. Внутренними совместителями называются физические лица, занимающие несколько должностей или в одном, или в различных подразделениях предприятия. Данная задача может быть решена посредством применения запроса со следующим текстом (листинг 9.27). Листинг 9.27. Пример получения списка внутренних совместителей
Запрос = Новый Запрос; Запрос.Текст = "ВЫБРАТЬ | Сотрудники.ФизическоеЛицо.Наименование КАК ФизЛицо, | Сотрудники.Подразделение КАК Подразделение, | Сотрудники.Должность КАК Должность |ИЗ | РегистрСведений.Сотрудники КАК Сотрудники |ГДЕ | Сотрудники.ФизическоеЛицо В | (ВЫБРАТЬ | Сотрудники.ФизическоеЛицо КАК ФизЛицо | ИЗ | РегистрСведений.Сотрудники КАК Сотрудники | СГРУППИРОВАТЬ ПО | Сотрудники.ФизическоеЛицо | ИМЕЮЩИЕ | КОЛИЧЕСТВО(Сотрудники.ФизическоеЛицо) > 1)"; Результат = Запрос.Выполнить(); Выборка = Результат.Выбрать(); Пока Выборка.Следующий() Цикл Сообщение = Новый СообщениеПользователю; Сообщение.Текст = Выборка.ФизЛицо + " " + Выборка.Подразделение + " " + Выборка.Должность; Сообщение.Сообщить(); КонецЦикла;
Том 1
В запросе выбирается информация по всем записям регистра, где упоминаются физические лица, соответствующие условию. Условие проверяет вхождения физических лиц в перечень, полученный вложенным запросом. Во вложенном запросе применяется группирование с применением агрегатной функции КОЛИЧЕСТВО() по полю ФизическоеЛицо, при этом условием будут отсечены те физлица, которые упоминались только один раз.
Получение данных из периодических регистров сведений Для периодических регистров сведений задачи получения информации для технологических вопросов решаются так же, как и было рассмотрено выше для непериодических регистров. Поэтому все примеры, рассмотренные в разделе «Получение данных из непериодических регистров сведений» (см. стр. 470), будут уместны и в этом случае. Единственное отличие в том, что к перечню ключевых полей добавляется поле Период, которое можно использовать в отборах. Так, метод Выбрать() для случая периодического регистра позволяет работать не только с отбором по значению измерения, но и с отбором по временному интервалу, в который могут попадать значения поля Период. Рассмотрим примеры получения информации из периодического (периодичность – В пределах дня) независимого регистра сведений ПерсонифицированныйПрайс (рис. 9.63).
Рис. 9.63. Структура регистра «ПерсонифицированныйПрайс»
Для получения выборки всех записей регистра в интервале дат между значениями, содержащимися в переменных НачалоИнтервала и КонецИнтервала, с отбором по номенклатурной позиции (содержится в переменной ВыбранныйТовар) можно использовать следующий фрагмент кода (листинг 9.28). Листинг 9.28. Пример получения записей периодического регистра сведений
// Подготовить структуру отбора по измерению "Номенклатура". СтруктураОтбора = Новый Структура("Номенклатура", ВыбранныйТовар); // Получить выборку записей. ВыборкаЗаписей = РегистрыСведений.ПерсонифицированныйПрайс.Выбрать(НачалоИнтервала, КонецИнтервала, СтруктураОтбора); Пока ВыборкаЗаписей.Следующий() Цикл
// Выполнить действие с очередной записью. // ...
КонецЦикла;
473
Глава 9. Хранение информации Необходимо помнить, что отбор при этом возможен только по одному полю и в качестве полей для отбора могут использоваться измерения или реквизиты регистра, для которых в конфигураторе установлен признак индексирования в значение Индексировать или установлен признак Ведущее.
Получение данных в этом случае можно проиллюстрировать следующей схемой (рис. 9.65).
Кроме того, для реализации необходимости включения/выключения записей «граничных периодов» нужно иметь в виду следующее: ■■ в параметр НачалоИнтервала передается начало интервала, в котором будут выбираться записи периодического регистра. Он может задаваться значениями типа Дата, МоментВремени, Граница. Если значение данного параметра не указано, то будут выбираться записи с самой ранней включительно; ■■ в параметр КонецИнтервала передается конец интервала, в котором будут выбираться записи периодического регистра. Он также может задаваться значениями типа Дата, МоментВремени, Граница. Если значение данного параметра не указано, то будут выбираться записи по самую последнюю включительно. В результате при передаче значений типа Дата или МоментВремени в выборку получим записи, включая значения НачалоИнтервала и КонецИнтервала (рис. 9.64).
Рис. 9.65. Получение записей, исключая граничные значения
Кроме того, если периодичность регистра меньше чем день (В пределах секунды или По позиции регистратора), то необходимо помнить, что дата в системе «1С:Предприятие» включает в себя и время. Даже если время не указано явно, оно принимает значение 00:00:00. То есть если в качестве параметра НачалоИнтервала передать значение «1 декабря 2009 года» (данное значение может быть получено так: '20091201'), а в качестве параметра КонецИнтервала передать «31 декабря 2009 года» ('20091231'), то в результате выборка будет построена с даты «01.12.2009 00:00:00» по дату «31.12.2009 00:00:00». То есть в результат, по сути, не войдут данные 31 декабря (рис. 9.66).
Рис. 9.64. Получение записей, включая граничные значения
Если же требуется получить записи, исключая граничные, то необходимо использовать объект Граница. Например, получение выборки в интервале дат, исключая границы, может быть выполнено следующим образом (листинг 9.29). Листинг 9.29. Пример получения записей регистра сведений
// Установить значения границ. ГраницаНачалаИнтервала = Новый Граница(НачалоИнтервала, ВидГраницы.Исключая); ГраницаКонцаИнтервала = Новый Граница(КонецИнтервала, ВидГраницы.Исключая); // Подготовить структуру отбора по измерению "Номенклатура". СтруктураОтбора = Новый Структура("Номенклатура", ВыбранныйТовар); // Получить выборку записей. ВыборкаЗаписей = РегистрыСведений.ПерсонифицированныйПрайс.Выбрать(ГраницаНачалаИнтервала, ГраницаКонцаИнтервала, СтруктураОтбора); Пока ВыборкаЗаписей.Следующий() Цикл
// Выполнить действие с очередной записью. // ...
КонецЦикла;
474
Рис. 9.66. Пример получения данных регистра сведений, когда интервал задан без явного указания времени
Для предотвращения возможных недоразумений по этому поводу удобно использовать функцию КонецДня(). Эта функция возвращает значение последней секунды дня, указанной в качестве параметра даты (листинг 9.30). Листинг 9.30. Пример использования функции «КонецДня()»
// Определить конец дня "правой" границы. КонецДняИнтервала = КонецДня(КонецИнтервала); // Получить выборку записей. ВыборкаЗаписей = РегистрыСведений.ЦеныНоменклатуры.Выбрать(НачалоИнтервала, КонецДняИнтервала); Пока ВыборкаЗаписей.Следующий() Цикл // Выполнить действие с очередной записью. // ... КонецЦикла;
Профессиональная разработка в системе «1С:Предприятие 8»
Хранение информации в регистрах сведений В результате будут получены записи с даты «01.12.2009 00:00:00» по дату «31.12.2009 23:59:59» включительно. При использовании запроса можно реализовывать не только перечисленные выше, но и гораздо более сложные условия, в том числе и по полю Период. Например, задача получения выборки данных всех записей регистра ПерсонифицированныйПрайс, которые датированы выходными днями (субботами и воскресениями), может быть решена посредством следующего запроса (листинг 9.31).
Часто встречаются задачи, в которых каждая запись периодического регистра сведений используется не как средство для хранения данных, а как средство для хранения информации истории изменения данных. Ведь в рассмотренном выше примере, если цена на товар для этого покупателя была установлена не на эту дату, а на какую-то другую, метод Получить() вернет структуру с пустыми значениями (рис. 9.67).
Листинг 9.31. Пример запроса
ВЫБРАТЬ ПерсонифицированныйПрайс.Период, ПерсонифицированныйПрайс.Покупатель, ПерсонифицированныйПрайс.Номенклатура, ПерсонифицированныйПрайс.Цена ИЗ РегистрСведений.ПерсонифицированныйПрайс КАК ПерсонифицированныйПрайс ГДЕ ДЕНЬНЕДЕЛИ(ПерсонифицированныйПрайс.Период) > 5
В запросе было применено условие с использованием функции работы с датами языка запросов – ДЕНЬНЕДЕЛИ(). Данная функция возвращает порядковые номера дней недели по переданному параметру. Рассмотрим примеры задач получения информации из периодического регистра сведений не в технологических целях, а для обслуживания задач учетных или аналитических механизмов. Если необходимо получить информацию значений ресурсов одной записи регистра, соответствующей указанным в параметрах значениям всех измерений и периода, объектная модель получения информации также позволяет использовать метод Получить().
Рис. 9.67. Пример использования метода «Получить()» для периодического регистра сведений
С прикладной точки зрения в ситуации, отображенной на схеме, при обращении к данным регистра пользователь, скорее всего, хотел получить актуальное для 12.10.2009 значение цены, а не установленное 12.10.2009. То есть в логике пользователя как само собой разумеющееся может лежать правило: «пока цена не сменилась, действует прежняя». И при обращении к данным регистра пользователь желает получить цену, установленную на некую дату, а если не установлена, то прежнюю, в общем случае – последнюю установленную.
Например, нужно сообщить, какую цену установили для покупателя Покупатель по номенклатурной позиции Товар, начиная с ДатаУстановки (листинг 9.32).
Для реализации подобной логики в функциональности периодического регистра сведений существует метод ПолучитьПоследнее(). Для тех же переменных получение последних актуальных данных может быть таким (листинг 9.33).
Листинг 9.32. Пример получения цен по номенклатурной позиции
Листинг 9.33. Пример использования метода «ПолучитьПоследнее()»
// Подготовить структуру отбора по измерениям. СтруктураОтбора = Новый Структура; СтруктураОтбора.Вставить("Покупатель", Покупатель); СтруктураОтбора.Вставить("Номенклатура", Товар);
// Подготовить структуру отбора по измерениям. СтруктураОтбора = Новый Структура; СтруктураОтбора.Вставить("Покупатель", Покупатель); СтруктураОтбора.Вставить("Номенклатура", Товар);
// Получить структуру с данными ресурсов записи. СтруктураРесурсов = РегистрыСведений.ПерсонифицированныйПрайс.Получить(ДатаУстановки, СтруктураОтбора); // Сообщить цену. Сообщение = Новый СообщениеПользователю; Сообщение.Текст = Строка(СтруктураРесурсов.Цена); Сообщение.Сообщить();
// Получить структуру с данными актуальных значений ресурсов. СтруктураРесурсов = РегистрыСведений.ПерсонифицированныйПрайс. ПолучитьПоследнее(ДатаУстановки, СтруктураОтбора); // Сообщить "последнюю" цену. Сообщение = Новый СообщениеПользователю; Сообщение.Текст = Строка(СтруктураРесурсов.Цена); Сообщение.Сообщить();
Том 1
475
Глава 9. Хранение информации В результате получим желаемый результат (рис. 9.68).
В ходе выполнения метода СрезПоследних() платформа «1С:Предприятие» фактически выполняет запрос к базе данных. Данный запрос реализует следующий алгоритм: 1. Выбрать записи таблицы регистра, соответствующие условиям отбора по значениям измерений, у которых значение поля Период меньше или равно значению параметра КонецПериода. 2. По выбранным записям получить максимальные значения поля Период для каждой комбинации значений полей измерений. Это будут данные вложенного запроса. Получается, что в нем известны ключи последних актуальных записей, то есть наиболее близких к дате среза. 3. Соединить таблицу вложенного запроса с основной таблицей регистра по равенству значений полей измерений и поля Период.
Рис. 9.68. Пример использования метода «ПолучитьПоследнее()»
Может встретиться задача, когда пользователь заранее не знает, для каких комбинаций значений измерений ему требуется получить данные последних актуальных (на дату КонецПериода) значений ресурсов регистра. То есть хочет получить все значения для всех комбинаций измерений (или для некоторых, соответствующих условиям отбора), рис. 9.69.
Рис. 9.69. Задача получения последних значений по комбинации значений измерений
Для решения подобных задач можно использовать метод СрезПоследних(), возвращающий таблицу значений, заполненную данными записей, наиболее поздних, ближайших к дате среза (КонецПериода), табл. 9.17. Таблица 9.17. Результат получения среза последних Покупатель
Номенклатура Цена
ООО «Сигма» ООО «Сигма» Ялта-ЛТД
Пульт VX Пульт PW Пульт VX
476
120,00 218,00 135,00
4. Из полученной таблицы получить интересующие данные последних актуальных записей. Подобную функциональность можно реализовать запросом по основной таблице периодического регистра сведений (листинг 9.34). Листинг 9.34. Пример получения среза последних запросом
ВЫБРАТЬ ПерсонифицированныйПрайс.Покупатель, ПерсонифицированныйПрайс.Номенклатура, ПерсонифицированныйПрайс.Цена ИЗ (ВЫБРАТЬ ПерсонифицированныйПрайс.Покупатель КАК Покупатель, ПерсонифицированныйПрайс.Номенклатура КАК Номенклатура, МАКСИМУМ(ПерсонифицированныйПрайс.Период) КАК Период ИЗ РегистрСведений.ПерсонифицированныйПрайс КАК ПерсонифицированныйПрайс ГДЕ ПерсонифицированныйПрайс.Период <= &КонецПериода // Указать другие условия отбора при необходимости. СГРУППИРОВАТЬ ПО ПерсонифицированныйПрайс.Покупатель, ПерсонифицированныйПрайс.Номенклатура) КАК ВложенныйЗапрос ВНУТРЕННЕЕ СОЕДИНЕНИЕ РегистрСведений.ПерсонифицированныйПрайс КАК ПерсонифицированныйПрайс ПО ВложенныйЗапрос.Покупатель = ПерсонифицированныйПрайс.Покупатель И ВложенныйЗапрос.Номенклатура = ПерсонифицированныйПрайс.Номенклатура И ВложенныйЗапрос.Период = ПерсонифицированныйПрайс.Период
Поскольку задачи получения среза последних встречаются достаточно часто, система «1С:Предприятие» позволяет использовать виртуальную таблицу получения среза последних, которая реализует описанный выше алгоритм.
Профессиональная разработка в системе «1С:Предприятие 8»
Хранение информации в регистрах сведений То есть вместо использования запроса по основной таблице регистра разработчик для получения среза может воспользоваться запросом, например, следующего вида (листинг 9.35). Как видите, текст запроса значительно проще. Листинг 9.35. Пример использования виртуальной таблицы «СрезПоследних»
ВЫБРАТЬ СрезЦен.Покупатель, СрезЦен.Номенклатура, СрезЦен.Цена ИЗ РегистрСведений.ПерсонифицированныйПрайс.СрезПоследних(&КонецПериода, ) КАК СрезЦен
Таким образом, за счет использования виртуальных таблиц разработчик работает сразу с производными данными, необходимыми для решения прикладных задач. А тонкости организации оптимального получения этих данных обеспечиваются системой. Что же за данные можно получить посредством виртуальной таблицы среза последних? Практически все, которые касаются записей. Виртуальная таблица СрезПоследних содержит следующие поля: ■■ Период – это поле имеет тип Дата. Содержит период, к которому относится запись регистра; ■■ Регистратор – это поле имеет тип ДокументСсылка.<имя>. Существует только в случаях, если периодичность регистра – По позиции регистратора. Данное поле содержит ссылку на документ-регистратор, к которому относится запись регистра; ■■ НомерСтроки – это поле имеет тип Число. Существует только в случаях, если периодичность регистра – По позиции регистратора. Содержит значение поля НомерСтроки записи движения регистра; ■■ Активность – это поле имеет тип Булево. Существует только в случаях, если периодичность регистра – По позиции регистратора. Содержит признак активности записи, то есть влияния на получение среза последних (или среза первых); ■■ <Измерение> – тип значения этого поля определяется типом измерения. Каждое из таких полей содержит значение измерения регистра. Имена полей совпадают с именами измерений, заданными для объекта конфигурации; ■■ <Ресурс> – тип значения этого поля определяется типом ресурса. Каждое из таких полей содержит значение ресурса регистра. Имена полей совпадают с именами ресурсов, заданными для объекта конфигурации; ■■ <Реквизит> – тип значения этого поля определяется типом реквизита. Каждое из таких полей содержит значение реквизита регистра. Имена полей совпадают с именами реквизитов, заданными для объекта конфигурации. Том 1
Виртуальная таблица среза последних не хранится в базе данных, а строится в момент обращения к ней. Поэтому при использовании ее в запросах поддерживается весьма гибкая функциональность за счет использования параметров: ■■ Дата – имеет тип Дата, МоментВремени или Граница. Если параметр не задан, будут выбираться наиболее поздние записи, то есть без ограничения по времени; ■■ Условие – содержит конструкцию языка запросов – условие. Строится по любым полям регистра сведений (или подчиненным им полям). Используется для ограничения состава исходных записей, по которым при построении виртуальной таблицы будет выполняться срез. Если параметр не указан, будут использоваться все активные записи регистра. Например, соответствующее применение условий в запросах с использованием виртуальных таблиц позволяет легко решать задачи отбора информации так, как это потребуется. Рассмотрим несколько примеров для периодического регистра сведений ЦеныНоменклатуры (рис. 9.70).
Рис. 9.70. Структура регистра «ЦеныНоменклатуры»
Рассмотрим следующую задачу: требуется получить информацию о том, по каким товарам на текущий момент есть цены ниже 100, кто за это ответственен, и когда он установил такую цену. Задача может быть решена следующим образом (листинг 9.36). Листинг 9.36. Пример получения данных из периодического регистра сведений
ВЫБРАТЬ ЦеныНоменклатурыСрезПоследних.Период, ЦеныНоменклатурыСрезПоследних.Номенклатура, ЦеныНоменклатурыСрезПоследних.ТипЦены, ЦеныНоменклатурыСрезПоследних.Цена, ЦеныНоменклатурыСрезПоследних.Ответственный ИЗ РегистрСведений.ЦеныНоменклатуры.СрезПоследних КАК ЦеныНоменклатурыСрезПоследних ГДЕ ЦеныНоменклатурыСрезПоследних.Цена < 100
Обратите внимание: в постановке задачи акцент ставился на текущие цены. Поэтому в запросе сначала выполняется срез последних, а потом в таблице среза определяются записи, в которых цена ниже 100.
477
Глава 9. Хранение информации То есть если когда-то на какой-то товар была низкая цена, но на текущий момент положение исправлено (установлена цена выше 100), то «никого за это наказывать не будем».
Также возможна ситуация, когда нужны данные среза всех первых следующих записей регистра (рис. 9.72).
Рассмотрим другую задачу: требуется получить информацию, по каким товарам вообще когда-нибудь устанавливались цены ниже 100, кто ответственен за последние назначения таких цен, и когда они выполнялись. Возможно следующее решение (листинг 9.37). Листинг 9.37. Пример получения данных из регистра сведений
ВЫБРАТЬ ЦеныНоменклатурыСрезПоследних.Период, ЦеныНоменклатурыСрезПоследних.Номенклатура, ЦеныНоменклатурыСрезПоследних.ТипЦены, ЦеныНоменклатурыСрезПоследних.Цена, ЦеныНоменклатурыСрезПоследних.Ответственный ИЗ РегистрСведений.ЦеныНоменклатуры.СрезПоследних(, Цена < 100) КАК ЦеныНоменклатурыСрезПоследних
В данном случае акцент сделан на записях регистра, в которых цена ниже 100. А вот уже для записей, соответствующих этому условию, будет произведен срез последних. То есть в данном случае отвечать будет последний, кто устанавливал низкие цены, даже если на текущий момент цена на этот товар уже совсем другая. Рассмотренная выше функциональность получения среза последних для периодического регистра, но только уже «с другим знаком», легко получается за счет применения методов ПолучитьПервое(), СрезПервых() и виртуальной таблицы СрезПервых. Для таких задач важны данные записей, соответствующих точке среза, или первых следующих после нее в истории изменения информации регистра. Например, для ситуации, когда нужны данные по конкретной комбинации значений измерений (рис. 9.71).
Рис. 9.72. Получение среза первых
По аналогии с работой в отношении получения последних актуальных приемы получения первых следующих абсолютно те же, только меняются название методов и виртуальной таблицы. Задача получения первых следующих записей заключается в том, чтобы найти записи с минимальным периодом среди тех записей, период которых равен или больше, чем указываемый параметр среза. Соответственно, если параметр среза (НачалоПериода или Дата) не указан, срез будет производиться по значению даты по умолчанию, то есть «01.01.01 00:00:00». А значит, в срез попадут самые первые по хронологии записи таблицы регистра.
Особенности получения данных из регистров сведений с режимом записи «Подчинение регистратору» Установка режима записи Подчинение регистратору означает добавление к физической таблице регистра сведений в базе данных ряда предопределенных полей: ■■ Регистратор, ■■ НомерСтроки, ■■ Активность. Кроме того, как было рассмотрено выше, для таких регистров невозможно наличие записей без ссылки на документ-регистратор. Данные особенности играют свою роль при получении информации из регистра. Для быстрого получения информации наборов записей, подчиненных некоему регистратору, имеются возможности использования объектной модели представления данных – метод ВыбратьПоРегистратору().
Рис. 9.71. Получение первых данных по комбинации значений измерений
478
Например, если ссылка на нужный документ хранится в переменной ДокументРегистратор, то получить записи регистра можно с помощью следующего кода (листинг 9.38). Профессиональная разработка в системе «1С:Предприятие 8»
Хранение информации в регистрах сведений Листинг 9.38. Пример получения данных из регистра сведений, подчиненного регистратору
ВыборкаДвиженийДокумента = РегистрыСведений.ЦеныНоменклатуры. ВыбратьПоРегистратору(ДокументРегистратор); Пока ВыборкаДвиженийДокумента.Следующий() Цикл
// Выполнить действие с очередной записью движения. // ...
КонецЦикла;
Аналогичного результата можно добиться, используя соответствующий отбор в запросе (листинг 9.39). Листинг 9.39. Пример получения данных регистра сведений запросом
Запрос = Новый Запрос; Запрос.Текст = " |ВЫБРАТЬ | * |ИЗ | РегистрСведений.ЦеныНоменклатуры КАК ЦеныНоменклатуры |ГДЕ | ЦеныНоменклатуры.Регистратор = &РегистраторОтбора"; Запрос.УстановитьПараметр("РегистраторОтбора", ДокументРегистратор); Результат = Запрос.Выполнить(); Выборка = Результат.Выбрать();
Листинг 9.41. Пример получения данных регистра сведений
ВЫБРАТЬ РАЗЛИЧНЫЕ ЦеныНоменклатуры.Регистратор ИЗ РегистрСведений.ЦеныНоменклатуры КАК ЦеныНоменклатуры ГДЕ (НЕ ЦеныНоменклатуры.Активность)
Важно помнить, что для получения срезов первых и срезов последних система использует только те записи, поле Активность которых имеет значение Истина. Снять или установить активность можно только для всех записей набора записей, подчиненных некоему регистратору. Таким образом, реализуется прикладная задача: при необходимости можно сделать документ «неиграющим» без удаления его движений. Но поскольку документ с прикладной точки зрения – это регистрация события, то отключение влияния события может выполняться только полностью для всех записей, принадлежащих данному документу. ПРИМЕЧАНИЕ
В остальном примеры и возможности получения данных из регистра сведений, описанные в разделах «Получение данных из непериодических регистров сведений» (см. стр. 470) и «Получение данных из периодических регистров сведений» (см. стр. 473), вполне применимы и для регистров сведений, подчиненных регистратору.
Пока Выборка.Следующий() Цикл
Проектирование структуры регистров сведений
Как было рассмотрено ранее, регистр сведений может содержать несколько измерений, ресурсов и реквизитов.
// Выполнить действие с очередной записью движения. // ...
КонецЦикла;
В ряде задач может оказаться полезным использование полей Активность и НомерСтроки. Например, рассмотрим задачу получения перечня «длинных» документов (которым, например, подчинено более 100 записей в движениях по регистру). Данная задача может быть решена посредством применения следующего запроса (листинг 9.40). Листинг 9.40. Пример получения данных из регистра сведений
ВЫБРАТЬ РАЗЛИЧНЫЕ ЦеныНоменклатуры.Регистратор ИЗ РегистрСведений.ЦеныНоменклатуры КАК ЦеныНоменклатуры ГДЕ ЦеныНоменклатуры.НомерСтроки > 100
Рассмотрим другую задачу: требуется получить перечень документов с неактивными записями. Эта задача может быть решена посредством следующего запроса (листинг 9.41). Том 1
Зачастую у разработчиков при проектировании прикладных решений возникает вопрос: «Что лучше? Создать несколько регистров с большим количеством ресурсов или, наоборот, создать много регистров, но с меньшим количеством ресурсов?». В общем случае единого ответа на этот вопрос нет. Для того чтобы облегчить принятие решения в каждой конкретной ситуации, приведем несколько моментов, на которые следует обращать внимание при проектировании регистров сведений. Структурный подход. Каждая запись в регистре сведений содержит информацию о том, что для данной комбинации ключевых полей установлены некоторые значения ресурсов. В том числе и в периодическом регистре сведений. То есть если запись добавляется или модифицируется, это выполняется для всех значений ресурсов. Нельзя отметить, что, начиная с такого-то момента, значение такого-то ресурса не меняется, а меняются только значения других ресурсов.
479
Глава 9. Хранение информации Восприятие пользователем. При проектировании регистра важно проанализировать, как реально меняются значения данных, которые будут храниться в регистре, и выработать определенную модель отражения этих изменений в базе данных. Важно, чтобы отражение предметной области в регистре правильно воспринималось пользователем. Например, при хранении информации о курсах валют приходится иметь дело с информацией о курсе и кратности каждой валюты (24 рубля за 100 японских йен – курс 24, кратность 100). Курс Центробанка меняется ежедневно, кратность… ну, наверное, один раз в несколько десятков лет. То есть если исходить из «накладных затрат» на выполнение операций с этой информацией в регистре, то напрашивается решение о разделении ее на два регистра: КурсыВалют и КратностиВалют. Однако с точки зрения восприятия информации пользователем данные о курсе отдельно от данных о кратности – это нонсенс. Ну а поскольку работать с курсом и кратностью всегда придется одновременно, то проще реализовать задачу одним регистром с двумя ресурсами. Учет потенциальных модификаций состава регистра. Как обсуждалось выше, состав существующего регистра сведений всегда можно расширить. Одним из направлений расширения является ввод новых разрезов информации, то есть измерений. Например, принимая решение по добавлению ресурса ПредпочитаемыйЦвет, в котором будет содержаться информация о том, какого цвета товары предпочитает покупатель, для регистра ПерсонифицированныйПрайс (рис. 9.73) желательно заранее уточнить, а не потребуется ли впоследствии добавить к такому регистру измерение Договор для более детального учета обещанных покупателю отпускных цен.
Рис. 9.73. Структура регистра «ПерсонифицированныйПрайс»
Если потребуется, то лучше будет все же разделить информацию между несколькими регистрами. В одном будет храниться информация о каких-то качественных пожеланиях покупателей, в другом – информация о ценах с другим уровнем детализации. Время получения данных, необходимых для работы механизмов решения. Например, при работе некоторого механизма важно получать данные объекта и данные, связанные с данным объектом. Очевидно, что получение этих связанных данных из нескольких ресурсов одного регистра (одной таблицы) будет происходить в общем случае быстрее, нежели получение этих данных из нескольких регистров (нескольких таблиц).
480
Время записи информации в базу данных. Запись в несколько регистров сведений в общем случае будет выполняться медленнее, нежели запись одной записи с несколькими ресурсами. «Слабое звено». Если данные одного из ресурсов нужно модифицировать очень часто, то объем базы будет расти существеннее, если в составе регистра много ресурсов. Особенно если какой-нибудь из ресурсов будет являться хранилищем значений, в котором будет храниться картинка или бинарные данные. Такие данные вообще целесообразнее выделять в отдельный регистр.
Хранение дополнительных характеристик Один из часто встречающихся вопросов хранения информации – это вопрос организации хранения значений характеристик, набор которых заранее неизвестен. Таким образом, при разработке прикладного решения нет возможности создать заранее набор реквизитов объекта. Кроме этого, велика вероятность, что конкретные характеристики будут использоваться не для всех объектов, а только для некоторого ограниченного их количества. Например, для некоторых элементов справочника Номенклатура может потребоваться хранить информацию об их цвете, мощности, габаритах (для бытовой техники); для других же – о размере, росте, материале и опять же о цвете (одежда); для третьих подобная информация вообще не имеет смысла (услуги). При этом не исключена вероятность, что автоматизируемая компания станет попутно торговать еще мобильными телефонами, что потребует наличия ряда специфичных характеристик номенклатуры, таких как поддерживаемые стандарты обмена информацией, наличие цифровой камеры, тип батареи и т. д. Классическая реляционная модель предполагает, что для хранения какойлибо информации в базе данных в таблице заводится колонка (поле) с определенным типом и именем. То есть введение реквизитов является естественным способом решения подобной задачи. Однако в рассматриваемом случае подобное решение является неэффективным и зачастую неприемлемым с точки зрения требований, предъявляемых заказчиком. Неэффективность решения «в лоб» заключается в том, что подавляющее большинство характеристик используются лишь для небольшого, ограниченного количества элементов справочника Номенклатура. Это означает, что, вводя для каждой характеристики отдельный реквизит, мы тем самым необоснованно увеличиваем объем хранимой информации. В самом деле, создав реквизит Размер (тип Число), мы добавили в физическую таблицу справочника Номенклатура новую колонку. Но эта колонка будет хранить «содержательные» данные только для элементов справочника из группы Профессиональная разработка в системе «1С:Предприятие 8»
Хранение дополнительных характеристик Одежда (которых, например, 100–150 штук). Если при этом общее количество элементов в справочнике Номенклатура будет равняться 10–15
тысячам, значит, практически для всех элементов справочника в этой колонке будет содержаться значение 0, т. к. данная характеристика для них не имеет смысла.
С практической точки зрения создание реквизитов для хранения значений характеристик в большинстве случаев может быть неприемлемо потому, что добавление нового реквизита возможно только в режиме работы Конфигуратор. В реальной ситуации, как правило, необходимо создавать новые характеристики непосредственно в процессе работы, в режиме 1С:Предприятие. Таким образом, путь ввода новых реквизитов может оказаться слишком «затратным» во всех смыслах. В данном разделе мы рассмотрим возможные варианты решения задач динамического дополнения состава информации, характеризующей объекты.
Хранение дополнительных характеристик определенного типа Рассмотрение задачи хранения дополнительных характеристик начнем с простого примера, когда все дополнительные характеристики, вводимые пользователем, имеют один и тот же тип значения. Допустим, необходимо организовать хранение дополнительной информации о контрагентах: ■■ ■■ ■■ ■■
кто из них относится к нерезидентам (зарубежные контрагенты); с кем из них можно торговать в кредит; кто относится к категории постоянных покупателей; и так далее.
Рис. 9.74. Структура регистра «КатегорииКонтрагентов»
Тип значения измерения Контрагент – СправочникСсылка.Контрагенты. Тип значения измерения Категория – СправочникСсылка.Категории. Использование справочника Категории как объекта для хранения классификатора категорий позволяет предоставить пользователям возможности динамической модификации этой информации. То есть ввод новой характеристики (категории) не требует помощи разработчика. Далее обратите внимание: в составе регистра нет ресурсов. Хотя, как описано в разделе «Хранение информации в регистрах сведений» на стр. 455, именно посредством ресурсов организуется хранение информации в регистрах сведений. Дело в том, что комбинации значений измерений обеспечивают уникальность каждой записи регистра, а наличие самой записи, по сути, и является информацией. Ведь по каждой комбинации Контрагент – Категория необходимо обеспечить хранение информации булевого типа. Если Истина, значит, контрагент относится к этой категории. Это в нашем случае реализовано просто наличием записи. Ну а значение Ложь в нашем случае будет реализовано отсутствием записи. Итак, общую схему хранения дополнительных характеристик контрагентов можно представить следующим образом (рис. 9.75).
Другими словами, необходимо обеспечить возможность ввода и хранения следующих характеристик контрагентов: ■■ Резидент (тип Булево – Истина, Ложь); ■■ ПостоянныйПокупатель (тип Булево – Истина, Ложь); ■■ <новая характеристика> (тип Булево – Истина, Ложь). Как было рассмотрено выше, вариант с булевыми реквизитами Резидент, ПостоянныйПокупатель и т. п. слишком «затратен» и неудобен. Один из вариантов решения этой задачи приведен в демонстрационной конфигурации «Хранение информации», которая находится на прилагаемом компакт-диске. Это использование справочника Категории для хранения видов характеристик и регистра сведений КатегорииКонтрагентов для хранения соответствия конкретной характеристики конкретному контрагенту (рис. 9.74). Том 1
Рис. 9.75. Общая схема хранения дополнительных характеристик
Дальнейшее использование этой информации в учетных или аналитических механизмах прикладного решения можно будет реализовывать посредством, например, соединений с информацией регистра.
481
Глава 9. Хранение информации Так, в составе демонстрационной конфигурации «Хранение информации», которая находится на прилагаемом компакт-диске, есть отчет ПродажиКонтрагентовИмеющихКатегорию, в котором пользователь может применять отборы по категориям контрагентов (рис. 9.76).
Краткий комментарий: условие отбора контрагентов по категориям реализуется во вложенном запросе по регистру сведений за счет использования языка запросов системой компоновки данных (инструкции, заключенные в {…}). Благодаря этому, вопрос организации отбора по категории берет на себя система компоновки данных. То есть пользователь сможет при необходимости обойтись вообще без отбора (тогда в отчет попадут все контрагенты из регистра сведений КатегорииКонтрагентов), организовать отбор по одной категории, по списку категорий, по всем категориям, кроме выбранных, и так далее. Реализация этой функциональности не требует усилий разработчика. Далее таблица неповторяющихся контрагентов, полученных во вложенном запросе, соединяется с таблицей оборотов регистра Продажи. Затем средствами системы компоновки данных в соответствии с настройками и структурой отчета, заданными разработчиком в схеме компоновки данных, отчет компонуется и выводится пользователю. В форме отчета пользователь может изменить отчетный период, настроить отбор, сортировку и условное оформление отчета по своему желанию и переформировать отчет. Здесь мы рассмотрели вариант отображения и отбора контрагентов с установленными категориями в отчете. От разработчика требовалось по крайней мере сформировать текст запроса.
Рис. 9.76. Отчет продажи контрагентов, имеющих категорию
Но ряд функциональных вопросов в таком решении платформа может взять на себя полностью. Так, если установить для измерений регистра КатегорииКонтрагентов свойство Ведущее, то пользователь при необходимости сможет быстро получать форму списка регистра с отбором по соответствующим значениям из форм справочников (рис. 9.77).
Сам отчет формируется при помощи системы компоновки данных. В схеме компоновки данных отчета создан набор данных – запрос, которому передается следующий текст запроса (листинг 9.42). Листинг 9.42. Пример запроса, используемого при формировании отчета
ВЫБРАТЬ ПродажиОбороты.Номенклатура КАК Номенклатура, ПродажиОбороты.Контрагент КАК Контрагент, ПродажиОбороты.КоличествоОборот КАК КоличествоОборот, ПродажиОбороты.СуммаОборот КАК СуммаОборот ИЗ (ВЫБРАТЬ РАЗЛИЧНЫЕ КатегорииКонтрагентов.Контрагент КАК Контрагент ИЗ РегистрСведений.КатегорииКонтрагентов КАК КатегорииКонтрагентов {ГДЕ КатегорииКонтрагентов.Категория.*}) КАК ВложенныйЗапрос ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.Продажи.Обороты(&НачалоПериода, &КонецПериода, , ) КАК ПродажиОбороты ПО ВложенныйЗапрос.Контрагент = ПродажиОбороты.Контрагент
482
Рис. 9.77. Использование команды перехода к списку регистра «Категории контрагентов» в панели навигации формы элемента справочника «Контрагенты»
Профессиональная разработка в системе «1С:Предприятие 8»
Хранение дополнительных характеристик Кроме того, при удалении объектов, с которыми связаны записи регистра, система будет автоматически удалять такие записи. Подробнее
Раздел «Дополнительная функциональность при создании и удалении записей регистра сведений», стр. 469.
Хранение дополнительных характеристик произвольного типа
иерархию, может включать в состав своих объектов реквизиты и табличные части, возможно использование предопределенных видов характеристик, заданных разработчиком. Однако самой важной особенностью объектов планов видов характеристик, отличающей их от других объектов, является использование свойства Тип значения. Это свойство позволяет определить список возможных типов данных, используемых для отдельных видов характеристик (то есть для каждого элемента плана видов характеристик), рис. 9.78.
Рассмотрим теперь более сложную и более распространенную задачу, когда все дополнительные характеристики, вводимые пользователем, имеют произвольный тип значения. Допустим, необходимо организовать хранение дополнительных характеристик номенклатурных позиций. При этом для ряда товаров необходимо организовать хранение информации о весе, для некоторых товаров – о цвете, для некоторых – об области применения и так далее. Пример решения данной задачи с использованием регистра сведений имеет право на жизнь. Однако, в отличие от рассмотренной в предыдущем разделе («Хранение дополнительных характеристик определенного типа») ситуации, здесь будем иметь дело с информацией уже не булевого, а произвольного, заранее неизвестного типа. То есть в регистре потребуется использование поля ресурса ЗначениеХарактеристики. При попытке реализации данного регистра в конфигурации встанет один существенный вопрос: какой тип значения должен быть у ресурса ЗначениеХарактеристики? Действительно, характеристики будут иметь не только разный смысл, но и различные типы значений. Получается, что для ввода произвольных данных в поле ресурса тип значения последнего должен быть составным и включать в себя все возможные типы значений. Но для каждой характеристики тип значения должен быть персональным. Чтобы не получилось, что пользователь может ввести цвет «01.01.2010 г.», а потом пытаться понять, как с этим работать.
Использование плана видов характеристик для хранения видов характеристик Для решения задачи хранения информации о соответствии видов характеристик и типов их значений в составе конфигурации следует использовать объект План видов характеристик. План видов характеристик по своему устройству очень похож на справочник. Он поддерживает работу пользователей с видами характеристик («элементами») и списками видов характеристик, может поддерживать Том 1
Рис. 9.78. Тип значения вида характеристики
То есть для вида характеристики Цвет можно определить тип значения СправочникСсылка.Цвета, для вида характеристики Год выпуска – тип значения Дата, для Уровня шума – Число и так далее. Кроме этого, возможно использование составных типов значений, в состав которых могут входить как примитивные типы (Дата, Число, Строка, Булево), так и ссылочные типы данных (ДокументСсылка.<имя>, СправочникСсылка.<имя> и так далее, включая ПланВидовХарактеристикСсылка.<имя>). Подробнее
Пример создания и использования плана видов характеристик ВидыХарактеристик приведен в составе демонстрационной конфигурации «Хранение информации», которая находится на прилагаемом компакт-диске.
Для того чтобы при описании типов значений для новых видов характеристик (элементов этого плана видов характеристик) пользователь мог выбирать значения только из определенного разработчиком списка, при конфигурировании используется свойство Тип значения характеристик (рис. 9.79).
483
Глава 9. Хранение информации ■■ свойство Дополнительные значения характеристик объекта конфигурации плана вида характеристик заполняется указанием справочника ЗначенияХарактеристик (рис. 9.81).
Рис. 9.80. Справочник «Значения характеристик» Рис. 9.79. Свойство «Тип значения характеристик»
Обратите внимание: на рисунке видно, что в состав типов значений характеристик плана ВидыХарактеристик включено использование справочника ЗначенияХарактеристик. Введение подобного справочника в состав решения помогает обеспечить самостоятельный ввод новых возможных значений новых характеристик самим пользователем в тех ситуациях, когда в составе конфигурации нет объектов для отображения новой сущности. Например, в процессе эксплуатации программы возникла необходимость создания новых видов характеристик Область применения, Вариант оплетки, Формат бумаги и так далее. Вместо того чтобы под каждую сущность создавать свой справочник или перечисление, все значения таких дополнительных характеристик можно хранить в справочнике ЗначенияХарактеристик (рис. 9.80). Однако для того чтобы при выборе значений характеристик из этого справочника информация разных видов характеристик не перемешивалась, нужно подчинить элементы справочника элементам плана вида характеристик. Это реализуется следующим образом: ■■ устанавливается владелец справочника ЗначенияХарактеристик – план видов характеристик ВидыХарактеристик;
484
Рис. 9.81. Свойство «Дополнительные значения характеристик»
Профессиональная разработка в системе «1С:Предприятие 8»
Хранение дополнительных характеристик Этого достаточно, например, для того, чтобы платформа взяла на себя вопросы реализации основной функциональности, касающейся заполнения, хранения и отображения связей между видом характеристики и возможными ее значениями (рис. 9.82).
Рис. 9.82. Использование команды перехода к списку значений характеристик в панели навигации формы плана видов характеристик
Таким образом, создав план видов характеристик, разработчик определяет возможности хранения в базе данных перечня видов характеристик и определяет область допустимых значений этих характеристик.
Описание дополнительных характеристик объектов конфигурации Естественно, характеристики объектов создаются не просто так, а для получения данных в разрезе этих характеристик. Но сначала нужно описать, где и как хранятся характеристики объектов конфигурации. Платформа предоставляет возможность сделать это прямо в дереве объектов конфигурации. Удобство такого решения очевидно: описав один раз связь между объектом конфигурации и его характеристиками, разработчику больше не придется в каждом отчете, использующем характеристики объекта, указывать, где и каким образом хранятся его характеристики. В результате все отчеты и динамические списки, в которых участвует объект конфигурации, будут «подхватывать» его характеристики. Описание характеристик объектов конфигурации содержится в свойстве Характеристики. Диалог для описания характеристик можно вызвать, нажав кнопку Характеристики на закладке Данные в окне редактирования объекта конфигурации, например, Справочник Номенклатура (рис. 9.83). Свойство Характеристики можно задать для таких объектов конфигурации, как Справочник, Том 1
Документ, Перечисление, План видов характеристик, План счетов, План видов расчета, План обмена, Задача, Бизнес-процесс. Команда Характери-
стики также доступна в контекстном меню дерева объектов конфигурации
и в палитре свойств этих объектов.
Рис. 9.83. Вызов диалога описания характеристик справочника «Номенклатура»
В диалоге описания дополнительных характеристик объекта конфигурации нужно указать, где хранятся виды характеристик и значения этих характеристик. В реальной практике часто требуется хранить дополнительные характеристики не одного, а сразу нескольких объектов конфигурации – например, справочников номенклатуры, контрагентов, различных документов и т. д. И хранить их можно по-разному. Это зависит от специфики конкретной задачи, предпочтений разработчика, пожеланий заказчика и т. п. Ниже мы рассмотрим по мере усложнения следующие варианты хранения дополнительных характеристик объектов конфигурации и их значений. 1. В качестве источника характеристик указывается план видов характеристик, а значения характеристик находятся в регистре сведений. При этом один план видов характеристик хранит виды характеристик только для одного объекта конфигурации. 2. План видов характеристик хранит виды характеристик для разных объектов конфигурации, а значения характеристик находятся так же, как и в предыдущем варианте, в регистре сведений. 3. Значения характеристик хранятся не в регистре сведений, а в справочнике, например, или в табличной части справочника. 4. В качестве источника характеристик указывается не план видов характеристик, а табличная часть справочника, которая хранит ссылки на виды характеристик.
485
Глава 9. Хранение информации
Варианты описания дополнительных характеристик Первый вариант Рассмотрим самый простой случай, когда в качестве источника характеристик указывается план видов характеристик, а значения характеристик находятся в регистре сведений. При этом один план видов характеристик хранит виды характеристик только для одного объекта конфигурации. Допустим, необходимо организовать хранение значений дополнительных характеристик номенклатурных позиций в регистре сведений. В составе демонстрационной конфигурации «Хранение информации», которая находится на прилагаемом компакт-диске, для этого используется регистр сведений ДополнительныеХарактеристики (рис. 9.84).
Дело в том, что в реальном решении такая связь может быть очень сложной. И хранение соответствия номенклатурных позиций и видов их характеристик может выполняться в других объектах конфигурации (например, в отдельном регистре сведений, хранящем связи «многие ко многим» между номенклатурными группами и видами характеристик, между отдельными номенклатурными позициями и группами видов характеристик и т. д.). А данные связи могут влиять на связи между видами характеристик и возможными их значениями. Поэтому реализация всех этих связей выполняется разработчиком конфигурации в рамках специфики поставленной задачи. Допустим, необходимо реализовать достаточно простой вариант, когда для любой номенклатурной позиции можно использовать любой вид характеристики, и нужно лишь обеспечить удобство редактирования записей регистра в отношениях между видом характеристики и возможными значениями. В демонстрационной конфигурации «Хранение информации», которая находится на прилагаемом компакт-диске, пример реализации этой задачи сделан с использованием свойств Связь по типу и Связи параметров выбора ресурса ЗначениеХарактеристики регистра сведений ДополнительныеХарактеристики.
Рис. 9.84. Структура регистра сведений «ДополнительныеХарактеристики»
Измерение Объект имеет тип значения СправочникСсылка.Номенклатура, свойство – Ведущее. Тип значения измерения ВидХарактеристики – ПланВидовХарактеристикСсылка.ВидыХарактеристик, свойство – Ведущее. Тип значения ресурса ЗначениеХарактеристики – Характеристика.ВидыХарактеристик. В результате регистром сведений будет поддерживаться уникальность записей по набору значений измерений Объект – ВидХарактеристики, а для значений ресурса ЗначениеХарактеристики тип значения будет определяться теми значениями, которые указаны в составе соответствующего плана видов характеристик. Однако необходимо понимать, что мы описали все необходимое для хранения характеристик, но не для организации заполнения. С точки зрения системы измерения Объект и ВидХарактеристики никак не связаны между собой. А при вводе значений в поле ресурса по умолчанию никак не учитывается выбранный в поле измерения вид характеристики – система будет предлагать заполнять поле любым из типов, описанных в плане видов характеристик. В описании структуры регистра никак не задается информация о логической связи полей, в которых хранятся виды характеристик и значения характеристик. Более того, зачастую это сделать было бы просто невозможно.
486
Для ограничения типов значений характеристики типами конкретного выбранного вида характеристики у ресурса ЗначениеХарактеристики в качестве значения свойства Связь по типу выбрано измерение регистра ВидХарактеристики, а свойство Связи параметров выбора ресурса ЗначениеХарактеристики установлено как Отбор.Владелец(ВидХарактеристики). Для этого при нажатии кнопки выбора из списка возможных реквизитов регистра измерение ВидХарактеристики перенесено в список параметров выбора (рис. 9.85). В результате значения, вводимые в поле Значение характеристики, будут соответствовать типу вида характеристики, выбранной в поле Вид характеристики. Кроме того, при выборе значений характеристики, содержащихся в справочнике Значения характеристик, для выбора будут предлагаться только те значения, которые относятся к выбранному виду характеристики (рис. 9.86). Подробнее
Остальная функциональность вопросов ввода, модификации, удаления данных посредством менеджера записи регистра реализуется системой и описана в разделе «Создание, изменение, удаление записей регистра сведений», стр. 462.
Таким образом, схему организации хранения дополнительных характеристик номенклатуры в рассмотренном решении в общем виде можно представить так (рис. 9.87). Профессиональная разработка в системе «1С:Предприятие 8»
Хранение дополнительных характеристик В этом случае описание характеристик номенклатуры примет следующий вид (рис. 9.88).
Рис. 9.88. Описание дополнительных характеристик справочника «Номенклатура»
Рис. 9.85. Свойства «Связь по типу» и «Связи параметров выбора» ресурса «ЗначениеХарактеристики»
После описания характеристик в свойствах объектов конфигурации в настройках отчетов и динамических списков объектов конфигурации можно использовать их характеристики. Например, в отчете, отражающем остатки номенклатуры на складах, можно настроить отбор по характеристикам номенклатуры (рис. 9.89).
Рис. 9.86. Соответствие вида характеристики и ее значений
Рис. 9.89. Настройка отбора в отчете с использованием характеристик номенклатуры
В результате отчет примет следующий вид (рис. 9.90).
Рис. 9.87. Общая схема хранения дополнительных характеристик одного объекта конфигурации
Том 1
487
Глава 9. Хранение информации
Рис. 9.90. Отчет «Остатки на складах» с отбором по характеристике номенклатуры «Цвет»
Второй вариант
Рис. 9.92. Реквизит «ВидОбъектов» плана видов характеристик
Усложним задачу. Пусть план видов характеристик хранит виды характеристик для разных объектов конфигурации, например для справочников номенклатуры, контрагентов и организаций. При этом значения характеристик находятся так же, как и в предыдущем варианте, в регистре сведений.
В регистре сведений ДополнительныеХарактеристики, хранящем значения характеристик, указывается, что тип измерения Объект будет составным и будет включать ссылки на справочники номенклатуры, контрагентов и организаций – СправочникСсылка.Номенклатура, СправочникСсылка. Контрагенты, СправочникСсылка.Организации (рис. 9.93).
В этом варианте в план видов характеристик необходимо ввести реквизит, позволяющий отделять характеристики одного объекта конфигурации от другого, а при описании характеристик каждого объекта указывать данный реквизит и его значение в полях Поле отбора видов и Значение отбора видов, чтобы отбирались характеристики именно этого объекта. Для реализации данного решения в демонстрационной конфигурации «Хранение информации», которая находится на прилагаемом компактдиске, создано перечисление ВидыОбъектов (рис. 9.91).
Рис. 9.91. Перечисление «ВидыОбъектов»
В план видов характеристик ВидыХарактеристик добавлен реквизит ВидОбъектов типа ПеречислениеСсылка.ВидыОбъектов (рис. 9.92).
488
Рис. 9.93. Тип измерения «Объект» регистра сведений «ДополнительныеХарактеристики»
Профессиональная разработка в системе «1С:Предприятие 8»
Хранение дополнительных характеристик Схему организации хранения дополнительных характеристик различных объектов конфигурации в рассмотренном решении в общем виде можно представить так (рис. 9.94).
Рис. 9.96. Заполнение реквизита «ВидОбъектов» плана видов характеристик Рис. 9.94. Общая схема хранения дополнительных характеристик различных объектов конфигурации
После
В этом случае описание характеристик одного из справочников, например, справочника контрагентов, примет следующий вид (рис. 9.95).
доступны дополнительные характеристики, относящиеся к справочнику контрагентов (ВидОбъектов – Справочник "Контрагенты"), в данном случае – Категория (рис. 9.97).
этого
при
настройке
списка
контрагентов
по
команде
Все действия Настроить список в списке доступных полей будут
Рис. 9.95. Описание дополнительных характеристик справочника «Контрагенты»
То есть при описании характеристик для справочника Контрагенты в Поле отбора видов указывается реквизит ВидОбъектов плана видов характеристик ВидыХарактеристик, а в поле Значение отбора видов указывается значение перечисления ВидыОбъектов – СправочникКонтрагенты. Для справочников Номенклатура и Организации значение поля Поле отбора видов будет таким же, а в поле Значение отбора видов нужно указать соответствующее значение перечисления ВидыОбъектов – СправочникНоменклатура или СправочникОрганизации. Теперь в режиме 1С:Предприятие останется только заполнить реквизит ВидОбъектов плана видов характеристик соответствующими значениями (рис. 9.96). Том 1
Рис. 9.97. Настройка динамического списка с использованием характеристик контрагентов
Например, при условии, что в регистре ДополнительныеХарактеристики присутствуют записи о контрагентах с выбранной категорией, список контрагентов примет следующий вид (рис. 9.98).
489
Глава 9. Хранение информации
Третий вариант Теперь рассмотрим случай, когда значения характеристик хранятся не в регистре сведений, а в табличной части справочника. Виды характеристик будут храниться по-прежнему в плане видов характеристик. В процессе работы прикладного решения для одного объекта (например, элемента справочника) может потребоваться указывать сразу несколько значений одной и той же характеристики. Так, для некоторых номенклатурных позиций может понадобиться указать сразу несколько значений характеристики Область применения: Связь, Медицина, Обучение и т. д. Это значит, что элемент справочника относится сразу к нескольким областям применения. Рис. 9.98. Список контрагентов с отбором по характеристике «Категория»
В рассмотренном примере Категория – это дополнительная характеристика справочника контрагентов, имеющая тип СправочникСсылка.Категории. Для того чтобы при вводе значений в регистр ДополнительныеХарактеристики пользователь мог выбирать из справочника Категории, нужно указать этот справочник в составе свойства Тип значения характеристик плана видов характеристик ВидыХарактеристик (рис. 9.99).
В этом случае уже не получится хранить значения характеристик, как раньше, в регистре сведений, потому что регистр сведений не позволит сделать запись с неуникальными значениями измерений (один и тот же объект и одна и та же характеристика). И значит, их можно хранить, например, прямо в табличной части этого самого элемента справочника. Как в этом случае для справочника будут описываться характеристики, мы сейчас и рассмотрим. В демонстрационной конфигурации «Хранение информации», которая находится на прилагаемом компакт-диске, к справочнику Номенклатура добавлена табличная часть ДополнительнаяИнформация, включающая в себя реквизиты ДополнительноеСвойство (тип значения ПланВидовХарактеристикСсылка.ВидыХарактеристик) и ЗначениеСвойства (тип значения Характеристика.ВидыХарактеристик), рис. 9.100.
Рис. 9.100. Структура справочника «Номенклатура»
Рис. 9.99. Тип значения характеристик
В заключение отметим, что если для справочника Организации реализовать первый вариант описания характеристик (без указания полей Поле отбора видов и Значение отбора видов), то даже при условии заполнения реквизита ВидОбъектов в плане видов характеристик при настройке списков и отчетов, в которых участвует данный справочник, все дополнительные характеристики будут представлены «общей кучей», без разбивки на виды объектов конфигурации.
490
В результате в самом объекте справочника можно указывать сразу несколько значений для одной и той же характеристики (рис. 9.101). Для обеспечения того, чтобы данные в табличной части вводились корректно, выполнены доработки, аналогичные рассмотренным в разделе «Первый вариант» на стр. 486. То есть задействованы свойства Связь по типу и Связи параметров выбора для реквизита ЗначениеСвойства табличной части ДополнительнаяИнформация. В целом схему организации хранения произвольных дополнительных характеристик номенклатуры в самом объекте можно представить так (рис. 9.102). Профессиональная разработка в системе «1С:Предприятие 8»
Хранение дополнительных характеристик что это «служебное» поле, мы можем его использовать (и используем) при описании того, где хранятся значения характеристик. Т. к. для каждой табличной части справочника существует отдельная таблица в базе данных, то записи этой табличной части всех элементов справочника хранятся в этой таблице. И именно по значению поля Ссылка можно определить, к какому же именно элементу справочника относятся эти записи. Поэтому при описании места хранения значений характеристик в качестве поля объекта мы указываем поле Ссылка, чтобы система отбирала из таблицы только те записи, которые относятся именно к этому элементу. Таким образом, табличная часть ДополнительнаяИнформация будет хранить значения характеристик номенклатуры так же, как и регистр сведений. Виды характеристик будут храниться по-прежнему в плане видов характеристик ВидыХарактеристик (рис. 9.104). Рис. 9.101. Форма элемента справочника «Номенклатура»
Рис. 9.104. Хранение дополнительных характеристик в табличной части справочника «Номенклатура» Рис. 9.102. Схема хранения значений дополнительных характеристик
В этом случае описание характеристик номенклатуры примет следующий вид (рис. 9.103).
В результате в отчете по остаткам номенклатуры на складах можно вывести значения дополнительных полей – характеристик, введенные в табличной части элементов номенклатуры (рис. 9.105).
Рис. 9.103. Описание дополнительных характеристик справочника «Номенклатура»
В отличие от предыдущих вариантов, где все поля мы создавали самостоятельно, тут в табличной части справочника используется поле Ссылка, которое мы не создавали. Это поле создает сама платформа, когда мы указываем, что у справочника будет табличная часть. Несмотря на то, Том 1
Рис. 9.105. Отчет «Остатки на складах» с дополнительными полями-характеристиками номенклатуры «Цвет», «Вес»
491
Глава 9. Хранение информации
Четвертый вариант В заключение рассмотрим случай, когда в качестве источника характеристик указывается не план видов характеристик, а табличная часть справочника, которая хранит ссылки на виды характеристик. А значения характеристик содержатся в регистре сведений. На практике одна и та же характеристика может использоваться одновременно для нескольких объектов конфигурации (например, как для справочника Номенклатура, так и для справочника Контрагенты). А такого рассмотренные выше способы описания характеристик не позволяют сделать. При использовании одного плана видов характеристик для всех объектов конфигурации (вариант 2) в его специальном реквизите мы указывали единственный объект конфигурации, к которому применяется эта характеристика. Значит, если есть необходимость применять эту характеристику и к другому объекту конфигурации, придется дублировать вид характеристики и в ней указывать другой объект конфигурации. Если для каждого объекта конфигурации использовать собственный план видов характеристик, то тоже придется дублировать вид характеристики, но уже в другом плане видов характеристик. Чтобы избежать такого дублирования, характеристики объединены в наборы характеристик, свойственные каждому объекту конфигурации. Эти наборы хранятся в отдельном справочнике, табличная часть которого и содержит описание характеристик каждого набора.
Рис. 9.107. Предопределенные элементы справочника «НаборыДополнительныхХарактеристик»
Схему организации хранения дополнительных характеристик различных объектов конфигурации в рассмотренном решении в общем виде можно представить так (рис. 9.108).
Для реализации данного решения в демонстрационной конфигурации «Хранение информации», которая находится на прилагаемом компакт-диске, создан справочник НаборыДополнительныхХарактеристик с табличной частью ДополнительныеСведения, включающей в себя реквизит Свойство (тип значения ПланВидовХарактеристикСсылка.ВидыХарактеристик), рис. 9.106.
Рис. 9.108. Схема хранения значений дополнительных характеристик
Рис. 9.106. Структура справочника «НаборыДополнительныхХарактеристик»
Справочник НаборыДополнительныхХарактеристик содержит предопределенные элементы, ссылки на которые позволяют создавать наборы характеристик, в которых одна и та же характеристика может применяться к различным объектам конфигурации (рис. 9.107).
492
В этом случае описание характеристик одного из справочников, например, справочника номенклатуры, примет следующий вид (рис. 9.109). При описании табличной части справочника НаборыДополнительныхХарактеристик в качестве источника характеристик в Поле ключа указывается поле Свойство табличной части, в Поле отбора видов – поле Ссылка справочника, в поле Значение отбора видов – значение ссылки на предопределенный элемент справочника НаборыДополнительныхХарактеристик. Профессиональная разработка в системе «1С:Предприятие 8»
Хранение дополнительных характеристик
Рис. 9.109. Описание дополнительных характеристик справочника «Номенклатура»
На приведенном выше рисунке важна только вторая запись. Именно о ней мы и говорим. А первая запись осталась от предыдущего примера. Но в принципе этот рисунок показывает и то, что характеристики объекта конфигурации могут находиться в разных местах, по-разному храниться, и все это можно описать в диалоге описания характеристик объекта конфигурации, в одном месте, с помощью нескольких записей. Таким образом, для каждого предопределенного элемента справочника НаборыДополнительныхХарактеристик в режиме 1С:Предприятие можно ввести свойственные ему наборы характеристик (рис. 9.110). Как видно из рисунка, сами характеристики содержатся в плане видов характеристик, а табличная часть элементов справочника хранит только ссылки на него. После этого при настройке динамических списков и отчетов, в которых участвует данный объект конфигурации, будут доступны его характеристики, указанные в табличной части справочника НаборыДополнительныхХарактеристик.
Том 1
Рис. 9.110. Набор дополнительных характеристик справочника «Номенклатура»
493
Глава 9. Хранение информации
494
Профессиональная разработка в системе «1С:Предприятие 8»
Место документов в концепции системы «1С:Предприятие»
Глава 10. Документы и последовательности Место документов в концепции системы «1С:Предприятие» При создании бизнес-приложений для решения задач учета, планирования, принятия решений, управления и т. д., как правило, используются определенные информационные модели. И, как правило, одно из центральных мест любой подобной модели занимает понятие события. Например, один из наиболее активно используемых вариантов исторически сложившейся информационной модели учетных решений можно представить в виде следующей схемы (рис. 10.1).
ного перебора записей событий и подсчета их влияния на показатели. Поэтому отражение результата влияния зарегистрированных событий на показатели обычно производится заранее. То есть не в момент, когда потребуется отчет, а в момент, когда событие только регистрируется. Для запоминания же состояния учитываемых таким образом показателей используются специальные регистры учета. Например, для классического бухгалтерского учета посредством двойной записи итоги хозяйственной деятельности в виде сальдо «оседают» на бухгалтерских счетах. Рассмотрим, что предлагает платформа «1C:Предприятие» для реализации информационных моделей бизнес-приложений. Платформа «1С:Предприятие» позволяет строить прикладные решения, оперируя совокупностями объектов: ■■ соответствующими прикладным сущностям, ■■ выбираемыми из набора жестко определенных в платформе классов объектов. Общую схему возможных вариантов взаимодействия прикладных объектов системы для решения той или иной задачи можно представить следующим образом (рис. 10.2).
Рис. 10.1. Информационная модель учетного решения
Основа учета – регистрация событий, происходящих с учитываемыми показателями. Она может выполняться посредством внесения записей в журналы, записью проводок и т. д. В общем, посредством документирования. Причем документирование должно производиться не в «вольной» форме, а согласуясь с заранее разработанными и стандартизованными обозначениями, зачастую сведенными в виде неких классификаторов. Конечно же, документирование нужно не как самоцель, а как обоснование информации, предоставляемой о состоянии учитываемых показателей. Так называемой отчетной информации. При выдаче же отчетной информации большое значение придается наглядности, удобству и быстроте ее получения. Для того чтобы обеспечить максимальную быстроту получения отчетной информации, идеально было бы получать ее сразу, минуя этап длительТом 1
Рис. 10.2. Варианты взаимодействия прикладных объектов
Можно отметить, что данная схема позволяет полностью реализовать функциональность предыдущей и при этом может обеспечить существенное расширение и дополнение ее.
495
Глава 10. Документы и последовательности Фактически она позволяет строить модели на более высоком уровне абстрагирования. Например, справочники, планы видов характеристик, перечисления, константы, планы счетов и планы видов расчетов могут использоваться не только для обеспечения заполнения документов, но и для заполнения некоторых видов регистров напрямую. А вообще – для хранения информации, не привязанной ко времени. Документы предназначены для ввода первичной информации, связанной с регистрацией событий, воздействующих на учитываемые в системе показатели. Если посмотреть на прикладные решения, то подавляющее большинство документов используют привязку ко времени – поле Дата, которое есть у всех документов. То есть можно говорить, что документы – это объекты для регистрации информации, для которой важна привязка ко времени. Для облегчения обеспечения действий, связанных с вводом, отображением, логикой учета документов, при необходимости используются такие объекты, как нумераторы, журналы документов, последовательности. Отчеты и обработки могут обеспечивать не только вывод информации в удобном для пользователя виде, но и ввод. То есть могут использоваться для обеспечения интерфейса выполнения воздействий на объекты, отвечающие за хранение информации. Однако сами для хранения информации не используются. Регистры же можно воспринимать как объекты, предназначенные для хранения «вторичной» информации о состоянии показателей со сложными привязками к моментам времени и периодам. Обычно эта информация получается в процессе переработки исходной информации, вводимой документами. Например, факт болезни нужно регистрировать посредством документа Больничный. Информация документа при его проведении будет отражена в регистре расчета зарплаты с тем, чтобы впоследствии, после проведения расчетных операций (включающих, например, вытеснение оклада за период болезни), из регистра можно было взять информацию о начисленном по болезни пособии и о начисленной заработной плате вообще. Однако опять же можно смотреть на использование регистров шире. Есть возможность использования регистров сведений (периодических или непериодических) с независимым режимом записи. То есть если это оправдано с точки зрения решения прикладной задачи, для таких регистров данные могут вводиться непосредственно, минуя этап работы с документом. Итак, подведем краткий итог: документирование событий – основа практически любой модели бизнес-приложений. Без документирования информация, получаемая из системы, была бы необоснованной, а значит, возможно, недостоверной. Таким образом, основное назначение документов – регистрация информации о происходящих событиях с привязкой ко времени.
496
Документы
Функциональность документов Для выполнения задач своего предназначения документы имеют соответствующий состав и обеспечивают возможность следующих основных действий: ■■ ■■ ■■ ■■ ■■ ■■ ■■
заполнение, запись, проведение, формирование движений по регистрам, расположение на оси времени, пометка на удаление, удаление.
Такой набор функциональности заложен в систему и обеспечивает быструю разработку и удобство использования документов. Разберем эти возможные действия подробнее.
Заполнение документов Заполнение документа может производиться разными способами в зависимости от прикладной задачи и необходимого уровня сервиса для пользователя. Самый простой вариант заполнения – ручной ввод документа (рис. 10.3). Данный вариант обеспечивается чаще всего посредством формы, имеющей в качестве основного реквизита объект документа. Тогда ряд элементов формы обеспечивает отображение и ввод значений в реквизиты формы, а ряд – инициацию процесса записи документа, когда данные реквизитов формы записываются в сами объекты. Формы, основным реквизитом которых назначен объект документа, и элементы этих форм обладают расширениями, позволяющими реализовывать специфичное поведение системы для облегчения работы разработчика с документами. Копирование. Вариант, когда новый документ создается копированием существующего, причем его данные заполняются данными существующего документа (рис. 10.4). Может инициироваться интерактивными действиями пользователя или программно – методом Скопировать(). Оба действия приводят к одному событию ПриКопировании и могут быть перехвачены обработчиком события, располагаемым в модуле документа. В самом обработчике может быть реализовано заполнение нового документа в зависимости от требуемого алгоритма (не обязательно только данными исходного документа). Профессиональная разработка в системе «1С:Предприятие 8»
Документы
Рис. 10.5. Создание документа вводом на основании
Рис. 10.3. Ручной ввод документа
Также в механизме заполнения участвуют свойства реквизитов объектов конфигурации Значение заполнения и Заполнять из данных заполнения. Если свойство реквизита Заполнять из данных заполнения установлено в значение Истина, то процедура стандартной обработки заполнения будет заполнять реквизит из данных заполнения (например, платформа автоматически будет заполнять реквизиты документов, по которым установлен отбор в форме списка). Если в данных заполнения нет данных для заполнения этого реквизита или свойство имеет значение Ложь, то реквизит будет заполнен из свойства Значение заполнения, если оно установлено. Программное заполнение документов. Может выполняться за счет операций присвоения значений реквизитам документа (рис. 10.6). В данном случае выбор элементов формы и событий, при обработке которых будут производиться эти действия, предоставлен разработчику конфигурации. Создание нового документа при этом может производиться посредством метода СоздатьДокумент() на сервере или ОткрытьФорму() на клиенте.
Рис. 10.4. Создание документа копированием
Заполнение. Вариант создания нового документа, который инициируется в следующих случаях: ■■ командой Создать в панели действий приложения или в форме списка документов (см. рис. 10.3); ■■ командой ввода на основании СоздатьНаОсновании (рис. 10.5); ■■ при программном вызове методов глобального контекста ОткрытьФорму() и ПолучитьФорму(); ■■ при программном вызове метода Заполнить(). Поскольку можно заполнять документ на основании данных любого объекта, то говорить об однозначном соответствии данных источника и документа-получателя не приходится. Поэтому само заполнение данных документа осуществляется в рамках обработчика события ОбработкаЗаполнения. Процедура обработчика располагается в модуле документа и содержит в качестве параметра объект-источник. Том 1
К данному способу прибегают обычно в случаях, когда создание нового документа должно производиться не вручную, не копированиемзаполнением, а в результате выполнения каких-либо программных алгоритмов.
Рис. 10.6. Программное заполнение документа
497
Глава 10. Документы и последовательности
Расположение на оси времени Поскольку документ является регистратором события, одной из важных задач документа является фиксация времени, когда событие имело место. Поэтому все документы имеют поле Дата. И, более того, система не позволяет записать документы с неустановленной датой (равной значению даты по умолчанию). Согласно значениям этого поля все записанные документы могут быть расположены на единой временной оси в хронологическом порядке (рис. 10.7).
Кроме того, в случаях, когда требуется обеспечить ввод и проведение документов реальным временем, можно воспользоваться возможностями механизма оперативного проведения документов и оперативной отметки времени. Это позволяет распределять документы на временной оси автоматически с соблюдением как минимум секундного интервала. подробнее
Раздел «Проведение документов», стр. 498.
Запись документов Запись объекта документа – физический процесс, заключающийся в сохранении значений реквизитов документов в базе данных. Может инициироваться интерактивными действиями пользователя или программно – методом Записать().
Рис. 10.7. Расположение документов на оси времени
Причем даже если ряд документов имеет одинаковое значение поля Дата, система «1С:Предприятие» имеет средства для обеспечения однозначного хронологического порядка – объект МоментВремени, содержащий дату и ссылку на документ (рис. 10.8).
Запись документа имеет несколько возможных режимов (просто – запись, проведение, отмена проведения). О происходящих при этих режимах записи процессах будет рассказано ниже. Общий же смысл использования этих режимов – обеспечение логических процессов бизнес-решения с использованием определенных «сценариев», заложенных в систему (удаление существующих движений, формирование новых, установка значения поля Проведен и прочее). Разработчик вправе принимать решения о необходимости применения того или иного сценария или механизма (рис. 10.9).
Рис. 10.8. Использование момента времени
Объект МоментВремени используется системой автоматически при решении задачи отображения списков документов в хронологическом порядке. Также его используют, когда требуется получить данные из регистров именно на момент времени документа. Однако необходимо заметить, что за счет использования момента времени можно только получить хронологию расположения документов, изменить же ее в пределах одной секунды невозможно. Хронологический порядок документов определяется системой при обращении к данным – по датам, а для одинаковых дат – по ссылкам документов. И для документов с одинаковым временем не зависит ни от порядка создания документов, ни от номера документа, ни от чего-то подобного. Если необходимо изменить хронологию документов, нужно менять значения поля Дата документов, «разводя» их в разные секунды.
498
Рис. 10.9. Запись документа
Проведение документов Обсуждая это действие, необходимо разделять два понятия: ■■ «Проведен» – состояние документа; ■■ «Проведение» – как процесс. Проведенность как состояние может быть установлена различными способами. Может классически – в результате выполнения процесса проведения, а может просто присвоением значения Истина свойству документа Проведен. Профессиональная разработка в системе «1С:Предприятие 8»
Документы С прикладной точки зрения документ считается проведенным, если обработка данного документа полностью завершена и принято решение, что данный документ должен участвовать в учете. То есть событие, регистрируемое документом, полностью описано и учтено в информационной модели. Для отражения этого состояния документа используется системное поле Проведен. Процесс проведения документа в системе является частным случаем записи документа. Если состояние проведения было достигнуто в процессе проведения документа, то, значит, были обработаны все события, связанные с записью документа в режиме проведения. А именно в обработчиках этих событий обычно и содержатся указания, что, где и как должно измениться в объектах информационной базы для реализации бизнес-логики, заложенной в решение (рис. 10.10).
Рис. 10.11. Отмена проведения документа
Рис. 10.12. Использование свойства «Проведен»
Формирование движений по регистрам Рис. 10.10. Проведение документа
Кроме того, зачастую используется процесс, обратный проведению, – отмена проведения. Выполнение этого процесса приводит к записи документа с отменой проведения. При этом выполняются обработчики, связанные с ним (рис. 10.11). Если же свойство Проведен просто установлено или снято для документа и документ был записан, то в результате для такого документа был выполнен процесс обычной записи документа. То есть часть событий не произошла для такого документа, а значит, не были обработаны соответствующим образом обработчики этих событий (рис. 10.12). Однако для каких-нибудь регламентных или вспомогательных обработок может оказаться важной такая возможность: получить проведенные документы без процесса проведения или непроведенные документы без процесса отмены проведения.
Том 1
По своему назначению регистры служат для запоминания и переработки информации, внесенной в систему, как правило, документами. Поэтому для записей любых регистров (за исключением регистров сведений с установленным режимом записи Независимый) обязательно наличие заполненного поля Регистратор. В этом поле должна находиться ссылка на документ, которому подчинен этот набор записей. Такие наборы записей называют движениями (рис. 10.13). Поведение системы во многом определяется наличием связи документов и подчиненных им движений. Например, движения отдельно от своих регистраторов существовать не могут. Поэтому при удалении документов или отмене проведения (если свойство Удаление движений установлено в значение, отличное от Не удалять) система производит поиск движений этого документа в таблицах всех регистров, для которых данный документ может быть регистратором, и удаляет их. Именно поэтому, например, не рекомендуется «про запас» указывать регистры, для которых документ может быть регистратором. Нужно указывать только те, которые действительно требуются для обеспечения бизнес-логики, заложенной в решение.
499
Глава 10. Документы и последовательности Для отслеживания различных стадий обработки этого документа используется регистр сведений ОперативноеУправлениеЗаказами (рис. 10.14).
Рис. 10.14. Регистр сведений «ОперативноеУправлениеЗаказами»
Заполнение регистра производится при реализации промежуточных операций обработки документа (рис. 10.15).
Рис. 10.13. Движения документа
Сами же движения могут: ■■ создаваться при проведении документов; ■■ создаваться при записи документов; ■■ формироваться в виде набора записей регистра (обязательно с отбором по регистратору); ■■ формироваться интерактивно (например, документом РучнаяОперация). То есть и непроведенные документы могут иметь движения по регистрам. Это обеспечивает возможность достаточно гибкого отражения ситуаций, возникающих в автоматизируемых задачах, и может быть использовано, когда обработка документа пользователем еще не завершена, но документ уже должен изменить некие учетные данные. Например, так может выглядеть задача последовательной обработки документа ЗаказПокупателя различными подразделениями компании.
500
Рис. 10.15. Промежуточные операции обработки документа
Сначала документ выписывается менеджером и записывается. При этом в регистре сведений ОперативноеУправлениеЗаказами формируется запись, указывающая, что данный заказ находится в стадии КФинансовомуКонтролю. Далее ответственный сотрудник финансового отдела проверяет возможность удовлетворения данного заказа с точки зрения допустимости долга покупателя и соблюдения ценовых порогов. В случае положительного решения выставляется флажок Отпуск разрешен. При записи документа с этим установленным флажком модифицируется запись в регистре Профессиональная разработка в системе «1С:Предприятие 8»
Документы сведений ОперативноеУправлениеЗаказами. Теперь для данного документа актуально состояние КРазмещению. Далее обработку документа выполняет менеджер отдела запасов. Он работает со всеми заказами, имеющими статус КРазмещению. Если принимается решение об отгрузке из наличных свободных остатков, устанавливается флажок Отгрузка из свободных остатков, и заказ записывается. При записи такого заказа его статус меняется на значение КРезервированию. Если же будет принято решение о выборе варианта Размещение в заказе поставщику, выполняется проведение документа с формированием движений по регистру ЗаказыПоставщикам.
Пометка на удаление документа Так же как и при работе с проведением, необходимо различать: ■■ состояние документа «ПометкаУдаления»; ■■ процесс «ПометкаУдаления». Документ считается помеченным на удаление в том случае, если в системное поле документа ПометкаУдаления записано значение Истина. Поведение документа, помеченного на удаление, имеет свои особенности. Например, такой документ не может быть проведен (рис. 10.16).
Заказы покупателей, перечисленные в регистре сведений ОперативноеУправлениеЗаказами и имеющие статус КРезервированию, проверяются и окончательно проводятся уже товароведом на складе. В таких случаях формируются движения по регистру Резервы (табл. 10.1). Таблица 10.1. Промежуточные операции обработки документа № Пользователь Стадия обработки
Движения по регистрам
Комментарий
Рис. 10.16. Проведение документа, помеченного на удаление
1
Менеджер
Заполнение
Регистр сведений
Формирование записи по заказу: статус К финансовому контролю
2
Финансовый отдел
Регистр сведений
Модификация записи по заказу: статус
3
Отдел запасов
Контроль кредитной линии Решение об отгрузке из свободных остатков или заказе поставщику
Регистр сведений
Модификация записи по заказу: статус К резервированию, если принято решение об отгрузке из свободных остатков Проведение документа с формированием движений по регистру Заказы поставщикам (движения по регистру Оперативное управление заказами автоматически удаляются) Проведение документа с формированием движений по регистру Резервы (движения по регистру Оперативное управление заказами автоматически удаляются)
Сам же процесс «ПометкаУдаления» обычно инициируется интерактивно или методом объекта документа УстановитьПометкуУдаления(ИСТИНА) и приводит к тому, что документ записывается с соответствующим значением поля ПометкаУдаления. При этом если документ был проведен, инициируется еще отмена проведения документа и удаление движений данного документа (рис. 10.17).
4
Склад
Оперативное управление заказами Оперативное управление заказами Оперативное управление заказами
Регистр остатков
Заказы поставщикам
Отметка Регистр остатков о постановке Резервы в очередь на отгрузку
К размещению
Обратите внимание: хотя движения по регистрам для обрабатываемого заказа формируются на каждой стадии обработки, «финальное проведение» выполняется только на последней стадии. Причем разработчик может выполнять его в рамках обработчика события ОбработкаПроведения, а может и самостоятельно, очищая старые движения, формируя новые и устанавливая свойство Проведен данного документа. Рис. 10.17. Установка пометки на удаление
Том 1
501
Глава 10. Документы и последовательности Обратите внимание: отмена проведения и удаление движений производятся при установке пометки удаления, только если документ был проведен. Если документ не был проведен, но имел движения, то при установке пометки удаления удаление движений не будет произведено. Если же для помеченного на удаление документа интерактивно снимается пометка удаления или применяется метод УстановитьПометкуУдаления(ЛОЖЬ), то инициируется запись документа с изменением значения на Ложь в поле ПометкаУдаления (рис. 10.18).
действия можно выполнить в обработчиках событий, связанных с записью документа. Например, если для документа ПоступлениеТоваров требуется «перехватить» изменение значения свойства ПометкаУдаления для уже записанного документа, можно поступить следующим образом (листинг 10.1). Листинг 10.1. Обработчик события «ПередЗаписью»
Процедура ПередЗаписью(Отказ, РежимЗаписи, РежимПроведения)
Рис. 10.18. Снятие пометки удаления
Кроме того, значение свойства ПометкаУдаления объекта документа можно устанавливать программно и просто записывать документ. В таких случаях инициация события ОбработкаУдаленияПроведения не происходит. И если при этом документ был изначально не проведен, он записывается помеченным на удаление. Если же подобные действия выполняются для проведенного документа, то система выдает предупреждение о невозможности записи документа и проведенного, и помеченного на удаление (рис. 10.19).
// Ограничить действия: только для записанных документов. Если Не ЭтоНовый() Тогда
// Получить пометку удаления текущего документа из базы данных. Запрос = Новый Запрос; Запрос.Текст = "ВЫБРАТЬ | ПоступлениеТоваров.ПометкаУдаления |ИЗ | Документ.ПоступлениеТоваров КАК ПоступлениеТоваров |ГДЕ | ПоступлениеТоваров.Ссылка = &ТекущийДокумент";
Запрос.УстановитьПараметр("ТекущийДокумент", Ссылка); Результат = Запрос.Выполнить(); Выборка = Результат.Выбрать(); Выборка.Следующий();
// Сравнить текущее значение пометки удаления // и взятое из базы данных. Если ПометкаУдаления <> Выборка.ПометкаУдаления Тогда Если ПометкаУдаления Тогда
// Выполнить действия при установке пометки удаления. // ...
Иначе
// Выполнить действия при снятии пометки удаления. // ...
КонецЕсли; КонецЕсли; КонецЕсли; КонецПроцедуры Рис. 10.19. Использование свойства «ПометкаУдаления»
А вот возможность помеченного на удаление документа иметь движения может быть полезной, если по какой-то причине необходимо отражать в учете данные документа, готовящегося к удалению. Например, пока не будет проведен документ, его заменяющий. Сами события «Установка пометки на удаление» и «Снятие пометки удаления» с точки зрения документа выделенными процессами не являются. Поскольку в любом случае идет речь о записи помеченного на удаление документа (или со снятой пометкой), то все необходимые
502
Удаление документов Удаление документов может производиться в составе механизма контроля ссылочной целостности. А может иметь место и непосредственное удаление объектов. Использование механизма контроля ссылочной целостности при удалении объектов или неиспользование определяется разработчиком и администратором конфигурации. Если документ имеет движения по регистрам, то при непосредственном удалении документа система автоматически удалит их. Профессиональная разработка в системе «1С:Предприятие 8»
Документы Событие ПередУдалением может обрабатываться в модуле объекта документа. Например, если требуется позволить непосредственное удаление только тех документов, которые не имеют движений, достаточно сделать следующее (листинг 10.2). Листинг 10.2. Обработчик события «ПередУдалением»
Процедура ПередУдалением(Отказ) Для Каждого НаборЗаписейРегистра из Движения Цикл
// Прочитать движения по каждому регистру. НаборЗаписейРегистра.Прочитать();
// Проверить наличие записей в движениях по конкретному регистру. Если НаборЗаписейРегистра.Количество()>0 Тогда Сообщение = Новый СообщениеПользователю; Сообщение.Текст = "Документ" + Метаданные().Представление() + " № " + Номер + " от " + Дата + " имеет движения!"; Сообщение.Сообщить(); Отказ = Истина; КонецЕсли;
КонецЦикла;
КонецПроцедуры
Состав документов Что в себя включают документы? Рассмотрим этот вопрос, учитывая области абстрагирования, использующиеся для работы с объектами в системе. Потому что в каждой области абстрагирования документ описывается по-разному. Можно говорить о составе документа как прикладного объекта, используемого для организации прикладного решения. Можно как об объекте конфигурации, позволяющем организовать работу в отношении реализации прикладной задачи в рамках конфигурации. Можно о составе таблиц, полей, индексов, посредством которых организовано непосредственное хранение данных документов (рис. 10.20).
Рис. 10.20. Понятие «Документ»
Том 1
Поскольку основной задачей документов как объектов прикладной области является регистрация событий, структура документов определяется именно этой задачей. Тогда что за информацию можно отражать в системе при регистрации события? Прежде всего, сам факт того, что событие произошло и когда оно произошло. Поэтому, как правило, для каждого события необходимо регистрировать порядковый номер этого события и дату происхождения. Соответственно, в состав любого документа включаются поля Номер и Дата. Это минимально возможный состав регистратора события. Действительно, могут иметь место ситуации, когда больше никакой информации относительно данных документа и не требуется. Например, для документов, отражающих регламентные операции («завершение периода», «снятие итогов» и т. п.). Для ситуаций, когда при регистрации события необходимо запоминать информацию, имеющую единичные значения для одного события, должны использоваться реквизиты документов. Например, Поставщик при регистрации факта поставки товаров. Для ситуации, когда при регистрации события необходимо запоминать информацию, имеющую множественные значения, необходимо использовать табличные части документов. Например, табличная часть Товары при регистрации факта поставки множества товаров. Как объект конфигурации для обеспечения решения задач прикладной области документ обладает свойствами (автонумерация, проведение и т. д.) и имеет в своем составе подчиненные объекты: ■■ Реквизиты документов – объекты, используемые для запоминания информации об объекте (документе), имеющей единичные значения для каждого экземпляра документа; ■■ Табличные части документов – объекты, используемые для запоминания дополнительной информации об объекте, представляемой в виде таблиц; ■■ Формы – объекты, используемые для обеспечения интерактивного ввода, просмотра и редактирования информации; ■■ Команды – объекты, используемые для разработки командного интерфейса документа. В модулях команд находятся обработчики для их выполнения; ■■ Макеты – объекты (например, табличные документы), обычно используемые при формировании печатных форм объекта. Для обеспечения возможности манипулирования данными при написании алгоритмов обработки информации документов используются соответствующие объекты встроенного языка. На самом нижнем уровне абстрагирования используются объекты информационной базы, обеспечивающие выполнение задач вышестоящих уровней.
503
Глава 10. Документы и последовательности
Структура таблиц базы данных На уровне объектов базы данных информация о документах хранится в следующих таблицах:
Допустим, в конфигурации для регистрации контактов – деловых встреч, звонков, писем – используется документ Событие (рис. 10.21).
■■ основная таблица документа, для каждого объекта конфигурации Документ; ■■ таблица табличной части документа, для каждой табличной части каждого объекта конфигурации Документ. Структура полей этих таблиц следующая. Основная таблица документа: ■■ Ссылка – уникальный идентификатор, позволяющий однозначно определить данную запись; ■■ ВерсияДанных – версия записи (изменяется после каждого обновления данной записи); ■■ ПометкаУдаления – Булево; ■■ Проведен – Булево; ■■ Дата – дата/время регистрируемого документа; ■■ Номер – номер регистрируемого документа (поле существует, если документ как объект конфигурации имеет длину номера, отличную от нуля); ■■ ПрефиксНомера – начало периода уникальности номера. Поле определено, если в конфигурации для документа задана поддержка уникальности номера в пределах периода; ■■ Реквизит1 – тип значения поля определяется типом значения реквизита; ■■ … ■■ РеквизитN – … Таблица табличной части документа: ■■ Ссылка – ссылка на документ, которому подчинена данная запись. Содержит то же значение, что и поле Ссылка основной таблицы документов; ■■ Ключ – ключ записи табличной части в рамках одного объекта базы данных; ■■ НомерСтроки – предопределенный реквизит табличной части, тип значения Число; ■■ Реквизит1 – тип значения поля определяется типом значения реквизита; ■■ … ■■ РеквизитN – …
504
Рис. 10.21. Документ «Событие»
В базе было записано 4 документа. 01.03.2010 был оформлен документ с номером Т-001, в котором зафиксировано проведение переговоров с контрагентом КомбиТранс и сторонней организацией Баязет. Далее 02.03.2010 был зафиксирован телефонный звонок Баязет документом Т-0002. Затем задним числом был введен документ Т-003, в котором зафиксирован выезд к заказчику Коринф. Последним документом с номером Т-004 был зафиксирован случайный звонок в офис. Данные этого документа в информационной базе будут храниться в таблице документа и таблице табличной части документа. Таблица документа будет иметь следующий вид (табл. 10.2). Таблица 10.2. Таблица документа «Событие» (левая часть) Ссылка
Пометка Удаления
Проведен
Дата
Номер
Док1 Док2 Док3 Док4
Ложь
Истина
Ложь
Истина
Ложь
Истина
Истина
Ложь
01.03.2010 10:00:00 02.03.2010 11:00:00 01.03.2010 13:00:30 02.03.2010 15:00:00
Т-001 Т-002 Т-003 Т-004
Таблица 10.2. Таблица документа «Событие» (правая часть) Вид События
Контрагент
Описание События
Ответственный
Переговоры Телефонный звонок Выезд к заказчику Телефонный звонок
КомбиТранс Баязет Коринф
Переговоры Выяснение реквизитов Переговоры Ошиблись номером
Иванов Петров Иванов Иванов
Обратите внимание: записи в самой таблице упорядочены согласно хронологии ввода информации. Таблица табличной части документа будет содержать записи только для тех документов, у которых она была заполнена (табл. 10.3). Профессиональная разработка в системе «1С:Предприятие 8»
Документы Таблица 10.3. Таблица табличной части документа «Событие» Ссылка НомерСтроки Контрагент
Лицо
Док1 Док1
Семенов Горбунков
1 2
Баязет Баязет
Если к реквизитам документа добавить еще реквизит, система при изменении конфигурации базы данных добавит к таблице документа еще одну колонку. Причем для «старых» записей значения этого поля будут заполнены соответствующими типу значения реквизита значениями по умолчанию. Аналогичные действия в отношении таблицы табличной части документа будут произведены, если к реквизитам табличной части документа добавить еще один реквизит.
Поле
Тип
Назначение
Представление
Строка
МоментВремени
МоментВремени
<Реквизиты>
Произвольный, определяется типом реквизита
<Табличные части>
РезультатЗапроса
Виртуальное поле, не хранится в базе данных. Строковое представление, содержащее имя документа, его номер и дату. Не может использоваться для операций сравнения в тексте запроса Виртуальное поле, не хранится в базе данных. Содержит объект МоментВремени (который включает в себя дату и ссылку на документ) Каждое из полей содержит значения реквизитов документа. Имена полей совпадают с названиями реквизитов, заданными для объекта конфигурации Каждое из полей содержит табличные части документа. Имена полей совпадают с названиями табличных частей, заданными для объекта конфигурации. Сами значения полей содержат результаты запросов по табличным частям документа. Результат запроса к табличной части состоит из колонок с именами, соответствующими именам реквизитов табличной части документа и колонки НомерСтроки
Чтобы обеспечить должное быстродействие при обращении к данным информационной базы, для таблиц хранения информации документов создаются следующие индексы: ■■ Ссылка; ■■ Дата + Ссылка; ■■ Номер + Ссылка – если для данного документа длина номера не равна нулю; ■■ Реквизит + Ссылка – если для данного реквизита свойство Индексировать установлено в значение Индексировать; ■■ Реквизит + Дата + Ссылка – если для данного реквизита свойство Индексировать установлено в значение Индексировать с доп. упорядочиванием; ■■ Реквизит – если документ включен в критерий отбора через данный реквизит; ■■ ПрефиксНомера + Номер + Ссылка – если для данного документа длина номера не равна нулю. Табличная модель обращения к данным (посредством запросов) дает возможность получения информации из этих таблиц в виде таблицы документа (табл. 10.4). Таблица 10.4. Состав таблицы документа Поле
Тип
Ссылка
ДокументСсылка.<Имя> Содержит ссылку на документ
ВерсияДанных
Строка
ПометкаУдаления
Булево
Номер
Число, Строка
Дата
Дата
Проведен
Булево
Том 1
Назначение
Содержит версию данных документа Содержит признак пометки на удаление Содержит номер документа Содержит дату документа Содержит признак проведенности документа
Отдельные вопросы типового использования документов Нумерация документов Для решения бизнес-задач зачастую серьезным вопросом является нумерация документов. Например, существует даже такое понятие, как «документы строгой учетности», предъявляющие определенные требования к порядку ведения нумерации документов. Для обеспечения этого и других вопросов в системе созданы следующие возможности: На уровне свойствами:
объекта
конфигурации
Документ
можно
управлять
■■ Длина номера – определяет разрядность поля, отводимого под номер документа; ■■ Контроль уникальности – определяет необходимость контроля неповторяемости номеров средствами системы перед записью объекта; ■■ Автонумерация – определяет необходимость формирования новых номеров средствами системы при попытке создания новых объектов; ■■ Периодичность (Непериодический, В пределах года, В пределах квартала, В пределах месяца, В пределах дня) – определяет границы периодов контроля уникальности и повторяемости номеров автонумерации;
505
Глава 10. Документы и последовательности ■■ Тип номера (Строка, Число) – определяет тип поля Номер; ■■ Нумератор – используется для возможности организации сквозной нумерации документов разных видов.
Автоматическая нумерация Автоматическая нумерация позволяет создавать новые документы с заведомо уникальными номерами в пределах указанной периодичности. Для включения этой возможности достаточно установить флажок Автонумерация. Тогда система будет присваивать каждому новому документу номер, на единицу больше самого большого номера среди документов данного вида в пространстве префикса документа, в том периоде, к которому относится дата документа. Причем независимо от того, создается этот новый документ интерактивно или программным способом. Механизм автонумерации позволяет работать в двух режимах: в режиме с возвратом неиспользованных номеров и в режиме без возврата неиспользованных номеров. Режим устанавливается свойством объекта метаданных Конфигурация РежимАвтонумерацииОбъектов. Режим автонумерации прикладных объектов конфигурации определяет, использовать или нет автоматически полученные номера объектов, если они не записаны в базу данных. Для документов, требующих непрерывной нумерации, которая будет реализована при записи, свойство РежимАвтонумерацииОбъектов необходимо установить в значение НеОсвобождатьАвтоматически (этот режим устанавливается стандартно), а значение ОсвобождатьАвтоматически можно использовать для обеспечения механизма нумерации, использующегося в предыдущих версиях платформы «1С:Предприятие». За выдачу номеров отвечает специальный менеджер автонумерации. Его использование позволяет существенно повысить параллельность работы за счет отсутствия блокировок базы данных.
Далее определяется самый большой номер с данным префиксом. Именно он впоследствии будет инкрементироваться для определения следующего номера. Приведем пример работы данного алгоритма. Допустим, в таблице документов содержатся записи со следующими номерами (табл. 10.5). Таблица 10.5. Номера документов Номер
АТ0001 МП_0009 АТР-3 Ф002
Наибольший по алфавиту префикс – Ф. Поскольку самый старший номер с таким префиксом Ф002, то автонумерацией будет создан следующий номер: Ф003. При первом получении номера по определенному пространству номеров и префиксу выполняется неблокирующее чтение максимального номера из базы данных, т. е. механизм автонумерации использует базу данных для получения максимального номера по определенному пространству номеров и префиксу только один раз. При последующих попытках получить очередной номер механизм автонумерации использует максимальный номер по данному пространству номеров и префиксу, как было описано ранее. Ниже на схемах показаны возможные варианты использования автонумерации. Если у свойства Периодичность документа установлено значение Непериодический, то в результате автонумерации будем видеть такую картину (рис. 10.22).
Механизм автонумерации выдает номера в разрезе пространств номеров и префиксов. Пространство номера в зависимости от типа объекта может содержать метаданные, владельца, период и др. В пределах пространства номеров номер выдается в разрезе префиксов. Префикс документа определяется системой путем приведения строковых номеров к числу. Причем к числовому формату цифры номеров приводятся от последней к первой, пока процесс не дойдет до символа, который невозможно распознать как число. После этого символы левой части номера считаются префиксами.
Рис. 10.22. Непериодическая автонумерация
Если у свойства Периодичность документа установлено значение В пределах года, то в результате автонумерации будем видеть такую картину (рис. 10.23).
По каждому префиксу хранится максимальный выданный номер, на основании которого выдается следующий номер. Один и тот же максимальный номер может соответствовать нескольким префиксам. Для получения максимального номера по пустому префиксу система определяет наибольший префикс по порядку алфавитного возрастания.
506
Рис. 10.23. Автонумерация в пределах года
Профессиональная разработка в системе «1С:Предприятие 8»
Документы Однако нельзя забывать о том, что при автонумерации следующий номер, выдаваемый системой, всегда на единицу больше самого старшего. Например, если в последнем примере (с периодичностью год) изменить дату «прошлогоднего документа», то можно получить такую картину: дата документа с номером 00118 была изменена на 01.01.2010. В результате последующие номера, формируемые автонумерацией, начинаются от 00119 (рис. 10.24).
Листинг 10.3. Установка нового номера в пределах префикса автонумерации
Процедура ПриУстановкеНовогоНомера(СтандартнаяОбработка, Префикс) Префикс = Организация.Префикс; КонецПроцедуры
Событие ПриУстановкеНовогоНомера вызывается при записи документа, только если для данного документа назначена автонумерация и только в транзакции записи, между событиями ПередЗаписью и ПриЗаписи объекта Документ (рис. 10.26).
Рис. 10.24. Работа автонумерации при изменении даты документа
Использование лидирующих нулей Если автонумерация применяется для номеров строкового типа, то в этом случае используются лидирующие нули в составе номера. Все пробелы перед самим номером замещаются нулями. Например, 00031. Это необходимо для обеспечения корректности поиска и сортировки по номеру. Иначе документ с номером 31 располагался бы раньше документа с номером 7 (рис. 10.25). Рис. 10.26. Установка нового номера документа в транзакции записи документа
Рис. 10.25. Использование лидирующих нулей
Параллельное ведение нумераций документов одного вида Например, выписываемые от разных юридических лиц накладные должны иметь нумерации, сквозные в пределах каждого отдельного юридического лица. Для решения этой проблемы устанавливается строковый тип номеров документа и автонумерация. Далее необходимо программно назначать префиксы автонумерации в обработчиках соответствующих событий. В результате система формирует новый номер по вышеописанным правилам, но только еще в пределах назначенного префикса автонумерации. Для назначения префикса автонумерации можно использовать обработчик события ПриУстановкеНовогоНомера или метод объекта документа УстановитьНовыйНомер(). Например, если необходимо установить новый номер в пределах префикса автонумерации, значение которого хранится в реквизите Префикс организации, указанной в реквизите документа Организация, можно поступить следующим образом (листинг 10.3). Том 1
Если в процедуре-обработчике этого события параметру Префикс назначить значение, то именно это значение и будет использовано в качестве префикса автонумерации для установки нового номера. Если же, кроме того, номер документа необходимо менять в ответ на изменение значения реквизита Организация, то в соответствующем обработчике события можно применить метод объекта документа УстановитьНовыйНомер(). Он устанавливает новый номер документа в пределах периода, в соответствии с установленной датой документа для заданного префикса автонумерации (листинг 10.4). Листинг 10.4. Обработчик события «ПриИзменении» элемента формы документа «Организация»
&НаКлиенте Процедура ОрганизацияПриИзменении(Элемент) // Установить новый номер согласно префиксу организации. УстановитьНовыйНомерНаСервере(); КонецПроцедуры
507
Глава 10. Документы и последовательности Из обработчика события, возникающего при изменении элемента формы Организация, вызывается метод объекта документа УстановитьНовыйНомерНаСервере() (листинг 10.5). Листинг 10.5. Использование метода документа «УстановитьНовыйНомерНаСервере()»
&НаСервере Процедура УстановитьНовыйНомерНаСервере() Документ = РеквизитФормыВЗначение("Объект"); Документ.УстановитьНовыйНомер(Объект.Организация.Префикс); ЗначениеВРеквизитФормы(Документ, "Объект"); КонецПроцедуры подробнее
Эти примеры приведены в демонстрационной конфигурации «Хранение информации», которая находится на прилагаемом компакт-диске, для документа ПриходныйКассовыйОрдер.
В результате подобных действий можно добиться того, что вне зависимости от порядка оформления документов по разным организациям нумерация будет сквозной именно по каждой из организаций. Вернее по префиксу каждой организации (рис. 10.27).
Рис. 10.28. Использование нумераторов
Для
решения
Нумератор.
такой
задачи
используется
объект
конфигурации
В нем описываются: ■■ ■■ ■■ ■■
Длина номера, Контроль уникальности, Периодичность, Тип номера.
Далее у всех документов – объектов конфигурации, для которых нужна сквозная нумерация, указывается этот нумератор и устанавливается свойство Автонумерация. В результате формирование нового номера производится при обращении уже не к одной таблице документов информационной базы, а к таблицам документов, которым назначен данный нумератор.
Запись документов Запись документа может производиться как из формы документа, так и не из формы документа. Рис. 10.27. Автонумерация с использованием префиксов
Хотелось бы упредить от попыток использования префиксов, которые целиком входят в состав других префиксов, например, АИ и А. В этом случае, как разбирали выше, при попытке формирования нового номера с префиксом А получим следующий номер от префиксации АИ. Дело в том, что механизм автонумерации считает префикс А зависимым от префикса АИ и изменяет максимальный номер зависимых префиксов в соответствии с номером того префикса, в состав которого они входят.
Организация сквозной нумерации при помощи нумераторов Кроме разделения нумерации может возникнуть обратная задача – обеспечение общей сквозной нумерации. Обычно это требуется, когда имеется несколько видов документов для отражения похожих хозяйственных операций, но необходимо организовать для них сквозную нумерацию, невзирая на вид документа (рис. 10.28).
508
В первом случае запись документа инициируется расширением формы документа (для функционирования этого расширения необходимо, чтобы основным реквизитом формы был объект документа). Работа расширения формы обеспечивает специфичное, удобное для пользователя поведение формы при редактировании и записи документа. Во втором случае форма документа не используется, а обращение идет непосредственно к объекту документа. При реализации записи документа из формы, кроме самой записи, выполняются еще стандартные действия, определяемые расширением формы: установка даты документа, установка режима проведения, запрет определенных действий пользователя и т. д. подробнее
Раздел «Особенности работы формы документа», стр. 520.
При записи документа не из формы выполняется только запись документа (рис. 10.29). Профессиональная разработка в системе «1С:Предприятие 8»
Документы Причем если модифицированы были значения реквизитов документа, а не табличной части документа, то данное действие вообще не выполняется; ■■ Запись данных в таблицы журналов, если данные документа используются в этих журналах; ■■ Запись данных в таблицы регистрации изменений планов обменов, если данный документ входит в состав обмениваемых данных. Причем сама запись документа может вызываться интерактивно или программно. Рис. 10.29. Запись документа
При выполнении самой записи документа производятся следующие действия: ■■ Контроль уникальности номера документа. Выполняется, если у документа как объекта конфигурации установлено свойство Контроль уникальности. При этом если у документа установлено свойство Автонумерация, при попытке редактирования номера документа будет получено предупреждение: «Номер заполняется при записи автоматически. Продолжить редактирование?». Затем, если номер документа был изменен, в транзакции записи между событиями ПередЗаписью и ПриЗаписи объекта Документ выполняется контроль уникальности номера документа, и, если номер не уникальный, транзакция записи отменяется; ■■ Проверка версии документа. Проверяется идентичность версий объекта документа и версии записей базы данных, хранящих данные этого документа. Если версии не совпадают, транзакция прерывается и выдается предупреждение: «Операция не может быть выполнена из-за несоответствия версии или отсутствия записи базы данных (возможно запись была изменена или удалена)!». Это необходимо, например, при следующей ситуации: некой обработкой программно было обеспечено, что для двух пользователей были открыты формы одного и того же документа. Первый пользователь изменил значение Контрагента в документе, второй – значение Номенклатуры. На момент первой попытки записи измененного документа версии объекта документа и записей базы данных совпадут – документ будет записан. Но при попытке записи документа другим пользователем версии не совпадут, и система не позволит записать параллельно измененный документ, поскольку данное действие может породить коллизии; ■■ Запись данных в таблицы документов; ■■ Запись данных в таблицы табличных частей документов. Данное действие оптимизировано по скорости исполнения. Это происходит за счет автоматического различения ситуаций, когда необходимо записать (модифицировать) данные всех записей, подчиненных записываемому документу, или только одной записи. Том 1
Интерактивно запись инициируется действиями пользователей, приводящими к выполнению системных действий: ■■ ■■ ■■ ■■
«Записать», «Провести и закрыть»/«Записать и закрыть», «Провести», «Отмена проведения».
Программно в контексте формы документа запись может быть инициирована посредством метода Записать() расширения формы документа. Причем методу может быть передана структура ПараметрыЗаписи, содержащая предопределенные параметры записи РежимЗаписи и РежимПроведения. Параметр
РежимЗаписи содержит значения из системного перечисления РежимЗаписиДокумента: Запись, ОтменаПроведения, Проведение. В зави-
симости от значения параметра поведение системы будет различным. Например, для значения Запись будет вызвана запись данного документа без проведения, для значения Проведение – запись с проведением, для значения ОтменаПроведения – запись с отменой проведения. Параметр РежимПроведения используется в случае записи документа с проведением и содержит значения из системного перечисления РежимПроведенияДокумента: Неоперативный, Оперативный. Для значения Неоперативный будет выполнено неоперативное проведение документа, т. е. проведение выполняется не в реальном времени (например, проведение задним числом), для значения Оперативный будет выполнено оперативное проведение документа, т. е. проведение выполняется в реальном времени (например, при этом может быть выполнен контроль текущих остатков).
Действие «Записать» При записи документа, вызванной интерактивным действием Записать или применением метода Записать(Новый Структура("РежимЗаписи", РежимЗаписиДокумента.Запись), кроме самой записи инициируется последовательность событий. Для непроведенного документа последовательность событий при записи из формы документа будет следующей (рис. 10.30а).
509
Глава 10. Документы и последовательности
Рис. 10.30а. Вызов событий при выполнении действия «Записать» для непроведенного документа
Следует иметь в виду, что для расширения формы документа платформа по умолчанию устанавливает свойство ПриЗаписиПерепроводить. То есть при записи проведенного документа будет автоматически выполняться его перепроведение. В этом случае для проведенного документа последовательность событий при записи из формы документа будет следующей (рис. 10.30б).
Рис. 10.30б. Вызов событий при выполнении действия «Записать» для проведенного документа
Если свойство ПриЗаписиПерепроводить у расширения формы документа не установлено, то последовательность событий при записи в форме для проведенного документа будет такой же, как и у непроведенного документа (см. рис. 10.30а). Для документа, у которого запрещено проведение (свойство Проведение установлено в значение Запретить), последовательность событий при записи из формы документа будет следующей (рис. 10.30в). Часть событий относится к контексту формы документа, и они могут быть перехвачены соответствующими обработчиками событий, располагаемыми в модуле формы документа. Часть событий относится к контексту объекта документа, и они могут быть перехвачены там. Заметьте, что при записи проведенного документа с перепроведением (см. рис. 10.30б) и при записи документа, у которого запрещено проведение (см. рис. 10.30в), кроме самой записи в контексте формы и в контексте объекта вызывается также событие ОбработкаПроверкиЗаполнения, которое вызывается расширением формы при необходимости проверки заполнения реквизитов при записи или при проведении документа в форме. В обработчиках этого события в модуле формы или в модуле объекта разработчик может самостоятельно реализовать проверку заполнения данных формы.
510
Рис. 10.30в. Вызов событий при выполнении действия «Записать» для документа, у которого запрещено проведение
Профессиональная разработка в системе «1С:Предприятие 8»
Документы В обработчиках события ПередЗаписью посредством установки параметру Отказ значения Истина можно предотвратить последующий набор действий. То есть, например, если установлен отказ в записи документа на уровне контекста формы документа, то последующие в показанной выше схеме события уже не произойдут, поскольку платформа прекращает выполнение данной последовательности действий.
Действие «Отмена проведения» В случае записи документа, вызванной системным действиями «Отмена проведения» или применением метода Записать(Новый Структура("РежимЗаписи", РежимЗаписиДокумента.ОтменаПроведения), кроме самой записи инициируются следующие события (рис. 10.32).
Действия «Провести и закрыть», «Провести» В случае записи документа, вызванной интерактивными действиями Провести и закрыть (если у документа не запрещено проведение), Провести или применением метода Записать(Новый Структура("РежимЗаписи", РежимЗаписиДокумента.Проведение), кроме самой записи инициируются следующие события (рис. 10.31).
Рис. 10.32. Вызов событий при выполнении действия «Отмена проведения»
То есть в этом случае появляется еще событие ОбработкаУдаленияПроведения. Процедура-обработчик этого события также может располагаться только в модуле объекта документа, содержит указание действий, которые должны быть выполнены при отмене проведения, и имеет параметр Отказ. Применение этого параметра аналогично разобранным выше случаям. Рис. 10.31. Вызов событий при выполнении действий «Провести и закрыть», «Провести»
То есть добавляется еще одно событие – ОбработкаПроведения. Процедура-обработчик этого события может находиться только в модуле объекта документа, предназначена для указания действий, которые нужно выполнить при проведении документа, и также имеет параметр Отказ. Действия с ним аналогичны предыдущему случаю. То есть последующие события уже не выполняются, если параметру Отказ установлено значение Истина. Том 1
Если запись документа производится не в форме, отличия состоят в том, что при выполнении этого действия не задействуются события, связанные с формой. Например, программная запись с проведением будет производиться следующим образом (рис. 10.33).
511
Глава 10. Документы и последовательности
Рис. 10.34. Последовательность работы с документом
Свойство «Проведение» объекта конфигурации Свойство Проведение объекта конфигурации значения Разрешить или Запретить.
Рис. 10.33. Последовательность событий при программной записи объекта документа с проведением
Проведение документов Ввод информации в документ в общем случае может осуществляться не за один раз. Кроме того, часть информации, необходимой для полной регистрации события в учетных механизмах, может становиться известной не сразу, а часть информации может быть получена в результате анализа и обработки исходной. Поэтому в системе есть возможность различать состояния документа – «введен» и «проведен». Для этого чаще всего разделяются операции ввода первичной информации (заполнение документа) и отражения данных документа в учете (обработка первичной информации и формирование движений), рис. 10.34. Обработку информации для отражения в учете и формирование движений по регистрам обычно выполняют при проведении документа. Данный механизм удобен для выполнения подобных действий.
Документ
может иметь
В первом случае поведение документа соответствует вышеописанному (разделение операций заполнения документа и отражения его данных в учетных механизмах). То есть именно для таких документов имеют смысл работа с полем Проведен и процесс Проведение. Если же свойство объекта конфигурации Проведение имеет значение Запретить, это означает, что такой документ вообще не должен проводиться. Такая ситуация может использоваться: ■■ для документов, для которых нет необходимости в индикации того, что выполнены изменения в учетных механизмах, либо когда такие изменения документами не производятся; ■■ для документов, которые используются для интерактивного ввода движений (например, документ Ручная операция). Поскольку в случае ручной операции нет разделения информации на исходную (информацию документа) и обработанную (информация, записываемая в регистр со ссылкой на документ), информация сразу же вводится в регистр (рис. 10.35).
Рассмотрим более подробно варианты проведения документов. Их использование определяется значениями свойств документа как объекта конфигурации, а именно: ■■ ■■ ■■ ■■
Проведение, Оперативное проведение, Удаление движений, Запись движений при проведении.
512
Рис. 10.35. Ручная операция
Профессиональная разработка в системе «1С:Предприятие 8»
Документы Для документов, у которых запрещено проведение, системное поле Проведен при записи получает значение Ложь. Но во всех таблицах, отображающих данные динамических списков документов или журналов документов, пиктограмма документов, у которых запрещено проведение, похожа на пиктограмму проведенных документов. Таким образом, система подсказывает пользователю, что больше никакой обработки для данных документов не требуется (рис. 10.36). Рис. 10.37. Общие случаи регистрации событий
Оперативное проведение используется в ситуациях, когда есть необходимость отличать проведение в реальном режиме времени (оперативное) от другого и выполнять различные действия для одного и другого режимов. Рис. 10.36. Пиктограмма документа, для которого запрещено проведение
Поведение форм, основным реквизитом которых является объект или список документа, учитывает значение свойства Проведение. Например, в командной панели формы документа с запрещенным проведением система не создает кнопок с действиями «Провести» или «Отмена проведения».
Вариант использования данного механизма может, например, включать разделение случаев (рис. 10.38): ■■ когда документ проводится в реальном времени и есть необходимость, например, проконтролировать остаток товаров на складе при проведении документа; ■■ когда проведение документа просто отражает уже свершившийся факт и нужно просто зафиксировать в учетных механизмах совершенное событие.
Однако система не запрещает попыток программной записи таких документов с проведением или с отменой проведения. Не запрещает, но все подобные попытки реализует по схеме обычной записи документа без проведения.
Свойство «Оперативное проведение» объекта конфигурации Свойство Оперативное проведение объекта конфигурации Документ может иметь значения Разрешить или Запретить. Для документов, у которых данное свойство имеет значение Разрешить, разрешено использование механизма оперативного проведения. Поскольку посредством документов производится регистрация событий, причем на временной оси, то в общем случае положение проводимого документа может быть отнесено к прошлому, настоящему или будущему. Как правило, документы, относимые к прошлому, регистрируют уже произошедшие события. Обычно такой способ регистрации называют «задним числом». В настоящем регистрируются события, которые только-только происходят. Такой способ регистрации называют «реальным временем». Кроме того, бывают ситуации, когда событие должно быть зарегистрировано в будущем. Например, при решении задач планирования (рис. 10.37). Том 1
Рис. 10.38. Оперативное и неоперативное проведение
С точки зрения технологических средств механизм оперативного проведения включает в себя: ■■ запрет проведения будущей датой; ■■ использование механизма оперативной отметки времени для принудительного изменения значения даты документа в случаях, когда это требуется. В ситуации, когда пользователи системы находятся в разных часовых поясах, в пределах одной информационной базы может существовать несколько последовательностей оперативных отметок времени, каждая – для своего часового пояса; ■■ передачу в обработчик события ОбработкаПроведения параметру РежимПроведения значения Оперативный системного перечисления РежимПроведенияДокумента.
513
Глава 10. Документы и последовательности В каких случаях можно намеренно не использовать механизм оперативного проведения? В любых, когда его использование не требуется логикой решаемой задачи. Например: ■■ когда нет нужды использовать разные алгоритмы проведения документов для оперативного или неоперативного режимов; ■■ когда не требуется при проведении документов обеспечивать их расположение в определенном порядке на временной оси посредством выдачи оперативных отметок времени. При отказе от использования механизма оперативного проведения главное – не нарушить логику его использования для других документов. Например, если для проведения документа Поступление товаров используется один и тот же алгоритм для любого вида проведения, это еще не означает, что можно установить запрет использования режима оперативного проведения. Его проведение будущей датой изменит данные оперативных итогов регистров именно будущей датой. То есть будет различие между актуальными итогами регистров и итогами на момент оперативной отметки времени. Это может привести к нарушению логики использования механизма оперативного проведения для документов Реализация товаров.
Свойство «Удаление движений» объекта конфигурации Свойство Удаление движений объекта конфигурации Документ может иметь значения Удалять автоматически при отмене проведения (стандартное значение), Удалять автоматически или Не удалять автоматически. В случае значения Удалять автоматически при отмене проведения для свойства Удаление движений движения, связанные с документом, удаляются автоматически только при удалении и отмене проведения документа. При проведении документа движения не удаляются, а перезаписываются. Такое поведение является стандартным для платформы «1С:Предприятие». Используя два других значения свойства Удаление движений, разработчик может реализовывать нестандартные сценарии проведения документа. В случае значения Удалять автоматически для свойства Удаление движений платформа сама автоматически удаляет старые записи движений, связанных с данным документом, в следующих ситуациях: ■■ при записи документа с проведением (старые записи удаляются, а новые формируются); ■■ при пометке документа на удаление (процесс, а не состояние); ■■ при отмене проведения документа (процесс, а не состояние).
514
В случае же значения Не удалять автоматически для свойства Удаление движений автоматическое удаление движений для этих ситуаций производиться не будет. Например, ответственность за правильность оформления заказов покупателей лежит на отделе продаж. Однако заказы выборочно контролируются финансовым отделом. При обнаружении нарушений в назначении цен документ снимается с проведения, что означает необходимость его дальнейшей доработки. Но движения по регистрам учета при этом удаляться не должны, чтобы не исключать данный заказ из учета вообще.
Свойство «Запись движений при проведении» объекта конфигурации Свойство Запись движений при проведении объекта конфигурации Документ может иметь значения Записывать выбранные (стандартное значение) или Записывать модифицированные. В случае значения Записывать выбранные разработчик должен в обработчике проведения документа в явном виде указать, какие наборы движений документа следует записывать. Для этого нужно установить свойство набора записей Записывать в значение Истина. После выхода из обработки проведения те наборы записей, у которых свойство Записывать все еще имеет значение Истина, будут автоматически записаны платформой. При выполнении записи движений, например, при оперативном проведении документа методом Записать(), свойство Записывать у записанных наборов движений сбрасывается в значение Ложь. Такое поведение является стандартным для платформы «1С:Предприятие» и оптимизирует запись измененных наборов записей без удаления движений в начале проведения. В случае значения Записывать модифицированные для свойства Запись движений при проведении после выхода из обработки проведения все модифицированные наборы записей будут автоматически записаны платформой.
Свойства «Привилегированный режим при проведении», «Привилегированный режим при отмене проведения» объекта конфигурации Для ускорения работы с документом платформа стандартно устанавливает свойства документа Привилегированный режим при проведении и Привилегированный режим при отмене проведения. В результате проведение и отмена проведения документа выполняются на сервере, без контроля прав, максимально быстро.
Профессиональная разработка в системе «1С:Предприятие 8»
Документы
Использование механизма оперативного проведения Рассмотрим, как работает механизм при интерактивном проведении из формы документа. Пусть документу как объекту конфигурации разрешено оперативное проведение (свойство Оперативное проведение имеет значение Разрешить), и свойство ИспользоватьРежимПроведения расширения формы документа имеет значение Автоматически. При этом значении режим проведения документов из формы будет подбираться системой автоматически, исходя из даты документа, позиции документа по отношению к оперативной отметке времени и других параметров.
Запрет проведения будущей датой При проведении документа система прежде всего проверит положение даты документа относительно текущей даты сеанса. Текущая дата сеанса равна системной дате компьютера, приведенной к часовому поясу сеанса. В свою очередь, часовой пояс сеанса изначально равен часовому поясу информационной базы (если он установлен – УстановитьЧасовойПоясИнформационнойБазы()) или часовому поясу сервера. Часовой пояс сеанса можно установить программно – УстановитьЧасовойПоясСеанса().
Рис. 10.39. Использование оперативной отметки времени
Если дата документа на день позже текущей даты сеанса, пользователь получит предупреждение: «Дата оперативно проводимого документа больше текущей. Документ не может быть проведен оперативно!». Проведение при этом не состоится. Если дата документа на день меньше текущей даты сеанса, документ будет проведен неоперативно. Если обе даты определяют один и тот же день, система принимает решение, что документ может быть проведен оперативно, то есть реальным временем.
Механизм оперативной отметки времени
Рис. 10.40. Формирование оперативной отметки времени
Для того чтобы документы располагались последовательно и не попадали внутрь одной секунды (внутри одной секунды порядок следования не будет зависеть от разработчика), система выполняет автоматическое изменение времени документа. Дата документа получает значение оперативной отметки времени, которая рассчитывается системой по определенному алгоритму.
Если одновременно проводить оперативно несколько документов, то результат работы данного механизма можно представить следующим образом (рис. 10.41).
Далее управление передается обработчику события ОбработкаПроведения, при этом параметр РежимПроведения получает значение РежимПроведенияДокумента.Оперативный (рис. 10.39). Механизм оперативной отметки времени позволяет при параллельной работе пользователей записывать оперативно проводимые документы с возрастающей последовательностью значений свойства Дата. Дата оперативно проводимого документа получается равной текущей дате сеанса или на секунду больше предыдущей выданной оперативной отметки времени (рис. 10.40). Том 1
Рис. 10.41. Использование оперативной отметки времени
515
Глава 10. Документы и последовательности Как уже говорилось выше, в пределах одной информационной базы может существовать несколько последовательностей оперативных отметок времени. Если все пользователи работают в одном и том же часовом поясе, то тогда последовательность оперативных отметок времени будет однаединственная. Если же есть пользователи, работающие в других часовых поясах, тогда таких последовательностей будет несколько, каждая для своего часового пояса. Последняя выданная оперативная отметка времени для каждого часового пояса сеанса хранится до момента выхода из программы последнего пользователя (включая и режим работы Конфигуратор). В клиент-серверном варианте работы системы эти отметки хранятся на сервере, в оперативной памяти. Хранение и выдачу оперативных отметок времени на сервере поддерживает сервис времени. В файловом варианте работы системы такие отметки хранятся в специальной служебной таблице информационной базы. Получение оперативной отметки времени может выполняться не только автоматически, но и разработчиком посредством метода ПолучитьОперативнуюОтметкуВремени(), листинг 10.6. Листинг 10.6. Получение оперативной отметки времени
НоваяОперативнаяОтметкаВремени = ПолучитьОперативнуюОтметкуВремени();
Хотелось бы обратить внимание на ограничение формирования даты документа при интерактивном проведении документа в пределах дня. Если в рамках одного дня уже выдана оперативная отметка времени со временем 23:59:59, то следующий оперативно проводимый документ того же дня выдаст пользователю сообщение о невозможности провести данный документ оперативно (в рамках того же дня) – «Дата документа не соответствует текущей дате или дате последнего оперативно проведенного документа. Документ не может быть проведен оперативно!», и проведение документа не состоится (рис. 10.42).
тивно или же иметь возможность провести документ неоперативно. Однако для того, чтобы пользователь мог выбирать режим проведения, свойство ИспользоватьРежимПроведения расширения формы документа должно быть установлено в значение Запрашивать, и у пользователя должно быть право на неоперативное проведение. Если же свойство ИспользоватьРежимПроведения имеет значение Автоматически или Оперативный, то платформа будет пытаться выполнить оперативное проведение документа, что приведет к сообщению об ошибке. подробнее
Раздел «Установка режима проведения», стр. 521.
Налицо определенное ограничение, накладываемое системой. Однако в практике ввода документов реальным временем столкнуться с ним почти невозможно. Для воспроизведения такой ситуации требуется, чтобы, например, 61 одновременно работающий пользователь в течение последней минуты уходящего дня начал проведение оперативно проводимых документов. Если же все же подобная ситуации при автоматизации некоего предприятия с ночным режимом работы имеет место, 61-й и последующие документы, скорее всего, можно уже датировать следующим днем либо обеспечить их возможность проведения в неоперативном режиме. Ведь невозможность оперативного проведения еще не означает невозможность проведения вообще. Кроме того, запись документов с проведением может еще вызываться и программно. В таком случае можно указать режим проведения в параметре РежимПроведения (листинг 10.7). Листинг 10.7. Указание режима программного проведения документа
Записать(РежимЗаписиДокумента.Проведение, РежимПроведенияДокумента.Оперативный);
Тогда поведение системы в отношении установки даты документа и передачи параметра обработчику события ОбработкаПроведения будет соответствовать оперативному проведению. Однако необходимо помнить, что дата документа при этом должна соответствовать дню текущей даты сеанса. Иначе обработка проведения пойдет по схеме неоперативного проведения. Рис. 10.42. Получение оперативной отметки времени следующим днем
Сделано это потому, что дата документа может иметь юридическое значение. Поэтому в такой ситуации у пользователя есть два варианта: изменить дату документа следующим днем и провести документ опера-
516
Проблемы выдачи оперативной отметки времени после 23:59:59 при программной записи документов с оперативным проведением нет. Поскольку программное проведение означает вмешательство неких алгоритмов в ход формирования, заполнения и записи документов, то в данном случае может оказаться, что некому реагировать на предупреждение Профессиональная разработка в системе «1С:Предприятие 8»
Документы о невозможности оперативного проведения в рамках того же дня. Поэтому система для подобного документа просто сформирует дату на секунду больше последней оперативной отметки времени. Если потребуется не допустить формирования и проведения документов с датой будущего дня, это можно обеспечить программно, в составе соответствующих обработчиков.
Передача значения «Оперативный» в параметр «РежимПроведения» обработчика события «ОбработкаПроведения» Итак, при оперативном проведении документов система позволяет добиться расстановки документов в идеальной хронологической последовательности (каждое событие зарегистрировано на момент его отражения в учете) и, кроме того, известить об этом обработчик проведения. То есть с точки зрения отражения документа в учете сам механизм оперативного проведения не выполняет никаких действий, он только передает параметр в обработчик проведения. Что это дает разработчику? Дает возможность отличать ситуации проведения документов реальным временем от иных ситуаций. А это уже впоследствии может быть использовано для решения прикладных задач. Может использоваться следующая градация действий при проведении документов: ■■ при оперативном проведении – помощь пользователю посредством контроля возможности операции и правильности ее оформления, после этого – отражение ее в учетных механизмах; ■■ при неоперативном проведении – отражение в учетных механизмах факта свершившегося события без всякой обработки. То есть, например, при проведении документа РеализацияТоваров алгоритм обработки оперативного проведения будет контролировать остатки товаров, перечисленных в табличной части документа, на складе, указанном в документе. Для этого в процедуре обработки проведения после записи движений документа будут получены актуальные остатки расходуемых товаров из регистра накопления ТоварыНаСкладах. В случае отрицательных остатков какого-либо товара на складе (а значит, невозможности отгрузки) пользователь будет получать соответствующее сообщение, и документ проводиться не будет. Если пользователь проводит документ, соответствующий уже произошедшему событию (неоперативно), нужда в контроле остатка отпадает. Например, вчера отключилось электричество, и не успели отразить в программе операцию отгрузки двух холодильников со склада. Вводя сегодня данные о событии вчерашней отгрузки, контролировать возможность данной операции уже бессмысленно, поскольку холодильники уже отгружены (листинг 10.8). Том 1
подробнее
Пример алгоритма проведения документа РеализацияТоваров содержится в демонстрационной конфигурации «Хранение информации», которая находится на прилагаемом компакт-диске. Листинг 10.8. Пример процедуры «ОбработкаПроведения»
Процедура ОбработкаПроведения(Отказ, РежимПроведения) // Укажем, по каким регистрам нужно записывать движения. Движения.ТоварыНаСкладах.Записывать = Истина; Движения.Продажи.Записывать = Истина; // Создать менеджер временных таблиц. МенеджерВТ = Новый МенеджерВременныхТаблиц; Запрос = Новый Запрос; // Укажем, какой менеджер временных таблиц использует этот запрос. Запрос.МенеджерВременныхТаблиц = МенеджерВТ; Запрос.Текст = "ВЫБРАТЬ | РеализацияТоваровСостав.Номенклатура, | РеализацияТоваровСостав.Номенклатура.Услуга КАК Услуга, | СУММА(РеализацияТоваровСостав.Количество) КАК | КоличествоВДокументе, | СУММА(РеализацияТоваровСостав.Сумма) КАК СуммаВДокументе |ПОМЕСТИТЬ НоменклатураДокумента |ИЗ | Документ.РеализацияТоваров.Состав КАК РеализацияТоваровСостав |ГДЕ | РеализацияТоваровСостав.Ссылка = &Ссылка | |СГРУППИРОВАТЬ ПО | РеализацияТоваровСостав.Номенклатура, | РеализацияТоваровСостав.Номенклатура.Услуга";
Запрос.УстановитьПараметр("Ссылка", Ссылка);
Результат = Запрос.Выполнить();
Запрос2 = Новый Запрос; Запрос2.МенеджерВременныхТаблиц = МенеджерВТ; Запрос2.Текст = "ВЫБРАТЬ | НоменклатураДокумента.Номенклатура, | НоменклатураДокумента.Услуга, | НоменклатураДокумента.КоличествоВДокументе, | ЕСТЬNULL(НоменклатураДокумента.СуммаВДокументе, 0) | КАК СуммаВДокументе |ИЗ | НоменклатураДокумента КАК НоменклатураДокумента"; Если РежимПроведения = РежимПроведенияДокумента.Оперативный Тогда // Установим необходимость блокировки данных в регистре ТоварыНаСкладах. Движения.ТоварыНаСкладах.БлокироватьДляИзменения = Истина; // Запишем пустые наборы записей, чтобы читать остатки без // учета данных в документе. Движения.ТоварыНаСкладах.Записать(); КонецЕсли;
Результат = Запрос2.Выполнить();
517
Глава 10. Документы и последовательности
ВыборкаДетальныеЗаписи = Результат.Выбрать();
Пока ВыборкаДетальныеЗаписи.Следующий() Цикл Если НЕ ВыборкаДетальныеЗаписи.Услуга Тогда // Сформировать движения по регистру ТоварыНаСкладах (расход). Движение = Движения.ТоварыНаСкладах.Добавить(); Движение.ВидДвижения = ВидДвиженияНакопления.Расход; Движение.Период = Дата; Движение.Номенклатура = ВыборкаДетальныеЗаписи.Номенклатура; Движение.Склад = Склад; Движение.Количество = ВыборкаДетальныеЗаписи.КоличествоВДокументе; КонецЕсли; // Сформировать движения по регистру Продажи. Движение = Движения.Продажи.Добавить(); Движение.Период = Дата; Движение.Номенклатура = ВыборкаДетальныеЗаписи.Номенклатура; Движение.Контрагент = Контрагент; Движение.Количество = ВыборкаДетальныеЗаписи.КоличествоВДокументе; Движение.Сумма = ВыборкаДетальныеЗаписи.СуммаВДокументе; Движение.ВидОперации = ВидОперации; КонецЦикла;
Движения.Записать();
Если РежимПроведения = РежимПроведенияДокумента.Оперативный Тогда // Проверить отрицательные остатки. Запрос3 = Новый Запрос; Запрос3.МенеджерВременныхТаблиц = МенеджерВТ; Запрос3.Текст = "ВЫБРАТЬ | ТоварыНаСкладахОстатки.Номенклатура, | ТоварыНаСкладахОстатки.КоличествоОстаток |ИЗ | РегистрНакопления.ТоварыНаСкладах.Остатки( | , | Номенклатура В | (ВЫБРАТЬ | НоменклатураДокумента.Номенклатура | ИЗ | НоменклатураДокумента) | И Склад = &Склад) КАК ТоварыНаСкладахОстатки |ГДЕ | ТоварыНаСкладахОстатки.КоличествоОстаток < 0"; Запрос3.УстановитьПараметр("Склад", Склад); РезультатСНехваткой = Запрос3.Выполнить(); ВыборкаРезультатаСНехваткой = РезультатСНехваткой.Выбрать(); Пока ВыборкаРезультатаСНехваткой.Следующий() Цикл Сообщение = Новый СообщениеПользователю(); Сообщение.Текст = "Не хватает " + Строка( ВыборкаРезультатаСНехваткой.КоличествоОстаток) + " единиц товара """ + ВыборкаРезультатаСНехваткой.Номенклатура + """ на складе """ + Склад + "."; Сообщение.Сообщить(); Отказ = Истина; КонецЦикла; КонецЕсли; КонецПроцедуры
518
Рассмотрим подробно последовательность действий в процедуре боткаПроведения.
Обра-
Сначала в обработчике указываются наборы записей, содержащие движения документа по регистрам, которые должны быть записаны при проведении документа. Для этого нужным наборам записей устанавливается свойство Записывать в значение Истина (например, Движения.ТоварыНаСкладах.Записывать = Истина). Затем данные табличной части документа РеализацияТоваров помещаются во временную таблицу. Эти данные посредством менеджера временных таблиц будут затем использованы в запросе для формирования движений документа и в запросе к регистру накопления для контроля остатков товаров на складах. Заметьте, что данные табличной части документа группируются по полям Номенклатура и Услуга, чтобы суммировать поля Количество и Сумма при наличии в документе нескольких строк с одинаковой номенклатурой. Затем в случае оперативного проведения документа (РежимПроведения = РежимПроведенияДокумента.Оперативный) данные регистра ТоварыНаСкладах блокируются путем установки свойства БлокироватьДляИзменения в значение Истина. Это делается для того, чтобы заблокировать остатки от чтения другими транзакциями до тех пор, пока не будет завершена текущая транзакция. А также движения данного документа в регистре очищаются путем записи пустого набора данных (Движения.ТоварыНаСкладах.Записать()). Это обеспечивает чтение остатков без учета существующих движений документа (в случае его перепроведения). Далее выполняется запрос к временной таблице, содержащей перечень расходуемых товаров, и в цикле выборки результата запроса формируются движения по нужным регистрам. Затем движения документа в регистрах записываются в явном виде (Движения.Записать()). Метод Записать() выполняет запись всех наборов движений, у которых свойство Записывать установлено в значение Истина. И, наконец, при оперативном проведении выполняется контроль достаточности остатка товаров на складе. Для этого после записи движений выполняется запрос для получения отрицательных остатков номенклатуры, содержащейся во временной таблице, и на складе, указанном в документе. После этого выборка записей запроса обходится в цикле, и, если есть такие записи, сообщение о них выводится пользователю. В результате документ не проводится, т. к. параметру Отказ присваивается значение Истина. Если каждый документ, формирующий движения в количественном учете, будет проводиться с поддержкой механизма оперативного проведения и движения его будут датироваться именно датой документа, то можно быть уверенным в двух фактах: ■■ не будет ситуации, когда два документа претендуют на одно и то же время (механизм выдачи оперативной отметки времени распределит их с интервалом в секунду); Профессиональная разработка в системе «1С:Предприятие 8»
Документы ■■ текущий проводимый документ находится на временной оси всегда позже последнего оперативно проведенного документа. А это важно при получении остатков из регистров. Так как кроме движений и помесячных остатков таблицы регистров хранят еще подсчитанные итоги, актуальные на момент времени последней записи в них. И если мы уверены, что «за» оперативной отметкой времени не было движений, то тогда для получения актуальных данных контроля остатка можно использовать виртуальную таблицу остатков регистра без указания параметра Период (или с указанием значения Неопределено в качестве его значения). Данная операция будет выполняться быстрее, если в качестве параметра передать значение момента времени документа. Потому что при отсутствии параметра система не будет пытаться обращаться к таблице записей регистра для «досчета» остатков до нужной временной точки, а сразу возьмет данные последних актуальных итогов из таблицы итогов данного регистра (рис. 10.43).
Листинг 10.9. Оперативное программное проведение документа
Записать(РежимЗаписиДокумента.Проведение, РежимПроведенияДокумента.Оперативный);
И если документ пытаются записать в будущем, выдается соответствующее предупреждение о невозможности выполнения данной операции. Но вот программное неоперативное проведение документов система не запрещает. Кроме того, при формировании движений можно добиться ситуации, чтобы Период движения не совпадал со значением Дата документа. То есть в принципе движения могут быть сформированы будущей датой. Ответственность за недопущение подобных фактов – на разработчике. В завершение хотелось бы отметить, что использование механизма оперативного проведения может быть составной частью более сложных алгоритмов. Например, для того, чтобы во время активного ввода информации сократить количество действий по отражению документов в учете (а значит, обеспечить большую скорость проведения документов), часть этих действий не выполняется при неоперативном проведении, а часть относится на действия, выполняемые регламентными обработками. Стратегия отражения документов в учетных механизмах выглядит тогда следующим образом:
Рис. 10.43. Получение итогов регистра
Но нужно понимать, что для корректности использования механизма оперативного проведения при данном алгоритме работы необходимо сделать так, чтобы никакими способами не были сформированы движения в будущем. Иначе использование актуальных итогов регистров в обработке проведения будет невозможно (вернее придется рассчитывать регистры на момент времени документа, но тогда какой смысл в оперативной работе, если при этом итоги регистров не будут актуальны на момент оперативно проводимого документа). В основном это обеспечивается системой: стандартные команды форм не позволяют пользователю оперативно проводить документы будущей датой и не предлагают в таких случаях проводить документы неоперативно. Кроме того, система при выполнении попытки программной записи с проведением в оперативном режиме (листинг 10.9) сначала выполняет проверку положения даты документа относительно дня оперативной отметки времени. Том 1
■■ при оперативном проведении – помощь пользователю посредством контроля возможности операции и правильности ее оформления, отражение совершаемого события только в механизмах, обеспечивающих контрольные функции при оперативном проведении других документов; ■■ при неоперативном проведении – отражение факта свершившегося события без всякой обработки и только в учетных механизмах; ■■ при проведении специальной регламентной обработкой – отдельно для каждого зарегистрированного события контроль возможности и правильности его оформления, отражение данного события во всех оставшихся учетных механизмах. Примером подобного использования механизма оперативного проведения можно считать задачу проведения документа, отражающего реализацию товаров со склада не только в количественном, но и в количественностоимостном учете. Постановка задачи может быть следующей: при реализации товаров со склада реальным временем (оперативное проведение) необходимо предварительно выполнить ряд проверок правомерности этой операции (наличие достаточного остатка на складе, контроль предоплаты со стороны покупателя). Эти проверки и сама регистрация факта отгрузки в количественном учете товаров на складе выполняются в обработке проведения документа. Если же требуется проведение документа реализации задним числом (неоперативное проведение), это означает необходимость отражения уже свершившегося факта. Тогда не требуется проверять предоплату и наличие
519
Глава 10. Документы и последовательности товаров на складе, поскольку товар уже отгружен клиенту. Нужно просто отразить факт отгрузки в количественном учете товаров на складе при проведении документа. Окончательное же отражение произошедших событий в механизме количественно-стоимостного учета товаров на складе производится посредством отдельной регламентной обработки, которая будет выполняться не в период активного ввода первичной информации, а впоследствии. При ее выполнении будут собраны все необходимые данные для всех еще не полностью отраженных событий, проведены все необходимые проверки и расчеты, и приписаны необходимые движения к документам реализации. Периодичность выполнения этой обработки определяется пользователем. Например, чтобы быть достаточной для получения регламентной отчетности (рис. 10.44).
Особенности работы формы документа Если
основной
реквизит формы имеет тип значения то для данной формы действует расширение формы документа. Посредством него решаются вопросы специфичной функциональности формы документа. Расширение помогает обрабатывать различные команды пользователя, выполнять предварительные проверки и другие сервисные действия. ДокументОбъект.<имя>,
Кроме того, действие расширения формы документа распространяется и на механизмы записи и проведения документа. При этом не важно, была вызвана запись документа интерактивными действиями пользователя в форме документа или средствами языка методом Записать(). Рассмотрим ряд примеров работы этих механизмов.
Установка даты документа при открытии формы Если дата документа изначально не установлена, то при открытии формы нового документа происходит установка дате документа значения текущей даты сеанса. Причем время документа будет установлено в зависимости от следующих настроек. Если свойство АвтоВремя расширения формы документа имеет значение НеИспользовать, то время документа будет установлено по значению текущей даты сеанса. В остальных случаях дате документа присваивается время начала дня (00:00:00), рис. 10.45.
Рис. 10.44. Проведение документа «Реализация товаров»
В случаях отказа от использования оперативного проведения разработчику достаточно лишь установить свойству Оперативное проведение документа как объекта конфигурации значение Запретить. И тогда все необходимые элементы работы механизма проведения придется реализовывать самостоятельно. То есть, например, при проведении документа предварительно проводить контроль даты документа, контроль возможности проведения документа и т. д.
520
Рис. 10.45. Установка даты нового документа при открытии формы документа
Профессиональная разработка в системе «1С:Предприятие 8»
Документы
Установка даты нового документа при записи нового документа в форме При записи документа в режиме оперативного проведения значение даты документа устанавливается согласно выданной оперативной отметке времени. Тут настройки свойств расширения формы не играют роли. Но если время документа «нулевое» (0:00:00), то при неоперативном проведении документа оно будет изменено согласно настройкам свойства АвтоВремя (рис. 10.46). Исключение – когда АвтоВремя имеет значение НеИспользовать. Тогда время документа не меняется.
Рис. 10.47. Данные документа «РеализацияТоваров» и движения документа в регистре «ТоварыНаСкладах»
Предотвращение подобных ситуаций достигается за счет установки свойства расширения формы документа ПриЗаписиПерепроводить в значение Истина. Тогда отказ в обработке проведения приведет к откату транзакции – документ не будет перезаписан.
Установка режима проведения
Рис. 10.46. Установка даты нового документа при записи документа в форме
Запрет интерактивной записи проведенного документа без проведения (перепроведения) Запрет интерактивной записи документа без проведения (перепроведения) используется, чтобы не создавалась, например, такая ситуация: сначала документ реализации был заполнен и проведен, при проведении сформированы движения по регистру с указанием количества, соответствующего количеству в документе. После этого пользователь исправил данные документа и сохранил без проведения (рис. 10.47). В результате таких манипуляций в документе будут записаны новые данные, а в движениях по регистру останутся данные от прошлого проведения документа, то есть они никак не будут соответствовать текущим данным документа. Том 1
При проведении документа из формы система проверяет наличие у пользователя соответствующих прав (Проведение, Интерактивное проведение, Интерактивное проведение неоперативное). Если их нет, то выдается сообщение о невозможности проведения документа, и запись с проведением документа из формы отменяется. Мы будем рассматривать только возможность отсутствия/наличия прав на неоперативное проведение, в зависимости от которого система может менять свое поведение, так как если нет первых двух прав, то документ не может быть проведен из формы в принципе. Если интерактивное проведение разрешено, сам выбор варианта проведения должен быть обусловлен логикой применения механизма установки режима проведения из формы. То есть в некоторых ситуациях система должна выбирать режим жестко, в некоторых право выбора режима можно предоставить пользователю. Для этого разработчик обладает рядом возможностей, предоставляемых системой посредством разграничения прав и расширениями формы документа. При записи документа из формы расширение формы документа выполняет установку режима проведения документа. Для реализации данного функционала система использует вариант (Автоматически, Оперативный, Неоперативный, Запрашивать), указанный в качестве значения свойства ИспользоватьРежимПроведения расширения формы документа.
521
Глава 10. Документы и последовательности Вариант «Автоматически»
Вариант «Оперативный»
Вариант Автоматически устанавливается посредством выбора значения Автоматически у свойства ИспользоватьРежимПроведения расширения формы документа. Платформа стандартно устанавливает это значение для новой формы.
Вариант Оперативный устанавливается посредством выбора значения Оперативный у свойства ИспользоватьРежимПроведения расширения формы документа.
При использовании данного варианта, в зависимости от ситуации и настроек, происходит первичный подбор режима проведения из вариантов Оперативный или Неоперативный. Для проводимого документа происходит проверка положения даты документа относительно текущей даты сеанса. Если дата документа (без учета времени) равна текущей дате сеанса, то система автоматически выбирает вариант проведения Оперативный. Если дата документа (без учета времени) больше текущей даты сеанса, пользователю выдается предупреждение: «Дата оперативно проводимого документа больше текущей. Документ не может быть проведен оперативно!», и проведение документа отменяется.
В данном варианте, если дата документа (без учета времени) меньше текущей даты сеанса, выдается предупреждение: «Дата оперативно проводимого документа меньше текущей. Документ не может быть проведен оперативно!», и проведение документа отменяется. Если дата документа (без учета времени) равна текущей дате сеанса, производится запись документа с оперативным проведением. Если дата документа (без учета времени) больше текущей даты сеанса, выдается предупреждение: «Дата оперативно проводимого документа больше текущей. Документ не может быть проведен оперативно!», и проведение документа отменяется (рис. 10.49).
Если дата документа (без учета времени) меньше текущей даты сеанса, выбирается вариант проведения Неоперативный. При этом если у пользователя нет права на неоперативное проведение, выдается предупреждение: «Недостаточно прав для неоперативного проведения», и проведение документа отменяется (рис. 10.48).
Рис. 10.49. Использование режима проведения «Оперативный»
Вариант «Неоперативный»
Вариант Неоперативный устанавливается посредством выбора значения Неоперативный у свойства ИспользоватьРежимПроведения расширения формы документа. Рис. 10.48. Использование режима проведения «Автоматически»
522
При использовании данного варианта проведение документа из формы всегда производится в неоперативном режиме, независимо от положения даты документа по отношению к текущей дате сеанса. Профессиональная разработка в системе «1С:Предприятие 8»
Документы При этом если у пользователя нет права на неоперативное проведение, выдается предупреждение: «Недостаточно прав для неоперативного проведения», и проведение документа отменяется (рис. 10.50).
Рис. 10.50. Использование режима проведения «Неоперативный»
Вариант «Запрашивать»
Вариант Запрашивать устанавливается посредством выбора значения Запрашивать у свойства ИспользоватьРежимПроведения расширения формы документа. Данный вариант реализован в системе для того, чтобы помочь пользователю принять решение о выборе режима проведения для каждой конкретной ситуации. В данном варианте пользователь перед началом проведения должен будет выбрать режим проведения документа в специальном системном окне (рис. 10.51).
Рис. 10.51. Выбор режима проведения
Поведение системы при этом варианте определяется прежде всего положением даты документа (без времени) по отношению к текущей дате сеанса. При равенстве этих дат далее проверяется, имеет ли пользователь право проводить документ неоперативно. Если пользователь такого права не имеет, система проводит данный документ в оперативном режиме. Если право на неоперативное проведение есть, пользователю выдается диалог с режимом выбора проведения. После выбора режима проведения система проводит документ соответственно в оперативном или неоперативном режиме (рис. 10.52). Том 1
Рис. 10.52. Использование режима проведения «Запрашивать» при условии равенства даты документа и текущей даты сеанса
Если дата документа (без учета времени) меньше текущей даты сеанса, поведение системы определяется опять же наличием права на неоперативное проведение у пользователя. Если пользователь таким правом не обладает, выдается предупреждение: «Дата оперативно проводимого документа меньше текущей. Документ не может быть проведен оперативно!», и проведение документа отменяется. Если право на неоперативное проведение есть, пользователю выдается диалог с режимом выбора проведения. После выбора неоперативного режима проведения система проводит документ в неоперативном режиме. Если же пользователь выберет оперативный режим проведения, выдается предупреждение: «Дата оперативно проводимого документа меньше текущей. Документ не может быть проведен оперативно!», и проведение документа отменяется (рис. 10.53). Если дата документа (без учета времени) больше текущей даты сеанса, система не позволяет проводить документ оперативно. Поэтому если права неоперативного проведения нет, сразу выдается предупреждение: «Дата оперативно проводимого документа больше текущей. Документ не может быть проведен оперативно!», и проведение документа отменяется. Если право на неоперативное проведение есть, пользователю выдается диалог с режимом выбора проведения. После выбора неоперативного режима проведения система проводит документ в неоперативном режиме. Если же пользователь выберет оперативный режим проведения, будет
523
Глава 10. Документы и последовательности выдано предупреждение: «Дата оперативно проводимого документа больше текущей. Документ не может быть проведен оперативно!», и проведение документа отменится (рис. 10.54).
Прочие функции Кроме выбора режима проведения и установки даты документа, расширение формы документа реализует также следующий функционал: ■■ при открытии формы проведенного документа, если у пользователя нет права Интерактивное изменение данных, форма переводится в режим ТолькоПросмотр; ■■ при открытии формы документа, в которой находятся таблицы, отражающие движения основного реквизита (объекта документа), эти движения автоматически считываются из базы данных и отображаются; ■■ при записи из формы (даже если и программной – посредством Записать()) система выполняет проверку прав на интерактивное проведение или интерактивную отмену проведения.
Ввод на основании
Рис. 10.53. Использование режима проведения «Запрашивать» при условии, что дата документа меньше текущей даты сеанса
Рис. 10.54. Использование режима проведения «Запрашивать» при условии, что дата документа больше текущей даты сеанса
524
Ввод на основании является одним из вариантов реализации заполнения нового объекта данными другого объекта. Чаще всего это действие применяется для документов, но может использоваться для ряда других объектов (Справочники, Планы видов характеристик, Планы счетов, Планы расчетов, Планы обменов, Бизнес-процессы, Задачи). Причем в общем случае вводится любой объект на основании любого.
Рис. 10.55. Пример использования ввода на основании
Профессиональная разработка в системе «1С:Предприятие 8»
Документы Механизм работы ввода на основании включает в себя формирование нового объекта и вызов обработчика события ОбработкаЗаполнения создаваемого объекта. Например, необходимо реализовать заполнение документа, реализующего отгрузку товаров, на основании объекта, содержащего информацию о том, что именно нужно отгрузить. Исходным объектом, применяемым в конкретном случае, может быть, например, документ ЗаказПокупателя или элемент справочника ДоговорыКонтрагентов (рис. 10.55). Ввод на основании может быть организован за счет интерфейсных средств или программно.
Интерактивный ввод на основании Интерфейсные возможности реализуются за счет соответствующих расширений форм и элементов форм. Кроме того, необходимо, чтобы в свойствах объекта конфигурации было указано, на основании каких объектов он может вводиться (рис. 10.56).
Рис. 10.56. Указание объектов, являющихся основанием для ввода
В результате: ■■ разработчику будет доступен вызов конструктора ввода на основании для документа РеализацияТоваров; ■■ в автозаполняемых командных панелях форм, у которых основным реквизитом является объект документа ЗаказПокупателя и объект элемента справочника Договоры, а также в командных панелях форм списков данных объектов появляется новое подменю СоздатьНаОсновании (рис. 10.57) с действием РеализацияТоваров. Если же данное подменю уже было, то к нему просто добавится указанное действие. Том 1
Рис. 10.57. Кнопка «Ввести на основании»
Посредством конструктора ввода на основании (или без его использования) в составе модуля объекта документа РеализацияТоваров может быть реализована процедура – обработчик события ОбработкаЗаполнения. Поскольку параметром ДанныеЗаполнения данной процедуры система передает ссылку на объект-источник, то у разработчика появляется возможность заполнить данные документа информацией объекта-источника. Для нашего примера ее текст может быть таким (листинг 10.10). Листинг 10.10. Пример процедуры «ОбработкаЗаполнения»
Процедура ОбработкаЗаполнения(ДанныеЗаполнения, СтандартнаяОбработка) Если ТипЗнч(ДанныеЗаполнения) = Тип("ДокументСсылка.ЗаказПокупателя") Тогда // Заполнение шапки. Договор = ДанныеЗаполнения.Договор; Контрагент = ДанныеЗаполнения.Контрагент; ОснованиеРеализации = ДанныеЗаполнения.Ссылка; // Заполнить табличную часть данными табличной части основания. Для Каждого ТекСтрокаСостав Из ДанныеЗаполнения.Состав Цикл НоваяСтрока = Состав.Добавить(); НоваяСтрока.Количество = ТекСтрокаСостав.Количество; НоваяСтрока.Номенклатура = ТекСтрокаСостав.Номенклатура; НоваяСтрока.Сумма = ТекСтрокаСостав.Сумма; НоваяСтрока.Цена = ТекСтрокаСостав.Цена; КонецЦикла; ИначеЕсли ТипЗнч(ДанныеЗаполнения) = Тип("СправочникСсылка.ДоговорыКонтрагентов") Тогда // Заполнение шапки. Контрагент = ДанныеЗаполнения.Владелец; ДатаПоставки = ДанныеЗаполнения.ДатаПоставки; Договор = ДанныеЗаполнения.Ссылка; ОснованиеРеализации = ДанныеЗаполнения.Ссылка; // Заполнить табличную часть данными табличной части основания. Для Каждого ТекСтрокаСпецификация Из ДанныеЗаполнения.Спецификация Цикл НоваяСтрока = Состав.Добавить(); НоваяСтрока.Количество = ТекСтрокаСпецификация.Количество; НоваяСтрока.Цена = ТекСтрокаСпецификация.Цена; НоваяСтрока.Номенклатура = ТекСтрокаСпецификация.Номенклатура; НоваяСтрока.Сумма = ТекСтрокаСпецификация.Сумма; КонецЦикла;
КонецЕсли;
КонецПроцедуры
525
Глава 10. Документы и последовательности подробнее
Данный пример приведен в демонстрационной конфигурации «Хранение информации», которая находится на прилагаемом компактдиске.
В результате, если пользователь в соответствующей форме выберет из подменю СоздатьНаОсновании действие РеализацияТоваров, произойдет создание нового документа и вызов обработчика события ОбработкаЗаполнения. То есть произойдут следующие события (рис. 10.58).
Сообщение.Текст = "Не заполнено поле 'Контрагент'!"; Сообщение.Сообщить(); Отказ = Истина; КонецЕсли; КонецЕсли; КонецПроцедуры
В случае выполнения условий, то есть если объектом-источником будет документ ЗаказПокупателя с невыбранным контрагентом, произойдет выдача сообщения пользователю и отказ от создания формы нового документа, вводимого на основании.
Программный ввод на основании Программный способ заполнения документа данными из других объектов реализуется посредством метода Заполнить(). Например, если в переменной СсылкаНаИсходныйОбъект содержится ссылка на некий заказ покупателя или на некий договор контрагента, то программное создание документа РеализацияТоваров с заполнением данных из исходного объекта и последующая его запись могут быть выполнены следующим образом (листинг 10.12). Листинг 10.12. Пример создания нового документа на основании
Рис. 10.58. Последовательность событий при интерактивном вводе на основании
Кроме того, произойдет заполнение значения параметра Основание расширения формы документа. Ему также будет присвоено значение ссылки на объект-источник. Это свойство можно активно использовать в обработчиках событий формы. Например, требуется запретить интерактивный ввод документа РеализацияТоваров на основании документа ЗаказПокупателя, если у последнего не заполнен контрагент. Для реализации этой задачи достаточно написать процедуру обработчика создания формы документа РеализацияТоваров, например, следующим образом (листинг 10.11). Листинг 10.11. Пример процедуры «ПриСозданииНаСервере»
&НаСервере Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка) Если ТипЗнч(Параметры.Основание) = Тип("ДокументСсылка.ЗаказПокупателя") Тогда Если Параметры.Основание.Контрагент.Пустая() Тогда Сообщение = Новый СообщениеПользователю();
526
НовыйДокумент = Документы.РеализацияТоваров.СоздатьДокумент(); НовыйДокумент.Дата = ТекущаяДата(); НовыйДокумент.Заполнить(СсылкаНаИсходныйОбъект); НовыйДокумент.Записать();
Сначала новый документ будет создан в оперативной памяти, заполнено свойство Дата текущим временем, далее посредством метода Заполнить() управление будет передано обработчику события ОбработкаЗаполнения. Обратите внимание: в результате применения программного заполнения документов контекст формы не задействуется (рис. 10.59). После заполнения документ записывается. Событие ПриУстановкеНовогоНомера произойдет в транзакции записи, только если для документа используется автонумерация. Причем в соответствии с установкой параметров метода Записать() по умолчанию в данном примере документ будет записан без проведения. Следует заметить, что событие ОбработкаЗаполнения есть не только у объектных данных (документов, справочников и т. п.), но и у регистра сведений, и оно располагается в модуле объекта РегистрСведенийНаборЗаписей.<имя>.
Профессиональная разработка в системе «1С:Предприятие 8»
Документы
Рис. 10.60. Цепочка документов, введенных на основании
– объект конфигурации, представляющий собой одну из составляющих механизма отборов информации. Критерии отбора позволяют разработчику реализовать предопределенные правила отборов информации за счет создания дополнительных индексов в таблицах объектов в базе данных. КритерийОтбора
Рис. 10.59. Последовательность событий при программном вводе на основании
Получение документов, введенных на основании Кроме того, при решении прикладных задач иногда возникает необходимость получения всех документов, связанных с неким исходным объектом. Например, в рамках некоего договора был оформлен ЗаказПокупателя, на основании документа ЗаказПокупателя был введен документ РеализацияТоваров, на основании РеализацииТоваров были введены СчетФактура и ПриходныйКассовыйОрдер. Впоследствии часть товара была возвращена, то есть на основании РеализацииТоваров был введен ВозвратТоваровОтПокупателя. Кроме того, аналогичная цепочка документов может быть оформлена в отношении другого ЗаказаПокупателя (рис. 10.60).
Для вышеприведенного примера можно создать новый критерий отбора ДокументыПоДоговору. Тип критерия отбора указывается в соответствии с типом данных, по которым будут отбираться объекты. То есть в данном примере – СправочникСсылка.ДоговорыКонтрагентов, но в общем случае может быть и составным. В составе критерия отбора указываются реквизиты объектов, по которым нужно будет производить отбор. В данном случае это реквизит Договор документов ЗаказПокупателя, ПриходныйКассовыйОрдер, РеализацияТоваров (рис. 10.61).
Поскольку все события происходили в рамках договорных отношений одного договора, пользователю может оказаться необходимо увидеть все документы, касающиеся этого договора, в одном списке. Для реализации этого в состав всех объектов, которые нужно отобрать по данному договору, можно включить реквизит, ссылающийся на данный договор. Пусть он называется Договор. Далее для реализации отбора подчиненных договору документов можно использовать запросы или, например, критерии отбора. Том 1
Рис. 10.61. Состав объектов, входящих в критерий отбора «ДокументыПоДоговору»
527
Глава 10. Документы и последовательности В результате для таблиц объектов (в данном случае для таблиц документов) в базе данных будут созданы индексы по полям, хранящим значения этих реквизитов. Обратите внимание: в состав критерия отбора можно включить несколько реквизитов одного и того же документа или несколько реквизитов табличной части документа. Согласно информации о типе критерия отбора в группе Перейти панели навигации форм объектов, имеющих соответствующий тип, платформа создает команды для открытия списка критерия отбора. В приведенном выше примере такие команды будут созданы в группе Перейти панели навигации формы элемента справочника ДоговорыКонтрагентов. По умолчанию эта команда невидима, но можно включить ее видимость на закладке Командный интерфейс в форме элемента (рис. 10.62).
Рис. 10.62. Команда открытия критерия отбора из формы элемента справочника «ДоговорыКонтрагентов»
В результате, открыв какой-либо элемент справочника ДоговорыКонтрагентов, можно перейти к списку документов, в которых указан данный договор (рис. 10.63).
Также разработчик может сам вставить команду для открытия списка критерия отбора в форму списка объекта соответствующего типа (в данном случае справочника ДоговорыКонтрагентов). Для этого нужно найти соответствующую глобальную параметризируемую команду на закладке редактора формы списка – Команды Глобальные команды Параметризуемые Элементы Список Имя критерия отбора(Элементы.Список.ТекущиеДанные.Ссылка), рис. 10.64.
Рис. 10.64. Открытие списка критерия отбора «Документы по договору» по текущему элементу справочника
Если же требуется обеспечить переходы другими средствами, то это можно реализовать программно. Достаточно лишь иметь в наличии ссылку на значение отбора. То есть для вышеприведенного примера критерия отбора и переменной СсылкаНаЗначениеОтбора это может быть реализовано так (листинг 10.13). Листинг 10.13. Пример использования критерия отбора
Рис. 10.63. Открытие списка критерия отбора «Документы по договору» по текущему элементу справочника
528
&НаКлиенте Процедура ОткрытьСписокКритерияОтбора(Команда) // Открыть форму списка критерия отбора с отбором по договору. ЗначениеОтбора = Новый Структура("Значение", СсылкаНаЗначениеОтбора); ПараметрыФормы = Новый Структура("Отбор", ЗначениеОтбора); ОткрытьФорму("КритерийОтбора.ДокументыПоДоговору.ФормаСписка", ПараметрыФормы); КонецПроцедуры
Профессиональная разработка в системе «1С:Предприятие 8»
Документы Краткий комментарий: сначала создается структура отбора ЗначениеОтбора со значением реквизита формы СсылкаНаЗначениеОтбора, содержащим ссылку на договор, и добавляется в структуру параметров формы ПараметрыФормы. Эти параметры передаются в форму списка критерия отбора ДокументыПоДоговору, и форма открывается с отбором по полю Значение списка критерия отбора, указанному в форме обработки ОткрытьФормуКритерияОтбора.
не предусмотрено специальных документов (в бухгалтерском учете их обычно называют ручными операциями). Либо когда при регистрации события пользователь заполняет ровно те поля, которые требуется заполнять в регистре. И ввод этой учетной информации не требует никакой дополнительной обработки.
Кроме того, может возникнуть потребность программного получения коллекции подчиненных документов (или других объектов), то есть соответствующих отбору по определенному значению. Это можно реализовать посредством объектной техники (листинг 10.14) или посредством запроса (листинг 10.15).
Например, в рамках демонстрационной конфигурации «Хранение информации», которая находится на прилагаемом компакт-диске, создан документ РучнаяОперация, данными которого будут только Дата и Номер. Поскольку проведение данного документа не предусматривается, свойству Проведение данного документа указано значение Запретить. Однако в разделе свойства Движения отмечен регистр, для которого данный документ может быть регистратором (ТоварыНаСкладах), рис. 10.65.
Листинг 10.14. Пример использования объектной техники
МассивСсылокНаОбъекты = КритерииОтбора.ДокументыПоДоговору.Найти(СсылкаНаЗначениеОтбора);
Рассмотрим подробнее возможность интерактивного формирования движений.
Листинг 10.15. Пример использования запроса
ВЫБРАТЬ ДокументыПоДоговору.Ссылка ИЗ КритерийОтбора.ДокументыПоДоговору(&Значение) КАК ДокументыПоДоговору
В качестве значения параметру Значение необходимо будет передать ссылку на значение отбора. Для функционирования конкретного критерия отбора в базе данных для исходных таблиц были созданы соответствующие индексы. Поэтому обеспечивается достаточно быстрая работа этого механизма.
Специальные случаи использования документов. Ручная операция
Рис. 10.65. Документ «РучнаяОперация»
Кроме типовой стратегии использования документов в конфигурации, когда движения формируются при проведении документов, система допускает и другие варианты участия документов в учетных механизмах. Так, в частности, допускается программное и интерактивное изменение записей регистров, в том числе и подчиненных регистратору. Причем от регистратора может использоваться только ссылка для определения отбора по регистратору. Остальное может быть выполнено вообще без использования данных документа.
Далее при создании формы документа в окне элементов формы необходимо разместить таблицу, отображающую данные Объект.Движения.ТоварыНаСкладах (рис. 10.66).
Такая возможность не нарушает общую модель использования документов и регистров, а лишь дополняет ее для решения нестандартных задач. Например, когда пользователям нужно предоставить возможность отражения в учетных механизмах операций, для которых в конфигурации
Однако необходимо иметь в виду, что поведение подобного документа может быть неожиданным для пользователей, привыкших работать с документами по стандартной схеме.
Том 1
Пользователь при работе с данным документом сможет интерактивно формировать или модифицировать движения данного документа по регистру ТоварыНаСкладах и записывать документ. При записи документа данные, отображаемые в этой таблице, будут записаны в регистр (рис. 10.67).
529
Глава 10. Документы и последовательности Кроме того, возможна ситуация, когда необходимо, чтобы движения существовали, но не участвовали в получении итогов регистра. Для этого можно снять активность записей движений. Необходимо помнить, что хотя Активность является свойством записей, однако она может быть установлена или снята только для всего набора записей данного регистратора по данному регистру. Программно это (листинг 10.16).
может
быть
выполнено
следующим
образом
Листинг 10.16. Изменение активности записей
Движения.ТоварыНаСкладах.УстановитьАктивность(Ложь);
Кроме того, «неожиданным» для пользователя может оказаться тот факт, что при копировании подобного документа содержимое таблицы движений автоматически копироваться не будет. Ведь там отображаются движения документа по регистру, а они не относятся к данным документа. Данный вопрос должен прорабатываться разработчиком. Рис. 10.66. Источник данных таблицы формы, отображающей движения документа в регистре «ТоварыНаСкладах»
Для реализации подобной функциональности необходимо воспользоваться обработчиком события ПриКопировании объекта документа (листинг 10.17). Листинг 10.17. Использование обработчика события «ПриКопировании»
Процедура ПриКопировании(ОбъектКопирования) // Перебрать движения документа-источника. ДвиженияОбъектаКопирования = РегистрыНакопления.ТоварыНаСкладах. ВыбратьПоРегистратору(ОбъектКопирования.Ссылка); Пока ДвиженияОбъектаКопирования.Следующий() Цикл Рис. 10.67. Схема документа «Ручная операция»
Например, при установке пометки удаления на такой документ не будет срабатывать отмена проведения и удаление движений документа. Ведь документ и не проводился (ему было запрещено проведение). А как же обеспечить удаление движений?
// Создать новую запись в движениях текущего документа. НовоеДвижение = Движения.ТоварыНаСкладах.Добавить();
// Заполнить поля новой записи регистра. НовоеДвижение.ВидДвижения = ДвиженияОбъектаКопирования.ВидДвижения; НовоеДвижение.Период = ДвиженияОбъектаКопирования.Период; НовоеДвижение.Номенклатура = ДвиженияОбъектаКопирования.Номенклатура; НовоеДвижение.Склад = ДвиженияОбъектаКопирования.Склад; НовоеДвижение.Количество = ДвиженияОбъектаКопирования.Количество; КонецЦикла;
Вариантов несколько:
КонецПроцедуры
■■ удалить сам документ. Тогда система удалит связанные с ним движения, поскольку записи регистра подчинены регистратору и в данном случае без регистратора существовать не могут; ■■ интерактивно удалить записи в таблице, отображающей движения документа, и записать документ; ■■ программно очистить движения, то есть создать пустой набор записей с отбором по данному регистратору, и записать его.
Поскольку обработчик события ПриКопировании в качестве параметра получает объект копируемого документа, то в самой процедуре считываются его движения. Далее в цикле перебора набора записей документа источника формируются новые записи уже в коллекции движений нового документа. Значения полей новых записей заполняются значением полей записей из движений документа-источника.
530
Профессиональная разработка в системе «1С:Предприятие 8»
Документы При интерактивном формировании движений документа в общем случае поле Период записей регистра доступно для редактирования. Это позволяет устанавливать произвольный период начала действия любой записи на итоги регистра. В ряде прикладных задач, однако, подобную «вольность» требуется пресечь. Для принудительной синхронизации поля Период, например, по значению даты документа можно использовать следующее (листинг 10.18).
Подобным образом могут решаться еще задачи для проводимых документов. Например, если пользователь должен иметь возможность в дополнение к сформированным при проведении документа движениям добавлять новые или вручную корректировать существующие движения.
Листинг 10.18. Синхронизация даты движений с датой документа в обработчике события «ПередЗаписью» формы документа
Но при этом разработчику обязательно нужно учитывать и корректно отрабатывать возможные попытки перепроведения документа с «интерактивно откорректированными» движениями. Если ничего не предпринимать, а свойство документа Удаление движений будет иметь значение Удалять автоматически, то система при перепроведении удалит старые движения и сформирует новые такими, какими их формирует обработка проведения. То есть результаты ручной коррекции будут потеряны.
&НаКлиенте Процедура ПередЗаписью(Отказ, ПараметрыЗаписи) Для Каждого ЗаписьРегистра Из Объект.Движения.ТоварыНаСкладах Цикл ЗаписьРегистра.Период = Объект.Дата; КонецЦикла; КонецПроцедуры
Саму синхронизацию в зависимости от реализуемого алгоритма работы с документом можно располагать или в обработчике события ПередЗаписью в модуле формы документа, или в модуле объекта документа. В первом случае синхронизация будет производиться только при интерактивной записи документа, во втором – и при программной записи тоже. Кроме того, как определяли в начале этого раздела, формирование движений не обязательно может идти от документа. Движения могут быть сформированы программно, посредством объекта НаборЗаписей регистра (просто с установленным отбором по нужному регистратору). Для синхронизации значения поля Дата записей регистра со значением поля Дата документа и для таких случаев необходимо использовать обработчик события ПередЗаписью самого набора записей (листинг 10.19). Листинг 10.19. Пример процедуры «ПередЗаписью» модуля набора записей регистра
Процедура ПередЗаписью(Отказ, Замещение)
// Получить дату регистратора. ДатаРегистратора = ЭтотОбъект.Отбор.Регистратор.Значение.Дата;
// Принудительно установить значение поля "Период" каждой записи. Для Каждого ЗаписьНабораЗаписей Из ЭтотОбъект Цикл ЗаписьНабораЗаписей.Период = ДатаРегистратора; КонецЦикла; КонецПроцедуры
Выше мы рассмотрели ситуации и задачи, которые могут возникнуть при интерактивном формировании движений документов, которым проведение запрещено. Том 1
То есть в форме документа можно также создать таблицу для интерактивной работы с набором записей данного документа по нужному (нужным) регистру.
Что именно должна выполнять конфигурация в подобной ситуации, зависит от постановки задачи. Все возможные предпосылки для ее решения у системы есть. Это и отключение автоматического удаления движений, и возможность отключения активности записей, и возможность реализации отказа в проведении документа, и т. д.
Журналы документов документов – объект конфигурации, предназначенный для обеспечения работы с документами нескольких видов в одном списке. Журнал
Посредством журналов легко обеспечивается интерактивный вызов следующих действий (например, посредством командной панели формы журнала): ■■ добавление нового документа; ■■ копирование документа; ■■ пометка на удаление документа/снятие пометки на удаление документа; ■■ удаление документа; ■■ открытие формы документа (для редактирования документа); ■■ проведение документа; ■■ отмена проведения документа; ■■ ввод на основании; ■■ переход к связанной информации (в том числе отображение списков движений документа); ■■ установка отбора, сортировки, группировки и условного оформления списка документов;
531
Глава 10. Документы и последовательности ■■ вывод данных из списка журнала документов в табличный документ или текстовый документ; ■■ изменение настройки списка отображаемых в журнале колонок; ■■ установка интервала дат в списке документов; ■■ поиск документа по значению в колонке списка/отмена поиска. С прикладной точки зрения журналы документов – средство группирования связанных по смыслу документов. Например, журнал КассовыеДокументы может включать в себя документы ПриходныйКассовыйОрдер, РасходныйКассовыйОрдер, Чек, ОтчетКассовойСмены и так далее. Для отображения данных только одного вида документов создавать журнал документов не стоит. Потому что формируемая по умолчанию или созданная в конфигурации форма списка документа целиком реализует ту же функциональность без лишних структурных затрат. По сути дела журналы документов – вторичные данные системы, представляющие собой еще одно представление списка документов. Каждый документ может входить в один или несколько журналов или не входить ни в один. Все определяется наличием необходимости работы с рядом документов в составе одного списка (рис. 10.68).
Рис. 10.69. Окно редактирования журнала документов
Наличие дополнительных граф в составе журнала дает возможность пользователю получать в списке журнала сведения о документах, дополнительные к вышеперечисленным. Графа журнала представляет собой перечень реквизитов документов, регистрируемых в журнале, значения которых нужно отображать в списке в одной колонке (рис. 10.70).
Рис. 10.68. Включение документов в различные журналы
Состав журналов В состав журнала как объекта конфигурации включаются регистрируемые документы и графы (рис. 10.69). При регистрации документа сразу же обеспечиваются возможности отображения в списке журнала таких полей, как: ■■ ■■ ■■ ■■ ■■
Тип документа, Дата, Номер, ПометкаУдаления, Проведен.
532
Рис. 10.70. Регистрация реквизитов документов в графе журнала
В списке журнала по каждому конкретному экземпляру документа информация будет отображаться для пользователя в составе только одной строки списка. Поэтому в каждую графу журнала можно включить только один реквизит для каждого вида документа и невозможно включать реквизиты табличной части документа. Кроме того, рекомендуется включать в состав одной графы данные одного типа значений или близких по смыслу типов значений. Например, графа ДокументОснование будет включать в себя данные значений соответствующих реквизитов разных видов документов. При этом типы значений реквизитов могут быть различными, но они близки по смыслу. Профессиональная разработка в системе «1С:Предприятие 8»
Журналы документов На уровне объектов базы данных информация журналов документов хранится в отдельных таблицах для каждого журнала документов. Эти таблицы имеют следующий состав полей и содержат следующую информацию: ■■ Ссылка – ссылка на регистрируемый в журнале документ; ■■ Дата – дата/время регистрируемого документа; ■■ ПометкаУдаления – пометка удаления регистрируемого документа (Булево); ■■ Проведен – пометка проведенности регистрируемого документа (Булево); ■■ Номер – номер регистрируемого документа (поле существует, если хоть один из регистрируемых документов имеет номер с длиной, отличной от нуля); ■■ Графа1 – содержимое соответствующих реквизитов регистрируемых документов. Тип значения поля определяется типом значений реквизитов регистрируемых документов; ■■ … – … ■■ ГрафаN – … Согласно вышеописанному можно сделать вывод о том, что состав и тип значения полей таблиц разных журналов отличаются. Кроме того, при добавлении новых документов к перечню зарегистрированных может меняться не только тип значения полей, но и состав полей.
В принципе число документов, регистрируемых в составе одного журнала, неограниченное – могут быть зарегистрированы хоть все документы конфигурации. При решении данного вопроса необходимо только помнить о необходимости обеспечения параллельности работы пользователей и достаточного уровня быстродействия системы при выполнении операций записи/удаления документов. В отношении обеспечения параллельности работы: ■■ при файл-серверном варианте использования программы транзакционные блокировки устанавливаются на уровне таблиц базы данных. Поэтому документы, входящие в один журнал, одновременно не смогут быть записаны; ■■ при клиент-серверном варианте использования программы блокировки устанавливаются на уровне записей. Поэтому блокировки СУБД допускают более высокую параллельность выполнения транзакций. В отношении скорости записи/удаления документов: чем меньше количество журналов, в которых регистрируется документ, тем быстрее проходит его запись или удаление. Поэтому к вопросу организации журналов в составе функционально наполненных конфигураций нужно подходить внимательно.
Например, если ранее все зарегистрированные документы имели номера нулевой длины, то добавление нового с номером ненулевой длины приведет к добавлению поля Номер в составе таблицы журнала.
Также внимательно следует подходить к вопросу определения граф журнала. Большое количество граф может сказаться на производительности системы при просмотре журнала. Поэтому при отображении динамических списков документов, входящих в журнал, из базы данных считываются только те поля, которые связаны с соответствующими колонками таблицы формы списка журнала. Это сделано для уменьшения объема выбираемой из базы данных информации.
Заполнение журналов
Последовательности документов
Заполнение/редактирование таблицы журнала происходит при записи/ удалении документов, в рамках той же транзакции. Причем только в следующих ситуациях: ■■ запись нового документа; ■■ запись документа, у которого есть изменения в реквизитах самого документа (изменения в табличных частях не приводят к необходимости «перезаполнения» записей в таблицах журналов); ■■ запись документа с измененной датой или номером, с изменением признака проведения или пометки удаления; ■■ удаление документа. Таким образом, функциональность журналов обеспечивается с минимальными временными затратами на ее поддержание. Сколько документов можно зарегистрировать в составе одного журнала? Том 1
Последовательность документов – средство группирования документов в едином хронологическом порядке для обеспечения ведения единой логики событий в рамках некоего механизма учета. В отличие от журналов документов, которые используются в основном для группирования документов в «интерфейсных интересах» (для визуализации), последовательности группируют документы для обеспечения правильного отражения данных документов в учете. Поскольку учетных механизмов в составе одной конфигурации может быть несколько, то и последовательностей может быть адекватное количество. Кроме того, сами модели применения объекта Последовательность могут отличаться. В качестве первого примера рассмотрим использование последовательности для учета правильности списания партий товаров со склада. Проведение ряда документов (документов реализации) обусловлено
533
Глава 10. Документы и последовательности состоянием данных, хранящихся в базе данных, на момент времени регистрации документов (остатки партий в регистре ПартииТоваров). Изменение же этих исходных данных впоследствии, после проведения документа, ставит под сомнение правильность прошлого отражения данного документа в учете. Например, документ реализации Рнк-1 оформлен и проведен после двух приходных накладных, оприходовавших товар (рис. 10.71).
Для новой ситуации движения документа Реализация, полученные в результате старого проведения, некорректны (табл. 10.7). Таблица 10.7. Записи регистра «ПартионныйУчет» Период
Регистратор
Вид движения Товар
Партия
Кол-во
Сумма
13.03.2010 15:00:01 23.03.2010 15:30:45 27.03.2010 12:30:45
ПоступлениеТоваров № 1 13.03.2010 15:00:01 ПоступлениеТоваров № 2 23.03.2010 15:30:45 Реализация № 1 27.03.2010 12:30:45
Приход
Пульт VH
Пнк-1
7
70
Приход
Пульт VH
Пнк-2
5
60
Расход
Пульт VH
Пнк-1
9
90
Ведь для списания девяти пультов одной партии Пнк-1 теперь недостаточно! К аналогичному печальному результату можно прийти и в случае любого изменения записей регистра задним числом (рис. 10.73). Рис. 10.71. Набор документов
При проведении было реализовано списание партий по методу FIFO (первый пришел – первый ушел). То есть расходная накладная использовала данные об остатках партий на момент ее проведения. В результате все операции были отражены в учете партий в виде следующих записей регистра ПартионныйУчет (табл. 10.6). Таблица 10.6. Записи регистра «ПартионныйУчет» Период
13.03.2010 15:00:01 23.03.2010 15:30:45 27.03.2010 12:30:45
Регистратор
ПоступлениеТоваров № 1 13.03.2010 15:00:01 ПоступлениеТоваров № 2 23.03.2010 15:30:45 Реализация № 1 27.03.2010 12:30:45
Вид движения
Приход
Товар
Партия
Пульт VH Пнк-1
Кол-во Сумма
10
100
Рис. 10.73. Пример изменения записей регистра задним числом
Приход
Пульт VH Пнк-2
5
60
В результате записи в регистре (учете) будут следующими (табл. 10.8).
Расход
Пульт VH Пнк-1
9
90
Таблица 10.8. Записи регистра «ПартионныйУчет»
Видно, что при реализации была частично списана партия Пнк-1. Далее было произведено изменение одной из исходных приходных накладных с последующим ее перепроведением (рис. 10.72).
Период
Регистратор
Вид движения Товар
Партия
Кол-во Сумма
01.03.2010 00:00:00
Ручная корректировка остатков РК-1 29.03.2010 17:00:00 ПоступлениеТоваров № 1 13.03.2010 15:00:01 ПоступлениеТоваров № 2 23.03.2010 15:30:45 Реализация № 1 27.03.2010 12:30:45
Приход
Пульт VH
РК-1
2
16
Приход
Пульт VH
Пнк-1
10
100
Приход
Пульт VH
Пнк-2
5
60
Расход
Пульт VH
Пнк-1
9
90
13.03.2010 15:00:01 23.03.2010 15:30:45 27.03.2010 12:30:45
То есть движения документа Реализация не отвечают требованиям метода списания FIFO. Рис. 10.72. Нарушение последовательности проведения документов
534
Для исправления ситуации объект Последовательность позволяет в таких случаях оперировать понятием граница последовательности. Профессиональная разработка в системе «1С:Предприятие 8»
Последовательности документов Это и есть момент времени максимально глубокого в прошлом изменения записей регистра (регистров), от которого зависит проведение документов, зарегистрированных в последовательности. Именно с этого момента возможны коллизии правильности ведения учета. То есть до границы последовательности документы проведены заведомо правильно, после – возможно, неправильно.
Устройство последовательностей Для создания объекта конфигурации Последовательность разработчик должен указать, какие документы необходимо регистрировать в последовательности, и список регистров, данные которых используются этими документами при своем проведении (рис. 10.75).
Сам процесс восстановления логики учета может быть реализован путем последовательного перепроведения документов, зарегистрированных в последовательности, начиная от границы последовательности, и называется восстановление последовательности. Другой вариант использования объекта Последовательность: пользователи в течение дня вводят поток заявок от покупателей и внутренних заявок. Причем в силу специфики автоматизируемого предприятия часто имеет место ситуация ввода нескольких заявок от одних и тех же покупателей или для одних и тех внутренних подразделений. Кроме того, возможен ввод «запоздавших» заявок прошлых дней. Документы записываются, но не проводятся. По окончании рабочего времени офиса автоматически включается обработка Консолидация заявок, которая собирает все непроведенные заявки (разных видов), начиная от границы последовательности, консолидирует их, оформляет соответствующим образом и проводит уже обобщенные заявки. Впоследствии исходные заявки удаляются. После этого граница последовательности смещается на момент времени последней проведенной консолидированной заявки (рис. 10.74).
Рис. 10.75. Свойства, относящиеся к использованию последовательности
Хотелось бы обратить внимание на то, что автоматическое отслеживание изменения таких данных осуществляется только для регистров: ■■ ■■ ■■ ■■
Рис. 10.74. Использование последовательности для консолидации заявок
Первый приведенный пример можно назвать классическим. Он касается давно существующей задачи «борьбы с коллизиями из-за работы пользователей задним числом». Данная задача полностью или в большей своей части может быть решена за счет встроенных в платформу автоматических средств объекта Последовательность. Второй приведенный пример показывает, что разработчик при использовании объекта Последовательность не обязательно должен замыкаться только на «коллизиях работы задним числом». Благодаря наличию различных программных средств и возможностей логика применения последовательностей документов определяется самим разработчиком. Том 1
регистров накопления, регистров сведений, регистров бухгалтерии, регистров расчета.
Но это не мешает при необходимости реализовать программными средствами изменение положения границы последовательности при изменении данных других объектов. Например, для последовательности документов, критичных к изменению условий в элементе справочника Договоры, при записи модифицированного элемента данного справочника можно программно установить границу последовательности на момент времени самого первого документа по этому договору. Кроме того, последовательность может иметь разрезы. Это реализуется включением измерений в данные последовательности. Например, если добавить в последовательность измерение Организация, то с прикладной точки зрения общая последовательность будет разбита на ряд последовательностей. Каждая из них может функционировать в рамках отдельной организации. То есть, например, будет возможно произвести восстановление последовательности документов только одной
535
Глава 10. Документы и последовательности организации, не затрагивая остальных. С другой стороны, наличие измерений не препятствует работе с последовательностью в целом. Для хранения данных объекта Последовательность в базе данных существуют две таблицы: таблица регистрации документов в последовательности и таблица границ последовательности. Состав колонок обеих таблиц сходен: Период, Регистратор, Измерение1, …, ИзмерениеN. Различно функциональное использование этих таблиц. Данные, хранящиеся в таблице регистрации документов, используются для решения вопросов, связанных с коллекцией зарегистрированных в последовательности документов. Причем в разрезе измерений. Для определенной комбинации значений измерений по одному регистратору в таблице регистрации документов может храниться только одна запись. Впоследствии данные этой таблицы могут использоваться, например, для получения упорядоченного по хронологии набора документов, которые требуется перепровести для восстановления последовательности. Или просто для получения массива ссылок на документы, записи по которым соответствуют некоему отбору по измерениям последовательности. Данные в таблице границ последовательностей хранят значения моментов времени границ последовательностей (Период + Регистратор) по каждому набору значений измерений последовательности. То есть уникальность записей таблицы границ последовательностей определяется набором значений измерений. Если измерений у последовательности нет, значит, в этой таблице будет только одна запись. Пример содержимого таблиц при наличии измерений у последовательности приведен в табл. 10.9 и табл. 10.10.
Работа с последовательностями Работа с последовательностью включает в себя три процесса: ■■ регистрация документа в последовательности; ■■ перемещение границы последовательности назад; ■■ перемещение границы последовательности вперед (восстановление границы последовательности). В принципе эти процессы, во-первых, независимы, во-вторых, могут выполняться системой автоматически или посредством программных действий, заложенных разработчиком.
Управление регистрацией документов в последовательности Для автоматической регистрации документа в последовательностях необходимо, чтобы свойство Заполнение последовательностей документа как объекта конфигурации было установлено в значение Заполнять автоматически. Если последовательность имеет измерения, то для обеспечения автоматического заполнения полей этих измерений в формируемой записи таблицы регистрации документов последовательности настраивается соответствие между реквизитами документа и измерениями последовательности документа (рис. 10.76).
Таблица 10.9. Пример таблицы регистрации документов в последовательности Период
Регистратор
Организация
Склад
01.03.2010 00:00:00 13.03.2010 15:00:01 23.03.2010 15:30:45 27.03.2010 12:30:45
Ручная корректировка остатков РК-1 29.03.2010 17:00:00
Сигма
Главный
ПоступлениеТоваров № 17 13.03.2010 15:00:01
Сигма
Торговый
ПоступлениеТоваров № 2 23.03.2010 15:30:45
Сигма
Торговый
Реализация № 1 27.03.2010 12:30:45
Марон
Главный
Таблица 10.10. Пример таблицы границ последовательности Организация Склад
Сигма Сигма Марон
536
Главный
Период
01.03.2010 00:00:00 Торговый 13.03.2010 15:00:01 Главный 27.03.2010 12:30:45
Регистратор
Ручная корректировка остатков РК-1 от 29.03.2010 17:00:00 ПоступлениеТоваров № 17 13.03.2010 15:00:01 Реализация № 1 27.03.2010 12:30:45
Рис. 10.76. Соответствие между реквизитами документа и измерениями последовательности
В случае указания соответствия между реквизитами документа (не табличной части) и измерениями последовательности при записи документа в таблице регистрации документов в последовательности формируется запись, в которой поля автоматически заполняются значениями из документа. Если при настройке такого соответствия указывается реквизит табличной части документа, то в таблице регистрации документов будет сформировано столько записей, сколько уникальных значений будет иметь данный реквизит табличной части документа в записываемом документе (рис. 10.77). Профессиональная разработка в системе «1С:Предприятие 8»
Последовательности документов и разных, то количество записей в таблице регистрации документов в последовательности может быть очень велико. Это может сказаться на производительности системы.
Если указывается несколько реквизитов одной табличной части, будет сформировано столько записей, сколько уникальных комбинаций из них указано в табличной части документа (рис. 10.78).
Следует иметь в виду еще один важный момент: при проведении документов, зарегистрированных в последовательности, платформа автоматически перемещает границу последовательности на момент регистрации этих документов, так как свойство Перемещение границы при проведении последовательности как объекта конфигурации стандартно установлено в значение Перемещать. Данная операция перемещения границы последовательности не может выполняться параллельно, соответственно, документы тоже не могут проводиться параллельно. Это может вызвать проблемы, если документы, участвующие в последовательности, должны вводиться в больших количествах.
Рис. 10.78. Пример формирования записей в таблице регистрации документов в последовательности
Регистрация документа в последовательности выполняется при записи документа. Процесс записи документа включает в себя следующие этапы (рис. 10.80).
Рис. 10.77. Пример формирования записей в таблице регистрации документов в последовательности
Во избежание данной ситуации можно установить это свойство в значение Не перемещать, тогда граница последовательности при проведении документов автоматически перемещаться не будет. Это позволит одновременно и регистрировать документ в последовательности, и параллельно проводить сразу несколько таких документов. Затем граница последовательности может быть перемещена программно при помощи специальной регламентной обработки.
Если же в соответствиях с измерениями последовательностей будут указаны реквизиты различных табличных частей, то документ будет зарегистрирован столько раз, сколько уникальных комбинаций значений можно составить (рис. 10.79).
Рис. 10.79. Пример формирования записей в таблице регистрации документов в последовательности
Исходя из вышесказанного, к вопросу добавления измерений в последовательность нужно подходить осмотрительно. Если для заполнения значений измерений использовать реквизиты табличных частей, да еще Том 1
Рис. 10.80. Действия, выполняемые при записи документа
537
Глава 10. Документы и последовательности В случае же записи документа с проведением очередность этапов процесса будет следующей (рис. 10.81).
Рис. 10.82. Действия, выполняемые при записи документа с отменой проведения
Рис. 10.81. Действия, выполняемые при записи документа с проведением
Добавляется обработка проведения документа и процесс переноса границы последовательности вперед при выполнении необходимых для этого условий. В случае же записи документа с отменой проведения последовательность действий будет следующей (рис. 10.82). Разработчику нужно помнить, что при создании новой последовательности документов автоматическая регистрация старых документов в ней не производится. Для осуществления регистрации нужно будет или перезаписать существующие документы, или написать обработку, которая зарегистрирует все нужные документы в последовательности. Если средств автоматической регистрации недостаточно или их использование неудобно, для управления регистрацией документа в последовательности документов служит набор записей регистрации в последовательности документов. У объекта документа есть свойство ПринадлежностьПоследовательностям. Его значением является коллекция наборов записей регистрации в последовательности документов. Для каждой последовательности, в которую входит документ, существует свой набор записей регистрации в последовательности документов (рис. 10.83).
538
Рис. 10.83. Последовательности, в которые входит документ
При автоматическом способе регистрации (напомним, для этого у документа как объекта конфигурации должен стоять признак автоматического заполнения последовательности) наборы записей таблиц регистрации документов в последовательностях автоматически заполняются до записи документа и записываются после записи документа в одной транзакции.
Профессиональная разработка в системе «1С:Предприятие 8»
Последовательности документов Поэтому если требуется программно очистить эти наборы записей и создать новые, можно это сделать в обработчике события ПередЗаписью или ПриЗаписи объекта документа (не путать с аналогичными обработчиками событий ПередЗаписью формы документа).
ПринадлежностьПоследовательностям объекта документа, при формиро-
Например, в составе последовательности документов ПартионныйУчет есть измерение Номенклатура. В табличной части Товары документа могут содержаться номенклатурные позиции, соответствующие услугам. По таким значениям измерения регистрировать документ в последовательности не нужно. Для того чтобы документ регистрировался в последовательности только по товарам (исключая услуги), можно сделать следующее (листинг 10.20).
Если же потребуется очистить всю таблицу записей регистрации документов в последовательности, то данную операцию легко выполнить программно. Запросом считать все регистраторы, на которые имеются ссылки в таблице записей регистрации документов. А затем по всем регистраторам записать пустой набор записей (листинг 10.21).
Листинг 10.20. Пример процедуры «ПередЗаписью» в модуле объекта документа «РеализацияТоваров»
Процедура ПередЗаписью(Отказ, РежимЗаписи, РежимПроведения)
НаборЗаписейРегистрации = ПринадлежностьПоследовательностям.ПартионныйУчет;
// Очистить автоматически сформированный набор записей регистрации. НаборЗаписейРегистрации.Очистить();
// Получить выборку товаров из табличной части документа. Запрос = Новый Запрос; Запрос.Текст = "ВЫБРАТЬ РАЗЛИЧНЫЕ | РеализацияТоваровСостав.Номенклатура |ИЗ | Документ.РеализацияТоваров.Состав КАК РеализацияТоваровСостав |ГДЕ | РеализацияТоваровСостав.Ссылка = &Ссылка | И (НЕ РеализацияТоваровСостав.Номенклатура.Услуга)";
вании новых записей достаточно было заполнить только значения измерений последовательности и поле Период, а поле Регистратор автоматически заполняется ссылкой на документ.
Листинг 10.21. Пример очистки таблицы регистрации документов в последовательности
Процедура ОчисткаТаблицыРегистрацииПоследовательностиПартионныйУчет()
// Получить все документы, зарегистрированные в последовательности. Запрос = Новый Запрос; Запрос.Текст = "ВЫБРАТЬ РАЗЛИЧНЫЕ | ПартионныйУчет.Регистратор |ИЗ | Последовательность.ПартионныйУчет КАК ПартионныйУчет";
Результат = Запрос.Выполнить(); Выборка = Результат.Выбрать();
// Создать набор записей таблицы регистрации последовательности // (при этом он пуст). НаборЗаписейРегистрации = Последовательности.ПартионныйУчет.СоздатьНаборЗаписей();
// Перебрать выборку из результата запроса. Пока Выборка.Следующий() Цикл
Запрос.УстановитьПараметр("Ссылка", Ссылка );
// Установить отбор по очередному зарегистрированному документу // в наборе записей. НаборЗаписейРегистрации.Отбор.Регистратор.Установить(Выборка.Регистратор);
Результат = Запрос.Выполнить(); Выборка = Результат.Выбрать();
// Записать пустой набор записей с замещением исходного. НаборЗаписейРегистрации.Записать();
// Добавить новые записи регистрации и заполнить их. Пока Выборка.Следующий() Цикл НоваяЗапись = НаборЗаписейРегистрации.Добавить(); НоваяЗапись.Номенклатура = Выборка.Номенклатура; НоваяЗапись.Период = Дата; КонецЦикла; КонецПроцедуры
Краткий комментарий: у элемента коллекции наборов записей регистрации документов в последовательности, соответствующей последовательности ПартионныйУчет, сначала очищаются все записи. Далее запросом получаются все номенклатурные позиции, входящие в табличную часть Товары текущего документа и не являющиеся услугами. В цикле перебора выборки из результата запроса добавляются в набор новые записи регистрации данного документа в последовательности ПартионныйУчет. Обратите внимание: в данном примере из-за того, что объект НаборЗаписейРегистрации был получен посредством свойства Том 1
КонецЦикла;
КонецПроцедуры
Как видно из примера, для чтения данных таблиц регистрации документов в последовательностях можно применять запросы. Кроме того, у разработчика есть возможность проверить, принадлежит ли данный документ последовательности, и посредством метода Принадлежит() объекта ПоследовательностьМенеджер.<имя>. Например, нужно проверить принадлежность документа последовательности ПартионныйУчет (листинг 10.22). Листинг 10.22. Проверка принадлежности документа последовательности
ФлагПринадлежности = Последовательности.ПартионныйУчет. Принадлежит(СсылкаНаПроверяемыйДокумент);
539
Глава 10. Документы и последовательности Или, например, проверить, принадлежит ли данный документ последовательности по конкретному значению измерения Номенклатура (листинг 10.23). Листинг 10.23. Проверка принадлежности последовательности
// Подготовить структуры отбора по значениям измерений последовательности. ОтборПоИзмерениям = Новый Структура; ОтборПоИзмерениям.Вставить("Номенклатура", СсылкаНаТовар); // Проверить принадлежность к последовательности в отношении нужного значения измерения. ФлагПринадлежности = Последовательности.ПартионныйУчет. Принадлежит(СсылкаНаДокумент, ОтборПоИзмерениям);
В приведенном примере, если документ зарегистрирован в данной последовательности по нужному значению измерения, переменная ФлагПринадлежности получит булево значение Истина; если нет – Ложь. В общем случае при формировании записей набора записей регистрации документов в последовательности поле Период может заполняться произвольным значением. То есть момент времени самого документа и момент времени регистрации документа в последовательности могут отличаться. Также в общем случае может отличаться от даты документа и значение поля Период записей движений по регистрам. Это может понадобиться для реализации какой-нибудь особой логики. Например, для решения задач сложного многоитерационного планирования, когда в течение месяца могут вводиться, дополняться, частично отменяться планы, касающиеся как текущего месяца, так и следующего. Поэтому движения по регистру могут регистрироваться и на момент времени документа, и на начало текущего месяца, и на начало следующего. Вероятные коллизии устраняются посредством использования объекта Последовательность. И поскольку документы планирования имеют разные приоритеты для разрешения коллизий планирования, регистрироваться в последовательности они могут не только на момент времени документа (рис. 10.84).
Рис. 10.84. Пример использования нестандартной регистрации документов в последовательности
540
Кроме того, для некоторых задач может оказаться полезным, что документ в разных последовательностях может регистрироваться на разные моменты времени, или в одних последовательностях регистрироваться, а в других – нет. Например, при раздельной работе с последовательностями ПартионныйУчет и Торговля.
Перемещение границы последовательности назад Перенос границы последовательности выполняется при записи набора записей регистров. Сам процесс автоматического перемещения границы последовательности назад (сбивание границы) состоит из следующих операций (рис. 10.85): ■■ проверка того, что граница последовательности больше момента времени записи регистра; ■■ перемещение границы последовательности на момент времени записи регистра.
Рис. 10.85. Автоматическое сбивание границы последовательности
На уровне таблиц базы данных результатом перемещения границы последовательности назад является модификация записей в таблице границ последовательностей. То есть запись с ключом, соответствующим нужной комбинации значений измерений, заменяется на запись с тем же ключом, но со значениями полей Период и Регистратор, соответствующими моменту регистрации в последовательности документа, которому подчинены измененные записи регистра. Важно понимать, что границу последовательности перемещают назад не документы, а движения регистров. Сделано это потому, что модификация (а также добавление или удаление) записей регистра не обязательно может быть связана с проведением или удалением документа. В платформе есть средства, позволяющие просто «приписывать» движения к документам, не используя объекты документов. Профессиональная разработка в системе «1С:Предприятие 8»
Последовательности документов Например, возможна следующая ситуация: граница последовательности Планирование установлена на дату: 01.04.2010 00:00:00. Затем 10.04.2010 обработкой Перепланирование к документу ПланПродаж № 14, выписанному (и проведенному) с датой 11.03.2010 10:11:00, были «приписаны» движения по регистру ПланыПродаж с указанием периода движений 31.03.2010 00:00:00. При этом старые движения документа не замещались. Кроме этого, сам документ был ранее зарегистрирован в последовательности на дату 01.03.2010 12:00:00. Измерений у последовательности нет. В результате этого действия граница последовательности будет перемещена назад при записи записей регистра именно на момент времени добавленных записей (рис. 10.86).
Также есть средства для получения данных таблицы границ последовательности. Данные о значениях границ последовательности можно получить запросом или с помощью методов ПолучитьГраницы() и ПолучитьГраницу() объекта ПоследовательностьМенеджер.<имя>. Например, получение таблицы текущих границ последовательностей может выглядеть следующим образом (листинг 10.25). Листинг 10.25. Пример получения границ последовательности
ТаблицаГраницПоследовательности = Последовательности.ПартионныйУчет.ПолучитьГраницы("Номенклатура");
Для использования метода ПолучитьГраницы() обязательно указание названий измерений (через запятую), которые будут разрезами в таблице границ. Кроме того, можно использовать второй параметр метода, указав там структуру отбора по значениям измерений. Результатом вышеприведенного примера будет таблица значений, включающая в себя колонки со значениями измерений (в данном случае Номенклатура) и колонку МоментВремени, в которой будут содержаться моменты времени границ последовательностей по хранящимся в последовательности комбинациям значений измерений. Кроме того, можно получать первую на временной оси границу последовательности для ситуации последовательности с измерениями (рис. 10.87). Реализуется это следующим образом (листинг 10.26). Рис. 10.86. Пример автоматического сбивания границы последовательности
То есть для перемещения назад границы последовательности ни дата документа, ни дата регистрации документа в последовательности значения не имеют. Но перенос (установка) границы последовательности программными средствами доступен разработчику на произвольный момент времени. Например, если требуется установить границу последовательности ПартионныйУчет на момент времени, состоящий из значений переменных ДатаУстановки, ДокументУстановки по значению измерения Номенклатура, содержащемуся в переменной НоменклатураУстановки (листинг 10.24). Листинг 10.24. Перенос границы последовательности на произвольный момент времени
Рис. 10.87. Пример границ последовательности «ПартионныйУчет»
// Подготовить параметры установки границы последовательности: // Момент времени установки. МоментУстановки = Новый МоментВремени(ДатаУстановки, ДокументУстановки);
Листинг 10.26. Получение минимальной границы последовательности
// Подготовить структуру отбора по значениям измерений последовательности. ОтборПоИзмерениям = Новый Структура; ОтборПоИзмерениям.Вставить("Номенклатура", НоменклатураУстановки);
В заключение хотелось бы еще раз обратить внимание на то, что в случае наличия измерений в последовательности перемещение границы последовательности назад происходит только для тех комбинаций значений измерений, которые уже присутствуют в таблице границ последовательности.
// Установить границы последовательности "Партионный учет". Последовательности.ПартионныйУчет.УстановитьГраницу(МоментУстановки, ОтборПоИзмерениям);
Том 1
ТекущаяГраницаПоследовательности = Последовательности.ПартионныйУчет.ПолучитьГраницу();
541
Глава 10. Документы и последовательности То есть если в рассмотренном выше примере, где существуют границы последовательности по номенклатурным позициям Самовар, Утюг, Холодильник, сформировать в регистре задним числом записи с другими номенклатурными позициями (не записывая документ), то граница последовательности ПартионныйУчет перемещаться назад не будет.
щими моменту регистрации в последовательности документа, проведение которого привело к восстановлению последовательности.
Восстановление последовательности
Сделано это по следующей причине: проведение документа – это сложный процесс, включающий в себя удаление предыдущих движений, установку признака проведенности, запись документа, запись движений документа и т. д., вплоть до «подтягивания» границы последовательности. Если разработчик отказался от этого процесса и просто формирует новые записи в регистре для некоего документа-регистратора (даже если тот является следующим после момента времени границы последовательности), то говорить о том, что с прикладной точки зрения последовательность восстановлена, слишком оптимистично и в принципе неверно. Например, нет никакой уверенности, что при перепроведении такого документа не возникнет коллизий.
Процесс переноса границы последовательности вперед называется восстановление последовательности. Необходимым условием автоматического восстановления последовательности является установка значения Перемещать свойству Перемещение границы при проведении последовательности как объекта конфигурации. Сам процесс автоматического восстановления последовательности выполняется только при проведении документа и состоит из следующих операций (рис. 10.88): ■■ проверка того, что момент регистрации документа больше, чем граница последовательности; ■■ проверка того, что в последовательности нет других проведенных документов в интервале между границей последовательности и моментом регистрации документа; ■■ установка границы последовательности на момент регистрации документа.
Автоматическое перемещение границы последовательности вперед происходит только при проведении документа. Не важно – нового или уже ранее проведенного, лишь бы соблюдались все условия алгоритма. Главное, что восстановление происходит именно при записи с проведением.
Но если такая уверенность есть или она обеспечена соответствующим комплексом мероприятий, предусмотренным разработчиком, то при необходимости для реализации неавтоматического переноса границы последовательности (назад или вперед) можно использовать программные средства – метод УстановитьГраницу() объекта ПоследовательностьМенеджер.<имя>. Использование механизма восстановления последовательности в прикладном смысле может быть разносторонним. При последовательном проведении всех документов, входящих в последовательность, начиная с момента границы последовательности, последовательность восстанавливается. И наоборот, при восстановлении последовательности перепроводятся проведенные документы, входящие в последовательность, но находящиеся за границей последовательности. Здесь хотелось бы отметить ряд особенностей.
Рис. 10.88. Автоматическое восстановление границы последовательности
На уровне таблиц базы данных результатом восстановления границы последовательности является модификация записей в таблице границ последовательностей. То есть запись с ключом, соответствующим нужной комбинации значений измерений, заменяется на запись с тем же ключом, но со значениями полей Период и Регистратор, соответствую-
542
Во-первых, хотя автоматическая регистрация документов в последовательности происходит при записи документа (при любой записи документа, не обязательно при проведении), при восстановлении последовательности производится перепроведение только проведенных документов. То есть только тех документов, у которых стоит признак проведения (рис. 10.89). Во-вторых, перепроводиться будут документы в хронологии, определяемой моментами регистрации документов в последовательности, а не моментами времени самих документов. Это может оказаться существенным, если документы регистрируются в последовательности на отличные от своих моменты времени (рис. 10.90). Профессиональная разработка в системе «1С:Предприятие 8»
Последовательности документов В последнем случае последовательность можно восстановить в целом, можно даже без указания по какой момент времени (листинг 10.27), а можно и в пределах указанных комбинаций измерений последовательности. Листинг 10.27. Пример использования метода «Восстановить()»
Последовательности.ПартионныйУчет.Восстановить(); Рис. 10.89. Проведение документов при восстановлении последовательности
Например, необходимо восстановить последовательность документов ПартионныйУчет по момент времени документа из переменной СсылкаНаДокумент по значению измерения Номенклатура, хранящемуся в переменной Товар. Вариант выполнения такого действия представлен в листинге 10.28. Листинг 10.28. Пример восстановления границы последовательности
// Сформировать момент времени, по который будет восстанавливаться последовательность. МоментВосстановленияПо = Новый МоментВремени(СсылкаНаДокумент.Дата, СсылкаНаДокумент); Рис. 10.90. Порядок проведения документов при восстановлении последовательности
В-третьих, если в составе последовательности есть измерения, а восстановление последовательности проводится общее (без разрезов по измерениям), то порядок перепроведения документов, которые нужно перепровести, опять же однозначно определяется хронологией регистрации документов в последовательности. Сам процесс восстановления последовательности документов по определенную дату может быть инициирован: ■■ посредством системной команды Проведение документов (рис. 10.91); ■■ программно, с помощью метода Восстановить() объекта ПоследовательностьМенеджер.<имя>.
// Сформировать таблицу отбора. ТаблицаКомбинацийИзмерений = Новый ТаблицаЗначений; // Добавить колонки с именами, соответствующими // именам измерений последовательности. ТаблицаКомбинацийИзмерений.Колонки.Добавить("Номенклатура"); // Добавить строку(и) со значением(ями) отбора. СтрокаТаблицы = ТаблицаКомбинацийИзмерений.Добавить(); СтрокаТаблицы.Номенклатура = СсылкаНаТовар; // Восстановить последовательность. Последовательности.ПартионныйУчет.Восстановить(МоментВосстановленияПо, ТаблицаКомбинацийИзмерений);
Параллельный ввод документов, участвующих в последовательности Как было описано выше, в базе данных информация последовательностей документов хранится в двух таблицах: ■■ таблице записей регистрации документов в последовательности, ■■ таблице границ последовательностей.
Рис. 10.91. Команда восстановления последовательностей
В первом случае есть возможность прервать интерактивный процесс восстановления последовательности путем нажатия комбинации клавиш Ctrl + Break. Том 1
Выполнение различных действий с последовательностью в клиентсерверном варианте использования программы порождает блокирование этих таблиц в различных диапазонах: ■■ при регистрации документа в последовательности происходит добавление или модификация набора записей таблицы регистрации документов в последовательности, подчиненного регистратору.
543
Глава 10. Документы и последовательности Поэтому заблокированным оказывается как минимум диапазон записей, соответствующих одному регистратору (плюс две граничные записи «вокруг» этого диапазона); ■■ при перемещении границы последовательности назад происходит модификация записей границ по соответствующим комбинациям значений измерений. Поэтому блокируются записи таблицы границ последовательности, соответствующие данным комбинациям значений измерений. А если измерений в последовательности нет, то вся таблица целиком; ■■ при перемещении границы последовательности вперед. Этот процесс происходит только при проведении документа, поэтому блокируются обе таблицы. Таблица регистрации документов в последовательности оказывается заблокированной в диапазоне от границы последовательности по момент времени регистрации проводимого документа в последовательности. То есть заблокированными могут оказаться записи, подчиненные документам не проведенным, но зарегистрированным в последовательности в указанном интервале. Таблица границ последовательностей будет заблокирована целиком. Если у последовательности есть измерения, то вышеописанные блокировки при данном действии будут касаться только записей с комбинациями значений измерений, совпадающими со значениями измерений записей регистрации; ■■ в файловом варианте работы системы в любом случае происходит блокировка таблиц целиком. Согласно данному описанию механизма блокировок видно, что узким местом обеспечения параллельности ввода и проведения документов
544
для клиент-серверного варианта работы системы являются действия, связанные с автоматическим перемещением границы последовательности. То есть если документ зарегистрирован в последовательности, то при его проведении система может предпринять попытку автоматического перемещения границы последовательности на момент регистрации данного документа. Это приведет к блокировке таблицы границ последовательности целиком или в диапазоне соответствующей комбинации значений измерений последовательности. Параллельно проводимый документ, входящий в ту же последовательность, при попытке заблокировать те же записи или таблицу не сможет этого сделать. В результате вместо параллельного проведения для таких документов получим последовательное. Одним из вариантов выхода из ситуации является отключение автоматического перемещения границы последовательности при проведении документов. Для этого свойству Перемещение границы при проведении последовательности как объекта конфигурации устанавливается значение Не перемещать. В этом случае при проведении документа, даже если он регистрируется в последовательности, система не предпринимает попытки перемещения границы (границ) последовательности. А блокировки, возникающие при регистрации разных документов в последовательности, не мешают друг другу. То есть тогда работа с объектом Последовательность не препятствует параллельному проведению документов. Необходимо лишь не забыть позже реализовывать перемещение границы последовательности, например, служебной обработкой.
Профессиональная разработка в системе «1С:Предприятие 8»
Оперативный учет. Описание задач, решаемых регистрами накопления
Глава 11. Учет движения средств Оперативный учет. Описание задач, решаемых регистрами накопления Практически все теории, тем или иным образом связанные с технологиями учета, управления, принятия решений и т. д., базируются на понятии «показатель». Показатель – данные, по которым можно судить о развитии, ходе, состоянии чего-нибудь. Оперативный учет – учет, позволяющий максимально быстро получать информацию о значениях показателей, учитываемых в автоматизируемой системе. Платформа системы «1С:Предприятие» предлагает удобное для учета показателей средство – регистры. Посредством их использования обеспечиваются необходимое быстродействие, функциональная гибкость и простота решения этих информационных задач. Как правило, информационные модели при этом включают не только одни регистры. Обычно используется следующая схема (рис. 11.1): ■■ документами регистрируются события, приводящие к изменению значений показателей; ■■ сами значения показателей хранятся в регистрах; ■■ посредством отчетов пользователи получают информацию о состоянии показателей и проводят ее анализ.
Какие же именно показатели используются при решении задач учета движения средств? И какие регистры нужно для них использовать? При автоматизации учета движения средств чаще приходится сталкиваться с ситуацией, когда в момент регистрации изменений показателя фиксируется не конечное итоговое значение показателя, а его приращение. Например, при регистрации поступления товаров на склад – количество поступивших товаров, а не находящихся в остатке; при регистрации выдачи денег подотчетнику фиксируется выданная сумма, а не оставшаяся в кассе, и тому подобное. А вот при получении данных из системы учета уже требуются накопленные (итоговые) значения показателей. Такие показатели называют показателями накопления. Для решения задачи учета показателей накопления «1С:Предприятие» используются регистры накопления.
в
системе
накопления – объект конфигурации, предназначенный для хранения итоговых (накопленных) значений показателей и хранения движений (приращений) показателей. Помимо итоговых значений показателей, регистр может хранить и промежуточные итоги, рассчитанные для указанных периодов. Регистр
Информация о приращениях показателей (заметьте, они могут быть как положительными, так и отрицательными) вносится в регистр накопления только посредством движений, то есть посредством наборов записей регистра, подчиненных документу-регистратору. Этим обеспечивается обоснованность регистрации изменений показателей – регистрацией событий, приводящих к этим изменениям. Упрощенно можно сравнить регистр накопления с неким «черным ящиком», «на вход» которого подаются значения приращений, а «на выходе» можно получить накопленные значения приращений (рис. 11.2). Как можно заметить из приведенного рисунка, показатели накопления имеют различный прикладной смысл. Различают следующие виды накапливаемых показателей: ■■ показатели остатков, ■■ оборотные показатели.
Рис. 11.1. Общая схема оперативного учета
Том 1
Итоги показателей остатков отражают значения учитываемых показателей на некоторый момент времени.
545
Глава 11. Учет движения средств
Рис. 11.4. Пример влияния изменений в прошлых периодах на показатели остатков
Рис. 11.2. Упрощенная схема регистра накопления
Итоги оборотных показателей отражают значения совокупного изменения показателя за временной интервал между двумя моментами времени (период). Если эти изменения положительные или отрицательные, можно оперировать такими понятиями, как Приход и Расход (рис. 11.3).
Рис. 11.3. Различные виды накапливаемых показателей
Таким образом, можно сказать, что показатели остатка и оборотные показатели характеризуют один и тот же процесс, но с разных сторон. Важно отметить, что показатели остатка имеют абсолютные итоги относительно момента начала ведения учета. При этом изменения в приращениях (движениях) любых прошлых периодов влияют на текущее значение итога. Рассмотрим пример, приведенный на рис. 11.4.
546
Изменения показателя Деньги в кассе фиксируются посредством документов Приходный кассовый ордер (ПКО) и Расходный кассовый ордер (РКО). Оформление поступления денег в январе повлияет на остатки, как на начало февраля, так и начало марта и т. д. В противоположность рассмотренному примеру итоги оборотных показателей за разные периоды независимы. Рассмотрим пример на рис. 11.5.
Рис. 11.5. Отсутствие влияния изменений в прошлых периодах на оборотные показатели
Изменения показателя Сумма проданного регистрируются посредством документа Расходная накладная (Рнк). Введенные изменения в объемах продаж января будут касаться только января, но никак не коснутся февральских объемов продаж. Для гибкого и эффективного решения задач прикладной области система «1С:Предприятие» позволяет использовать два вида регистров накопления. Профессиональная разработка в системе «1С:Предприятие 8»
Структура регистра накопления Регистры накопления остатков позволяют получать итоговые значения показателей остатков и, кроме того (суммируя приращения этих показателей за периоды), позволяют получать обороты. Например, при решении задачи учета товаров на складах может понадобиться как значение остатка товаров на момент времени, так и оборот поступлений или расходов товара за периоды времени. Если же для некоторых сущностей накопление остатков смысла не имеет и требуется накапливать только обороты, тогда следует использовать оборотные регистры накопления. Например, учет оборотов продаж компании. О продажах всегда можно говорить только в отношении временного периода. ВНИМАНИЕ!
Перечисленные виды регистров накопления не являются в общем случае взаимозаменяющими. Каждый из них предназначен для решения своего собственного круга прикладных задач. Например, для решения задач, связанных с учетом только оборотных показателей, не следует использовать регистры остатков и, наоборот, не следует пытаться вести учет показателей остатков на оборотных регистрах. Подобные попытки могут привести как минимум к неоправданному снижению быстродействия прикладного решения или вообще к некорректности данных учета.
Ресурсы используются для хранения информации как о приращениях, так и о самих значениях показателей. По сути, каждый ресурс хранит данные одного показателя. Однако регистры могут быть не только одномерными. Например, для решения задачи учета количества товаров нерационально оперировать большим количеством ресурсов (показателей) типа КоличествоХолодильников, КоличествоПылесосов, КоличествоПультовVH и т. д. Лучше использовать один ресурс (показатель) Количество, но ввести разрез учета – ПоНоменклатурнымПозициям. В регистрах накопления разрезы учета реализуются с помощью измерений. В состав регистра можно включить более одного измерения, поэтому в общем случае регистр накопления можно представить как n-мерную систему разрезов учета (измерений), в узлах которой хранятся совокупные данные ресурсов (итоги), рис. 11.7.
Структура регистра накопления В состав регистра накопления как объекта конфигурации входят измерения, ресурсы и реквизиты (рис. 11.6).
Рис. 11.7. Многомерная модель регистра накопления
На представленной схеме – двумерная модель хранимой в регистре информации по итогам. Разрезы учета (измерения) – Номенклатура и Склад. Узлами пересечений этих разрезов учета будут все возможные комбинации значений номенклатурных позиций на складах. Итог показателя Количество в каждом узле пересечения отражает данные: сколько (в количественном выражении) конкретной номенклатуры находится на конкретном складе. Данные этой графической двумерной модели можно представить в виде табличной модели (табл. 11.1). Таблица 11.1. Табличное представление данных регистра
Рис. 11.6. Состав регистра накопления
Том 1
Номенклатура
Склад
Количество
Барометр G5 Барометр G5 Пульт VH Станция G121
Главный Фили-2 Фили-2 Главный
30 15 11 5
547
Глава 11. Учет движения средств Каждая строка содержит значение итога ресурса Количество для конкретной комбинации значений разрезов учета Номенклатура и Склад. Из достоинств табличной модели сейчас хотелось бы отметить универсальность. Если графическое отображение более чем трехмерного пространства тяжело или вообще невозможно для человеческого восприятия, то табличная модель в принципе не ограничивает количество разрезов учета. Впоследствии будет рассмотрено, что хранение итогов регистров в базе данных основано именно на использовании табличной модели. Реквизиты – дополнительные характеристики движений, то есть первичных записей регистра. Реквизиты не влияют на итоги, хранимые в регистре. На вышеприведенной схеме, отражающей итоги, нет места реквизитам. Однако реквизиты могут быть использованы при решении задач анализа выполненных движений. То есть таких задач, в которых работа идет только с приращениями показателей, безотносительно их итоговых значений. Например, если при формировании движений регистра ТоварыНаСкладах заполнять соответствующие значения: поступление, реализация в розницу, реализация оптом, списание, перемещение и т. д. для реквизита ВидОперации, то впоследствии можно будет анализировать, какая из операций производится чаще других, какая реже; какие операции не выполняли в течение последнего квартала и т. п. Итак, в отношении задач, решаемых регистрами накопления, структура регистра как объекта конфигурации позволяет вести многомерный учет как приращений, так и итогов показателей накопления, с возможностью при необходимости использования дополнительных характеристик движений. Для обеспечения данных возможностей предусмотрена соответствующая структура таблиц базы данных и порядок работ с ними. Данные каждого регистра накопления хранятся в базе данных в двух таблицах: ■■ таблица движений регистра накопления, ■■ таблица итогов регистра накопления. Существует два вида регистров накопления, и каждый предназначен для ведения учета показателей своего вида (остатков или оборотов). И, как разбирали выше, задачи учета показателей этих видов различны. Поэтому структура таблиц базы данных для регистров накопления разных видов тоже отличается. Она оптимизирована под решение соответствующих задач. Для регистра накопления остатков состав колонок таблицы движений следующий: ■■ Период – дата записи. Совместно с полями Регистратор и НомерСтроки определяет положение данной записи на временной оси;
548
■■ Регистратор – ссылка на документ, которому подчинена данная запись; ■■ НомерСтроки – уникальный номер данной записи в наборе записей регистра, подчиненных документу, указанному в поле Регистратор; ■■ ВидДвижения – значение системного перечисления ВидДвиженияНакопления, обозначающее направление приращения указанных в записи ресурсов на итоги по этим ресурсам (Приход или Расход); ■■ Активность – тип Булево. Содержит признак влияния записи на итоги регистра; ■■ <Измерение> – значение измерения. Количество таких полей равно количеству измерений, определенных в данных регистра как объекта конфигурации; ■■ <Ресурс> – значение ресурса. Количество таких полей равно количеству ресурсов, определенных в данных регистра как объекта конфигурации; ■■ <Реквизит> – значение реквизита. Количество таких полей равно количеству реквизитов, определенных в данных регистра как объекта конфигурации. Таблица движений регистра хранит данные о выполненных по регистру движениях. Таблица итогов регистра накопления остатков хранит текущие итоги на момент времени последнего движения (актуальные итоги). Дополнительно к этому могут храниться промежуточные итоги, если установлен период рассчитанных итогов. Период рассчитанных итогов влияет только на производительность при получении итогов на некоторую промежуточную дату; если он установлен, итоги будут получены быстрее. Структура таблицы итогов регистра накопления остатков следующая: ■■ Период – дата, на которую актуально состояние хранимого в таблице итога; ■■ <Измерение> – значение измерения – разреза учета хранимых итогов. Количество таких полей равно количеству измерений, определенных в данных регистра как объекта конфигурации; ■■ <Ресурс> – значение итога ресурса. Количество таких полей равно количеству ресурсов, определенных в данных регистра как объекта конфигурации; ■■ Разделитель – поле, позволяющее распараллелить обновление записей итогов. Добавляется в структуру таблицы итогов для регистров накопления, у которых установлено свойство Разрешить разделение итогов. Пример заполнения таблицы движений регистра накопления остатков приведен в табл. 11.2. Для вышеприведенного примера заполнения таблицы движений регистра таблица итогов регистра после расчета итогов по 31.05.2010 будет выглядеть так, как показано в табл. 11.3. Профессиональная разработка в системе «1С:Предприятие 8»
Структура регистра накопления
Истина Пульт VH
Главный 1
10
1
Приход
Истина Пульт VH
Главный 9
90
2
Приход
Истина Пульт PW
Главный 7
490
1
Приход
Ложь
Фили-2
5
60
1
Расход
Истина Пульт VH
Главный 8
80
1
Приход
Истина Пульт PW
Фили-2
1
17
1
Приход
Истина Пульт VH
Фили-2
1
18
Склад
Пульт VH
Сумма
Приход
Количество
1
Номенклатура
Активность
Поступление товаров № 1 13.05.2010 15:00:00 Поступление товаров № 2 13.05.2010 15:00:01 Поступление товаров № 2 13.05.2010 15:00:01 Поступление товаров № 3 23.05.2010 15:30:45 Реализация № 1 27.05.2010 12:30:45 Поступление товаров № 4 31.05.2010 23:59:59 Поступление товаров № 5 01.06.2010 00:00:00
Вид движения
Регистратор
03.04.2010 15:00:00 13.05.2010 15:00:01 13.05.2010 15:00:01 23.05.2010 15:30:45 27.05.2010 12:30:45 31.05.2010 23:59:59 01.06.2010 00:00:00
Номер строки
Период
Таблица 11.2. Пример заполнения таблицы движений регистра накопления остатков
Таблица 11.3. Пример заполнения таблицы итогов регистра накопления остатков Период
Итоги апреля 2010 года
Итоги мая 2010 года (граница рассчитанных итогов)
Текущие итоги
01.05.2010 00:00:00 01.06.2010 00:00:00 01.06.2010 00:00:00 01.06.2010 00:00:00 01.11.3999 00:00:00 01.11.3999 00:00:00 01.11.3999 00:00:00 01.11.3999 00:00:00
Номенклатура Склад
Количество Сумма
Пульт VH
Главный 1
10
Пульт VH
Главный 2
20
Пульт PW
Главный 7
490
Пульт PW
Фили-2
1
17
Пульт VH
Фили-2
1
18
Пульт VH
Главный 2
20
Пульт PW
Главный 7
490
Пульт PW
Фили-2
17
1
Обратите внимание: данные таблицы итогов содержат значения итогов ресурсов для всех возможных комбинаций значений измерений. Исключения составляют итоги, если для данной комбинации значений измерений значения всех ресурсов равны нулю. Такие записи в таблице итогов не хранятся за ненадобностью, потому что с прикладной точки зрения ситуация «нет итогов по данной комбинации значений измерений» равносильна ситуации «по данной комбинации значений измерений все итоги равны нулю». Том 1
В разделе «Получение данных из регистров накопления» на стр. 568 рассматривается, как при решении задач получения данных о значениях показателей (ресурсов) система может оптимальным с точки зрения быстродействия способом обращаться к данным как таблицы движений, так и таблицы итогов регистра. Структура таблиц оборотного регистра накопления, хранимых в базе данных, схожа. Отличие заключается только в том, что для оборотных регистров не существует понятия вид движения и понятия текущие итоги. Состав колонок таблицы движений оборотного регистра накопления следующий: ■■ Период – дата записи. Совместно с полями Регистратор и НомерСтроки определяет положение данной записи на временной оси; ■■ Регистратор – ссылка на документ, которому подчинена данная запись; ■■ НомерСтроки – уникальный номер данной записи в наборе записей регистра, подчиненных документу, указанному в поле Регистратор; ■■ Активность – тип Булево. Содержит признак влияния записи на итоги регистра; ■■ <Измерение> – значение измерения. Количество таких полей равно количеству измерений, определенных в данных регистра как объекта конфигурации; ■■ <Ресурс> – значение ресурса. Количество таких полей равно количеству ресурсов, определенных в данных регистра как объекта конфигурации; ■■ <Реквизит> – значение реквизита. Количество таких полей равно количеству реквизитов, определенных в данных регистра как объекта конфигурации. Структура таблицы итогов оборотного регистра накопления тоже схожа: ■■ Период – период (месяц), за который накоплен оборот итогов ресурсов; ■■ <Измерение> – значение измерения – разреза учета хранимых итогов. Количество таких полей равно количеству измерений, определенных в данных регистра как объекта конфигурации, у которых установлено свойство Использование в итогах; ■■ <Ресурс> – значение итога оборота ресурса. Количество таких полей равно количеству ресурсов, определенных в данных регистра как объекта конфигурации; ■■ Разделитель – поле, позволяющее распараллелить обновление записей итогов. Добавляется в структуру таблицы итогов для регистров накопления, у которых установлено свойство Разрешить разделение итогов. Но вот сами данные, хранимые в таблице итогов, и механизмы их использования коренным образом отличаются от регистра остатков. Для оборотного регистра в таблице итогов хранятся посчитанные суммарные обороты
549
Глава 11. Учет движения средств (итоги) ресурсов за каждый месяц, в рамках которого были зарегистрированы движения в данном регистре. Пример заполнения таблицы движений оборотного регистра накопления Продажи представлен в табл. 11.4.
Номенклатура
Контрагент
Количество
Сумма
Реализация № 1 27.05.2010 12:30:45 Реализация № 2 29.05.2010 15:00:01 Реализация № 3 13.06.2010 15:00:00 Реализация № 3 23.06.2010 10:00:00 Реализация № 4 23.06.2010 15:30:45 Реализация № 5 01.10.2010 08:59:59
Активность
Регистратор
27.05.2010 12:30:45 29.05.2010 15:00:01 13.06.2010 15:00:00 23.06.2010 10:00:00 23.06.2010 15:30:45 01.11.2010 08:59:59
Номер строки
Период
Таблица 11.4. Пример заполнения таблицы движений оборотного регистра накопления
1
Истина
Пульт VH
Ялта-Лтд
9
135
1
Истина
Пульт VH
10
150
1
Истина
Пульт VH
1
15
1
Истина
Пульт VH
1
15
1
Ложь
Пульт PW
Компания "Риона" Компания "Риона" Компания "Риона" Крона
1
90
1
Истина
Пульт PW
Ялта-Лтд
1
95
Для таблиц итогов создается следующий индекс:
Таблица 11.5. Пример заполнения таблицы итогов оборотного регистра накопления
Итоги мая 2010 года Итоги июня 2010 года Итоги ноября 2010 года
01.05.2010 00:00:00 01.05.2010 00:00:00 01.06.2010 00:00:00 01.11.2010 00:00:00
Номенклатура Контрагент
Количество
Сумма
Пульт VH
Ялта-Лтд
9
135
Пульт VH
Компания "Риона"
10
150
Пульт VH
Компания "Риона"
2
30
Пульт PW
Ялта-Лтд
1
95
В разделе «Получение данных из регистров накопления» на стр. 568 будет рассмотрено, в каких случаях и какими средствами достигается оптимальное быстродействие при получении данных оборотных регистров. Здесь же следует сказать, что как для регистров остатков, так и для оборотных регистров система «1С:Предприятие» индексирует таблицы движений и таблицы итогов. При этом для таблиц движений регистров создаются следующие индексы: ■■ Период + Регистратор + НомерСтроки;
550
■■ Период + Измерение1 + Измерение2 + … + ИзмерениеN + Разделитель – по всем измерениям регистра; ■■ Измерение + Период, если для измерения Измерение свойство Индексировать установлено в значение Индексировать. Использование индексов позволяет еще больше сократить время выполнения операций с данными регистра. Однако необходимо иметь в виду, что Microsoft SQL Server накладывает определенное ограничение на количество полей, входящих в составной индекс, – не более 16 полей в индексе. Поэтому работа с регистрами, имеющими очень большое количество измерений, может быть неэффективна по скорости из-за невозможности использования индексных таблиц. Подробнее
Для вышеприведенного примера заполнения таблицы движений таблица итогов регистра будет заполнена следующим образом (табл. 11.5).
Период
■■ Регистратор + НомерСтроки; ■■ Измерение + Период + Регистратор + НомерСтроки, если для измерения Измерение свойство Индексировать установлено в значение Индексировать; ■■ Реквизит + Период + Регистратор + НомерСтроки, если для реквизита Реквизит свойство Индексировать установлено в значение Индексировать.
Том 2, приложение «Хранение данных», раздел «Индексы таблиц базы данных».
Механизмы заполнения таблиц регистров накопления в базе данных Как было определено выше, данные каждого регистра накопления хранятся в двух таблицах базы данных: ■■ таблице движений регистра накопления, ■■ таблице итогов регистра накопления. В таблицу движений регистра записи могут вводиться пользователем вручную, генерироваться в процессе выполнения обработок либо при проведении документов. Подробнее
Раздел «Запись данных в таблицу движений регистра накопления», стр. 551.
При формировании данных таблицы итогов важно обеспечить их непротиворечивость данным таблицы движений. Чтобы, например, не получилось, что по данным таблицы движений за все время в кассу предприятия Профессиональная разработка в системе «1С:Предприятие 8»
Механизмы заполнения таблиц регистров накопления в базе данных пришло 100 рублей, ушло 50 рублей, но таблица итогов содержит данные об остатке 1 000 рублей. Поэтому заполнение таблицы итогов осуществляется системой согласно данным активных записей таблицы движений, при расчете итогов (автоматическом или инициированным специальными методами). Подробнее
Раздел «Механизмы заполнения таблицы итогов регистра накопления», стр. 563.
То есть пользователь или разработчик не могут непосредственно записывать данные в таблицу итогов регистра накопления, зато могут инициализировать действия системы, производящие расчет и заполнение итогов (рис. 11.8).
При необходимости разработчик может отключать или включать расчет итогов при записи движений. Это может понадобиться для того, чтобы повысить скорость записи набора записей регистра при массовых загрузках данных. Например, требуется загрузить массив информации по документам и их движениям (листинг 11.2). Листинг 11.2. Пример отключения использования итогов регистра накопления
// Отключить использование итогов регистра. РегистрыНакопления.ПартииТоваров.УстановитьИспользованиеИтогов(Ложь); Для Каждого Элемент из МассивИнформации Цикл
// Выполнить действия по загрузке документов (регистраторов) // и наборов записей регистра. // ...
// Записать загруженные наборы записей. // ...
КонецЦикла; // Включить использование итогов регистра // (одновременно выполнится пересчет итогов). РегистрыНакопления.ПартииТоваров.УстановитьИспользованиеИтогов(Истина);
В приведенном примере обеспечивается ситуация, когда заполнение таблицы итогов выполняется разово, а не при каждой записи набора записей загружаемых документов. Дело в том, что при включении использования итогов система производит пересчет всех итогов с момента самого раннего движения, сделанного после отключения активности итогов. Рис. 11.8. Заполнение таблицы итогов регистра накопления
Если признак расчета итогов регистра включен, то расчет и заполнение данными таблицы итогов регистра производятся автоматически при записи набора записей. Проверить значение признака расчета итогов можно с помощью метода ПолучитьИспользованиеИтогов() менеджера регистра накопления (листинг 11.1). Листинг 11.1. Пример использования метода «ПолучитьИспользованиеИтогов()»
ПризнакИспользованияИтогов = РегистрыНакопления.ПартииТоваров.ПолучитьИспользованиеИтогов();
Если ПризнакИспользованияИтогов Тогда Сообщение = Новый СообщениеПользователю(); Сообщение.Текст = "Итоги по регистру 'ПартииТоваров' рассчитываются"; Сообщение.Сообщить(); КонецЕсли;
Том 1
В отношении использования подобных приемов необходимо понимать, что при отключенном расчете итогов регистра система не может обеспечить непротиворечивость данных таблиц движений и итогов регистра. Поэтому попытки обращений к итогам такого регистра будут отклоняться системой с выдачей соответствующих предупреждений об этом.
Запись данных в таблицу движений регистра накопления Для понимания работы механизмов формирования или модификации записей в таблице движений регистра накопления необходимо, прежде всего, исходить из положения о том, что все записи в регистрах уникальны с точки зрения комбинации значений в ключевых полях. Регистры накопления не поддерживают независимого формирования записей без использования документа-регистратора. Этим достигается обоснованность информации регистров – данными документов.
551
Глава 11. Учет движения средств То есть обоснованность информации объектов, осуществляющих учет показателей, данными объектов, осуществляющих первичную регистрацию событий, приводящих к изменению значений показателей. С другой стороны, к одному регистратору может быть отнесено более одной записи движения. Поэтому для регистров накопления в таблице движений ключевыми являются поля Регистратор и НомерСтроки (рис. 11.9).
Соответственно, для заполнения или модификации данных таблицы движений есть две возможности: ■■ посредством создания набора записей регистра с обязательным отбором по регистратору; ■■ посредством использования свойства объекта документа Движения, представляющего собой коллекцию наборов записей, подчиненных данному регистратору. ПРИМЕЧАНИЕ
Можно сказать, что свойство Движения объекта документа представляет собой определенный «сервис», призванный облегчить труд разработчика по созданию движений документа. В этом свойстве содержатся пустые наборы записей по всем регистрам, по которым документ может выполнять движения. Для этих наборов записей уже установлен отбор по регистратору, соответствующему текущему документу.
Сами же действия по записи могут инициироваться как программно (при выполнении обработок), так и интерактивно. Примеры подобных действий приводятся ниже.
Свойство «Движения» объекта документа Рис. 11.9. Набор записей регистра накопления
Для обеспечения манипулирования записями регистра при формировании или модифицировании движений используется объект встроенного языка системы РегистрНакопленияНаборЗаписей.<имя>. В отношении регистров накопления эти действия выполняются при использовании обязательного отбора по регистратору. То есть запись модифицированных данных в таблицу движений регистра накопления не может выполняться отдельно для каждого движения, а только «блоками», то есть наборами записей, подчиненных одному регистратору.
Свойство Движения – это свойство объекта документа (ДокументОбъект.<Имя>). Состав наборов записей, входящих в эту коллекцию, определяется системой исходя из информации, хранящейся в конфигурации. Модификация этого состава может осуществляться при работе с документом как с объектом конфигурации (рис. 11.10).
Поле НомерСтроки система заполняет автоматически, при добавлении или вставке новой записи в набор записей, отобранных по первому ключевому полю Регистратор. Поле НомерСтроки содержит порядковый номер записи в наборе записей, подчиненных одному регистратору. Кроме того, в регистре накопления не могут существовать записи с пустым значением поля Регистратор, то есть не подчиненные ни одному регистратору или «подчиненные пустому регистратору». Это противоречило бы принципу «обоснованности данных регистра накопления». Таким образом, в отношении движений регистров накопления можно констатировать строгую связь с двумя классами объектов конфигурации: ■■ с регистрами как «хранителями» движений, ■■ с документами как с «обоснованием» формирования и наличия движений.
552
Рис. 11.10. Регистры, для которых документ является регистратором
Профессиональная разработка в системе «1С:Предприятие 8»
Механизмы заполнения таблиц регистров накопления в базе данных Кроме этого, состав наборов записей, создаваемых системой в свойстве Движения, может быть изменен при редактировании регистра как объекта конфигурации (рис. 11.11).
Важно понимать, что платформа во многих механизмах использует обращение к элементам коллекции Движения. Например, при удалении документа система будет для каждого регистра, в котором он может быть регистратором, проверять наличие движений документа с целью их удаления. Поэтому не рекомендуется включать в коллекцию Движения элементы «с запасом». И наоборот, если не указано, что документ может быть регистратором для некоего регистра, то система никоим образом не позволит записать в данный регистр движения данного документа.
Формирование наборов записей посредством свойства объекта документа «Движения» Формирование новых наборов записей включает в себя операции, состоящие: ■■ из добавления новых записей к набору записей, ■■ заполнения полей записей, ■■ записи набора записей.
Рис. 11.11. Документы, которые могут создавать движения в регистре
Благодаря использованию данного свойства облегчается работа разработчика, которому необходимо сформировать или модифицировать набор (наборы) записей регистра (регистров), подчиненных данному документу (рис. 11.12).
Например, требуется сформировать движения по регистру ТоварыНаСкладах на основании данных документа ПоступлениеТоваров. Причем информация для заполнения полей записей движений в основном находится в табличной части Состав документа. Данная операция в листинге 11.3.
может
быть
выполнена
так,
как
показано
Листинг 11.3. Пример формирования движений документа
// Укажем, что движения по данному регистру нужно записывать. Движения.ТоварыНаСкладах.Записывать = Истина; // Перебрать коллекцию строк табличной части документа. Для Каждого ТекСтрокаСостав Из Состав Цикл
// Добавить новую запись к набору записей регистра ТоварыНаСкладах. Движение = Движения.ТоварыНаСкладах.Добавить();
// Заполнить поля добавленной записи. Движение.ВидДвижения = ВидДвиженияНакопления.Приход; Движение.Период = Дата; Движение.Номенклатура = ТекСтрокаСостав.Номенклатура; Движение.Склад = Склад; Движение.Количество = ТекСтрокаСостав.Количество; Движение.ВидОперации = ВидОперации;
КонецЦикла;
Рис. 11.12. Свойство «Движения» объекта документа
Том 1
Краткий комментарий: сначала указываются наборы записей, содержащие движения документа по регистрам, которые должны быть записаны при проведении документа.
553
Глава 11. Учет движения средств
10
Приход
Истина
Пульт PW
Главный
7
554
Вид движения
Активность
Номенклатура
Склад
Количество
Пульт PW
Главный
7
Приход
Истина
Шнур R-100 Главный
100
Вид движения
Активность
Номенклатура
Склад
Количество
ПоступлениеТоваров № 1 13.05.2010 15:00:01 ПоступлениеТоваров № 1 13.05.2010 15:00:01 ПоступлениеТоваров № 1 13.05.2010 15:00:01 ПоступлениеТоваров № 1 13.05.2010 15:00:01 ПоступлениеТоваров № 1 13.05.2010 15:00:01
1
Приход
Истина
Пульт VH
Главный
10
2
Приход
Истина
Пульт PW
Главный
7
3
Приход
Истина
Пульт VH
Главный
10
4
Приход
Истина
Пульт PW
Главный
7
5
Приход
Истина
Шнур R-100 Главный
100
Если же запись набора записей будет выполняться с замещением (листинг 11.5), то старый набор записей будет замещен, и после выполнения операции регистр будет содержать записи, показанные в табл. 11.9. Листинг 11.5. Запись набора записей с замещением
Движения.ТоварыНаСкладах.Записать(Истина); // Альтернативный вариант вызова. Движения.ТоварыНаСкладах.Записать(); Таблица 11.9. Состав записей регистра накопления Регистратор
Движения.ТоварыНаСкладах.Записать(Ложь);
Номер строки
Регистратор
13.05.2010 15:00:01 13.05.2010 15:00:01 13.05.2010 15:00:01 13.05.2010 15:00:01 13.05.2010 15:00:01
Период
Листинг 11.4. Запись набора записей с добавлением
Истина
Таблица 11.8. Состав записей регистра накопления
Записывается новый набор записей (табл. 11.7). Тогда если при записи набора записей для параметра Замещать будет указано значение Ложь (листинг 11.4), то записи, существовавшие в регистре накопления, будут сохранены, и к ним будут добавлены новые записи из записываемого набора (табл. 11.8).
Приход
13.05.2010 15:00:01 13.05.2010 15:00:01 13.05.2010 15:00:01
ПоступлениеТоваров № 1 1 13.05.2010 15:00:01 ПоступлениеТоваров № 1 2 13.05.2010 15:00:01 ПоступлениеТоваров № 1 3 13.05.2010 15:00:01
Приход
Истина
Пульт VH
Главный 10
Приход
Истина
Пульт PW
Главный 7
Приход
Истина
Шнур R-100
Главный 100
Количество
Главный
10
Склад
Пульт VH
Главный
Номенклатура
Количество
Истина
Пульт VH
Активность
Склад
Приход
Истина
Вид движения
Номенклатура
ПоступлениеТоваров № 1 1 13.05.2010 15:00:01 ПоступлениеТоваров № 1 2 13.05.2010 15:00:01
Активность
Регистратор
13.05.2010 15:00:01 13.05.2010 15:00:01
Вид движения
Период
Номер строки
Таблица 11.6. Состав записей регистра накопления
Приход
Номер строки
Например, в регистре ТоварыНаСкладах присутствует набор записей, подчиненный регистратору ПоступлениеТоваров № 1 (табл. 11.6).
ПоступлениеТоваров № 1 13.05.2010 15:00:01 ПоступлениеТоваров № 1 13.05.2010 15:00:01 ПоступлениеТоваров № 1 13.05.2010 15:00:01
Номер строки
Параметр Замещать может принимать значения типа Булево, по умолчанию – значение Истина. Действие данного параметра проявляется в случае, если на момент записи нового (или модифицированного) набора записей в регистре присутствуют еще записи, подчиненные данному же регистратору.
13.05.2010 15:00:01 13.05.2010 15:00:01 13.05.2010 15:00:01
Регистратор
Следует учитывать, что при автоматической записи движений они будут записаны с замещением, то есть старые движения документа будут замещены новыми. Если же при записи движений документа нужно добавлять новые движения к старым, то для этого нужно использовать параметр Замещать метода Записать() набора записей регистра накопления и явно записывать набор записей с параметром Замещать, установленным в значение Ложь.
Период
После выхода из обработки проведения те наборы записей, у которых свойство Записывать имеет значение Истина, будут автоматически записаны платформой. После этого свойство Записывать у этих наборов движений будет установлено в значение Ложь.
Таблица 11.7. Записываемый набор записей
Период
Формирование новых записей движений и их заполнение выполняются в цикле перебора строк табличной части документа. Для каждой строки добавляется новая запись к набору записей регистра ТоварыНаСкладах, полученному как элемент коллекции свойства Движения данного объекта документа. Поскольку метод Добавить() возвращает сам добавленный объект, новая запись получается в переменную Движение. Дальнейшее заполнение полей записи осуществляется посредством этой переменной.
Профессиональная разработка в системе «1С:Предприятие 8»
Механизмы заполнения таблиц регистров накопления в базе данных Данная возможность позволяет решать различные прикладные задачи, связанные: ■■ с добавлением новых движений к старым, ■■ замещением старых движений новыми. Хотелось бы отметить, что все вышеописанные действия по формированию движений типизированы, и большая часть кода посвящена заполнению полей регистра значениями полей документа. Поэтому для облегчения написания соответствующего кода разработчик может использовать конструктор движений документа (рис. 11.13).
Рис. 11.13. Конструктор движений документа
Программное изменение данных регистра можно использовать при проведении документа, а можно и без проведения. Поскольку заполнение учетных данных чаще всего выполняется во время операции проведения документа, то конструктор движений документа создает соответствующий код именно в рамках процедуры обработчика события ОбработкаПроведения.
Формирование движений при проведении документа Проведение документов чаще всего используется для формирования движений документов. Этому способствует удобство функциональных решений, заложенных в платформу. Например: ■■ С точки зрения платформы отдельного процесса «проведение» не существует. Есть запись документа с проведением, причем в рамках одной транзакции. Том 1
подробнее
Раздел «Запись документов», стр. 508.
Таким образом, в момент выполнения обработчика события ОбработкаПроведения документ уже записан. То есть разработчику не нужно беспокоиться о предотвращении попыток проведения незаписанных документов (рис. 11.14).
Рис. 11.14. Последовательность событий при записи документа с проведением
■■ Свойство Удаление движений документа как объекта конфигурации стандартно устанавливается платформой в значение Удалять автоматически при отмене проведения. Это значит, что при перепроведении документа движения, подчиненные данному документу, перезаписываются, а при отмене проведения движения документа автоматически удаляются. Если разработчик захочет реализовать нестандартный вариант проведения документа и установит свойство Удаление движений в значение Удалять автоматически, то при записи документа с проведением сначала будут удалены все старые движения документа. То есть на момент выполнения обработчика события ОбработкаПроведения в регистрах не будет наборов записей с движениями данного документа. ■■ При записи с проведением система автоматически запишет выбранные и незаписанные наборы записей, находящиеся в свойстве Движения. Это еще один «сервис», обеспечиваемый свойством Движения. Отсюда следуют два важных вывода. Во-первых, если наборы записей необходимо записывать с добавлением, то это нужно выполнять в явном
555
Глава 11. Учет движения средств виде, т. к. при автоматической записи движений они будут записаны с замещением. Во-вторых, последовательность обращения к регистрам при автоматической записи движений будет одна и та же для разных документов. Это позволяет снизить вероятность взаимных блокировок при проведении документа в конкурентных режимах работы. В случаях, если необходимо программно вызвать саму обработку проведения, инициируется запись документа с проведением. Пример программного вызова проведения документа в оперативном режиме приведен в листинге 11.6. Листинг 11.6. Пример программного вызова проведения документа
Записать(РежимЗаписиДокумента.Проведение, РежимПроведенияДокумента.Оперативный); Подробнее
В демонстрационной конфигурации «Хранение информации», которая находится на прилагаемом компакт-диске, в обработке ДействияСДвижениямиРегистраНакопления приводится пример перепроведения документов РеализацияТоваров в интервале с ДатаНачала по ДатаОкончания.
Рассмотрим этот пример (листинг 11.7).
Говоря о записи документа, необходимо отдельно упомянуть случай, когда документ записывается с проведением в форме самого документа. Запись в форме позволяет использовать функциональность, определяемую расширением формы документа: установка даты документа, установка режима проведения, запрет определенных действий пользователя и т. д. подробнее
Раздел «Особенности работы формы документа», стр. 520.
В качестве примера записи в форме в демонстрационной конфигурации «Хранение информации», которая находится на прилагаемом компактдиске, в командную панель формы документа РеализацияТоваров добавлена кнопка Провести неоперативно. Действия, выполняемые по нажатии этой кнопки, представлены в листингах 11.8, 11.9. Листинг 11.8. Обработчик события нажатия кнопки «Провести неоперативно»
&НаКлиенте Процедура ПровестиНеоперативно(Команда) ПровестиНеоперативноНаСервере(); КонецПроцедуры
Листинг 11.7. Пример перепроведения документов «РеализацияТоваров»
// Получить ссылки на проведенные документы в требуемом интервале. Запрос = Новый Запрос; Запрос.Текст = "ВЫБРАТЬ | РеализацияТоваров.Ссылка |ИЗ | Документ.РеализацияТоваров КАК РеализацияТоваров |ГДЕ | РеализацияТоваров.Дата МЕЖДУ &ДатаНачала И &ДатаОкончания | И РеализацияТоваров.Проведен"; Запрос.УстановитьПараметр("ДатаНачала", ДатаНачала); Запрос.УстановитьПараметр("ДатаОкончания", ДатаОкончания); Результат = Запрос.Выполнить(); // Перебрать ссылки полученных документов. Выборка = Результат.Выбрать(); Пока Выборка.Следующий() Цикл // Перепровести каждый документ неоперативно. Документ = Выборка.Ссылка.ПолучитьОбъект(); Документ.Записать(РежимЗаписиДокумента.Проведение); КонецЦикла;
Здесь инициировалось проведение в неоперативном режиме. Значение по умолчанию параметра РежимПроведения метода объекта документа Записать() – именно РежимПроведенияДокумента.Неоперативный.
556
Листинг 11.9. Пример записи документа с неоперативным проведением в форме
&НаСервере Процедура ПровестиНеоперативноНаСервере(); // Установить использование режима неоперативного проведения. ИспользоватьРежимПроведения = ИспользованиеРежимаПроведения.Неоперативный;
// Выполнить проведение в форме. Записать(Новый Структура("РежимЗаписи", РежимЗаписиДокумента.Проведение));
КонецПроцедуры
В данном примере используется свойство ИспользоватьРежимПроведения и метод Записать() расширения формы документа.
Формирование движений в объекте документа, но без проведения документа С прикладной точки зрения часто возникает потребность сформировать движения для документов, чья обработка еще полностью не завершена, и завершена будет, возможно, не в этом сеансе работы с программой, а через некоторое время. Поэтому платформа «1С:Предприятие» позволяет в способе формирования движений не ограничиваться только проведением документа. Профессиональная разработка в системе «1С:Предприятие 8»
Механизмы заполнения таблиц регистров накопления в базе данных Однако нужно помнить, что кроме выполнения самих движений при формировании движений вне процедуры, обрабатывающей проведение документа, необходимо: ■■ контролировать, чтобы документ был сохранен на момент записи движений в регистр (записи должны содержать ссылку на регистратор); ■■ решать, что делать со старыми движениями документа; ■■ явно записывать сформированные наборы записей движений. подробнее
Пример формирования движений без проведения документа приведен в демонстрационной конфигурации «Хранение информации», которая находится на прилагаемом компакт-диске.
В командной панели формы документа ПоступлениеТоваров создано подменю Действия с движениями. В нем находится команда Формирование движений. Обработчик действия данной команды (листинги 11.11, 11.12) передает управление процедуре ФормированиеДвиженийБезПроведения() модуля объекта документа (листинг 11.10). Листинг 11.10. Пример формирования движений документа без проведения
Процедура ФормированиеДвиженийБезПроведения() Экспорт // Проверить и записать документ, если ранее не записан. Если ЭтоНовый() Тогда Записать(); КонецЕсли; Для Каждого ТекСтрокаСостав Из Состав Цикл // Сформировать и заполнить запись движения. Движение = Движения.ТоварыНаСкладах.Добавить(); Движение.ВидДвижения = ВидДвиженияНакопления.Приход; Движение.Период = Дата; Движение.Номенклатура = ТекСтрокаСостав.Номенклатура; Движение.Склад = Склад; Движение.Количество = ТекСтрокаСостав.Количество; Движение.ВидОперации = ВидОперации; КонецЦикла; // Записать движения регистров с замещением старых наборов записей. Движения.ТоварыНаСкладах.Записать(); КонецПроцедуры
Краткий комментарий: сначала необходимо убедиться, что ссылка на данный документ уже есть в базе данных, то есть документ не новый. Если нет, документ записывается, поскольку без ссылки на регистратор движения в регистре накопления сформированы быть не могут. Затем формируется Том 1
новый набор записей в цикле перебора строк табличной части Состав документа. Далее сформированный набор записей записывается в регистр. Также следует обратить внимание на то, что в заголовке процедуры, выполняющей эти действия, указано ключевое слово Экспорт. В результате данная процедура доступна в контексте объекта документа. Вызов данной процедуры выполняется из модуля формы данного документа. Основным реквизитом формы документа как раз и является объект документа, поэтому процедура будет доступна в контексте формы документа. Но для того, чтобы вызвать процедуру объекта документа, нужно сначала конвертировать основной реквизит формы Объект в этот объект (листинги 11.12, 11.13). Листинг 11.11. Обработчик действия команды «ФормированиеДвижений»
&НаКлиенте Процедура ФормированиеДвижений(Команда) ФормированиеДвиженийДокумента(); КонецПроцедуры Листинг 11.12. Пример вызова процедуры из формы документа
&НаСервере Процедура ФормированиеДвиженийДокумента() Документ = РеквизитФормыВЗначение("Объект"); Документ.ФормированиеДвиженийБезПроведения(); КонецПроцедуры
В принципе вызов этой процедуры может быть реализован почти из любого модуля программы. Для этого нужно лишь получить объект документа (например, из ссылки на документ), листинг 11.13. Листинг 11.13. Пример вызова процедуры из модуля обработки
// Получить объект документа. Документ = СсылкаНаДокумент.ПолучитьОбъект(); // Вызвать процедуру модуля объекта документа, формирующую движения. Документ.ФормированиеДвиженийБезПроведения();
Модификация существующих движений документа Кроме задачи формирования новых движений без проведения документа разработчикам иногда приходится решать задачи изменения информации в движениях (модификации движений), снятия активности движений документа или вообще удаления движений. Технология их решения абсолютно та же. Это запись наборов записей регистра, только соответствующим образом модифицированных.
557
Глава 11. Учет движения средств Для модификации движений можно сначала прочитать набор записей движений, далее модифицировать записи и записать уже модифицированный набор записей движений.
Подробнее
В демонстрационной конфигурации «Хранение информации», которая находится на прилагаемом компакт-диске, в форме документа ПоступлениеТоваров приведен пример заполнения поля реквизита Поставщик регистра ТоварыНаСкладах значением из константы ОсновнойПоставщик.
Обратите внимание: элемент коллекции свойства документа Движения представляет собой набор записей регистра. Но он, пока не прочитан, пуст (рис. 11.15).
Рассмотрим этот пример (листинг 11.14). Листинг 11.14. Пример модификации движений документа
// Получить значение основного поставщика. ОсновнойПоставщик = Константы.ОсновнойПоставщик.Получить(); // Прочитать набор записей движений по регистру "ТоварыНаСкладах". Документ = РеквизитФормыВЗначение("Объект"); НаборЗаписей = Документ.Движения.ТоварыНаСкладах; НаборЗаписей.Прочитать(); // Модифицировать каждую запись в прочитанных движениях. Если НаборЗаписей.Количество()<> 0 Тогда Для Каждого Движение Из НаборЗаписей Цикл Рис. 11.15. Коллекция «Движения» содержит пустые наборы записей
Поэтому, для того чтобы модифицировать записи регистра, необходимо сначала прочитать данные наборы записей (рис. 11.16).
Движение.Поставщик = ОсновнойПоставщик;
КонецЦикла;
// Записать измененный набор записей. НаборЗаписей.Записать(); КонецЕсли;
Снятие активности движений – по сути дела та же задача модификации движений документа, только в отношении поля Активность, и может выполняться аналогично. Однако с прикладной точки зрения свойство записи движения Активность особое. Во-первых, наличие активных движений документа в регистре означает, что данный документ отражен в неком аспекте учета. Вернее, в учете отражено событие, зафиксированное данным документом. Во-вторых, наличие движений документа со снятой активностью означает, что движения данного документа не используются в учетном механизме. В-третьих, наличие движений документа в регистре, из которых часть активна, а часть неактивна, с точки зрения практического применения нонсенс. Например, попробуйте представить себе ситуацию: «Отгружено пять пылесосов и холодильник, но не совсем. Холодильник не отгружен». Поэтому платформа не допускает записи набора записей движений регистра, если часть записей в этом наборе активна, а часть – нет (рис. 11.17).
Рис. 11.16. Чтение набора записей
558
В системе предусмотрена возможность установки и снятия активности целиком для всего набора записей посредством метода УстановитьАктивность() набора записей регистра накопления. Профессиональная разработка в системе «1С:Предприятие 8»
Механизмы заполнения таблиц регистров накопления в базе данных подробнее
В демонстрационной конфигурации «Хранение информации», которая находится на прилагаемом компакт-диске, в форме документа ПоступлениеТоваров при выполнении действия ОчиститьДвиженияДокумента выполняется удаления движений документа.
Рассмотрим этот пример (листинг 11.16). Листинг 11.16. Пример удаления движений документа
Документ = РеквизитФормыВЗначение("Объект"); // Перебрать наборы записей по регистрам Для Каждого НаборЗаписей Из Документ.Движения Цикл
// Очистить набор записей движений по регистру. НаборЗаписей.Очистить(); // Записать набор записей. НаборЗаписей.Записать();
КонецЦикла; Рис. 11.17. Варианты использования свойства «Активность»
Подробнее
В демонстрационной конфигурации «Хранение информации», которая находится на прилагаемом компакт-диске, в форме документа ПоступлениеТоваров приводится пример снятия активности всех движений документа по регистрам.
Однако если бы была полная уверенность, что ни один из наборов записей регистров для данного объекта документа на момент выполнения процедуры не прочитан, то предварительную очистку можно было бы не делать (листинг 11.17). Листинг 11.17. Пример удаления движений документа
Документ = РеквизитФормыВЗначение("Объект");
Рассмотрим этот пример (листинг 11.15).
// Перебрать наборы записей по регистрам. Для Каждого НаборЗаписей Из Документ.Движения Цикл
Листинг 11.15. Пример снятия активности записей
Документ = РеквизитФормыВЗначение("Объект"); // Перебрать наборы записей по регистрам. Для Каждого НаборЗаписей Из Документ.Движения Цикл
// Прочитать движения по регистру. НаборЗаписей.Прочитать(); // Снять активность. НаборЗаписей.УстановитьАктивность(Ложь); // Записать набор записей. НаборЗаписей.Записать();
КонецЦикла;
И, наконец, операция удаления движений документа. Она сводится к записи пустого набора записей регистра. В ситуации, когда набор записей регистра прочитан и не пуст, можно использовать его предварительную очистку. Том 1
// Записать набор записей. НаборЗаписей.Записать();
КонецЦикла
Интерактивное формирование наборов записей с помощью свойства «Движения» объекта документа Описанный выше функционал системы касался наиболее часто встречающихся решений задач формирования движений документов. То есть пользователь отвечает за правильность ввода информации в документ, а разработчик – за правильность работы обработок, интерпретирующих и записывающих в регистры учетную информацию, полученную согласно данным документов. Однако иногда могут встречаться ситуации, когда не требуется никакой дополнительной обработки для вводимой пользователем информации.
559
Глава 11. Учет движения средств То есть тогда можно обеспечить ввод информации напрямую в данные регистра, без промежуточной регистрации ее в данных документа. Для регистров накопления в любой ситуации возможно содержание информации только с использованием документа-регистратора. Поэтому в таких случаях для обеспечения требования обоснованности данных регистра наличием регистратора и желания уменьшить избыточность хранения информации в базе данных возможно применение технологии, условно называемой «ручная операция».
ванных данных в регистр нажмет кнопку Перечитать (или выполнит команду формы Все действия Перечитать), то он получит предупреждение (рис. 11.20).
В форме документа отображаются данные и документа, и движений регистра, которые подчинены данному документу (рис. 11.18).
Рис. 11.19. Форма документа «РучнаяОперация»
Рис. 11.20. Предупреждение при перечитывании данных
Рис. 11.18. Редактирование движений вручную
В состав демонстрационной конфигурации «Хранение информации», которая находится на прилагаемом компакт-диске, входит документ РучнаяОперация. Его создание и технологические вопросы, возникающие при его использовании, подробно описаны в разделе «Специальные случаи использования документов. Ручная операция» на стр. 529. Хотелось бы только еще раз подчеркнуть, что для облегчения работы разработчика здесь использовалось свойство Движения объекта документа. И таблица в форме документа отображает данные одного из элементов этой коллекции – набора записей движений по регистру ТоварыНаСкладах. Пользователь, работая с формой документа, на самом деле интерактивно модифицирует считанные данные набора записей движений регистра, подчиненных данному документу (рис. 11.19). А вопросы отображения данных регистра в таблице формы, записи модифицированных данных из реквизита формы в таблицу движений регистра и т. д. берет на себя платформа посредством возможностей, предоставляемых расширением формы документа. Причем системой отрабатывается большинство ситуаций, которые могут привести к коллизиям. Например, если пользователь после внесения изменений в содержимое таблицы формы, но до записи модифициро-
560
Если перечитать данные до записи модифицированных данных в регистр (ответ – Да), то последние изменения будут потеряны.
Запись набора записей регистра без использования свойства «Движения» В разделе «Свойство «Движения» объекта документа» на стр. 552 были описаны действия с объектом документа, приводящие к чтению, модификации, добавлению и записи наборов записей в регистр. Те же самые результаты можно получить и без использования объекта документа, работая непосредственно с набором записей (рис. 11.21). В данном случае для модификации движений документа не используется объект документа (используется только ссылка на документ). Поэтому при выполнении обработок массового формирования или модификации движений, связанных не с единичными документами, а с большими массивами документов, уместнее применение приемов работы, основанных на использовании набора записей регистра, т. к. этот способ является менее ресурсоемким. Например, в состав конфигурации уже заполненной базы данных ввели новый оборотный регистр Продажи со следующей структурой (рис. 11.22). Профессиональная разработка в системе «1С:Предприятие 8»
Механизмы заполнения таблиц регистров накопления в базе данных Листинг 11.18. Пример формирования движений документов
Рис. 11.21. Использование набора записей регистра накопления
Рис. 11.22. Структура регистра «Продажи»
Он должен заполняться при проведении документа РеализацияТоваров данными документа (включая данные его табличной части Состав), поэтому в обработку проведения данного объекта конфигурации были внесены соответствующие изменения. Однако существует уже достаточно много документов РеализацияТоваров, оформленных и проведенных еще в то время, когда нового регистра не было. Как для них сформировать движения по новому регистру? Можно, конечно, перепровести все ранее проведенные документы РеализацияТоваров. Однако при проведении документа не только выполняются движения по новому регистру. Формируются движения по другим регистрам, записываются данные в таблицу документа, в таблицы журналов документов и т. д. Поэтому данное решение может оказаться неудобным в отношении скорости исполнения или по другим причинам. В данной ситуации более эффективным выглядит применение следующей обработки. Из базы данных запросом выбрать ссылки на проведенные документы РеализацияТоваров и другие данные этих документов, необходимые для формирования движений. Эти данные можно получить из таблицы документа. Перебирая выборку результата запроса, применять отбор по регистраторам (ссылкам на документы) для формирования наборов записей движений, подчиненных этим документам (листинг 11.18). Том 1
Процедура ФормированиеДвиженийПоПродажамДляВсехРеализацияТоваров() // Обратиться к набору записей регистра. НаборЗаписейРегистра = РегистрыНакопления.Продажи.СоздатьНаборЗаписей(); // Прочитать из базы данных данные, необходимые для формирования движений. Запрос = Новый Запрос; Запрос.Текст = "ВЫБРАТЬ | РеализацияТоваровСостав.Ссылка КАК Ссылка, | РеализацияТоваровСостав.Ссылка.Дата, | РеализацияТоваровСостав.Ссылка.Контрагент, | РеализацияТоваровСостав.Ссылка.ВидОперации, | РеализацияТоваровСостав.Номенклатура, | РеализацияТоваровСостав.Количество, | РеализацияТоваровСостав.Сумма |ИЗ | Документ.РеализацияТоваров.Состав КАК РеализацияТоваровСостав |ГДЕ | РеализацияТоваровСостав.Ссылка.Проведен |ИТОГИ ПО | Ссылка"; Результат = Запрос.Выполнить(); // Перебрать все документы из результата запроса. ВыборкаДокументов = Результат.Выбрать(ОбходРезультатаЗапроса.ПоГруппировкам); Пока ВыборкаДокументов.Следующий() Цикл // Установить отбор набора записей по регистратору, к которому будут приписаны движения. НаборЗаписейРегистра.Отбор.Регистратор.Установить(ВыборкаДокументов.Ссылка); // Перебрать данные о составе документа, необходимые для заполнения формируемых движений. ВыборкаДетальныхЗаписей = ВыборкаДокументов.Выбрать(); Пока ВыборкаДетальныхЗаписей.Следующий() Цикл // Сформировать движения по регистру Продажи. НоваяЗапись = НаборЗаписейРегистра.Добавить(); НоваяЗапись.Период = ВыборкаДетальныхЗаписей.Дата; НоваяЗапись.Номенклатура = ВыборкаДетальныхЗаписей.Номенклатура; НоваяЗапись.Количество = ВыборкаДетальныхЗаписей.Количество; НоваяЗапись.Сумма = ВыборкаДетальныхЗаписей.Сумма; НоваяЗапись.Контрагент = ВыборкаДокументов.Контрагент; НоваяЗапись.ВидОперации = ВыборкаДокументов.ВидОперации; КонецЦикла; // Записать сформированные для очередного документа движения. НаборЗаписейРегистра.Записать(); // Очистить набор записей регистра // перед использованием для следующего документа. НаборЗаписейРегистра.Очистить(); КонецЦикла; КонецПроцедуры
561
Глава 11. Учет движения средств подробнее
Данный пример приведен в составе обработки ДействияСДвижениямиРегистраНакопления демонстрационной конфигурации «Хранение информации», которая находится на прилагаемом компакт-диске.
Еще раз хотелось бы подчеркнуть, что данная обработка вообще не обращается к объектам документов. По сути, движения «приписываются» к документам «без ведома объектов документов». Подобным же образом можно решать не только задачи формирования новых движений документов, но и модификации существующих движений. Примеры чтения движений регистров накопления будут приведены ниже, в разделе «Получение движений регистров накопления» на стр. 568.
В данном примере использовался следующий прием: набор записей регистра, не прочитанный из базы, пуст. Если записать пустой набор записей регистра с замещением, это приведет к удалению движений замещаемого в рамках отбора набора записей. В заключение хотелось бы только еще раз подчеркнуть – для регистров накопления все действия с модификацией наборов записей регистра можно выполнять только в рамках отбора по регистратору, то есть документу, которому подчинен этот набор записей.
Интерактивное формирование движений с помощью формы набора записей
Частным случаем операций модификации наборов записей регистров накопления является удаление движений. Удалить движения регистра Продажи в пределах заданного временного интервала можно следующим образом (листинг 11.19).
Выше, в разделе «Интерактивное формирование наборов записей с помощью свойства «Движения» объекта документа» на стр. 559, рассматривался пример, когда в рамках формы документа пользователю предоставлялись возможности интерактивного формирования/модификации движений документа.
Листинг 11.19. Пример удаления движений документа
Если пользователю необходимо предоставить те же интерактивные возможности, но без использования формы документа, задача может быть решена посредством использования формы набора записей.
&НаСервереБезКонтекста Процедура УдалитьДвиженияПоПродажамЗаПериод(ДатаНачала, ДатаОкончания) // Обратиться к набору записей регистра. НаборЗаписейРегистра =РегистрыНакопления.Продажи.СоздатьНаборЗаписей(); // Получить из базы данных ссылки на документы, у которых нужно удалить движения. Запрос = Новый Запрос; Запрос.Текст = "ВЫБРАТЬ РАЗЛИЧНЫЕ | Продажи.Регистратор |ИЗ | РегистрНакопления.Продажи КАК Продажи |ГДЕ | Продажи.Период МЕЖДУ &ДатаНачала И &ДатаОкончания"; Запрос.УстановитьПараметр("ДатаНачала", ДатаНачала); Запрос.УстановитьПараметр("ДатаОкончания", ДатаОкончания); Результат = Запрос.Выполнить(); // Перебрать все документы из результата запроса. Выборка = Результат.Выбрать(); Пока Выборка.Следующий() Цикл // Установить отбор набора записей по регистратору, к которому будут приписаны движения. НаборЗаписейРегистра.Отбор.Регистратор.Установить(Выборка.Регистратор); // Записать пустой набор записей движений для очередного документа. НаборЗаписейРегистра.Записать(); КонецЦикла; КонецПроцедуры
562
подробнее
В демонстрационной конфигурации «Хранение информации», которая находится на прилагаемом компакт-диске, в форме списка документа РучнаяОперация приведен подобный пример.
В состав регистра ТоварыНаСкладах включена форма ФормаНабораЗаписей, основной реквизит которой имеет тип РегистрНакопленияНаборЗаписей. ТоварыНаСкладах. Вызов данной формы может осуществляться любой обработкой или командой. Единственное, для возможности выполнения действий по модификации наборов записей регистра накопления необходимо помнить об обязательности установки отбора по регистратору. Вызов формы набора записей регистра ТоварыНаСкладах реализуется из формы списка документа РучнаяОперация (рис. 11.23).
Рис. 11.23. Форма списка документа «РучнаяОперация»
Профессиональная разработка в системе «1С:Предприятие 8»
Механизмы заполнения таблиц регистров накопления в базе данных Обработчик команды ОткрытьФормуНабораЗаписей реализован следующим образом (листинг 11.20).
Механизмы заполнения таблицы итогов регистра накопления
Листинг 11.20. Пример использования формы набора записей
Таблицы итогов регистров накопления заполняются автоматически вследствие добавления, удаления или модификации наборов записей в таблице движений регистра, если для этого регистра не отключен режим расчета итогов.
&НаКлиенте Процедура ОткрытьФормуНабораЗаписей(Команда) // Получить ссылку на текущий документ. ТекущийДокумент = Элементы.Список.ТекущаяСтрока; // Открыть форму набора записей с отбором по регистратору. ЗначениеОтбора = Новый Структура("Регистратор", ТекущийДокумент); ПараметрыФормы = Новый Структура("Отбор", ЗначениеОтбора); ОткрытьФорму("РегистрНакопления.ТоварыНаСкладах.Форма. ФормаНабораЗаписей", ПараметрыФормы) КонецПроцедуры
Краткий комментарий: сначала создается структура отбора ЗначениеОтбора с ключом Регистратор, содержащим ссылку на текущий документ (Элементы.Список.ТекущаяСтрока), и добавляется в структуру параметров формы ПараметрыФормы. Эти параметры передаются в форму набора записей ФормаНабораЗаписей, и эта форма открывается с отбором по полю Регистратор регистра накопления ТоварыНаСкладах. В форме набора записей пользователь может интерактивно модифицировать как сам набор записей (удалять, добавлять, копировать и т. д.), так и содержимое полей записей, входящих в набор записей. Впоследствии модифицированный набор может быть сохранен, то есть записан в регистр (рис. 11.24).
Расчет итогов производится согласно записям таблицы движений регистра, если свойство Активность этих записей имеет значение Истина. Но для разных видов регистров накопления заполнение данных таблицы итогов выполняется по разным правилам. Это объясняется спецификой показателей, учитываемых посредством регистров. подробнее
Раздел «Оперативный учет. Описание задач, решаемых регистрами накопления», стр. 545.
Механизм заполнения таблицы итогов регистра накопления остатков В таблице итогов регистра остатков хранятся текущие итоги и могут храниться итоги рассчитанных периодов. Текущие (актуальные) итоги – это итоговые значения учитываемых в регистре ресурсов (показателей) на момент времени заведомо больший, нежели любое значение поля Период записей таблицы движений. Для определенности текущие итоги регистров остатков датированы на 01.11.3999 00:00:00. Итоги рассчитанных периодов содержат данные конечных значений ресурсов для каждого месяца, предшествующего границе рассчитанных итогов. При записи набора активных записей в таблице движений всегда рассчитываются и перезаписываются текущие итоги в таблице итогов, если у регистра установлен признак использования итогов.
Рис. 11.24. Форма набора записей регистра
Обеспечение выполнения этих действий и устранение возможных коллизий реализуются средствами расширения формы набора записей регистра. Том 1
Данные итогов периодов в таблице итогов появляются вследствие расчета итогов. Такой расчет может быть инициирован посредством системной команды Управление итогами. Для этого нужно вызвать стандартную функцию Управление итогами (Все функции Стандартные) и переключить ее в режим Полные возможности (рис. 11.25). Период для подсчета итогов – всегда месяц. Чтобы установить границу рассчитанных итогов сразу для всех регистров накопления остатков, можно переключить обработку в режим Часто используемые возможности и выполнить команду Установить период рассчитанных итогов.
563
Глава 11. Учет движения средств Таблица 11.11. Таблица итогов регистра накопления остатков
Итоги апреля 2010 года
Итоги мая 2010 года (граница рассчитанных итогов)
Текущие итоги
Рис. 11.25. Стандартная обработка «Управление итогами»
Также расчет итогов может быть выполнен программно (листинг 11.21). Листинг 11.21. Программный расчет итогов регистра
РегистрыНакопления.ТоварыНаСкладах.УстановитьПериодРассчитанныхИтогов(Дата(2010, 05, 31));
Например, пусть таблица движений регистра накопления будет заполнена данными, как показано в табл. 11.10.
Период
Номенклатура
Склад
Количество Сумма
01.05.2010 00:00:00 01.06.2010 00:00:00 01.06.2010 00:00:00 01.06.2010 00:00:00 01.11.3999 00:00:00 01.11.3999 00:00:00 01.11.3999 00:00:00 01.11.3999 00:00:00
Пульт VH
Главный
1
10
Пульт VH
Главный
2
20
Пульт PW
Главный
7
490
Пульт PW
Фили-2
1
17
Пульт VH
Фили-2
1
18
Пульт VH
Главный
2
20
Пульт PW
Главный
7
490
Пульт PW
Фили-2
1
17
Обратите внимание: майские итоги хранятся с указанием периода 01.06.2010 00:00:00, потому что итоги рассчитаны на начало июня. То есть при их расчете учтены все записи, которые зафиксированы в мае, включая 31.05.2010 23:59:59 (рис. 11.26).
Пульт VH
Главный 1
10
1
Приход Истина
Пульт VH
Главный 9
90
2
Приход Истина
Пульт PW
Главный 7
490
1
Приход Ложь
Пульт VH
Фили-2
5
60
1
Расход Истина
Пульт VH
Главный 8
80
1
Приход Истина
Пульт PW
Фили-2
1
17
1
Приход Истина
Пульт VH
Фили-2
1
18
Сумма
Склад
Приход Истина
Количество
Номенклатура
1
Активность
ПоступлениеТоваров № 1 13.05.2010 15:00:00 ПоступлениеТоваров № 2 13.05.2010 15:00:01 ПоступлениеТоваров № 2 13.05.2010 15:00:01 ПоступлениеТоваров № 3 23.05.2010 15:30:45 Реализация № 1 27.05.2010 12:30:45 ПоступлениеТоваров № 4 31.05.2010 23:59:59 ПоступлениеТоваров № 5 01.09.2010 00:00:00
Вид движения
Регистратор
03.04.2010 15:00:00 13.05.2010 15:00:01 13.05.2010 15:00:01 23.05.2010 15:30:45 27.05.2010 12:30:45 31.05.2010 23:59:59 01.09.2010 00:00:00
Номер строки
Период
Таблица 11.10. Таблица движений регистра накопления остатков
Для вышеприведенного примера заполнения таблицы движений регистра таблица итогов регистра после расчета итогов по 31.05.2010 будет выглядеть так, как показано в табл. 11.11.
564
Рис. 11.26. Хранение рассчитанных итогов регистра накопления остатков
Наличие посчитанных по конец каждого месяца итогов положительно сказывается на быстродействии обращений к остаткам регистра. Как будет еще более подробно описано ниже, в разделе «Получение остатков» на стр. 573, расчет остатков начинается с определения ближайшего равного или большего итога (хранимого в таблице итогов регистра) с последующим «досчетом» остатка на нужный момент времени по таблице движений. Но зачастую может сложиться ситуация, что граница рассчитанных итогов очень сильно «отстает» от периода самой последней записи в регистре. Данное положение не сказывается на функциональности регистра, сказывается только на быстродействии обращений к его остаткам. Поскольку досчет тогда будет производиться, скорее всего, по большому количеству записей. Профессиональная разработка в системе «1С:Предприятие 8»
Механизмы заполнения таблиц регистров накопления в базе данных
Например, если к вышеприведенным примерам в таблицу движений добавить еще записи, представленные в табл. 11.14, то таблица итогов регистра после общего пересчета итогов в результате будет заполнена так, как показано в табл. 11.15.
1
Приход Истина
Пульт VH
Главный
9
90
2
Приход Истина
Пульт PW
Главный
7
490
1
Приход Истина
Пульт PW
Фили-2
10
120
1
Приход Ложь
Пульт PW
Главный
1
1
1
Приход Ложь
Пульт VH
Фили-2
5
60
1
Расход
Истина
Пульт VH
Главный
8
80
1
Приход Истина
Пульт PW
Фили-2
1
17
1
Приход Истина
Пульт VH
Фили-2
1
18
В этом случае будет производиться перерасчет итогов только по комбинации значений измерений Пульт PW и Фили-2 (табл. 11.13). Ведь свойство Активность движений документа Поступление товаров № 7 имеет значение Ложь. Таблица 11.13. Таблица итогов регистра накопления остатков Период
01.05.2010 00:00:00 01.06.2010 00:00:00 01.06.2010 00:00:00 01.06.2010 00:00:00 01.11.3999 00:00:00 01.11.3999 00:00:00 01.11.3999 00:00:00 01.11.3999 00:00:00
Том 1
Номенклатура
Пульт VH Пульт VH Пульт PW Пульт PW Пульт VH Пульт VH Пульт PW Пульт PW
Склад
Главный Главный Главный Фили-2 Фили-2 Главный Главный Фили-2
Количество
1 2 7 11 1 2 7 11
Сумма
10 20 490 137 18 20 490 137
02.06.2010 10:00:00 02.06.2010 10:00:00
РеализацияТоваров № 2 1 02.06.2010 10:00:00 РеализацияТоваров № 2 2 02.06.2010 10:00:00
Сумма
10
Количество
1
Расход
Истина Пульт VH
Главный
2
20
Расход
Истина Пульт PW
Главный
1
70
Номенклатура
Сумма
Главный
Номер строки
Количество
Пульт VH
Регистратор
Склад
Приход Истина
Период
Номенклатура
1
Активность
Вид движения
Регистратор
Поступление товаров № 1 13.05.2010 15:00:00 Поступление товаров № 2 13.05.2010 15:00:01 Поступление товаров № 2 13.05.2010 15:00:01 Поступление товаров № 6 13.05.2010 15:00:01 Поступление товаров № 7 13.05.2010 15:00:01 Поступление товаров № 3 23.05.2010 15:30:45 Реализация № 1 27.05.2010 12:30:45 Поступление товаров № 4 31.05.2010 23:59:59 Поступление товаров № 5 01.09.2010 00:00:00
Номер строки
Период
03.04.2010 15:00:00 13.05.2010 15:00:01 13.05.2010 15:00:01 15.05.2010 11:00:01 15.05.2010 11:01:01 23.05.2010 15:30:45 27.05.2010 12:30:45 31.05.2010 23:59:59 01.06.2010 00:00:00
Склад
Таблица 11.14. Записи, добавляемые в регистр накопления остатков
Таблица 11.12. Добавление записей в таблицу движений регистра накопления остатков
Активность
Например, пусть к записям регистра добавляются записи, выделенные в табл. 11.12.
Если в результате расчета текущих итогов или итогов периода окажется, что по некой комбинации значений измерений итоги всех ресурсов «выводятся в ноль», то данная запись удаляется системой из таблицы итогов при общем пересчете итогов.
Вид движения
При добавлении, удалении, модификации записей таблицы движений регистра система автоматически производит пересчет всех рассчитанных итогов, начиная с того периода (месяца), к которому относится значение поля Период записей. Так же пересчитываются текущие итоги. Этот процесс захватывает все записи итогов, в которых указаны значения измерений модифицируемых записей. Главное, чтобы значение поля Активность модифицируемых записей таблицы движений было Истина.
Таблица 11.15. Таблица итогов регистра накопления остатков Период
Номенклатура Склад
Количество
Сумма
01.05.2010 00:00:00 01.06.2010 00:00:00 01.06.2010 00:00:00 01.06.2010 00:00:00 01.11.3999 00:00:00 01.11.3999 00:00:00 01.11.3999 00:00:00
Пульт VH Пульт VH Пульт PW Пульт PW Пульт VH Пульт PW Пульт PW
1 2 7 11 1 6 11
10 20 490 137 18 420 137
Главный Главный Главный Фили-2 Фили-2 Главный Фили-2
Если впоследствии будет произведен расчет итогов по 30.06.2010, то таблица итогов примет вид, представленный в табл. 11.16. Таблица 11.16. Таблица итогов регистра накопления остатков Период
Номенклатура
Склад
Количество
Сумма
01.05.2010 00:00:00 01.06.2010 00:00:00 01.06.2010 00:00:00 01.06.2010 00:00:00 01.07.2010 00:00:00 01.07.2010 00:00:00 01.07.2010 00:00:00 01.11.3999 00:00:00 01.11.3999 00:00:00 01.11.3999 00:00:00
Пульт VH Пульт VH Пульт PW Пульт PW Пульт VH Пульт PW Пульт PW Пульт VH Пульт PW Пульт PW
Главный Главный Главный Фили-2 Фили-2 Главный Фили-2 Фили-2 Главный Фили-2
1 2 7 11 1 6 11 1 6 11
10 20 490 137 18 420 137 18 420 137
565
Глава 11. Учет движения средств Таблица 11.18. Таблица итогов оборотного регистра накопления
Механизм заполнения таблицы итогов оборотного регистра накопления
Период
При добавлении, удалении или модификации наборов записей в таблице движений всегда рассчитываются итоги в том периоде (месяце), к которому принадлежит значение поля Период записи. В отличие от регистра остатков, этот процесс не зависит от периода рассчитанных итогов базы данных (рис. 11.27).
Итоги марта 2010 года Итоги апреля 2010 года Итоги июня 2010 года
01.03.2010 00:00:00 01.03.2010 00:00:00 01.04.2010 00:00:00 01.06.2010 00:00:00
Номенклатура Контрагент
Количество
Сумма
Пульт VH
Ялта-Лтд
9
135
Пульт VH
Компания "Риона"
10
150
Пульт VH
Компания "Риона"
2
30
Пульт PW
Ялта-Лтд
1
95
Например, для отражения ситуации «возврат от покупателя» в регистр Продажи можно добавить такую запись (табл. 11.19).
Номенклатура
Контрагент
Количество
Сумма
Реализация № 1 27.03.2010 12:30:45 Реализация № 2 29.03.2010 15:00:01 Реализация № 3 13.04.2010 15:00:00 Реализация № 4 23.04.2010 10:00:00 Реализация № 5 23.04.2010 15:30:45 Реализация № 6 01.06.2010 08:59:59
Активность
Регистратор
27.03.2010 12:30:45 29.03.2010 15:00:01 13.04.2010 15:00:00 23.04.2010 10:00:00 23.04.2010 15:30:45 01.06.2010 08:59:59
1
Истина
Пульт VH
Ялта-Лтд
9
135
1
Истина
Пульт VH
Компания "Риона"
10
150
1
Истина
Пульт VH
Компания "Риона"
1
15
1
Истина
Пульт VH
Компания "Риона"
1
15
1
Ложь
Пульт PW
Крона
1
90
1
Истина
Пульт PW
Ялта-Лтд
1
95
Для вышеприведенного примера заполнения таблицы движений система заполнит таблицу итогов регистра следующим образом (табл. 11.18). Обратите внимание: поле Период заполняется значением даты начала периода (месяца), по которому хранятся итоги. Хотя для оборотного регистра не существует понятий «расход» и «приход», при необходимости можно использовать формирование движений с отрицательными значениями ресурсов.
566
Ялта-Лтд -1
Сумма
Количество
Истина Пульт PW
Контрагент
Номенклатура
Активность
1
17.06.2010 ВозвратОтПокупателя № 1 17:30:00 17.06.2010 17:30:00
-95
В результате система пересчитает июньские итоги по комбинации значений измерений ПультPW, Ялта-Лтд.
Номер строки
Период
Таблица 11.17. Таблица движений оборотного регистра накопления
Номер строки
Пример заполнения таблицы движений оборотного регистра Продажи представлен в табл. 11.17.
Регистратор
Для расчета итогов учитываются только записи, у которых поле Активность имеет значение Истина.
Период
Таблица 11.19. Запись, добавляемая в оборотный регистр накопления
Рис. 11.27. Хранение рассчитанных итогов оборотного регистра накопления
Поскольку при общем пересчете итогов для оборотного регистра также удаляются записи, содержащие нулевые значения всех ресурсов, то содержание таблицы итогов после этого будет следующим (табл. 11.20). Таблица 11.20. Таблица итогов оборотного регистра накопления Период
01.03.2010 00:00:00 01.03.2010 00:00:00 01.04.2010 00:00:00
Номенклатура
Контрагент
Количество
Сумма
Пульт VH
Ялта-Лтд
9
135
Пульт VH
Компания "Риона"
10
150
Пульт VH
Компания "Риона"
2
30
Режим разделения итогов Использование режима разделения итогов обеспечивает более высокую параллельность работы при записи в регистр, что позволяет ускорить запись в регистр и избежать блокировок в тех случаях, когда разные пользователи записывают данные с одинаковыми значениями измерений за один и тот же период.
Профессиональная разработка в системе «1С:Предприятие 8»
Механизмы заполнения таблиц регистров накопления в базе данных При использовании режима разделения итогов система при одновременной записи движений несколькими сеансами не будет обновлять одни и те же записи итогов, а будет записывать изменения итогов в отдельные записи. При получении итогов эти данные складываются. Таким образом, обеспечивается и поддержание в актуальном состоянии итогов (например, для быстрого получения отчетов), и параллельность записи движений. Как было рассказано выше, таблица итогов содержит алгебраическую сумму движений (с учетом вида движений) по каждой комбинации измерений. И при записи движений записи в таблице итогов автоматически пересчитываются. Считываемые записи таблицы итогов в момент пересчета блокируются. Таким образом, документы, содержащие движения по одинаковым комбинациям значений измерений, не могут быть проведены параллельно. Например, таблица движений регистра накопления содержит следующие записи (табл. 11.21).
Номенклатура
Склад
Количество
Сумма
ПоступлениеТоваров № 1 13.05.2010 15:00:01 ПоступлениеТоваров № 1 13.05.2010 15:00:01 ПоступлениеТоваров № 2 13.05.2010 15:00:01 Реализация № 1 15.05.2010 12:30:45
Вид движения
Регистратор
13.05.2010 15:00:01 13.05.2010 15:00:01 13.05.2010 15:00:01 15.05.2010 12:30:45
Номер строки
Период
Таблица 11.21. Таблица движений регистра накопления остатков
1
Приход
Пульт VH
Главный
9
90
2
Приход
Пульт PW
Главный
7
490
1
Приход
Пульт VH
Главный
5
50
1
Расход
Пульт VH
Главный
8
80
Таким образом, в приведенном примере документы ПоступлениеТоваров № 1 и ПоступлениеТоваров № 2 не могут быть параллельно проведены, так как не могут быть записаны параллельно записи таблицы итогов регистра накопления по комбинации значений измерений ПультVH – Главный.
После записи документа Реализация № 1 записи таблицы итогов будут выглядеть следующим образом (табл. 11.23). Таблица 11.23. Таблица итогов регистра накопления остатков Разделитель
Номенклатура
Склад
Количество Сумма
0 1 0
Пульт VH Пульт VH Пульт PW
Главный Главный Главный
1 5 7
10 50 490
При получении итогов регистра накопления запросом или методом встроенного языка или при пересчете итогов записи сворачиваются по комбинациям значений измерений. При этом избыточные записи из регистра удаляются (табл. 11.24). Таблица 11.24. Таблица итогов регистра накопления остатков Номенклатура
Склад
Количество Сумма
Пульт VH Пульт PW
Главный Главный
6 7
60 490
Новые записи с уже существующими комбинациями измерений создаются системой только в случае, если параллельно выполняются две и более транзакции. Таким образом, увеличение количества записей итогов зависит от количества одновременно выполняемых транзакций. Заметим, что данный механизм не работает в файловом варианте, так как там поддерживается только блокировка на уровне таблиц. Разумеется, работа данного механизма влечет за собой дополнительные накладные расходы (наличие поля в таблицах итогов, увеличение количества записей в таблицах итогов). Чтобы управлять работой данного механизма, предусмотрены две возможности.
Разделитель
Номенклатура
Склад
Количество
Сумма
В конфигурации для регистров введено свойство Разрешить разделение итогов. Стандартно для новых регистров накопления, создаваемых в конфигурации, это свойство включено. Установка этого свойства позволяет включить или отключить возможность разделения итогов для конкретного регистра. Отключение свойства полностью исключает влияние данного механизма на работу регистра, так как само поле, используемое для разделения итогов, не включается в структуру регистра. Например, отключение данной возможности полезно для регистров, которые не используются при параллельной работе пользователей. Например, для регистров, всегда заполняемых специальными регламентными обработками.
0 1 0
Пульт VH Пульт VH Пульт PW
Главный Главный Главный
9 5 7
90 50 490
Признак использования разделения итогов для регистров (для которых разделение итогов разрешено в конфигурации) может быть получен и установлен программно методами менеджера регистра накопления
Механизм разделения итогов вводит в состав хранимой таблицы итогов специальное поле (Разделитель), позволяющее распараллелить обновление записей итогов. Например, если одновременно записываются документы ПоступлениеТоваров № 1 и ПоступлениеТоваров № 2, то записи таблицы итогов будут выглядеть следующим образом (табл. 11.22). Таблица 11.22. Таблица итогов регистра накопления остатков
Том 1
567
Глава 11. Учет движения средств ПолучитьРежимРазделенияИтогов() нияИтогов(), а также в стандартной
и УстановитьРежимРазделефункции управления итогами
(Все функции Стандартные Управление итогами Полные возможности Разделение итогов Включить разделение итогов/Выключить разделение итогов). Такая возможность позволяет включать или выключать режим
разделения итогов в зависимости от условий работы пользователей в конкретной организации. Например, при интенсивном параллельном вводе информации этот режим может быть полезен. Но если с системой работает небольшое количество пользователей, то выигрыш от его применения будет небольшой, а некоторое замедление при получении отчетов и лишние записи в таблицах итогов фактически будут лишними (неоправданными).
Получение данных из регистров накопления Вопросы получения данных из регистров накопления могут касаться как получения движений, так и получения итоговых значений, учитываемых в регистре показателей. Получение движений может требоваться как для решения технологических задач работы с информацией регистров, так и для решения аналитических задач, но касающихся только приращений, учитываемых в регистрах показателей. Приемы и средства решения этих задач, как правило, не зависят от вида регистра, то есть одинаковы для регистров остатков и оборотных регистров. Это объясняется тем, что в любом случае обращение к данным движений в регистрах (хоть запросом, хоть посредством объектной модели) интерпретируется в запрос СУБД к таблице движений регистра. А приемы работы с одной таблицей базы данных практически одинаковы, тем более что состав полей и их содержимое, хоть бы и для разных видов регистров накопления, весьма схожи. Получение движений можно производить посредством следующих приемов (табл. 11.25). Таблица 11.25. Способы получения движений Табличная модель Регистр остатков
Оборотный регистр
Запрос к основной таблице регистра
Объектная модель Регистр остатков
Оборотный регистр
Методы Выбрать() и ВыбратьПоРегистратору() менеджера регистра
А вот приемы получения разных видов итогов и эффективности этих действий по скорости выполнения для разных видов регистров, как будет рассматриваться ниже, сильно отличаются. Тут проявляются различия в природе показателей, учитываемых в регистрах остатков и оборотных регистрах (описаны в разделе «Оперативный учет. Описание задач, решаемых регистрами накопления» на стр. 545). Природа этих
568
показателей такова, что требуются различные способы хранения промежуточных итогов (описаны в разделе «Структура регистра накопления» на стр. 547). В целом действия, которые выполняются при получении итогов регистров, можно классифицировать следующим образом (табл. 11.26). Таблица 11.26. Способы получения итогов Табличная модель Регистр остатков
Получение остатков Получение оборотов Получение остатков и оборотов
Оборотный регистр
Запрос к таблице остатков Запрос к таблице оборотов
Объектная модель Регистр остатков
Оборотный регистр
Метод Остатки() менеджера регистра Метод Обороты() менеджера регистра
Запрос к таблице остатков и оборотов
Следует заметить, что для любого действия, связанного с получением итогов регистра накопления, справедливы следующие утверждения: ■■ итоги ресурсов собираются только по активным записям; ■■ итоги можно получать только по тем регистрам, у которых использование итогов включено. При попытке получения итогов для регистра накопления с отключенными итогами выдается сообщение об ошибке.
Получение движений регистров накопления С точки зрения методических приемов чтение данных движений регистров накопления одинаково как для задач последующей модификации движений, так и для задач анализа движений регистров накопления. Например, для последующей обработки необходимо выбрать содержимое движений документов РеализацияТоваров по регистру ТоварыНаСкладах с отбором по складу СкладОтбора. При этом необходимо посчитать количество движений, выполненных каждым регистратором. Решение этой задачи может быть таким. В запросе обращаемся к данным основной таблицы регистра ТоварыНаСкладах, в качестве выходных указываем поля, соответствующие полям таблицы движений. Отбор выполняем по значению поля Склад и вхождению значений поля Регистратор в таблицу документов РеализацияТоваров. Выводим промежуточные итоги количества значений поля НомерСтроки в разрезе по регистраторам (в принципе подсчет количества можно было реализовать по любому из полей), листинг 11.22. Профессиональная разработка в системе «1С:Предприятие 8»
Получение данных из регистров накопления Листинг 11.22. Пример получения движений регистра накопления
Запрос = Новый Запрос; Запрос.Текст = "ВЫБРАТЬ | ТоварыНаСкладах.Период, | ТоварыНаСкладах.Регистратор КАК Регистратор, | ТоварыНаСкладах.НомерСтроки КАК НомерСтроки, | ТоварыНаСкладах.Активность, | ТоварыНаСкладах.ВидДвижения, | ТоварыНаСкладах.Номенклатура, | ТоварыНаСкладах.Склад, | ТоварыНаСкладах.Количество, | ТоварыНаСкладах.Поставщик |ИЗ | РегистрНакопления.ТоварыНаСкладах КАК ТоварыНаСкладах |ГДЕ | ТоварыНаСкладах.Склад = &Склад | И ТоварыНаСкладах.Регистратор ССЫЛКА Документ.РеализацияТоваров |ИТОГИ | КОЛИЧЕСТВО(НомерСтроки) |ПО | Регистратор"; Запрос.УстановитьПараметр("Склад", СкладОтбора); Результат = Запрос.Выполнить(); ВыборкаРегистратор = Результат.Выбрать(ОбходРезультатаЗапроса.ПоГруппировкам); Пока ВыборкаРегистратор.Следующий() Цикл // Выполнить действия в цикле перебора регистраторов. // ... ВыборкаДвижения = ВыборкаРегистратор.Выбрать(); Пока ВыборкаДвижения.Следующий() Цикл // Выполнить действия в цикле перебора движений. // ... КонецЦикла; КонецЦикла;
Дальнейшее развитие приведенного алгоритма может идти в различных направлениях. Можно вывести в табличный документ содержимое движений регистра, а можно результат запроса использовать для модификации данных наборов записей с последующей записью измененных движений в регистр. Рассмотрим более подробно вопросы быстродействия системы при получении движений регистра накопления тем или иным способом.
Том 1
Вопросы быстродействия системы при получении движений Как правило, при решении задач, связанных с чтением движений из регистров накопления, для повышения эффективности решений большое значение имеют вопросы использования состава регистра накопления и использования табличной или объектной модели обращения к данным. Рассмотрим пример. Пусть необходимо подсчитать по данным регистра ТоварыНаСкладах, в каком количестве поставлялись товары в разрезе поставщиков. Данная задача может быть решена несколькими способами. Например, можно использовать внутреннее соединение основной таблицы регистра ТоварыНаСкладах и таблицы документа ПоступлениеТоваров (листинг 11.23). Листинг 11.23. Пример получения движений с использованием соединения с таблицей документа
ВЫБРАТЬ ПоступлениеТоваров.Контрагент КАК Поставщик, ТоварыНаСкладах.Номенклатура, СУММА(ТоварыНаСкладах.Количество) КАК Количество ИЗ РегистрНакопления.ТоварыНаСкладах КАК ТоварыНаСкладах ВНУТРЕННЕЕ СОЕДИНЕНИЕ Документ.ПоступлениеТоваров КАК ПоступлениеТоваров ПО ТоварыНаСкладах.Регистратор = ПоступлениеТоваров.Ссылка ГДЕ ТоварыНаСкладах.Период МЕЖДУ &ДатаНачала И &ДатаОконачания СГРУППИРОВАТЬ ПО ТоварыНаСкладах.Номенклатура, ПоступлениеТоваров.Контрагент
Условием соединения является равенство значений поля Регистратор таблицы регистра и поля Ссылка таблицы документа. Подобный способ получения движений в общем случае может оказаться неудобным, например, если поставки фиксируются несколькими видами документов. В этом случае усложнится текст запроса и замедлится его выполнение за счет большого количества соединений. Более удобным является подход с использованием реквизита регистра. Если для решения данной задачи в состав регистра включить реквизит Поставщик (тип значения – СправочникСсылка.Контрагенты), то значение поля реквизита можно будет заполнять при проведении только нужных документов. И тогда, независимо от количества видов документов поставки, задача будет решаться запросом только к основной таблице регистра (листинг 11.24).
569
Глава 11. Учет движения средств Листинг 11.24. Пример получения движений регистра накопления
ВЫБРАТЬ ТоварыНаСкладах.Поставщик, ТоварыНаСкладах.Номенклатура, СУММА(ТоварыНаСкладах.Количество) КАК Количество ИЗ РегистрНакопления.ТоварыНаСкладах КАК ТоварыНаСкладах ГДЕ ТоварыНаСкладах.Период МЕЖДУ &ДатаНачала И &ДатаОконачания И ТоварыНаСкладах.Поставщик <> &ПустойПоставщик СГРУППИРОВАТЬ ПО ТоварыНаСкладах.Поставщик, ТоварыНаСкладах.Номенклатура
Дополнительное условие «по непустым поставщикам» – отсечет из подсчета результатов (и из самих результатов) записи, которые сформированы ненужными документами. Например, перемещениями, реализацией и прочими (при проведении этих документов поле Поставщик не заполнялось). Значение же параметра ПустойПоставщик может быть установлено следующим образом (листинг 11.25). Листинг 11.25. Установка значения параметра «ПустойПоставщик»
Запрос.УстановитьПараметр("ПустойПоставщик", Справочники.Контрагенты.ПустаяСсылка());
Необходимо иметь в виду, что при использовании реквизитов составного типа незаполненное при проведении документа поставки значение реквизита будет иметь тип Неопределено. Поэтому для варианта, когда реквизит Поставщик имеет составной тип, значение параметра ПустойПоставщик может быть установлено следующим образом (листинг 11.26). Листинг 11.26. Пример установки параметра «ПустойПоставщик»
Запрос.УстановитьПараметр("ПустойПоставщик", Неопределено);
Если же при проведении документов реквизит может как не заполняться, так и заполняться пустыми значениями, возможно, придется в запросе учесть ряд вариантов значения реквизита (листинг 11.27). Листинг 11.27. Пример установки параметров запроса
Запрос.УстановитьПараметр("ПустойПоставщик", Неопределено); Запрос.УстановитьПараметр("ПустойПоставщикКонтрагент", Справочники.Контрагенты.ПустаяСсылка()); Запрос.УстановитьПараметр("ПустойПоставщикФизЛицо", Справочники.ФизическиеЛица.ПустаяСсылка());
В приведенном примере предполагается, что реквизит Поставщик имеет составной тип, включающий типы СправочникСсылка.Контрагенты и СправочникСсылка.ФизическиеЛица.
570
Итак, за счет изменения состава регистра, использования реквизитов можно применять более эффективные по скорости алгоритмы для получения движений регистров накопления. Обращение к данным одной таблицы базы данных всегда будет проходить быстрее, нежели обращение к данным той же таблицы, но в соединении с другими таблицами базы данных. Таким образом, за счет «структурных изменений» ряд задач можно сводить только к работе с таблицей движений регистра накопления. При обращении к данным таблицы движений регистра разработчик может применять обращение посредством выборки (объектная модель работы с данными) или посредством запроса (табличная модель чтения данных). С точки зрения обращения к информации базы данных выборка – это тот же самый запрос. При одинаковых условиях и выборка, и прямое обращение запросом работают одинаково эффективно. Разница в том, что выборка не так «гибка», зато получает данные порциями (это особенно важно, если ожидается большой объем данных в результате запроса). Для получения данных выборка использует механизм динамического чтения данных. Посредством этого механизма чтение данных осуществляется по блокам, а не целиком сразу всех. Кроме того, при использовании выборки объекты считываются целиком. Работа же посредством запроса позволяет считывать содержимое только тех полей, которые используются в запросе. Операция перебора всех движений регистров с помощью выборки может осуществляться, например, следующим образом (листинг 11.28). Листинг 11.28. Пример получения движений регистра накопления с помощью выборки
ВыборкаДвижений = РегистрыНакопления.ТоварыНаСкладах.Выбрать(); Пока ВыборкаДвижений.Следующий() Цикл // Выполнить действие с очередным движением. // ... КонецЦикла;
Кроме таких простых операций, возможно выполнять и более «тонкие» действия. Например, в ходе работы пользователя требуется оперативно определять факт того, что были поставки определенного поставщика в заданном временном интервале. При решении данной задачи у реквизита Поставщик регистра ТоварыНаСкладах свойству Индексировать следует установить значение Индексировать (рис. 11.28). В результате в базе данных будет создан составной индекс по полям Поставщик + Период + Регистратор + НомерСтроки. Данные этого индекса система использует при обращении к движениям и посредством запроса, и посредством выборки. Профессиональная разработка в системе «1С:Предприятие 8»
Получение данных из регистров накопления далее, как в отношении значений поля Период записей движений, так и в отношении Регистратор или НомерЗаписи. Чтобы добиться подобной гибкости в отношении границ временного интервала выборки, можно использовать различные варианты значений параметров НачалоИнтервала и КонецИнтервала. В параметр НачалоИнтервала передается начало интервала, в котором будут выбираться записи регистра накопления. Он может задаваться значениями типа Дата, МоментВремени и Граница. Если значение данного параметра не указано, то будут выбираться записи с самой ранней включительно. В параметр КонецИнтервала передается конец интервала, в котором будут выбираться записи регистра накопления. Он может задаваться значениями типа Дата, МоментВремени и Граница. Если значение данного параметра не указано, то будут выбираться записи по самую последнюю включительно. Рис. 11.28. Индексирование реквизита регистра накопления
Использование выборки позволит получить данные не медленнее, нежели посредством запроса (листинг 11.29).
В результате при передаче значений типа Дата или МоментВремени в выборку получим записи, включая значения НачалоИнтервала и КонецИнтервала (рис. 11.29).
Листинг 11.29. Получение движений регистра накопления с помощью выборки
ОтборПоПоставщику = Новый Структура("Поставщик", ПоставщикОтбора); ВыборкаДвижений = РегистрыНакопления.ТоварыНаСкладах.Выбрать(НачалоИнтервала, КонецИнтервала, ОтборПоПоставщику); Сообщение = Новый СообщениеПользователю(); Если ВыборкаДвижений.Следующий() Тогда Сообщение.Текст = "В указанном интервале были поставки от " + ПоставщикОтбора.Наименование; Иначе Сообщение.Текст = "В указанном интервале поставок от " + ПоставщикОтбора.Наименование + " не было"; КонецЕсли; Сообщение.Сообщить();
Очевидно, что в переменные ПоставщикОтбора, НачалоИнтервала, КонецИнтервала нужно передать соответствующие значения. ВНИМАНИЕ!
Необходимо помнить о том, что при использовании метода Выбрать() в качестве параметра Отбор может использоваться структура, имеющая только один элемент. Для более гибких или сложных отборов следует использовать получение данных посредством запроса.
Рис. 11.29. Получение записей, включая границы интервала
Если требуется получить записи, исключая граничные, необходимо использовать объект Граница. Пример получения выборки в интервале дат, исключая границы интервала, приведен в листинге 11.30 и на рис. 11.30. Листинг 11.30. Пример получения записей, исключая границы интервала
ГраницаНачалаИнтервала = Новый Граница(НачалоИнтервала,ВидГраницы.Исключая); ГраницаКонцаИнтервала = Новый Граница(КонецИнтервала, ВидГраницы.Исключая); ВыборкаДвижений = РегистрыНакопления.ТоварыНаСкладах.Выбрать(ГраницаНачалаИнтервала, ГраницаКонцаИнтервала); Пока ВыборкаДвижений.Следующий() Цикл // Выполнить действие с очередным движением. // ... КонецЦикла;
Теперь чуть подробнее остановимся на использовании параметров НачалоИнтервала и КонецИнтервала. При работе с запросом можно произвольным образом использовать условия больше/меньше, равно/не равно, больше или равно, между и так Том 1
Рис. 11.30. Получение записей, исключая границы интервала
571
Глава 11. Учет движения средств Кроме выборок всех записей можно при необходимости осуществлять выборку записей, подчиненных некоему документу. Это может быть реализовано посредством метода ВыбратьПоРегистратору().
А теперь рассмотрим один из примеров, когда в условиях усложнения задачи применение объектной модели обращения к информации базы данных уже менее эффективно, чем обращение посредством запроса.
Например, если в переменной РегистраторОтбора содержится ссылка на регистратор, по которому нужно отобрать все его движения, то код, получающий такую выборку, будет выглядеть следующим образом (листинг 11.31).
Например, в составе оборотного регистра Продажи есть реквизит ВидОперации (рис. 11.31).
Листинг 11.31. Пример получения движений по регистратору
ВыборкаДвижений = РегистрыНакопления.ТоварыНаСкладах. ВыбратьПоРегистратору(РегистраторОтбора); Пока ВыборкаДвижений.Следующий() Цикл // Выполнить действие с очередным движением. // ... КонецЦикла;
Поскольку, как обсуждалось выше, в разделе «Структура регистра накопления» на стр. 547, для таблицы движений регистра поле Регистратор является индексируемым, быстродействие подобной выборки будет достаточно высоким, не медленнее, чем применение запроса (листинг 11.32). Листинг 11.32. Пример получения движений регистратора с помощью запроса
Запрос = Новый Запрос; Запрос.Текст = "ВЫБРАТЬ | ТоварыНаСкладах.Период, | ТоварыНаСкладах.Регистратор, | ТоварыНаСкладах.НомерСтроки, | ТоварыНаСкладах.Активность, | ТоварыНаСкладах.ВидДвижения, | ТоварыНаСкладах.Номенклатура, | ТоварыНаСкладах.Склад, | ТоварыНаСкладах.Количество, | ТоварыНаСкладах.Поставщик |ИЗ | РегистрНакопления.ТоварыНаСкладах КАК ТоварыНаСкладах |ГДЕ | ТоварыНаСкладах.Регистратор = &РегистраторОтбора"; Запрос.УстановитьПараметр("РегистраторОтбора", РегистраторОтбора); Результат = Запрос.Выполнить(); Выборка = Результат.Выбрать(); Пока Выборка.Следующий() Цикл // Выполнить действие с очередным движением. // ... КонецЦикла;
572
Рис. 11.31. Структура регистра «Продажи»
При проведении документов продажи формируются движения по этому регистру. Необходимо предпринять некие действия по фактам произведенных розничных продаж (вид операции – РеализацияВРозницу) с ценой меньше закупочной. Закупочная цена хранится в одноименных реквизитах элементов справочника Номенклатура. Поиск таких фактов посредством запроса может быть выполнен так, как показано в листинге 11.33. Листинг 11.33. Пример получения движений регистра накопления с помощью запроса
Запрос = Новый Запрос; Запрос.Текст = "ВЫБРАТЬ | Продажи.Регистратор, | Продажи.Номенклатура |ИЗ | РегистрНакопления.Продажи КАК Продажи |ГДЕ | Продажи.Период МЕЖДУ &ДатаНачала И &ДатаОкончания | И Продажи.ВидОперации = &РозничнаяПродажа | И Продажи.Сумма / Продажи.Количество < | Продажи.Номенклатура.ЗакупочнаяЦена"; Запрос.УстановитьПараметр("ДатаНачала", ДатаНачала); Запрос.УстановитьПараметр("ДатаОкончания", ДатаОкончания); Запрос.УстановитьПараметр("РозничнаяПродажа", Перечисления.ВидыОпераций.РеализацияВРозницу); Результат = Запрос.Выполнить(); Выборка = Результат.Выбрать(); Пока Выборка.Следующий() Цикл
// Выполнить действия по факту продажи ниже закупочной цены. // ...
КонецЦикла;
Посредством выборки движений регистра аналогичный результат может быть получен так, как показано в листинге 11.34. Профессиональная разработка в системе «1С:Предприятие 8»
Получение данных из регистров накопления Листинг 11.34. Пример получения движений регистра накопления с помощью выборки
Выборка = РегистрыНакопления.Продажи.Выбрать(ДатаНачала, ДатаОкончания); Пока Выборка.Следующий() Цикл Если Выборка.ВидОперации = Перечисления.ВидыОпераций.РеализацияВРозницу И Выборка.Сумма/Выборка.Количество < Выборка.Номенклатура.ЗакупочнаяЦена Тогда
Поле
Тип
Назначение
<Измерение>
Произвольный, определяется типом измерения
<Ресурс>
Число
<Реквизит>
Произвольный, определяется типом реквизита
Каждое из полей содержит значения измерений регистра. Имена полей совпадают с именами измерений, заданными для объекта конфигурации Каждое из полей содержит значения ресурса регистра. Имена полей совпадают с именами ресурсов, заданными для объекта конфигурации Каждое из полей содержит значения реквизитов регистра. Имена полей совпадают с именами реквизитов, заданными для объекта конфигурации
// Выполнить действия по факту продажи ниже закупочной цены. // ...
КонецЕсли; КонецЦикла;
Использование выборки в данной ситуации является очень неэффективным решением. В первом случае условие превышения закупочной цены будет обеспечено выполнением неявного левого внешнего соединения всей таблицы регистра с таблицей справочника за один раз.
Основная таблица для оборотного регистра имеет почти аналогичный состав. Отличие заключается в том, что она не содержит поле ВидДвижения.
Во втором случае проверка условия
Получение остатков
справочника в базе данных для каждого элемента коллекции движений.
Получение итогов остатков регистра накопления, конечно же, возможно только в отношения регистра накопления остатков.
Выборка.Сумма/Выборка.Количество < Выборка.Номенклатура.ЗакупочнаяЦена потребует обращений к данным
Это был только один из примеров, когда в условиях более сложных задач чтения движений применение запросов более эффективно, нежели применение выборки. А вообще посредством запроса возможен доступ практически ко всему содержимому таблицы движений регистра накопления. Для этого используется так называемая основная таблица регистра накопления. Это реальная таблица, содержащая данные таблицы движений регистра в базе данных. Состав полей этой таблицы представлен в табл. 11.27. Таблица 11.27. Состав полей основной таблицы регистра накопления остатков Поле
Тип
Назначение
Содержит период, к которому относится запись регистра Регистратор ДокументСсылка.<имя> Содержит ссылку на документ-регистратор движения НомерСтроки Число Содержит номер строки, определяемый как порядковый номер записи в наборе записей, подчиненных документу-регистратору Активность Булево Содержит признак активности записи, то есть влияния на получение итогов регистра МоментВремени МоментВремени Виртуальное поле, не хранится в базе данных. Содержит объект МоментВремени (который включает в себя дату и ссылку на документ) ВидДвижения ВидДвиженияНакопления Содержит вид движения данной записи (Приход или Расход) Период
Том 1
Дата
Применение табличного или объектного подхода для решения этой задачи определяется сложностью и необходимой гибкостью совершаемых при этом действий.
Виртуальная таблица остатков Для получения данных по остаткам из регистра накопления остатков запросом используется виртуальная таблица остатков. Ее данные представляют собой итоги ресурсов в разрезе измерений (табл. 11.28). Таблица 11.28. Состав полей виртуальной таблицы «Остатки» регистра накопления остатков Поле
Тип
Назначение
Произвольный, Каждое из полей содержит значения измерений определяется регистра. Имена полей совпадают с именами измерений, типом измерения заданными для объекта конфигурации <Ресурс>Остаток Число Имена полей совпадают с именами ресурсов, заданными для объекта конфигурации. Имена полей составляются из названий ресурсов с добавлением слова «Остаток» <Измерение>
Параметры виртуальной таблицы остатков представлены в табл. 11.29.
573
Глава 11. Учет движения средств
■■ подбирается больший или равный значению параметра Период момент времени, на который рассчитаны остатки; ■■ на этот момент времени получаются остатки из таблицы итогов; ■■ если момент времени, на который считаются остатки, не совпадает с моментом времени итогов, то остатки досчитываются по движениям за период с момента требуемого запроса остатков по момент итогов. Реализуется это за счет объединения отобранных записей таблицы итогов и таблицы движений регистра; ■■ группирование результата виртуальной таблицы выполняется согласно составу выходных полей запроса, использующего поля виртуальной таблицы. Для получения результата запроса система преобразует текст запроса, написанного на встроенном языке системы «1С:Предприятие», в запрос СУБД. В данный запрос включается соответствующий текст подзапроса, получающийся согласно описанному выше алгоритму. В отношении сортировки записей, полученных виртуальной таблицей остатков, необходимо заметить, что если разработчик в запросе не применит ключевые слова УПОРЯДОЧИТЬ ПО или АВТОУПОРЯДОЧИВАНИЕ, то в общем случае система не будет производить упорядочивание записей. То есть таблица результата виртуальной таблицы «самогруппируется», но не «самосортируется».
Таблица 11.30. Таблица движений регистра накопления
13.05.2010 15:00:01 13.05.2010 15:00:01 23.05.2010 15:30:45 27.05.2010 12:30:45 31.05.2010 23:59:59 01.06.2010 00:00:00 11.06.2010 13:59:00 11.09.2010 11:00:00
ПоступлениеТоваров № 1 13.05.2010 15:00:01 ПоступлениеТоваров № 1 13.05.2010 15:00:01 ПоступлениеТоваров № 2 23.05.2010 15:30:45 Реализация № 1 27.05.2010 12:30:45 ПоступлениеТоваров № 3 31.05.2010 23:59:59 ПоступлениеТоваров № 4 01.06.2010 00:00:00 ПоступлениеТоваров № 5 11.06.2010 13:59:00 ПоступлениеТоваров № 5 11.09.2010 11:00:00
Количество
Сам алгоритм построения этой виртуальной таблицы включает в себя следующие этапы:
Например, в базе данных таблицы движений и итогов регистра остатков заполнены так, как показано в табл. 11.30 и 11.31.
Склад
Виртуальная таблица остатков не хранится в базе данных, а строится в момент обращения к ней. Для построения виртуальной таблицы всегда используются данные таблицы итогов регистра базы данных и, при необходимости, таблицы движений регистра. При этом учитываются значения параметров виртуальной таблицы.
■■ требуются ли только текущие итоги; ■■ требуются ли остатки на момент времени, находящийся до границы рассчитанных итогов; ■■ как много записей находится между требуемым моментом расчета итогов и ближайшим (более поздним) моментом уже рассчитанных итогов в таблице итогов.
Номенклатура
Используется для указания периода, НА значение которого будут рассчитаны остатки. Если параметр не задан, итоги рассчитываются ПО самую последнюю запись Конструкция языка Строится по полям измерений, регистра накопления запросов – условие (или по подчиненным им полям). Используется для ограничения состава исходных записей, по которым при построении виртуальной таблицы будут собираться итоги. Если параметр не указан, для сбора итогов будут анализироваться все активные записи регистра
Активность
<Условие>
Назначение
Вид движения
Дата, МоментВремени, Граница
Номер строки
Тип
<Период>
Регистратор
Параметр
Можно сделать ряд выводов о скорости получения виртуальной таблицы остатков. Она зависит от следующих факторов:
Период
Таблица 11.29. Параметры виртуальной таблицы «Остатки» регистра накопления остатков
1
Приход
Истина
Пульт VH
Главный
10
2
Приход
Истина
Пульт PW
Главный
7
1
Приход
Ложь
Пульт VH
Фили-2
5
1
Расход
Истина
Пульт VH
Главный
9
1
Приход
Истина
Пульт PW
Фили-2
1
1
Приход
Истина
Пульт PW
Фили-2
2
1
Приход
Истина
Пульт PW
Фили-2
1
1
Приход
Истина
Пульт PW
Фили-2
1
Таблица 11.31. Таблица итогов регистра накопления Период
Номенклатура
Склад
Количество
01.06.2010 00:00:00 01.06.2010 00:00:00 01.06.2010 00:00:00 01.11.3999 00:00:00 01.11.3999 00:00:00 01.11.3999 00:00:00
Пульт VH Пульт PW Пульт PW Пульт VH Пульт PW Пульт PW
Главный Главный Фили-2 Главный Главный Фили-2
1 7 1 1 7 5
Рассмотрим случай, когда требуется получить итоги регистра с помощью кода, приведенного в листинге 11.35.
574
Профессиональная разработка в системе «1С:Предприятие 8»
Получение данных из регистров накопления Листинг 11.35. Пример получения итогов регистра накопления
ВЫБРАТЬ ТоварыНаСкладахОстатки.Номенклатура КАК Номенклатура, ТоварыНаСкладахОстатки.Склад КАК Склад, ТоварыНаСкладахОстатки.КоличествоОстаток КАК Количество ИЗ РегистрНакопления.ТоварыНаСкладах.Остатки(&Период) КАК ТоварыНаСкладахОстатки
В зависимости от значения, переданного параметру виртуальной таблицы остатков Период, система будет выполнять следующие действия: 1. Если передать значение Неопределено (листинг 11.36) или значение даты по умолчанию (листинг 11.37), то будут получены актуальные данные непосредственно из таблицы итогов, без обращений к таблице движений (табл. 11.32). Листинг 11.36. Установка параметра запроса значением «Неопределено»
Запрос.УстановитьПараметр("Период", Неопределено); Листинг 11.37. Установка параметра запроса значением даты по умолчанию
Запрос.УстановитьПараметр("Период", Дата(1, 1, 1)); Таблица 11.32. Результат выполнения запроса Номенклатура
Пульт VH Пульт PW Пульт PW
Склад
Главный Главный Фили-2
Количество
1 7 5
2. Если передать значение типа Дата, совпадающее с датой рассчитанных итогов (листинг 11.38), то будут получены данные на начало даты «1 июня 2010 года» непосредственно из таблицы итогов, без обращений к таблице движений (табл. 11.33). Листинг 11.38. Установка параметра запроса значением даты
Запрос.УстановитьПараметр("Период", Дата(2010, 6, 1)); Таблица 11.33. Результат выполнения запроса Номенклатура
Склад
Количество
Пульт VH Пульт PW Пульт PW
Главный Главный Фили-2
1 7 1
ПРИМЕЧАНИЕ
Заметьте, движения документа ПоступлениеТоваров № 4, сформированные на эту же дату, учтены не будут. Потому что момент времени этих движений позже начала даты.
Том 1
3. Если передать значение типа Дата, не совпадающее с датой рассчитанных итогов, то возможны несколько вариантов. Рассмотрим каждый из них. а) Значение даты находится в середине рассчитанного периода (листинг 11.39). Листинг 11.39. Установка параметра запроса значением даты
Запрос.УстановитьПараметр("Период", Дата(2010, 5, 20));
В этом случае сначала будут получены данные на начало даты «1 июня 2010 года» из таблицы итогов (табл. 11.34). Таблица 11.34. Данные, полученные из таблицы итогов Номенклатура
Склад
Количество
Пульт VH Пульт PW Пульт PW
Главный Главный Фили-2
1 7 1
Затем будут получены записи из таблицы движений в интервале между началом 20 мая 2010 и началом 1 июня 2010 года. Причем только те, у которых поле Активность имеет значение Истина. Поскольку «досчитываться» значения остатков будут в обратную сторону, то данные ресурсов таблицы движений получаются со знаком, обратным виду движения (табл. 11.35). Таблица 11.35. Данные, полученные из таблицы движений Номенклатура
Склад
Количество
Пульт VH Пульт PW
Главный Фили-2
9 -1
Далее эти записи объединяются, группируются, убираются записи, содержащие нулевые значения всех ресурсов (табл. 11.36). Таблица 11.36. Результат выполнения запроса Номенклатура
Склад
Количество
Пульт VH Пульт PW
Главный Главный
10 7
б) Значение даты (листинг 11.40).
находится
в
конце
рассчитанного
периода
Листинг 11.40. Установка параметра запроса значением даты
Запрос.УстановитьПараметр("Период", Дата(2010, 5, 31));
575
Глава 11. Учет движения средств В этом случае сначала будут получены данные на начало даты «1 июня 2010 года» из таблицы итогов (табл. 11.37). Таблица 11.37. Данные, полученные из таблицы итогов Номенклатура
Пульт VH Пульт PW Пульт PW
Склад
Количество
Главный Главный Фили-2
1 7 1
Затем будут получены записи из таблицы движений в интервале между началом 31 мая 2010 и началом 1 июня 2010 года, с учетом вида движении и «обратного подсчета» (табл. 11.38). Таблица 11.38. Данные, полученные из таблицы движений Номенклатура
Пульт PW
Склад
Количество
Фили-2
-1
Далее записи объединятся, и по этим данным будут посчитаны остатки на нужный период (табл. 11.39). Таблица 11.39. Результат выполнения запроса Номенклатура
Склад
Количество
Пульт VH Пульт PW
Главный Главный
1 7
в) Значение даты представляет собой конец дня последней даты рассчитанного периода (листинг 11.41). Листинг 11.41. Установка параметра запроса значением даты
Запрос.УстановитьПараметр("Период", КонецДня(Дата(2010, 5, 31)));
В этом случае сначала будут получены данные на начало даты «1 июня 2010 года» из таблицы итогов (табл. 11.40). Таблица 11.40. Данные, полученные из таблицы итогов Номенклатура Склад
Количество
Пульт VH Пульт PW Пульт PW
1 7 1
Главный Главный Фили-2
Затем будут получены записи из таблицы движений в интервале между концом 31 мая 2010 и началом 1 июня 2010 года с учетом вида движения и «обратного подсчета». К таким записям как раз и относится датированное последней секундой дня движение документа ПоступлениеТоваров № 3 (табл. 11.41).
576
Таблица 11.41. Данные, полученные из таблицы движений Номенклатура Склад
Количество
Пульт PW
-1
Фили-2
Далее записи объединятся, и по этим данным будут посчитаны остатки на нужный период (табл. 11.42). Таблица 11.42. Результат выполнения запроса Номенклатура Склад
Количество
Пульт VH Пульт PW
1 7
Главный Главный
г) Значение даты является началом даты нерассчитанного периода (листинг 11.42). Листинг 11.42. Установка параметра запроса значением даты
ПериодВключая = Новый Граница(Дата(2010, 6, 1), ВидГраницы.Включая) Запрос.УстановитьПараметр("Период", ПериодВключая);
Значение параметра больше, чем начало дня «01.06.2010», поэтому будут взяты данные из таблицы итогов на больший период, то есть текущие итоги (табл. 11.43). Таблица 11.43. Данные, полученные из таблицы итогов Номенклатура Склад
Количество
Пульт VH Пульт PW Пульт PW
1 7 5
Главный Главный Фили-2
Будут взяты записи из таблицы движений, в интервале между значением параметра и периодом текущих итогов (с учетом операции «обратного подсчета»). Заметьте, движения, датированные «01.06.2010 00:00:00», сюда не попадают (табл. 11.44). Таблица 11.44. Данные, полученные из таблицы движений Номенклатура Склад
Количество
Пульт PW Пульт PW
-1 -1
Фили-2 Фили-2
Далее записи объединятся, и по этим данным будут посчитаны остатки на нужный период (табл. 11.45).
Профессиональная разработка в системе «1С:Предприятие 8»
Получение данных из регистров накопления Таблица 11.45. Результат выполнения запроса Номенклатура Склад
Пульт VH Пульт PW Пульт PW
Количество
Главный 1 Главный 7 Фили-2 3
Аналогично поступила бы система, если бы в качестве параметра было передано значение типа МоментВремени с датой 01.06.2010 00:00:00 и ссылкой на какой-нибудь документ. Кроме того, хотелось бы заметить, что если бы в последнем примере граница рассчитанных итогов стояла бы не в конце мая, а хотя бы в конце июня, то не пришлось бы досчитывать от текущих итогов. Достаточно было бы досчитать от ближайшего, но большего периода рассчитанных итогов. Использование в любых «неровных» ситуациях именно обратного досчета объясняется тем, что при решении оперативных задач вправе ожидать более напряженной работы с текущими итогами или близкими к текущему моменту, нежели получение остатков прошлых месяцев или даже лет. Усложнение же механизма расчета итогов остатков «анализатором» ситуации (от какого периода итогов ближе до нужного значения параметра) нецелесообразно, поскольку для обеспечения работы «анализатора» пришлось бы получать записи таблицы движений в обе стороны (и назад, и вперед). То есть «анализатор» сам работал бы дольше, чем «обратный досчет». Однако пересчет текущих итогов (если у регистра установлен признак использования итогов) каждый раз при записи набора активных записей в таблице движений может быть неэффективным. Например, когда период рассчитанных итогов регулярно устанавливается обработкой и есть уверенность в хранении посчитанных итогов на начало каждого месяца, может быть выгоднее «досчитывать» остатки от хранимых итогов. В таком случае можно не устанавливать использование текущих итогов для регистра остатков – УстановитьИспользованиеТекущихИтогов(Ложь). Если использование текущих итогов выключено, то расчет актуальных остатков будет производиться следующим образом: сначала будут получены остатки на самые поздние хранимые итоги, а потом по движениям за оставшийся период будут получены актуальные остатки. Данный подход позволяет увеличить параллельность при записи наборов записей данного регистра, так как не требуется обновления текущих итогов. Получить признак использования текущих итогов из встроенного языка можно методом менеджера регистра накопления остатков ПолучитьИспользованиеТекущихИтогов(). Включить или выключить использование текущих итогов можно методом УстановитьИспользованиеТекущихИтогов(Истина/Ложь), а также в стандартной функции управления итогами Том 1
(Все функции Стандартные Управление итогами Полные возможности Текущие итоги Включить использование текущих итогов/Выключить использование текущих итогов).
Таким образом, можно сделать вывод, что быстродействие получения остатков реальным временем (актуальных) вообще не зависит от общего объема накопленной в базе данных информации. Для получения же данных на прошедшие моменты времени при использовании расчета промежуточных ежемесячных итогов среднее быстродействие построения виртуальной таблицы получения остатков определяется не общим объемом базы данных, а количеством движений по регистру, формируемым в течение месяца. Это очень важно для недопущения деградации системы при многолетней эксплуатации базы данных. Кроме того, хотелось бы обратить внимание, что на каждом этапе выполнения алгоритма, когда система получает данные из той или иной таблицы базы данных, применяются отборы только тех записей, которые удовлетворяют условиям, описанным в параметрах виртуальной таблицы остатков.
Использование метода «Остатки()» менеджера регистра накопления Если при получении данных об остатках не применяется сложных отборов либо эти данные впоследствии не нужно соединять с другими данными, можно использовать также и объектную модель доступа к данным – метод Остатки() менеджера регистра накопления. Например, если требуется сообщить остатки на складах по некой товарной позиции, как это показано в листинге 11.43. Листинг 11.43. Пример получения остатков регистра накопления с использованием объектной модели
Отбор = Новый Структура("Номенклатура", ТоварОтбора); ТаблицаОстатков = РегистрыНакопления.ТоварыНаСкладах.Остатки(МоментВремени, Отбор, "Склад", "Количество"); Для Каждого СтрокаТаблицы Из ТаблицаОстатков Цикл Сообщение = Новый СообщениеПользователю(); Сообщение.Текст = "Склад " + СтрокаТаблицы.Склад + ": Остаток " + СтрокаТаблицы.Количество; Сообщение.Сообщить(); КонецЦикла;
Метод Остатки() возвращает таблицу значений, содержащую данные об остатках регистра, вычисленных на момент значения параметра МоментВремени. При этом будет использован отбор, согласно значению параметра Отбор, а сама таблица значений свернута по полю Склад, с суммированием значений поля Количество.
577
Глава 11. Учет движения средств Механизм построения результата метода Остатки() практически тот же, что и в случае применения виртуальной таблицы получения остатков. В качестве типов значения переменных, передаваемых параметру МоментВремени, возможны те же, что использовались для виртуальной таблицы получения остатков. То есть Дата, МоментВремени, Граница. Особенности применения различных значений и их использование системой при подсчете данных будут рассмотрены ниже, в разделе «Особенности использования периодов и моментов времени при получении остатков» на стр. 578. Различия проявляются в условиях отбора информации. Посредством параметра Отбор типа Структура можно строить только простейшие отборы на равенство значений измерений. Например, как показано в листинге 11.44. Листинг 11.44. Пример получения остатков регистра накопления
Отбор = Новый Структура("Номенклатура, Склад", ТоварОтбора, СкладОтбора);
Но варианты более сложных отборов, например, отбор по двум значениям измерения Номенклатура, для метода Остатки() неприемлемы.
Листинг 11.46. Пример получения остатков на «Период» методом «Остатки()»
ТаблицаОстатков = РегистрыНакопления.ТоварыНаСкладах.Остатки(Период);
Параметр Период виртуальной таблицы остатков и метода Остатки() может получать значения типа Дата, МоментВремени и Граница, кроме того, может быть вообще не указан, или иметь значение Неопределено, или содержать значение даты по умолчанию '00010101000000'. Последние три случая (не указан, или Неопределено, или значение даты по умолчанию) приводят к построению таблицы остатков с данными актуальных остатков (учитывающих все активные записи регистра). Если в качестве параметра передается значение типа Дата, важно помнить следующие моменты. Дата в системе «1С:Предприятие» включает в свой состав время. Даже если время не указано явно, оно принимает значение 00:00:00. То есть если в качестве параметра передать «31 декабря 2009 года» (данное значение может быть получено так: '20091231'), то в результате таблица остатков будет построена на дату 31.12.2009 00:00:00 (рис. 11.32).
Последние два параметра метода Остатки() касаются операции свертки полученных в запросе СУБД данных перед выгрузкой в таблицу значений. Однако если значения данных параметров не указывать, то результирующая таблица значений будет содержать колонки, соответствующие всем измерениям и/или всем ресурсам. Недостаточная гибкость объектной модели чтения итогов регистров объясняется тем, что в платформе на объектные методы возлагаются в основном задачи обеспечения записи, модификации и динамического чтения данных реальных таблиц базы данных. А задачи гибкого, тонкого, эффективного чтения для обеспечения последующего анализа состояния учитываемых в системе показателей возлагаются на более подходящие для этого инструменты – объекты Запрос, ПостроительОтчета, АнализДанных и т. п.
Особенности использования периодов и моментов времени при получении остатков Рассмотрим различные ситуации получения остатков запросом (листинг 11.45) или с помощью метода Остатки(), листинг 11.46.
Рис. 11.32. Получение остатков на дату
Таблица получения остатков строится на начало даты, то есть не включая дату границы интервала. Выше приведены примеры использования запроса к виртуальной таблице остатков и использования метода Остатки(). И в том и другом случае, если в таблице движений регистра будут присутствовать записи со значением поля Период, равным дате 31.12.2009 23:59:59, они не будут учтены (рис. 11.33), если получать данные на конец дня.
Листинг 11.45. Пример получения остатков на «Период» запросом
Если необходимо учесть и их тоже, следует применять параметр с типом значения Граница.
ВЫБРАТЬ ТоварыНаСкладахОстатки.Номенклатура КАК Номенклатура, ТоварыНаСкладахОстатки.Склад КАК Склад, ТоварыНаСкладахОстатки.КоличествоОстаток КАК Количество ИЗ РегистрНакопления.ТоварыНаСкладах.Остатки(&Период) КАК ТоварыНаСкладахОстатки
Параметр «Период» типа «МоментВремени» для получения остатков используют, если требуются итоги, полученные с точностью большей, чем до секунды. Например, если несколько документов имеют одинаковое время, но при проведении каждого из них требуется получать данные, актуальные на момент времени документа (рис. 11.34).
578
Период
Профессиональная разработка в системе «1С:Предприятие 8»
Получение данных из регистров накопления
Рис. 11.33. Получение остатков, не включая дату границы интервала
Номенклатура
Склад
Количество
ПоступлениеТоваров № 2 1 23.05.2010 15:30:45 Реализация № 1 1 27.05.2010 12:30:45 Реализация № 2 1 27.05.2010 12:30:45
Активность
Регистратор
23.05.2010 15:30:45 27.05.2010 12:30:45 27.05.2010 12:30:45
Вид движения
Период
Номер строки
Таблица 11.46. Таблица движений регистра накопления
Приход
Истина
Пульт VH
Фили-2
5
Расход
Истина
Пульт VH
Фили-2
4
Расход
Истина
Пульт VH
Фили-2
1
Таблица 11.47. Полученные итоги Номенклатура
Склад
Количество
Пульт VH
Фили-2
5
Если получить остатки на момент времени, включающий дату 27.05.2010 12:30:45 и ссылку на документ Реализация № 1, получим такие же итоги (табл. 11.47).
Рис. 11.34. Момент времени документа
Объект МоментВремени состоит из даты и ссылки на документ и может быть получен посредством применения метода МоментВремени() ссылки или объекта документа (листинг 11.47). Листинг 11.47. Получение момента времени документа
МоментВремениДокумента = СсылкаНаДокумент.МоментВремени();
Также значение типа МоментВремени может быть получено с помощью конструктора (листинг 11.48).
А вот если получить остатки на момент времени, включающий дату 27.05.2010 12:30:45 и ссылку на документ Реализация № 2, получим следующий результат (табл. 11.48). Таблица 11.48. Полученные итоги Номенклатура
Склад
Количество
Пульт VH
Фили-2
1
При получении таблицы остатков с указанием параметра Период типа МоментВремени, полученного из даты документа и ссылки на документ, необходимо иметь в виду, что данные получаются, исключая записи движений самого документа (рис. 11.35).
Листинг 11.48. Получение момента времени с помощью конструктора
МоментВремениДокумента = Новый МоментВремени(СсылкаНаДокумент.Дата, Документ);
В случае использования конструктора возможно указание даты, не совпадающей с датой документа. Рассмотрим следующий пример получения остатков на момент времени документа. Например, есть следующие записи таблицы движений регистра остатков (табл. 11.46). Если получить остатки на дату 27.05.2010 12:30:45, то получим следующий результат (табл. 11.47). Рис. 11.35. Получение остатков на момент времени документа
Том 1
579
Глава 11. Учет движения средств Для случаев, когда необходимо получить данные об остатках, включая движения, относящиеся к дате или моменту времени, применяют значения параметра «Период» с типом значения «Граница». Объект Граница получается посредством применения соответствующего конструктора. Именно в конструкторе указывается вид границы. В случае получения остатков на конец дня граница может быть создана так, как показано в листинге 11.49. Листинг 11.49. Создание границы с помощью конструктора
ГраницаПоДату = Новый Граница(КонецДня(ДатаОтчета), ВидГраницы.Включая);
В этом случае остатки будут получены, включая движения на дату формирования отчета (рис. 11.36).
Рис. 11.37. Получение остатков, включая движения указанного документа
Получение оборотов Задачи получения итогов оборотов могут решаться и для регистров остатков, и для оборотных регистров. И в том и в другом случае возможно чтение информации как посредством запроса, так и посредством метода Обороты(). Разберем подробнее, в чем разница применения этих подходов.
Виртуальная таблица оборотов
Рис. 11.36. Получение остатков, включая движения на дату формирования отчета
В случае получения остатков на момент времени документа граница может быть создана так, как показано в листинге 11.50. Листинг 11.50. Создание границы с помощью конструктора
ГраницаПоДокумент = Новый Граница(СсылкаНаДокумент.МоментВремени(), ВидГраницы.Включая);
В этом случае остатки будут получены, включая движения указанного документа (рис. 11.37).
580
Виртуальная таблица оборотов регистра накопления остатков позволяет получать итоговые значения оборотов ресурсов (далее будем называть «оборотов») за временной интервал (далее будем называть «период»). Итоговые значения могут быть получены в разрезе комбинаций значений измерений и/или в развороте дополнительной периодичности. Виртуальная таблица оборотов регистра накопления остатков имеет следующий состав полей: ■■ Период – это поле имеет тип Дата. Оно существует только в случаях, если указано значение параметра виртуальной таблицы оборотов Периодичность: Год, Полугодие, Квартал, Месяц, Декада, Неделя, День, Секунда, Минута, Час, Регистратор или Запись. Данное поле содержит начальную дату периода, к которому относится оборот регистра; ■■ Регистратор – это поле имеет тип ДокументСсылка.<имя>. Оно существует только в случаях, если указано значение параметра виртуальной таблицы оборотов Периодичность: Регистратор или Запись. Данное поле содержит ссылку на документ-регистратор, к которому относится оборот регистра; ■■ НомерСтроки – это поле имеет тип Число. Оно существует только в тех случаях, когда указано значение параметра виртуальной таблицы оборотов Периодичность: Запись. Содержит значение поля НомерСтроки записи движения регистра; Профессиональная разработка в системе «1С:Предприятие 8»
Получение данных из регистров накопления ■■ <Измерение> – это поле может иметь произвольный тип, который определяется типом измерения. Количество таких полей равно количеству измерений регистра накопления. Каждое из этих полей содержит значения измерений регистра. Имена полей совпадают с названиями измерений, заданными для объекта конфигурации; ■■ <Ресурс>Оборот – это поле имеет тип Число. Количество таких полей равно количеству ресурсов регистра накопления. Каждое из полей содержит значения, посчитанные как сумма приходов за минусом суммы расходов ресурса регистра накопления по всем движениям внутри соответствующего периода. Имена полей составляются из названий ресурсов с добавлением слова «Оборот»; ■■ <Ресурс>Приход – это поле имеет тип Число. Количество таких полей равно количеству ресурсов регистра накопления. Каждое из полей содержит значения, посчитанные как сумма приходов ресурса регистра накопления по всем движениям внутри соответствующего периода. Имена полей составляются из названий ресурсов с добавлением слова «Приход»; ■■ <Ресурс>Расход – это поле имеет тип Число. Количество таких полей равно количеству ресурсов регистра накопления. Каждое из полей содержит значения, посчитанные как сумма расходов ресурса регистра накопления по всем движениям внутри соответствующего периода. Имена полей составляются из названий ресурсов с добавлением слова «Расход». В отличие от регистра накопления остатков, оборотный регистр накапливает только обороты. То есть для ресурсов оборотного регистра не существует понятий «Приход» и «Расход». Поэтому состав полей виртуальной таблицы оборотов оборотного регистра накопления несколько короче состава полей аналогичной таблицы регистра накопления остатков: ■■ Период – это поле имеет тип Дата. Оно существует только в случаях, если указано значение параметра виртуальной таблицы оборотов Периодичность: Год, Полугодие, Квартал, Месяц, Декада, Неделя, День, Секунда, Минута, Час, Регистратор или Запись. Данное поле содержит начальную дату периода, к которому относится оборот регистра; ■■ Регистратор – это поле имеет тип ДокументСсылка.<имя>. Оно существует только в случаях, если указано значение параметра виртуальной таблицы оборотов Периодичность: Регистратор или Запись. Данное поле содержит ссылку на документ-регистратор, к которому относится оборот регистра; ■■ НомерСтроки – это поле имеет тип Число. Оно существует только в случаях, если указано значение параметра виртуальной таблицы оборотов Периодичность: Запись. Содержит значение поля НомерСтроки записи движения регистра; Том 1
■■ <Измерение> – это поле может иметь произвольный тип, который определяется типом измерения. Количество таких полей равно количеству измерений регистра накопления. Каждое из этих полей содержит значения измерений регистра. Имена полей совпадают с названиями измерений, заданными для объекта конфигурации; ■■ <Ресурс>Оборот – это поле имеет тип Число. Количество таких полей равно количеству ресурсов регистра накопления. Каждое из полей содержит значения, посчитанные как сумма значений ресурса регистра накопления по всем движениям внутри соответствующего периода. Имена полей составляются из названий ресурсов с добавлением слова «Оборот». Параметры виртуальной таблицы оборотов для любого регистра накопления следующие: ■■ НачалоПериода – это поле может иметь тип Дата, МоментВремени или Граница. Используется для указания начала периода расчета оборотов. Значение этого параметра по умолчанию включается в период расчета оборотов. Если параметр не задан, обороты рассчитываются с самой первой записи; ■■ КонецПериода – Дата, МоментВремени, Граница. Используется для указания конца периода расчета оборотов. Значение этого параметра по умолчанию включается в период расчета оборотов. Если параметр не задан, обороты рассчитываются по самую последнюю запись; ■■ Периодичность – содержит конструкцию языка запросов. Задается одним из следующих вариантов: Период, Запись, Регистратор, Секунда, Минута, Час, День, Неделя, Декада, Месяц, Квартал, Полугодие, Год. Используется для указания дополнительного разворота оборотов по периодичности. При указании значения Период обороты представляются за весь период (с НачалоПериода по КонецПериода) без дополнительных разворотов. В остальных случаях с разворотом по записям, регистраторам, неделям, декадам, месяцам, кварталам, полугодиям, годам соответственно. Значение по умолчанию – Период; ■■ Условие – содержит конструкцию языка запросов – условие. Строится по полям измерений, регистра накопления (или подчиненных им полям). Используется для ограничения состава исходных записей, по которым при построении виртуальной таблицы оборотов будут собираться обороты. Если параметр не указан, для сбора оборотов будут анализироваться все активные записи регистра. Виртуальная таблица оборотов не хранится в базе данных, а строится в момент обращения к ней. В качестве иллюстрации работы виртуальной таблицы оборотов рассмотрим следующий пример. Пусть таблица движений регистра ТоварыНаСкладах заполнена так, как показано в табл. 11.49.
581
Глава 11. Учет движения средств
Приход
Истина
Пульт PW
Главный
7
1
Приход
Ложь
Пульт VH
Фили-2
5
1
Расход
Истина
Пульт VH
Главный
9
1
Приход
Истина
Пульт PW
Фили-2
1
1
Приход
Истина
Пульт PW
Фили-2
2
1
Приход
Истина
Пульт PW
Фили-2
1
1
Приход
Истина
Пульт PW
Фили-2
1
Для получения оборотов используется запрос, текст которого представлен в листинге 11.51. Листинг 11.51. Пример получения оборотов регистра накопления
ВЫБРАТЬ ТоварыНаСкладахОбороты.Период, ТоварыНаСкладахОбороты.Номенклатура, ТоварыНаСкладахОбороты.Склад, ТоварыНаСкладахОбороты.КоличествоОборот, ТоварыНаСкладахОбороты.КоличествоПриход, ТоварыНаСкладахОбороты.КоличествоРасход ИЗ РегистрНакопления.ТоварыНаСкладах.Обороты( , , Месяц, ) КАК ТоварыНаСкладахОбороты
Тогда в результате выполнения приведенного запроса будет получен следующий результат (табл. 11.50). Таблица 11.50. Результат выполнения запроса Период
Номенклатура Склад
01.05.2010 00:00:00 01.05.2010 00:00:00 01.05.2010 00:00:00 01.06.2010 00:00:00 01.09.2010 00:00:00
Пульт VH
Главный
Пульт PW
582
Количество оборот
Количество приход
Количество расход
Главный
7
7
0
Пульт PW
Фили-2
1
1
0
Пульт PW
Фили-2
3
3
0
Пульт PW
Фили-2
1
1
0
1
10
9
Это верно даже для ситуации, когда поле Период записей движений, подчиненных одному регистратору, заполнено разными значениями. В качестве иллюстрации рассмотрим следующий пример. Пусть таблица движений регистра накопления содержит записи, приведенные в табл. 11.51. Таблица 11.51. Таблица движений регистра накопления
13.05.2010 15:00:01 13.05.2010 15:00:01 23.05.2010 11:30:45 23.05.2010 11:30:45 23.05.2010 11:30:45
ПоступлениеТоваров № 1 13.05.2010 15:00:01 ПоступлениеТоваров № 1 13.05.2010 15:00:01 РучнаяОперация № 1 23.05.2010 11:30:45 РучнаяОперация № 1 23.05.2010 11:30:45 РучнаяОперация № 1 23.05.2010 11:30:45
Количество
2
Склад
10
Номенклатура
Главный
Активность
Пульт VH
Вид движения
Количество
Истина
Номер строки
Склад
Приход
В случае же использования дополнительного разворота итогов по регистраторам или записям в поле Период содержится значение поля Период записи движения по регистру.
Регистратор
Номенклатура
1
Как видите, в данном примере при использовании дополнительного разворота итогов по месяцам в поле Период для каждой записи указывается начальная дата месяца.
Период
Активность
ПоступлениеТоваров № 1 13.05.2010 15:00:01 ПоступлениеТоваров № 1 13.05.2010 15:00:01 ПоступлениеТоваров № 2 23.05.2010 15:30:45 Реализация № 1 27.05.2010 12:30:45 ПоступлениеТоваров № 3 31.05.2010 23:59:59 ПоступлениеТоваров № 4 01.06.2010 00:00:00 ПоступлениеТоваров № 5 11.06.2010 13:59:00 ПоступлениеТоваров № 5 11.09.2010 11:00:00
Вид движения
Регистратор
13.05.2010 15:00:01 13.05.2010 15:00:01 23.05.2010 15:30:45 27.05.2010 12:30:45 31.05.2010 23:59:59 01.06.2010 00:00:00 11.06.2010 13:59:00 11.09.2010 11:00:00
Номер строки
Период
Таблица 11.49. Таблица движений регистра «ТоварыНаСкладах»
1
Приход
Истина
Пульт VH
Главный
10
2
Приход
Истина
Пульт PW
Главный
7
1
Приход
Истина
Пульт VH
Фили-2
5
2
Расход
Истина
Пульт PW
Главный
7
3
Расход
Истина
Пульт VH
Фили-2
1
Для получения оборотов используется запрос, текст которого представлен в листинге 11.52. Листинг 11.52. Пример получения оборотов регистра накопления
ВЫБРАТЬ ТоварыНаСкладахОбороты.Период, ТоварыНаСкладахОбороты.Регистратор, ТоварыНаСкладахОбороты.Номенклатура, ТоварыНаСкладахОбороты.Склад, ТоварыНаСкладахОбороты.КоличествоОборот, ТоварыНаСкладахОбороты.КоличествоПриход, ТоварыНаСкладахОбороты.КоличествоРасход ИЗ РегистрНакопления.ТоварыНаСкладах.Обороты( , , Регистратор, ) КАК ТоварыНаСкладахОбороты
Тогда в результате выполнения приведенного запроса будет получен следующий результат (табл. 11.52). Профессиональная разработка в системе «1С:Предприятие 8»
Получение данных из регистров накопления Итак, результаты и методики применения виртуальной таблицы оборотов для регистров остатков и оборотных регистров весьма схожи. Но вот алгоритмы получения этих результатов средствами системы сильно разнятся.
Для сравнения в листинге 11.53.
Количество оборот
Количество приход
Количество расход
ПоступлениеТоваров № 1 13.05.2010 15:00:01 ПоступлениеТоваров № 1 13.05.2010 15:00:01 РучнаяОперация № 1 23.05.2010 11:30:45 РучнаяОперация № 1 23.05.2010 11:30:45
Склад
Регистратор
13.05.2010 15:00:01 13.05.2010 15:00:01 23.05.2010 11:30:45 23.05.2010 11:30:45
Номенклатура
Период
Таблица 11.52. Результат выполнения запроса
Пульт VH
Главный
10
10
0
Пульт PW
Главный
7
7
0
Пульт VH
Фили-2
4
5
1
Пульт PW
Главный
-7
0
7
выполним
запрос,
текст
которого
Алгоритм, применяемый системой для получения оборотов регистра накопления остатков Для построения виртуальной таблицы оборотов регистра накопления остатков всегда используются данные таблицы движений регистра (из базы данных). При этом учитываются значения параметров виртуальной таблицы оборотов. Сам алгоритм построения этой виртуальной таблицы включает в себя следующие этапы:
приведен
Листинг 11.53. Пример получения оборотов регистра накопления
■■ получение записей из таблицы движений регистра согласно установленным значениям параметров виртуальной таблицы; ■■ группирование полученных записей согласно указанной в параметрах виртуальной таблицы периодичности.
ВЫБРАТЬ ТоварыНаСкладахОбороты.Регистратор, ТоварыНаСкладахОбороты.Номенклатура, ТоварыНаСкладахОбороты.Склад, ТоварыНаСкладахОбороты.КоличествоОборот, ТоварыНаСкладахОбороты.КоличествоПриход, ТоварыНаСкладахОбороты.КоличествоРасход ИЗ РегистрНакопления.ТоварыНаСкладах.Обороты( , , Регистратор, ) КАК ТоварыНаСкладахОбороты
Сортировка не выполняется. И хотя зачастую порядок записей в результате оказывается соответствующим желаемому, для гарантированного упорядочивания в тексте запроса нужно указывать ключевые слова УПОРЯДОЧИТЬ ПО или АВТОУПОРЯДОЧИВАНИЕ.
Результат выполнения этого запроса представлен в табл. 11.53.
Для обеспечения максимальной скорости выполнения запроса по этой виртуальной таблице также важно правильное применение отборов по измерениям.
Регистратор
Номенклатура
Склад
Количество оборот
Количество приход
Количество расход
Таблица 11.53. Результат выполнения запроса
ПоступлениеТоваров № 1 13.05.2010 15:00:01 ПоступлениеТоваров № 1 13.05.2010 15:00:01 РучнаяОперация № 1 23.05.2010 11:30:45 РучнаяОперация № 1 23.05.2010 11:30:45
Пульт VH Пульт PW Пульт VH Пульт PW
Главный Главный Фили-2 Главный
10 7 4 -7
10 7 5 0
0 0 1 7
Как видите, записи результата запроса оказываются сгруппированы по полям Период и Регистратор, даже если нет выходного поля Период. Это объясняется тем, что для определения момента времени, с которого движения регистра начинают действовать на итоги, «регистратор» является уточнением «периода». Том 1
Таким образом, скорость построения виртуальной таблицы оборотов регистра накопления остатков не зависит от периода рассчитанных итогов, а зависит от количества записей движений регистра, попавших в требуемый период построения таблицы.
подробнее
Правила применения таких отборов описаны в разделе «Применение отборов в запросах, использующих виртуальные таблицы регистров накопления», стр. 602.
Алгоритм, применяемый системой для получения оборотов оборотного регистра накопления Для построения виртуальной таблицы оборотов оборотного регистра накопления могут использоваться или только данные таблицы движений регистра, или только таблицы итогов (из базы данных), или и данные таблицы движений, и таблицы итогов. Для эффективного применения той или иной стратегии учитываются значения параметров виртуальной таблицы оборотов.
583
Глава 11. Учет движения средств Сам алгоритм построения этой виртуальной таблицы включает в себя следующие этапы: ■■ получение записей из базы данных из таблицы движений или таблицы итогов регистра согласно установленным значениям параметров виртуальной таблицы; ■■ группирование полученных записей согласно указанной в параметрах виртуальной таблицы периодичности. При выполнении первого этапа анализируется, можно ли использовать данные таблицы итогов регистра для формирования запроса. В таблице итогов регистра хранятся данные месячных оборотов. Эти данные будут использованы в случаях, когда дополнительная периодичность не задана или задана равной или большей месяцу и в интервал формирования виртуальной таблицы попадают целые месяцы. Остальная информация при необходимости получается из таблицы движений. В качестве иллюстрации работы виртуальной таблицы оборотов рассмотрим следующие примеры. Пусть таблица движений оборотного регистра Продажи заполнена следующим образом (табл. 11.54).
Номенклатура
Контрагент
Количество
Сумма
Реализация № 1 27.05.2010 12:30:45 Реализация № 2 29.05.2010 15:00:01 Реализация № 3 13.06.2010 15:00:00 Реализация № 3 23.06.2010 10:00:00 Реализация № 4 23.06.2010 15:30:45 Реализация № 5 01.08.2010 08:59:59
Активность
Регистратор
27.05.2010 12:30:45 29.05.2010 15:00:01 13.06.2010 15:00:00 23.06.2010 10:00:00 23.06.2010 15:30:45 01.08.2010 08:59:59
Номер строки
Период
Таблица 11.54. Таблица движений оборотного регистра «Продажи»
1
Истина
Пульт VH
Ялта-Лтд
9
135
1
Истина
Пульт VH
Компания "Риона" 10
150
1
Истина
Пульт VH
Компания "Риона" 1
15
1
Истина
Пульт VH
Компания "Риона" 1
15
1
Ложь
Пульт PW
Крона
1
90
1
Истина
Пульт PW
Ялта-Лтд
1
95
Соответственно, таблица итогов будет заполнена так, как показано в табл. 11.55.
584
Таблица 11.55. Таблица итогов оборотного регистра накопления «Продажи» Период
Номенклатура
Контрагент
Количество
Сумма
01.05.2010 00:00:00 01.05.2010 00:00:00 01.06.2010 00:00:00 01.08.2010 00:00:00
Пульт VH
Ялта-Лтд
9
135
Пульт VH
Компания "Риона"
10
150
Пульт VH
Компания "Риона"
2
30
Пульт PW
Ялта-Лтд
1
95
Рассмотрим выполнение запроса, представленного в листинге 11.54. Листинг 11.54. Пример получения оборотов регистра накопления
ВЫБРАТЬ ПродажиОбороты.Номенклатура, ПродажиОбороты.КоличествоОборот КАК Количество, ПродажиОбороты.СуммаОборот КАК Сумма ИЗ РегистрНакопления.Продажи.Обороты(&НачалоПериода, &КонецПериода, , ) КАК ПродажиОбороты
1. Если параметрам запроса присвоить значения даты по умолчанию или Неопределено (листинг 11.55), то алгоритм построения виртуальной таблицы оборотов будет использовать данные только таблицы итогов (табл. 11.56). Листинг 11.55. Пример установки параметров запроса
Запрос.УстановитьПараметр("НачалоПериода", Неопределено); Запрос.УстановитьПараметр("КонецПериода", Неопределено); Таблица 11.56. Промежуточная выборка данных из таблицы итогов Номенклатура
Количество
Сумма
Пульт VH Пульт VH Пульт VH Пульт PW
9 10 2 1
135 150 30 95
После этапа группирования результат виртуальной таблицы будет выглядеть так, как показано в табл. 11.57. Таблица 11.57. Результат выполнения запроса Номенклатура Количество
Сумма
Пульт VH Пульт PW
315 95
21 1
Профессиональная разработка в системе «1С:Предприятие 8»
Получение данных из регистров накопления 2. Если параметрам запроса присвоить значения так, что в период входит только целое число месяцев (листинг 11.56), то алгоритм построения виртуальной таблицы будет использовать данные только таблицы итогов (табл. 11.58). Листинг 11.56. Пример установки параметров запроса
Запрос.УстановитьПараметр("НачалоПериода", Дата(2010, 5, 01)); Запрос.УстановитьПараметр("КонецПериода", Дата(2010, 6, 30, 23, 59, 59)); Таблица 11.58. Промежуточная выборка данных из таблицы итогов Номенклатура Количество Сумма
Пульт VH Пульт VH Пульт VH
9 10 2
135 150 30
Записи этих таблиц будут объединены, и после этапа группирования результат виртуальной таблицы будет выглядеть так, как показано в табл. 11.62. Таблица 11.62. Результат выполнения запроса Номенклатура Количество
Сумма
Пульт VH
315
21
Обратите внимание: результат не отличается от результата предыдущего примера. Однако из-за того, что значение параметра НачалоПериода не совпадало с началом месяца, система была вынуждена обращаться как к таблице итогов, так и к таблице движений регистра.
После этапа группирования результат виртуальной таблицы будет выглядеть так, как показано в табл. 11.59.
4. Если параметрам запроса присвоить значения так, что в период не входит целое число месяцев (листинг 11.58), то алгоритм построения виртуальной таблицы оборотов будет использовать только данные таблицы движений регистра (табл. 11.63).
Таблица 11.59. Результат выполнения запроса
Листинг 11.58. Пример установки параметров запроса
Номенклатура Количество Сумма
Пульт VH
21
315
3. Если параметрам запроса присвоить значения так, что в период входит не только целое число месяцев (листинг 11.57), то алгоритм построения виртуальной таблицы оборотов будет сначала использовать данные таблицы итогов по целым месяцам (в нашем случае – за июнь), табл. 11.60. Листинг 11.57. Пример установки параметров запроса
Запрос.УстановитьПараметр("НачалоПериода", Дата(2010, 5, 20)); Запрос.УстановитьПараметр("КонецПериода", Дата(2010, 6, 30, 23, 59, 59)); Таблица 11.60. Промежуточная выборка данных из таблицы итогов Номенклатура
Количество
Сумма
Пульт VH
2
30
Затем по не поместившимся в целые месяцы движениям данные будут получены из таблицы движений (табл. 11.61). Таблица 11.61. Промежуточная выборка данных из таблицы движений Номенклатура Количество
Сумма
Пульт VH Пульт VH
135 150
Том 1
9 10
Запрос.УстановитьПараметр("НачалоПериода", Дата(2010, 5, 20)); Запрос.УстановитьПараметр("КонецПериода", Дата(2010, 6, 23, 23, 59, 59)); Таблица 11.63. Промежуточная выборка данных из таблицы движений Номенклатура
Количество
Сумма
Пульт VH Пульт VH Пульт VH Пульт VH
9 10 1 1
135 150 15 15
После этапа группирования результат виртуальной таблицы будет выглядеть так, как показано в табл. 11.64. Таблица 11.64. Результат выполнения запроса Номенклатура Количество Сумма
Пульт VH
21
315
Как видите, хотя интервал между значениями параметров превышал 30 дней, он не включал в себя целых месяцев. Этого было достаточно, чтобы виртуальная таблица оборотов строилась по таблице движений. 5. Если параметр Периодичность имеет значение, меньшее месяца (листинг 11.59), то независимо от значений параметров НачалоПериода и КонецПериода виртуальная таблица оборотов будет строиться по записям таблицы движений регистра.
585
Номенклатура
Склад
Количество
1
Расход
Истина
Пульт VH
Главный
9
1
Приход
Истина
Пульт PW
Фили-2
1
1
Приход
Истина
Пульт PW
Фили-2
2
1
Приход
Истина
Пульт PW
Фили-2
1
1
Приход
Истина
Пульт PW
Фили-2
1
Тогда после выполнения кода, приведенного в листинге 11.60, будет получен результат, показанный в табл. 11.66.
подробнее
Правила применения таких отборов описаны в разделе «Применение отборов в запросах, использующих виртуальные таблицы регистров накопления», стр. 602.
Метод «Обороты()»
Листинг 11.60. Пример получения оборотов регистра накопления
ТаблицаОборотов = РегистрыНакопления.ТоварыНаСкладах.Обороты(); Таблица 11.66. Результат выполнения метода «Обороты()»
В ситуациях, когда при получении данных об оборотах не применяется сложных отборов либо эти данные впоследствии не нужно соединять с другими данными, а дополнительная периодичность оборотов не требуется, можно использовать объектную модель чтения информации – метод Обороты(). Данный метод применим только для регистров накопления, у которых включено использование итогов. При получении результата используются только записи активных движений. Например, пусть таблица движений регистра ТоварыНаСкладах заполнена следующим образом (табл. 11.65).
Активность
Номенклатура
Склад
Количество
ПоступлениеТоваров № 1 1 13.05.2010 15:00:01 ПоступлениеТоваров № 1 2 13.05.2010 15:00:01 ПоступлениеТоваров № 2 1 23.05.2010 15:30:45
Вид движения
Регистратор
Номер строки
Период
13.05.2010 15:00:01 13.05.2010 15:00:01 23.05.2010 15:30:45
Номенклатура
Склад
Количество Приход Количество Расход
Пульт VH Пульт PW Пульт PW
Главный Главный Фили-2
10 7 5
9 0 0
Кроме полных оборотов, посредством метода Обороты() возможно и получение данных в некотором временном интервале, с отбором на равенство значений измерений. Например, если требуется сообщить обороты по некой товарной позиции (ссылка на нее – в переменной ТоварОтбора) в интервале между НачалоПериода и КонецПериода (листинг 11.61). Листинг 11.61. Пример получения оборотов регистра накопления
Таблица 11.65. Таблица движений регистра накопления
586
Реализация № 1 27.05.2010 12:30:45 ПоступлениеТоваров № 3 31.05.2010 23:59:59 ПоступлениеТоваров № 4 01.06.2010 00:00:00 ПоступлениеТоваров № 5 11.06.2010 13:59:00 ПоступлениеТоваров № 5 11.08.2010 11:00:00
Активность
Для обеспечения максимальной скорости выполнения запроса по этой виртуальной таблице также важно правильное применение отборов по измерениям.
27.05.2010 12:30:45 31.05.2010 23:59:59 01.06.2010 00:00:00 11.06.2010 13:59:00 11.08.2010 11:00:00
Вид движения
Таким образом, видно, что получение виртуальной таблицы оборотов оборотного регистра может выполняться гораздо быстрее, нежели виртуальной таблицы оборотов регистра остатков, за счет использования накопленных месячных итогов оборотов.
Регистратор
ВЫБРАТЬ ПродажиОбороты.Номенклатура, ПродажиОбороты.КоличествоОборот КАК Количество, ПродажиОбороты.СуммаОборот КАК Сумма ИЗ РегистрНакопления.Продажи.Обороты(&НачалоПериода, &КонецПериода, Неделя, ) КАК ПродажиОбороты
Период
Листинг 11.59. Пример установки параметров запроса
Номер строки
Глава 11. Учет движения средств
Приход
Истина
Пульт VH
Главный
10
Приход
Истина
Пульт PW
Главный
7
Приход
Ложь
Пульт VH
Фили-2
5
Отбор = Новый Структура("Номенклатура",ТоварОтбора); ТаблицаОборотов = РегистрыНакопления.ТоварыНаСкладах.Обороты(НачалоПериода, КонецПериода, Отбор, "Номенклатура",); Для Каждого СтрокаТаблицы Из ТаблицаОборотов Цикл Сообщение = Новый СообщениеПользователю(); Сообщение.Текст = "Номенклатура " + СтрокаТаблицы.Номенклатура + ": Приход " + СтрокаТаблицы.КоличествоПриход + "; Расход " + СтрокаТаблицы.КоличествоРасход; Сообщение.Сообщить(); КонецЦикла;
Профессиональная разработка в системе «1С:Предприятие 8»
Получение данных из регистров накопления В качестве типов значения переменных, передаваемых параметрам НачалоПериода и КонецПериода, возможны те же, что использовались для виртуальной таблицы получения оборотов, то есть Дата, МоментВремени и Граница. Особенности применения различных значений и их использование системой при подсчете данных будут рассмотренным ниже, в разделе «Особенности использования периодов и моментов времени при получении оборотов» на стр. 587.
Особенности использования периодов и моментов времени при получении оборотов
Посредством параметра Отбор типа Структура можно строить простейшие отборы на равенство значений измерений. Например, так (листинг 11.62).
Последние случаи (не указан, Неопределено или значение даты по умолчанию) приводят к построению таблицы оборотов с данными, учитывающими все активные записи регистра.
Листинг 11.62. Пример установки отбора при получении оборотов регистра накопления
Отбор = Новый Структура("Номенклатура, Склад", ТоварОтбора, СкладОтбора);
Последние два параметра метода Обороты() касаются операции свертки данных в запросе СУБД перед выгрузкой в таблицу значений. Однако если значения данных параметров не указывать, то результирующая таблица значений будет содержать колонки, соответствующие всем измерениям и/или всем ресурсам. В приведенном примере (см. листинг 11.61) было указано только измерение Номенклатура, в результате произошла свертка по колонке Номенклатура с суммированием значений колонок КоличествоПриход и КоличествоРасход. Применение метода Обороты() для оборотного регистра практически аналогично применению этого метода для регистра остатков.
Параметры НачалоПериода и КонецПериода виртуальной таблицы оборотов и метода Обороты() могут получать значения типа Дата, МоментВремени и Граница, кроме того, могут быть вообще не указаны, иметь значение Неопределено или значение даты по умолчанию.
Если в качестве параметра передается значение типа Дата, важно помнить следующие моменты. Дата в системе «1С:Предприятие» включает в свой состав время. Даже если время не указано явно, оно принимает значение 00:00:00. То есть если в качестве параметра НачалоПериода передать значение 1 декабря 2009 года (данное значение может быть получено так: '20091201'), а в качестве параметра КонецПериода передать 31 декабря 2009 года ('20091231'), то в результате и виртуальная таблица получения оборотов, и результат метода Обороты() будут построены с даты 01.12.2009 00:00:00 по дату 31.12.2009 00:00:00. То есть в обороты, по сути, войдут данные продаж только первой секунды 31 декабря (рис. 11.38).
Единственное отличие состоит в названии колонок таблицы значений, получаемой в результате применения метода. В данном случае их имена совпадают с именами измерений и ресурсов. Например, если требуется на основе данных регистра Продажи сообщить об объемах продаж по конкретной номенклатурной позиции (ссылка на нее – в переменной ТоварОтбора) в интервале между НачалоПериода и КонецПериода, в разрезе покупателей, то можно использовать следующий фрагмент кода (листинг 11.63). Листинг 11.63. Пример получения оборотов оборотного регистра накопления
Отбор = Новый Структура("Номенклатура", ТоварОтбора); ТаблицаОборотов = РегистрыНакопления.Продажи.Обороты(НачалоПериода, КонецПериода, Отбор, "Контрагент",); Для каждого СтрокаТаблицы Из ТаблицаОборотов Цикл Сообщение = Новый СообщениеПользователю(); Сообщение.Текст = "Покупатель " + СтрокаТаблицы.Контрагент + ": Количество " + СтрокаТаблицы.Количество + "; Сумма " + СтрокаТаблицы.Сумма; Сообщение.Сообщить(); КонецЦикла;
Том 1
Рис. 11.38. Получение оборотов на даты указанного интервала
Для предотвращения возможных недоразумений по этому поводу удобно использовать функцию КонецДня(). Эта функция возвращает значение последней секунды дня, указанной в качестве параметра даты (листинги 11.64, 11.65).
587
Глава 11. Учет движения средств Листинг 11.64. Пример получения оборотов регистра накопления на конец дня
Запрос = Новый Запрос; Запрос.Текст = "ВЫБРАТЬ | ТоварыНаСкладахОбороты.Номенклатура, | ТоварыНаСкладахОбороты.Склад, | ТоварыНаСкладахОбороты.КоличествоОборот, | ТоварыНаСкладахОбороты.КоличествоПриход, | ТоварыНаСкладахОбороты.КоличествоРасход |ИЗ | РегистрНакопления.ТоварыНаСкладах.Обороты(&НачалоПериода, &КонецПериода) | КАК ТоварыНаСкладахОбороты"; Запрос.УстановитьПараметр("НачалоПериода", НачалоПериода); Запрос.УстановитьПараметр("КонецПериода", КонецДня(КонецПериода)); Листинг 11.65. Пример получения оборотов регистра накопления на конец дня
Рис. 11.40. Включение граничных записей при получении оборотов
ТаблицаОборотов = РегистрыНакопления.ТоварыНаСкладах.Обороты(НачалоПериода, КонецДня(КонецПериода));
Параметры «НачалоПериода» и «КонецПериода» типа «МоментВремени» используют для получения оборотов, если требуются итоги, полученные с точностью большей, чем до секунды. Например, если несколько документов имеют одинаковое время, но для решения задачи нужно получение оборотов с начала месяца по момент времени текущего документа (рис. 11.41).
В обоих случаях в результате будут получены данные оборотов с даты 01.12.2009 00:00:00 по дату 31.12.2009 23:59:59 включительно (рис. 11.39).
Рис. 11.39. Получение оборотов на конец дня
Таблица оборотов строится с включением записей, соответствующих граничным периодам. То есть с начала секунды значения параметра НачалоПериода по конец секунды параметра КонецПериода (рис. 11.40). Если в вышеприведенных примерах вместо конца дня 31.12.2009 23:59:59 указать дату 01.01.2010 00:00:00 и в таблице движений регистра будут присутствовать записи со значением поля Период, равным дате 01.01.2010 00:00:00, то они будут учтены. То есть с прикладной точки зрения получится, что в результат запроса войдут данные первой секунды 2010 года.
588
Рис. 11.41. Использование момента времени при получении оборотов
Данная задача может быть решена посредством метода Обороты() или применения запроса с указанием значений параметров НачалоПериода и КонецПериода, вычисляемых следующим образом (листинг 11.66). Листинг 11.66. Пример указания границ периода с использованием момента времени
НачалоПериода = НачалоМесяца(СсылкаНаДокумент.Дата); КонецПериода = Новый МоментВремени(СсылкаНаДокумент.Дата, СсылкаНаДокумент);
Профессиональная разработка в системе «1С:Предприятие 8»
Получение данных из регистров накопления В обоих случаях обороты будут получены, включая движения документа, ссылка на который содержится в переменной СсылкаНаДокумент. Для случаев, когда необходимо получить данные об оборотах, исключая движения, относящиеся к дате или моменту времени, применяют значения параметров НачалоПериода и КонецПериода с типом значения Граница. Объект Граница получается посредством применения соответствующего конструктора. Именно в конструкторе указывается вид границы. Например, если требуется получить обороты в интервале дат, исключая первую и последнюю секунды, можно использовать следующий код (листинг 11.67). Листинг 11.67. Пример задания границ интервала с использованием объекта «Граница»
ГраницаСДатыИсключая = Новый Граница(НачалоПериода, ВидГраницы.Исключая); ГраницаНаДатуИсключая = Новый Граница(КонецДня(КонецПериода), ВидГраницы.Исключая);
Если требуется получить обороты с начала месяца (включая) по момент времени документа, исключая движения самого документа, тогда можно поступить следующим образом (листинг 11.68, рис. 11.42). Листинг 11.68. Пример задания границ интервала
ГраницаСНачалаМесяца = НачалоМесяца(СсылкаНаДокумент.Дата); ГраницаНаДокумент = Новый Граница(СсылкаНаДокумент.МоментВремени(), ВидГраницы.Исключая);
Агрегаты Для оптимизации получения итоговых данных из оборотных регистров накопления, например, для быстрого получения аналитических отчетов в различных разрезах, в системе «1С:Предприятие» реализован механизм агрегатов. Агрегат – физическая таблица в базе данных, в которой хранятся сводные обороты всех ресурсов регистра за определенный период, по набору измерений и с периодичностью, соответствующими конкретному агрегату. Таблиц-агрегатов в базе данных может быть много (они отличаются друг от друга набором измерений и периодичностью), в то время как таблица итогов (она хранит обороты в разрезе всех измерений регистра) – одна. За счет этого и обеспечивается более быстрый доступ к итоговым данным, если режим использования агрегатов включен. Однако необходимо учитывать, что: ■■ во-первых, оборотный регистр, использующий агрегаты, должен иметь не более 30 измерений; ■■ во-вторых, агрегаты рассчитаны на крупные внедрения, в которых требуется анализировать сотни и миллионы записей в регистрах. Поэтому не имеет смысла использовать их в регистрах, содержащих менее 3–5 тысяч записей. Зачем вообще использовать агрегаты? Для ответа на этот вопрос вспомним механизм получения итоговых данных оборотных регистров накопления. Для получения различных аналитических отчетов обычно используется виртуальная таблица оборотов оборотного регистра накопления. Как было рассказано выше, для построения этой таблицы в зависимости от параметров, переданных в виртуальную таблицу оборотов, могут использоваться или данные только таблицы движений регистра, или данные только таблицы итогов, или данные таблицы движений и таблицы итогов. В таблице итогов регистра хранятся данные месячных оборотов. Эти данные будут использованы в случаях, когда дополнительная периодичность не задана или задана равной или большей месяцу и в интервал формирования виртуальной таблицы попадают целые месяцы. Остальная информация при необходимости получается из таблицы движений.
Рис. 11.42. Использование границы при получении оборотов
Самый быстрый способ получения итоговых данных из оборотного регистра – путем запроса только к таблице итогов. Но на практике зачастую большую или меньшую часть требуемых данных приходится досчитывать по таблице движений. И совсем уже катастрофический случай, когда таблицей итогов воспользоваться не удается и приходится все рассчитывать по таблице движений. При использовании агрегатов в подавляющем большинстве запросов к информационной базе система сможет выбрать один или несколько агрегатов для получения из них нужных данных, не обращаясь к таблице
Том 1
589
Глава 11. Учет движения средств движений регистра. Таким образом, скорость исполнения запросов может быть значительно увеличена, следовательно, аналитические отчеты будут выполняться быстрее, что особенно важно для крупных внедрений.
1. Сначала в конфигураторе нужно создать необходимый список агрегатов, который будет использовать оборотный регистр накопления. Сделать это можно двумя способами:
Нужно понимать, что использование или неиспользование агрегатов никак не сказывается на прикладном коде или тексте запросов, написанных разработчиком. Если у оборотного регистра накопления есть агрегаты и разрешено их использование, то при получении итоговых данных из регистра платформа будет работать в режиме агрегатов, что при больших объемах данных регистра будет эффективнее. Если агрегатов нет или их использование запрещено, платформа будет работать в режиме итогов, как было описано выше.
□□ В режиме 1С:Предприятие при помощи стандартной функции Управление итогами (Все функции Стандартные Управление итогами Полные возможности Агрегаты Оптимальные…) рассчитать оптимальные агрегаты для регистра, сохранить список агрегатов в файл <имя регистра>.xml (рис. 11.44) и затем в конфигураторе, в диалоге редактирования агрегатов регистра загрузить их из файла командой Открыть оптимальные агрегаты. Из встроенного языка можно получить список оптимальных агрегатов методом менеджера регистра накопления ОпределитьОптимальныеАгрегаты(). При первом построении списка агрегатов платформа анализирует только таблицу движений регистра. Если агрегаты для регистра ранее использовались, то платформа анализирует также и статистику использования этих агрегатов. На основании этих данных платформа предлагает набор агрегатов для регистра, которые она считает оптимальными.
В составе демонстрационной конфигурации «Хранение информации», которая находится на прилагаемом компакт-диске, находится оборотный регистр накопления ПродажиАгрегаты, содержащий 34 тысячи записей и использующий агрегаты. Данные в этом регистре получены случайным образом и никакого прикладного значения не имеют. Но на примере этого регистра мы проиллюстрируем работу с агрегатами. Работа с агрегатами может быть представлена следующей схемой (рис. 11.43).
Рис. 11.44. Получение списка оптимальных агрегатов
ВНИМАНИЕ!
Чтобы закладка Агрегаты обработки Управление итогами стала доступной, нужно создать хотя бы один агрегат вручную (при помощи команды контекстного меню оборотного регистра накопления Открыть агрегаты).
Рис. 11.43. Общая схема работы с агрегатами
590
□□ Создать собственный список агрегатов регистра на основе анализа запросов к регистру. Для этого нужно использовать диалог редактирования агрегатов регистра. Вызвать его можно из дерева конфигурации при помощи команды контекстного меню оборотного регистра накопления Открыть агрегаты или из окна редактирования объекта конфигурации, на закладке Данные, при помощи кнопки Агрегаты. Профессиональная разработка в системе «1С:Предприятие 8»
Получение данных из регистров накопления 2. После обновления конфигурации базы данных включить для регистра режим использования агрегатов. Это можно сделать в режиме 1С:Предприятие при помощи стандартной функции Управление итогами (Все функции Стандартные Управление итогами Полные возможности Агрегаты Режим Включить режим агрегатов). Из встроенного языка можно установить режим агрегатов методом менеджера регистра накопления УстановитьРежимАгрегатов(). 3. Далее необходимо выполнить перестроение агрегатов. Это можно сделать в режиме 1С:Предприятие при помощи стандартной функции Управление итогами (Все функции Стандартные Управление итогами Полные возможности Агрегаты Перестроить…). Из встроенного языка можно перестроить использование агрегатов методом менеджера регистра накопления ПерестроитьИспользованиеАгрегатов(). Перестроение сети агрегатов нужно для того, чтобы платформа определила, какие из агрегатов она будет использовать в ближайшее время. Для этого платформа анализирует имеющиеся агрегаты и статистику запросов к регистру. Операцию перестроения нужно производить регулярно. Особенно в случаях, если характер данных в регистре мог измениться или есть вероятность изменения состава запросов к регистру, что ведет к изменению статистики использования агрегатов. После перестроения агрегатов платформа заполняет дату перестроения и вычисляет эффект от использования агрегатов для регистра. Эффект измеряется в процентах и показывает, насколько быстрее будет выполняться запрос при использовании агрегатов по сравнению с запросом при использовании таблицы итогов. 4. Затем необходимо выполнить обновление агрегатов, так как, в отличие от таблицы итогов, агрегаты автоматически не заполняются данными. Это можно сделать в режиме 1С:Предприятие при помощи стандартной функции Управление итогами (Все функции Стандартные Управление итогами Полные возможности Агрегаты Обновить…). Из встроенного языка можно обновить данные агрегатов методом менеджера регистра накопления ОбновитьАгрегаты(). При обновлении агрегатов происходит перенос данных из таблиц движений, которые были произведены после предыдущего обновления агрегатов, в таблицы агрегатов, которые в данный момент используются платформой. Если в информационную базу постоянно вводится много новых данных, то обновлять агрегаты нужно часто (каждый час, минуту, секунду). Если в агрегатах не найдется нужных итоговых данных, система все равно досчитает их по таблице движений, что будет значительно медленнее. Поэтому обновление агрегатов влияет лишь на производительность, а не на саму возможность получения актуальных итогов. 5. Далее следует накопить статистику использования агрегатов. Для этого нужно в течение некоторого интервала времени, например месяца, выполнять типовые задачи, использующие данные регистра, для которого включен режим использования агрегатов. В процессе работы необходимо выполнять обновление агрегатов. Том 1
6. По прошествии выбранного временного интервала, например, через месяц, следует заново рассчитать оптимальные агрегаты (метод ОпределитьОптимальныеАгрегаты()). Данная операция не является регулярной, ее можно выполнять при необходимости, когда количественные изменения в статистике использования агрегатов переходят в качественные. Судить об этом можно по существенному падению производительности на текущем списке агрегатов или по существенному изменению характера данных или состава запросов к регистру и т. п. 7. Затем необходимо определить, требуется ли изменение списка агрегатов для регистра. Если нет, то следует продолжить работу, перейдя на шаг 3. 8. Если необходимо обновить список агрегатов регистра, то в диалоге редактирования агрегатов регистра следует загрузить необходимые (или все) агрегаты из списка оптимальных командой Открыть оптимальные агрегаты. Затем нужно обновить конфигурацию базы данных и продолжить работу с шага 3. ВНИМАНИЕ!
Обновление агрегатов можно выполнять в фоновом режиме, в процессе работы пользователей. При этом есть возможность обновлять агрегаты порциями, и рекомендуется использовать режим разделения итогов. Перестроение сети агрегатов и получение оптимальных агрегатов – довольно длительные и ресурсоемкие операции. Поэтому лучше их выполнять в период минимальной нагрузки на систему, например, ночью. Поскольку после получения оптимальных агрегатов может потребоваться реструктуризация базы данных, нужно быть заранее готовым к тому, что работа пользователей на это время должна быть прекращена.
Следует отдельно сказать об установке свойства Использование в диалоге редактирования агрегатов регистра в конфигураторе. Стандартно это свойство устанавливается в значение Авто. Это значит, что при перестроении агрегатов платформа сама будет решать, использовать данный агрегат или нет. Если же свойство Использование агрегата установить в значение Всегда, то независимо от «желания» платформы она будет использовать данный агрегат при получении итоговых данных (рис. 11.45). Например, разработчик может создать специальный агрегат, обеспечивающий максимально быстрое получение руководителем какого-то аналитического отчета, и установить для него свойство Использование в значение Всегда. Но предположим, этот отчет выполняется довольно редко. Тогда при перестроении списка агрегатов платформа, проанализировав статистику запросов, не сможет исключить его из списка используемых агрегатов, а будет использовать его всегда в соответствии с желанием разработчика.
591
Глава 11. Учет движения средств Таблица 11.68. Детальные показатели остатков и оборотов Номенклатура
Пульт PW Пульт PW Пульт PW Пульт PW Рис. 11.45. Свойство агрегата «Использование»
Пульт VH Пульт VH
Получение остатков и оборотов в одной таблице
Пульт VH
Для решения прикладных задач управления ресурсами предприятий система предоставляет возможности учета этих ресурсов (впрочем, как и любых других показателей) на регистрах накопления. Как правило, в подобных ситуациях речь идет о показателях остатков. Потому что именно показатели остатков позволяют ответить на вопрос, какое именно значение имел этот показатель в тот или иной момент времени. Но для полноценного контроля зачастую мало информации только о значениях остатков. Требуется видеть одновременно и статическую картину, и как она была получена (динамику развития ситуации). Например, для контроля наличия товара на складах предприятия пользователю часто необходимо видеть картину и остатков, и оборотов за некий промежуток времени (табл. 11.67). Таблица 11.67. Показатели остатков и оборотов Номенклатура Количество начальный остаток
Количество Количество Количество Количество конечный остаток оборот приход расход
Пульт PW Пульт VH
15 11
1 10
14 1
15 10
1 9
То есть информацию о начальном остатке значения ресурса (КоличествоНачальныйОстаток), о том, какой за указанные промежуток времени был оборот данного ресурса (КоличествоОборот), как этот оборот был получен (КоличествоПриход, КоличествоРасход), какое конечное значение ресурса после этого получилось (КоличествоКонечныйОстаток). Увидев такую картину укрупнено, пользователь может потребовать показать ее более детально, с дополнительной периодичностью до дня, когда происходили события в отношении товаров на складах (табл. 11.68).
592
Период
13.05.2010 0:00:00 17.05.2010 0:00:00 31.05.2010 0:00:00 13.05.2010 0:00:00 27.05.2010 0:00:00
Количество Количество Количество Количество Количество начальный конечный оборот приход расход остаток остаток
1 1
15 8
14 7
15 7
1 0
8
11
3
3
0
11
15
4
5
1
10 10
11 20
1 10
10 10
9 0
20
11
-9
0
9
Обратите внимание: в результате подробного варианта представления данных длина таблицы может возрастать на несколько порядков. И тогда для быстрого осмысления «локальных участков» информации важно, чтобы значения полей НачальныйОстаток и КонечныйОстаток отражали реальную картину дня и были согласованы с информацией об остатках по предыдущему и последующему периоду (дням). То есть значения полей остатков верхнего уровня группирования информации (по номенклатуре) в данном отчете не получены простым суммированием таких же полей нижнего уровня группирования информации (по дням), а скорее перенесены из соответствующих записей нижнего уровня. А ведь пользователь может потребовать еще большей детальности, уже внутри дня. Для построения таких отчетов можно отдельно получить остатки, отдельно получить обороты и затем каким-либо образом обработать полученные данные. Такой способ в принципе возможен, но достаточно трудоемок. Поэтому в рамках платформы системы «1С:Предприятие» предусмотрены специальные механизмы для решения подобных задач. Они основаны на применении виртуальной таблицы остатков и оборотов регистра накопления остатков и включают в себя реализацию достаточно сложных алгоритмов, решающих одновременно вопросы требуемой функциональности и возможной оптимизации с точки зрения быстродействия. Разработчик же может пользоваться уже готовыми результатами. Но для эффективного использования данных механизмов важно понимать их возможности и принципы реализации. Ниже эти вопросы рассматриваются более подробно.
Профессиональная разработка в системе «1С:Предприятие 8»
Получение данных из регистров накопления
Виртуальная таблица остатков и оборотов Виртуальная таблица остатков и оборотов регистра накопления остатков позволяет получать итоговые значения и остатков, и оборотов ресурсов за временной интервал. Итоговые значения могут быть получены в разрезе комбинаций значений измерений и/или в развороте дополнительной периодичности. Виртуальная таблица остатков и оборотов содержит следующие поля: ■■ Период – имеет тип Дата. Поле существует, только если указано значение параметра виртуальной таблицы остатков и оборотов Периодичность: Год, Полугодие, Квартал, Месяц, Декада, Неделя, Секунда, Минута, Час, День, Регистратор или Запись. Данное поле содержит начальную дату периода, к которому относится оборот регистра; ■■ Регистратор – имеет тип ДокументСсылка.<имя>. Поле существует, если указано значение параметра виртуальной таблицы остатков и оборотов Периодичность: Регистратор или Запись. Данное поле содержит ссылку на документ-регистратор, к которому относится оборот регистра; ■■ НомерСтроки – имеет тип Число. Это поле существует, если указано значение параметра виртуальной таблицы остатков и оборотов Периодичность: Запись. Содержит значение поля НомерСтроки записи движения регистра; ■■ <Измерение> – тип произвольный, определяется типом измерения. Количество таких полей равно количеству измерений регистра накопления. Каждое из полей содержит значения измерений регистра. Имена полей совпадают с названиями измерений, заданными для объекта конфигурации; ■■ <Ресурс>Оборот – имеет тип Число. Количество таких полей равно количеству ресурсов регистра накопления. Каждое из полей содержит значения, посчитанные как сумма приходов за минусом суммы расходов ресурса регистра по всем движениям внутри соответствующего периода. Имена полей составляются из названий ресурсов с добавлением слова «Оборот»; ■■ <Ресурс>Приход – имеет тип Число. Количество таких полей равно количеству ресурсов регистра накопления. Каждое из полей содержит значения, посчитанные как сумма приходов ресурса регистра по всем движениям внутри соответствующего периода. Имена полей составляются из названий ресурсов с добавлением слова «Приход»; ■■ <Ресурс>Расход – имеет тип Число. Количество таких полей равно количеству ресурсов регистра накопления. Каждое из полей содержит значения, посчитанные как сумма расходов ресурса регистра по всем движениям внутри соответствующего периода. Имена полей составляются из названий ресурсов с добавлением слова «Расход»;
Том 1
■■ <Ресурс>НачальныйОстаток – имеет тип Число. Количество таких полей равно количеству ресурсов регистра накопления. Каждое из полей содержит значение остатка ресурса на начало соответствующего периода. Имена полей составляются из названий ресурсов с добавлением слова «НачальныйОстаток»; ■■ <Ресурс>КонечныйОстаток – имеет тип Число. Количество таких полей равно количеству ресурсов регистра накопления. Каждое из полей содержит значение остатка ресурса на конец соответствующего периода. Имена полей составляются из названий ресурсов с добавлением слова «КонечныйОстаток». Виртуальная таблица остатков и оборотов имеет следующие параметры: ■■ <НачалоПериода> – Дата, МоментВремени или Граница. Используется для указания начала периода расчета итогов. Значение начала периода по умолчанию включается в период расчета итогов. Если параметр не задан, итоги рассчитываются с самой первой записи; ■■ <КонецПериода> – Дата, МоментВремени или Граница. Используется для указания конца периода расчета итогов. Значение конца периода по умолчанию включается в период расчета итогов. Если параметр не задан, итоги рассчитываются по самую последнюю запись; ■■ <Периодичность> – конструкция языка запросов. Задается одним из следующих вариантов: Период, Запись, Регистратор, Секунда, Минута, Час, День, Неделя, Декада, Месяц, Квартал, Полугодие, Год. Используется для указания дополнительного разворота итогов по периодичности. При указании значения Период обороты представляются за весь период (с НачалоПериода по КонецПериода) без дополнительных разворотов. В остальных случаях – с разворотами по записям, регистраторам, неделям, декадам, месяцам, кварталам, полугодиям, годам соответственно. Значение по умолчанию – Период; ■■ <МетодДополнения> – конструкция языка запросов. Задается одним из следующих вариантов: Движения, ДвиженияИГраницыПериода. Используется для указания включения граничных периодов в состав выдаваемых виртуальной таблицей записей. Если выбирается вариант Движения, то граничные периоды не будут включаться (будут выданы записи только за те периоды, когда имели место движения). Если выбирается вариант ДвиженияИГраницыПериода, то граничные периоды будут включаться независимо от наличия или отсутствия движений в рамках интервала между НачалоПериода и КонецПериода. Значение по умолчанию – ДвиженияИГраницыПериода; ■■ <Условие> – конструкция языка запросов – условие. Строится по полям измерений, регистра накопления (или подчиненным им полям). Используется для ограничения состава исходных записей, по которым при построении виртуальной таблицы будут собираться итоги. Если параметр не указан, то для сбора итогов будут анализироваться все активные записи регистра.
593
Глава 11. Учет движения средств
В случае же использования дополнительной периодичности на каждом этапе алгоритма запросы выполняются, результаты запросов объединяются, полученная в результате объединения таблица записывается во временную таблицу базы данных, чтобы впоследствии быть использованной при выполнении основного запроса, в рамках которого была применена виртуальная таблица остатков и оборотов. Рассмотрим примеры использования виртуальной таблицы остатков и оборотов для регистра ТоварыНаСкладах. Пусть таблица движений регистра ТоварыНаСкладах заполнена так, как показано в табл. 11.69.
594
Активность
Номенклатура
Склад
Количество
Если дополнительная периодичность не указана, то расчет всех данных производится в рамках одного запроса, включающего подзапросы, согласно разделам алгоритма. Подзапросы при этом примерно те же, что и для получения соответствующих виртуальных таблиц получения остатков и оборотов.
ПоступлениеТоваров № 1 10.04.2010 11:00:00 ПоступлениеТоваров № 2 10.04.2010 11:00:00 ПоступлениеТоваров № 3 13.05.2010 15:00:01 ПоступлениеТоваров № 3 13.05.2010 15:00:01 ПоступлениеТоваров № 8 17.05.2010 18:00:00 ПоступлениеТоваров № 4 23.05.2010 15:30:45 Реализация № 1 27.05.2010 12:30:45 ПоступлениеТоваров № 5 31.05.2010 13:00:00 ПоступлениеТоваров № 6 31.05.2010 14:00:00 Реализация № 2 31.05.2010 15:59:00 ПоступлениеТоваров № 7 31.05.2010 23:59:59
Вид движения
■■ получение остатков на начало заданного периода (так же, как это выполняется для построения виртуальной таблицы остатков); ■■ получение оборотов за заданный период с заданной периодичностью (так же, как это выполняется для построения виртуальной таблицы оборотов); ■■ объединение полученных остатков и оборотов с учетом значения параметра МетодДополнения; ■■ досчет значений остатков для каждой записи.
10.04.2010 11:00:00 10.04.2010 11:01:00 13.05.2010 15:00:01 13.05.2010 15:00:01 17.05.2010 18:00:00 23.05.2010 15:30:45 27.05.2010 12:30:45 31.05.2010 13:00:00 31.05.2010 14:00:00 31.05.2010 15:59:00 31.05.2010 23:59:59
Номер cтроки
Сам алгоритм построения этой виртуальной таблицы включает в себя следующие этапы:
Регистратор
Виртуальная таблица может строиться только по тем регистрам, у которых использование итогов включено. При попытке выполнения запроса, в котором используется виртуальная таблица остатков для регистра накопления с отключенными итогами, выдается сообщение об ошибке.
Таблица 11.69. Таблица движений регистра накопления
Период
Виртуальная таблица остатков и оборотов не хранится в базе данных, а строится в момент обращения к ней. Для построения виртуальной таблицы всегда используются данные таблицы итогов и таблицы движений регистра (из базы данных). При этом учитываются значения параметров виртуальной таблицы. Итоги ресурсов собираются только по активным записям.
1
Приход
Истина
Пульт PW
Главный
1
1
Приход
Истина
Пульт VH
Фили-2
10
1
Приход
Истина
Пульт VH
Главный
10
2
Приход
Истина
Пульт PW
Главный
7
1
Приход
Истина
Пульт PW
Розничный
3
1
Приход
Ложь
Пульт VH
Фили-2
5
1
Расход
Истина
Пульт VH
Главный
9
1
Приход
Истина
Пульт PW
Фили-2
1
1
Приход
Истина
Пульт PW
Фили-2
2
1
Расход
Истина
Пульт PW
Фили-2
1
1
Приход
Истина
Пульт PW
Фили-2
2
Допустим, выполняется следующий запрос (листинг 11.69). Листинг 11.69. Пример получения остатков и оборотов регистра накопления
ВЫБРАТЬ ТоварыНаСкладахОстаткиИОбороты.Номенклатура, ТоварыНаСкладахОстаткиИОбороты.Склад, ТоварыНаСкладахОстаткиИОбороты.КоличествоНачальныйОстаток, ТоварыНаСкладахОстаткиИОбороты.КоличествоКонечныйОстаток, ТоварыНаСкладахОстаткиИОбороты.КоличествоОборот, ТоварыНаСкладахОстаткиИОбороты.КоличествоПриход, ТоварыНаСкладахОстаткиИОбороты.КоличествоРасход ИЗ РегистрНакопления.ТоварыНаСкладах.ОстаткиИОбороты КАК ТоварыНаСкладахОстаткиИОбороты АВТОУПОРЯДОЧИВАНИЕ
Профессиональная разработка в системе «1С:Предприятие 8»
Получение данных из регистров накопления Таблица 11.71. Результат выполнения запроса
Склад
Количество начальный остаток
Количество конечный остаток
Количество оборот
Количество приход
Количество расход
Период
Номенклатура
Тогда результат выполнения приведенного запроса будет выглядеть следующим образом (табл. 11.70).
Пульт PW
Главный
1
8
7
7
0
Пульт PW
Розничный 0
3
3
3
0
Пульт PW
Фили-2
0
4
4
5
1
Пульт VH
Главный
0
10
10
10
0
Пульт VH
Главный
10
1
-9
0
9
Таблица 11.70. Результат выполнения запроса Номенклатура Склад
Количество начальный остаток
Количество Количество Количество Количество конечный оборот приход расход остаток
Пульт PW Пульт PW Пульт PW Пульт VH Пульт VH
0 0 0 0 0
8 3 4 1 10
Главный Розничный Фили-2 Главный Фили-2
8 3 4 1 10
8 3 5 10 10
0 0 1 9 0
Для получения информации с дополнительным разворотом по временным периодам, например по дням, когда были движения, можно применять следующий вариант написания запроса (листинг 11.70). Листинг 11.70. Пример получения остатков и оборотов регистра накопления
ВЫБРАТЬ ТоварыНаСкладахОстаткиИОбороты.Период, ТоварыНаСкладахОстаткиИОбороты.Номенклатура, ТоварыНаСкладахОстаткиИОбороты.Склад, ТоварыНаСкладахОстаткиИОбороты.КоличествоНачальныйОстаток, ТоварыНаСкладахОстаткиИОбороты.КоличествоКонечныйОстаток, ТоварыНаСкладахОстаткиИОбороты.КоличествоОборот, ТоварыНаСкладахОстаткиИОбороты.КоличествоПриход, ТоварыНаСкладахОстаткиИОбороты.КоличествоРасход ИЗ РегистрНакопления.ТоварыНаСкладах.ОстаткиИОбороты(&НачалоПериода, &КонецПериода, День, Движения,) КАК ТоварыНаСкладахОстаткиИОбороты АВТОУПОРЯДОЧИВАНИЕ
Если при этом значения параметров установлены так, как показано в листинге 11.71, то в результате выполнения запроса будут получены данные, представленные в табл. 11.71. Листинг 11.71. Пример установки параметров запроса
Запрос.УстановитьПараметр("НачалоПериода", '20100501'); Запрос.УстановитьПараметр("КонецПериода", КонецДня('20100531'));
Обратите внимание: значение поля Период соответствует началу каждого дня (дополнительная периодичность была именно День). Поскольку в параметрах виртуальной таблицы был указан метод дополнения Движения, то в данном случае выходная таблица содержит записи по всем комбинациям значений измерений, по которым в периоде с НачалоПериода по КонецПериода были движения. Поэтому в рассмотренном примере в таблице результата не оказалось записей с комбинацией Пульт VH и Фили-2. Том 1
13.05.2010 00:00:00 17.05.2010 00:00:00 31.05.2010 00:00:00 13.05.2010 00:00:00 27.05.2010 00:00:00
Если же в выходной таблице результата должна быть информация по остаткам номенклатурных позиций на складах, несмотря на наличие или отсутствие движений внутри периода между НачалоПериода и КонецПериода, то виртуальная таблица остатков и оборотов может быть построена следующим образом (листинг 11.72). Листинг 11.72. Пример получения остатков и оборотов регистра накопления
ВЫБРАТЬ ТоварыНаСкладахОстаткиИОбороты.Период, ТоварыНаСкладахОстаткиИОбороты.Номенклатура, ТоварыНаСкладахОстаткиИОбороты.Склад, ТоварыНаСкладахОстаткиИОбороты.КоличествоНачальныйОстаток, ТоварыНаСкладахОстаткиИОбороты.КоличествоКонечныйОстаток, ТоварыНаСкладахОстаткиИОбороты.КоличествоОборот, ТоварыНаСкладахОстаткиИОбороты.КоличествоПриход, ТоварыНаСкладахОстаткиИОбороты.КоличествоРасход ИЗ РегистрНакопления.ТоварыНаСкладах.ОстаткиИОбороты(&НачалоПериода, &КонецПериода, День, , ) КАК ТоварыНаСкладахОстаткиИОбороты АВТОУПОРЯДОЧИВАНИЕ
Если значения параметров установлены так же (см. листинг 11.71), то благодаря тому, что параметр МетодДополнения имеет по умолчанию значение ДвиженияИГраницыПериода, получается следующий результат (табл. 11.72).
595
Глава 11. Учет движения средств С какой скоростью система получает результат виртуальной таблицы остатков и оборотов?
Количество приход
Количество расход
Остаток на границу «КонецПериода» Остаток на границу «НачалоПериода» Остаток на границу «КонецПериода»
Количество оборот
Остаток на границу «КонецПериода»
Количество конечный остаток
Остаток на границу «КонецПериода»
Количество начальный остаток
Остаток на границу «КонецПериода»
01.05.2010 00:00:00 13.05.2010 00:00:00 31.05.2010 00:00:00 17.05.2010 00:00:00 31.05.2010 00:00:00 31.05.2010 00:00:00 31.05.2010 00:00:00 13.05.2010 00:00:00 27.05.2010 00:00:00 31.05.2010 00:00:00 01.05.2010 00:00:00 31.05.2010 00:00:00
Склад
Остаток на границу «НачалоПериода»
Номенклатура
Период
Таблица 11.72. Результат выполнения запроса
Пульт PW
Главный
1
1
0
0
0
Пульт PW
Главный
1
8
7
7
0
Пульт PW
Главный
8
8
0
0
0
Пульт PW
Розничный
0
3
3
3
0
Пульт PW
Розничный
3
3
0
0
0
Пульт PW
Фили-2
0
4
4
5
1
Пульт PW
Фили-2
4
4
0
0
0
Пульт VH
Главный
0
10
10
10
0
Пульт VH
Главный
10
1
-9
0
9
Пульт VH
Главный
1
1
0
0
0
Пульт VH
Фили-2
10
10
0
0
0
Пульт VH
Фили-2
10
10
0
0
0
Исходя из приведенного выше описания алгоритма, можно сказать, что в общем случае скорость построения виртуальной таблицы остатков и оборотов зависит от периода рассчитанных итогов (для расчета начальных остатков) и от количества записей движений регистра, попавших в требуемый период построения таблицы, а больше всего от дополнительной периодичности разворота результатов, указанной в параметрах виртуальной таблицы. От количества записей за другие периоды (например, за прошлые годы) скорость выполнения этой задачи не зависит. Для обеспечения максимальной скорости выполнения запроса по этой виртуальной таблице также важно правильное применение отборов по измерениям. подробнее
Правила применения таких отборов описаны в разделе «Применение отборов в запросах, использующих виртуальные таблицы регистров накопления», стр. 602.
Особенности использования периодов и моментов времени при получении остатков и оборотов По умолчанию при использовании виртуальной таблицы остатков и оборотов итоги по остаткам и оборотам рассчитываются, включая граничные периоды (рис. 11.46).
Для комбинаций измерений, по которым были начальные остатки на момент НачалоПериода, добавились записи, содержащие значения этих остатков и в поле КоличествоНачальныйОстаток, и в поле КоличествоКонечныйОстаток, до записей, содержащих данные по движениям. Для комбинаций измерений, по которым были конечные остатки на момент КонецПериода, добавились записи, содержащие значения этих остатков и в поле КоличествоНачальныйОстаток, и в поле КоличествоКонечныйОстаток, после записей, содержащих записи по движениям. В результате цель достигнута: в таблицу результата запроса попадают записи также и по тем комбинациям значений измерений, по которым не было движений во временном интервале построения виртуальной таблицы остатков и оборотов.
596
Рис. 11.46. Получение остатков и оборотов, включая границы периода
Поэтому все особенности использования параметров НачалоПериода и КонецПериода аналогичны виртуальной таблице оборотов (см. раздел «Особенности использования периодов и моментов времени при получении оборотов», стр. 587). Профессиональная разработка в системе «1С:Предприятие 8»
Получение данных из регистров накопления
Предположим, что таблица движений регистра ТоварыНаСкладах заполнена так, как показано в табл. 11.73.
Склад
Количество
1
Приход
Истина
Пульт PW
Главный
1
1
Приход
Истина
Пульт VH
Фили-2
10
1
Приход
Истина
Пульт VH
Главный
10
2
Приход
Истина
Пульт PW
Главный
7
1
Приход
Истина
Пульт PW
Розничный 3
1
Приход
Ложь
Пульт VH
Фили-2
5
1
Расход
Истина
Пульт VH
Главный
9
1
Приход
Истина
Пульт PW
Фили-2
1
1
Приход
Истина
Пульт PW
Фили-2
2
1
Расход
Истина
Пульт PW
Фили-2
1
1
Приход
Истина
Пульт PW
Фили-2
2
Если параметры запроса установлены так, как показано в листинге 11.74, результат выполнения запроса будет иметь вид, представленный в табл. 11.74. Листинг 11.74. Пример установки параметров запроса
Запрос.УстановитьПараметр("НачалоПериода", '20100501'); Запрос.УстановитьПараметр("КонецПериода", КонецДня('20100531')); Таблица 11.74. Результат выполнения запроса Номенклатура Склад
Пульт PW Пульт PW Пульт PW Пульт PW Пульт VH Пульт VH
Том 1
Номенклатура
ВЫБРАТЬ ТоварыНаСкладахОстаткиИОбороты.Номенклатура КАК Номенклатура, ТоварыНаСкладахОстаткиИОбороты.Склад, ТоварыНаСкладахОстаткиИОбороты.КоличествоНачальныйОстаток КАК КоличествоНачальныйОстаток, ТоварыНаСкладахОстаткиИОбороты.КоличествоКонечныйОстаток КАК КоличествоКонечныйОстаток, ТоварыНаСкладахОстаткиИОбороты.КоличествоОборот КАК КоличествоОборот, ТоварыНаСкладахОстаткиИОбороты.КоличествоПриход КАК КоличествоПриход, ТоварыНаСкладахОстаткиИОбороты.КоличествоРасход КАК КоличествоРасход ИЗ РегистрНакопления.ТоварыНаСкладах.ОстаткиИОбороты(&НачалоПериода, &КонецПериода, , Движения, ) КАК ТоварыНаСкладахОстаткиИОбороты ИТОГИ СУММА(КоличествоНачальныйОстаток), СУММА(КоличествоКонечныйОстаток), СУММА(КоличествоОборот), СУММА(КоличествоПриход), СУММА(КоличествоРасход) ПО Номенклатура АВТОУПОРЯДОЧИВАНИЕ
Активность
Листинг 11.73. Пример получения остатков и оборотов регистра накопления
ПоступлениеТоваров № 1 10.04.2010 11:00:00 ПоступлениеТоваров № 2 10.04.2010 11:00:00 ПоступлениеТоваров № 3 13.05.2010 15:00:01 ПоступлениеТоваров № 3 13.05.2010 15:00:01 ПоступлениеТоваров № 8 17.05.2010 18:00:00 ПоступлениеТоваров № 4 23.05.2010 15:30:45 Реализация № 1 27.05.2010 12:30:45 ПоступлениеТоваров № 5 31.05.2010 13:00:00 ПоступлениеТоваров № 6 31.05.2010 14:00:00 Реализация № 2 31.05.2010 15:59:00 ПоступлениеТоваров № 7 31.05.2010 23:59:59
Вид движения
Например, для запроса, текст которого приведен в листинге 11.73, итоги будут получены простым суммированием данных соответствующих записей.
10.04.2010 11:00:00 10.04.2010 11:01:00 13.05.2010 15:00:01 13.05.2010 15:00:01 17.05.2010 18:00:00 23.05.2010 15:30:45 27.05.2010 12:30:45 31.05.2010 13:00:00 31.05.2010 14:00:00 31.05.2010 15:59:00 31.05.2010 23:59:59
Номер строки
Для того чтобы задействовать этот алгоритм, система прежде всего должна распознать необходимость специфичного расчета итогов по полям остатков.
Регистратор
Отдельного рассмотрения заслуживает вопрос расчета итогов по полям остатков, поскольку с прикладной точки зрения не всегда они могут быть получены простым суммированием, а должны рассчитываться с привлечением специального алгоритма.
Таблица 11.73. Таблица движений регистра накопления
Период
Расчет итогов по полям остатков при использовании виртуальной таблицы остатков и оборотов
Количество Количество Количество Количество Количество начальный конечный оборот приход расход остаток остаток
1 Главный 1 Розничный 0 Фили-2 0 0 Главный 0
15 8 3 4 1 1
14 7 3 4 1 1
15 7 3 5 10 10
1 0 0 1 9 9
597
Глава 11. Учет движения средств Теперь изменим текст запроса так, как показано в листинге 11.75.
Таблица 11.75. Результат выполнения запроса Склад
ВЫБРАТЬ ТоварыНаСкладахОстаткиИОбороты.Номенклатура КАК Номенклатура, ТоварыНаСкладахОстаткиИОбороты.Период КАК Период, ТоварыНаСкладахОстаткиИОбороты.Склад, ТоварыНаСкладахОстаткиИОбороты.КоличествоНачальныйОстаток КАК КоличествоНачальныйОстаток, ТоварыНаСкладахОстаткиИОбороты.КоличествоКонечныйОстаток КАК КоличествоКонечныйОстаток, ТоварыНаСкладахОстаткиИОбороты.КоличествоОборот КАК КоличествоОборот, ТоварыНаСкладахОстаткиИОбороты.КоличествоПриход КАК КоличествоПриход, ТоварыНаСкладахОстаткиИОбороты.КоличествоРасход КАК КоличествоРасход ИЗ РегистрНакопления.ТоварыНаСкладах.ОстаткиИОбороты(&НачалоПериода, &КонецПериода, День, ДвиженияИГраницыПериода,) КАК ТоварыНаСкладахОстаткиИОбороты ИТОГИ СУММА(КоличествоНачальныйОстаток), СУММА(КоличествоКонечныйОстаток), СУММА(КоличествоОборот), СУММА(КоличествоПриход), СУММА(КоличествоРасход) ПО Номенклатура АВТОУПОРЯДОЧИВАНИЕ
В этом случае при расчете итогов остатков система будет действовать по следующему алгоритму: ■■ исходные записи временной промежуточной таблицы (записанной в базе данных в процессе выполнения алгоритма построения виртуальной таблицы остатков и оборотов) упорядочиваются по полям первого уровня (в нашем случае – Номенклатура и Склад), далее – хронологически; ■■ при обходе упорядоченных записей: □□ первые записи по каждой комбинации полей первого уровня используются для суммирования начального остатка; □□ последние записи по каждой комбинации полей первого уровня используются для суммирования конечного остатка. Если использовать тот же вариант установки значений параметров виртуальной таблицы остатков и оборотов (см. листинг 11.74), то таблица результата будет выглядеть уже по-другому (табл. 11.75). Серым фоном отмечены те поля, которые были просуммированы при получении итогов полей остатков по номенклатуре. Аналогичным образом система поступила бы, если бы группировок итогов было больше. Главное, что они перечислены в запросе до группировки итогов Период.
598
Период
Номенклатура
Листинг 11.75. Пример получения остатков и оборотов регистра накопления
Пульт PW Пульт PW Главный
01.05.2010 00:00:00 Пульт PW Главный 13.05.2010 00:00:00 Пульт PW Главный 31.05.2010 00:00:00 Пульт PW Розничный 17.05.2010 00:00:00 Пульт PW Розничный 31.05.2010 00:00:00 Пульт PW Фили-2 31.05.2010 00:00:00 Пульт PW Фили-2 31.05.2010 00:00:00 Пульт VH Пульт VH Главный 13.05.2010 00:00:00 Пульт VH Главный 27.05.2010 00:00:00 Пульт VH Главный 31.05.2010 00:00:00 Пульт VH Фили-2 01.05.2010 00:00:00 Пульт VH Фили-2 31.05.2010 00:00:00
Количество Количество Количество Количество Количество начальный конечный оборот приход расход остаток остаток
1 1
15 1
14 0
15 0
1 0
1
8
7
7
0
8
8
0
0
0
0
3
3
3
0
3
3
0
0
0
0
4
4
5
1
4
4
0
0
0
10 0
11 10
1 10
10 10
9 0
10
1
-9
0
9
1
1
0
0
0
10
10
0
0
0
10
10
0
0
0
Если среди итогов есть группировка Период (листинг 11.76), алгоритм расчета полей остатков еще более сложный. Листинг 11.76. Пример получения остатков и оборотов регистра накопления
ВЫБРАТЬ ТоварыНаСкладахОстаткиИОбороты.Номенклатура КАК Номенклатура, ТоварыНаСкладахОстаткиИОбороты.Период КАК Период, ТоварыНаСкладахОстаткиИОбороты.Склад, ТоварыНаСкладахОстаткиИОбороты.КоличествоНачальныйОстаток КАК КоличествоНачальныйОстаток, ТоварыНаСкладахОстаткиИОбороты.КоличествоКонечныйОстаток КАК КоличествоКонечныйОстаток, ТоварыНаСкладахОстаткиИОбороты.КоличествоОборот КАК КоличествоОборот, ТоварыНаСкладахОстаткиИОбороты.КоличествоПриход КАК КоличествоПриход, ТоварыНаСкладахОстаткиИОбороты.КоличествоРасход КАК личествоРасход ИЗ РегистрНакопления.ТоварыНаСкладах.ОстаткиИОбороты(&НачалоПериода, &КонецПериода, День, ДвиженияИГраницыПериода,) КАК ТоварыНаСкладахОстаткиИОбороты ИТОГИ СУММА(КоличествоНачальныйОстаток),
Профессиональная разработка в системе «1С:Предприятие 8»
Получение данных из регистров накопления СУММА(КоличествоКонечныйОстаток), СУММА(КоличествоОборот), СУММА(КоличествоПриход), СУММА(КоличествоРасход) ПО Номенклатура, Период АВТОУПОРЯДОЧИВАНИЕ
Для приведенного примера при расчете полей остатков будут выполняться следующие действия: ■■ расчет итогов для группировки (группировок) перед группировкой Период (в нашем примере это расчет для группировки Номенклатура) выполняется по тому же алгоритму, что в предыдущем примере; ■■ расчет итогов для группировки Период: □□ исходные записи временной промежуточной таблицы остатков и оборотов (записанной в базе данных в процессе выполнения алгоритма построения виртуальной таблицы остатков и оборотов) упорядочиваются по полям, использованным в группировках выше (в нашем случае это группировка Номенклатура), затем хронологически (по полю Период), далее – по оставшимся полям первого уровня (в нашем случае Склад); □□ внутри группировки первого уровня (Номенклатура) для каждого значения группировки Период рассчитываются значения полей остатков посредством обходов записей и суммирования значений нужных полей: ○○ для начального остатка: обход всех записей, у которых дата больше или равна значению даты группировки Период, начиная от этой даты (то есть «вниз»). При обходе выполняется суммирование значений поля НачальныйОстаток для записей, содержащих различные (ранее не встреченные в процессе обхода) комбинации значений полей первого уровня (в нашем примере Номенклатура и Склад); ○○ для конечного остатка: обход всех записей, у которых дата меньше или равна значению даты группировки Период, начиная от этой даты (то есть «вверх»). При обходе выполняется суммирование значений поля КонечныйОстаток для записей, содержащих различные (ранее не встреченные в процессе обхода) комбинации значений полей первого уровня (в нашем примере Номенклатура и Склад). Для наглядности работы алгоритма расчета итогов остатков группировки Период рассмотрим фрагмент заполнения таблицы результата. Пусть заполнение регистра будет тем же, что рассматривали раньше (см. табл. 11.73), с теми же значениями параметров НачалоПериода и КонецПериода (см. листинг 11.74). Расчет промежуточных итогов остатков товара Пульт PW для значения периода 17.05.2010 00:00:00 будет произведен по следующей схеме (табл. 11.76). Том 1
Таблица 11.76. Результат расчета промежуточных итогов Номенклатура
Упорядоченные записи из временной таблицы остатков и оборотов Рассчитываемая запись итога по периоду
Пульт PW Пульт PW Пульт PW Пульт PW Пульт PW
Упорядоченные записи из временной таблицы остатков и оборотов
Пульт PW Пульт PW Пульт PW
Период
01.05.2010 00:00:00 13.05.2010 00:00:00 17.05.2010 00:00:00 17.05.2010 00:00:00 31.05.2010 00:00:00 31.05.2010 00:00:00 31.05.2010 00:00:00 31.05.2010 00:00:00
Склад
Количество начальный остаток
Количество конечный остаток
Главный
1
1
Главный
1
8
8
11
Розничный
0
3
Главный
8
8
Розничный
3
3
Фили-2
0
4
Фили-2
4
4
Серым фоном отмечены те поля, которые были просуммированы при получении итогов. В целом таблица результата запроса будет выглядеть как на табл. 11.77. Обратите внимание: «особыми» алгоритмами были рассчитаны только поля остатков, поля же оборотов рассчитываются простым суммированием в рамках требуемых группировок. Для более сложных случаев, когда среди группировочных полей итогов есть и предшествующие полю Период, и находящиеся после него, алгоритм расчета итогов включает в себя следующие этапы: ■■ расчет итогов для группировок, предшествующих группировке Период; ■■ расчет итогов для группировки Период; ■■ расчет итогов для группировок после группировки Период производится как для обычных полей, то есть простым суммированием. Хотелось бы еще раз подчеркнуть, что в любом случае применение этих «особых» алгоритмов происходит уже после того, как виртуальная таблица остатков и оборотов была получена и сохранена во временной таблице базы данных. Рассмотрим еще ряд особенностей различных вариантов использования полей остатков, когда система будет применять еще более сложные алгоритмы.
599
Глава 11. Учет движения средств Таблица 11.77. Результат выполнения запроса Количество начальный остаток
Количество конечный остаток
Количество оборот
Количество приход
Количество расход
15
14
15
1
Пульт PW 01.05.2010 00:00:00 Пульт PW 01.05.2010 00:00:00
1
1
0
0
0
Итоги по граничному значению «НачалоПериода» Итоги по периоду «День»
1
1
0
0
0
1
8
7
7
0
1
8
7
7
0
8
11
3
3
0
3
3
3
0
11
15
4
5
1
8
8
0
0
0
Розничный 3
3
0
0
0
Фили-2
0
4
4
5
1
Фили-2
4
4
0
0
0
10
11
1
10
9
10
10
0
0
0
10
10
0
0
0
10
20
10
10
0
0
10
10
10
0
20
11
-9
0
0
10
1
-9
0
9
11
11
0
0
0
Главный
1
1
0
0
0
Фили-2
10
10
0
0
0
Пульт PW 13.05.2010 00:00:00 Пульт PW 13.05.2010 00:00:00 Итоги по периоду «День» Пульт PW 17.05.2010 00:00:00 Пульт PW 17.05.2010 00:00:00 Итоги по периоду «День» Пульт PW 31.05.2010 00:00:00 Итоги по граничному Пульт PW 31.05.2010 значению «КонецПериода» 00:00:00 Итоги по граничному Пульт PW 31.05.2010 значению «КонецПериода» 00:00:00 Пульт PW 31.05.2010 00:00:00 Итоги по граничному Пульт PW 31.05.2010 значению «КонецПериода» 00:00:00 Итоги по номенклатурной Пульт VH позиции Итоги по периоду «День» Пульт VH 01.05.2010 00:00:00 Итоги по граничному Пульт VH 01.05.2010 значению 00:00:00 «НачалоПериода» Итоги по периоду «День» Пульт VH 13.05.2010 00:00:00 Пульт VH 13.05.2010 00:00:00 Итоги по периоду «День» Пульт VH 27.05.2010 00:00:00 Пульт VH 27.05.2010 00:00:00 Итоги по периоду «День» Пульт VH 31.05.2010 00:00:00 Итоги по граничному Пульт VH 31.05.2010 значению «КонецПериода» 00:00:00 Итоги по граничному Пульт VH 31.05.2010 значению «КонецПериода» 00:00:00
600
Склад
1
Период
Пульт PW
Номенклатура
Итоги по номенклатурной позиции Итоги по периоду «День»
Получение итогов по одному полю остатков
Главный
Главный
Розничный 0
Главный
Фили-2
Главный
Главный
Для того чтобы запрос мог рассчитать итоги по полям остатка, необходимо чтобы в запросе получались оба значения остатка за период (начальный и конечный). Если в запросе получается только один остаток и по нему ведется расчет итога, программа неявно добавит в запрос получение данных из информационной базы поле парного остатка. Например, в случае выполнения запроса, представленного в листинге 11.77, будет неявно добавлено поле ТоварыНаСкладахОстаткиИОбороты.КоличествоКонечныйОстаток, потому что иначе возникли бы сложности с расчетом итогов последних периодов, если в них не было движений. Листинг 11.77. Пример получения остатков и оборотов регистра накопления
ВЫБРАТЬ ТоварыНаСкладахОстаткиИОбороты.Номенклатура КАК Номенклатура, ТоварыНаСкладахОстаткиИОбороты.Период КАК Период, ТоварыНаСкладахОстаткиИОбороты.Склад, ТоварыНаСкладахОстаткиИОбороты.КоличествоНачальныйОстаток КАК КоличествоНачальныйОстаток, ТоварыНаСкладахОстаткиИОбороты.КоличествоОборот КАК КоличествоОборот, ТоварыНаСкладахОстаткиИОбороты.КоличествоПриход КАК КоличествоПриход, ТоварыНаСкладахОстаткиИОбороты.КоличествоРасход КАК КоличествоРасход ИЗ РегистрНакопления.ТоварыНаСкладах.ОстаткиИОбороты(&НачалоПериода, &КонецПериода, День, ДвиженияИГраницыПериода,) КАК ТоварыНаСкладахОстаткиИОбороты ИТОГИ СУММА(КоличествоНачальныйОстаток), СУММА(КоличествоОборот), СУММА(КоличествоПриход), СУММА(КоличествоРасход) ПО Номенклатура, Период АВТОУПОРЯДОЧИВАНИЕ
Аналогичным образом система поступает и в ситуации, когда поле-остаток используется в выражении (листинг 11.78). Листинг 11.78. Пример получения остатков и оборотов регистра накопления
ВЫБРАТЬ ТоварыНаСкладахОстаткиИОбороты.Номенклатура КАК Номенклатура, ТоварыНаСкладахОстаткиИОбороты.Период КАК Период, ТоварыНаСкладахОстаткиИОбороты.Склад, ТоварыНаСкладахОстаткиИОбороты.КоличествоКонечныйОстаток * ТоварыНаСкладахОстаткиИОбороты.Номенклатура.ЗакупочнаяЦена КАК СуммаКонечныйОстаток, ТоварыНаСкладахОстаткиИОбороты.КоличествоОборот * ТоварыНаСкладахОстаткиИОбороты.Номенклатура.ЗакупочнаяЦена КАК СуммаОборот, ТоварыНаСкладахОстаткиИОбороты.КоличествоПриход * ТоварыНаСкладахОстаткиИОбороты.Номенклатура.ЗакупочнаяЦена КАК СуммаПриход,
Профессиональная разработка в системе «1С:Предприятие 8»
Получение данных из регистров накопления ТоварыНаСкладахОстаткиИОбороты.КоличествоРасход * ТоварыНаСкладахОстаткиИОбороты.Номенклатура.ЗакупочнаяЦена КАК СуммаРасход ИЗ РегистрНакопления.ТоварыНаСкладах.ОстаткиИОбороты(&НачалоПериода, &КонецПериода, День, ДвиженияИГраницыПериода,) КАК ТоварыНаСкладахОстаткиИОбороты ИТОГИ СУММА(СуммаКонечныйОстаток), СУММА(СуммаОборот), СУММА(СуммаПриход), СУММА(СуммаРасход) ПО Номенклатура, Период АВТОУПОРЯДОЧИВАНИЕ
В этом случае будет неявно добавлено поле ТоварыНаСкладахОстат-
киИОбороты.КоличествоНачальныйОстаток * ТоварыНаСкладахОстаткиИОбороты.Номенклатура.ЗакупочнаяЦена.
Получение итогов по регистратору или номеру строки Поле Период записей, подчиненных одному регистратору, в общем случае может иметь неодинаковые значения. Поэтому для определения момента времени, начиная с которого запись влияет на рассчитываемые итоги, сначала учитывается значение поля Период записи, потом Регистратор, а потом – НомерСтроки. В результате из-за того, что регистратор, по сути, является уточнением периода, при расчете итогов по регистратору необходимо иметь в виду, что получать итоги по регистратору можно только внутри группировки Период. Если получить итоги по регистратору до получения итогов по периоду, они могут оказаться некорректными! Аналогично итоги по номеру строки можно получать только внутри группировки по периоду и регистратору.
Получение итогов остатков в комбинации с другими полями В ситуациях, когда выходные поля запроса получаются посредством выражения, содержащего начальный или конечный остаток, действия системы аналогичны. В этом случае запрос будет манипулировать значениями, вычисленными согласно описанным правилам. То есть значение поля, представленного в листинге 11.79, будет являться произведением конечного остатка и закупочной цены.
Том 1
Листинг 11.79. Поле выборки запроса
ТоварыНаСкладахОстаткиИОбороты.КоличествоКонечныйОстаток * ТоварыНаСкладахОстаткиИОбороты.Номенклатура.ЗакупочнаяЦена КАК СуммаКонечныйОстаток,
Но если в составе выражения используется более одного поля начального или конечного остатка, то итоги по таким полям получаются уже простым суммированием. Рассмотрим запрос, представленный в листинге 11.80. Листинг 11.80. Пример получения остатков и оборотов регистра накопления
ВЫБРАТЬ ТоварыНаСкладахОстаткиИОбороты.Номенклатура КАК Номенклатура, ТоварыНаСкладахОстаткиИОбороты.Период КАК Период, ТоварыНаСкладахОстаткиИОбороты.Склад, ТоварыНаСкладахОстаткиИОбороты.КоличествоНачальныйОстаток КАК КоличествоНачальныйОстаток, ТоварыНаСкладахОстаткиИОбороты.КоличествоКонечныйОстаток КАК КоличествоКонечныйОстаток, ТоварыНаСкладахОстаткиИОбороты.КоличествоКонечныйОстаток – ТоварыНаСкладахОстаткиИОбороты.КоличествоНачальныйОстаток КАК Разница ТоварыНаСкладахОстаткиИОбороты.КоличествоКонечныйОстаток * ТоварыНаСкладахОстаткиИОбороты.КоличествоНачальныйОстаток КАК Произведение ИЗ РегистрНакопления.ТоварыНаСкладах.ОстаткиИОбороты(&НачалоПериода, &КонецПериода, День, ДвиженияИГраницыПериода,) КАК ТоварыНаСкладахОстаткиИОбороты ИТОГИ СУММА(КоличествоНачальныйОстаток), СУММА(КоличествоКонечныйОстаток), СУММА(Разница), СУММА(Произведение) ПО Номенклатура, Период АВТОУПОРЯДОЧИВАНИЕ
Если установить параметры запроса так, как показано в листинге 11.81, то результат выполнения запроса будет выглядеть так, как показано в табл. 11.78. Листинг 11.81. Установка параметров запроса
Запрос.УстановитьПараметр("НачалоПериода", '20100501'); Запрос.УстановитьПараметр("КонецПериода", КонецДня('20100531'));
601
Глава 11. Учет движения средств Таблица 11.78. Результат выполнения запроса Номенклатура
Пульт PW Пульт PW Пульт PW Пульт PW Пульт PW Пульт PW Пульт PW Пульт PW Пульт PW Пульт PW Пульт PW Пульт PW Пульт VH Пульт VH Пульт VH Пульт VH Пульт VH Пульт VH Пульт VH Пульт VH Пульт VH Пульт VH
Период
01.05.2010 00:00:00 01.05.2010 00:00:00 13.05.2010 00:00:00 13.05.2010 00:00:00 17.05.2010 00:00:00 17.05.2010 00:00:00 31.05.2010 00:00:00 31.05.2010 00:00:00 31.05.2010 00:00:00 31.05.2010 00:00:00 31.05.2010 00:00:00 01.05.2010 00:00:00 01.05.2010 00:00:00 13.05.2010 00:00:00 13.05.2010 00:00:00 27.05.2010 00:00:00 27.05.2010 00:00:00 31.05.2010 00:00:00 31.05.2010 00:00:00 31.05.2010 00:00:00
Склад
Использование соединений с таблицей остатков и оборотов
Количество Количество Разница начальный конечный остаток остаток
Произведение
1 1
15 1
11 0
98 1
1
1
0
1
1
8
7
8
1
8
7
8
8
11
3
0
0
3
3
0
11
15
4
89
Главный
8
8
0
64
Розничный
3
3
0
9
Фили-2
0
4
4
0
Фили-2
4
4
0
16
10 10
11 10
1 0
211 100
10
10
0
100
10
20
10
0
0
10
10
0
20
11
-9
10
10
1
-9
10
11
11
0
101
Главный
1
1
0
1
Фили-2
10
10
0
100
Главный
Главный
Розничный
Фили-2
Главный
Главный
В случае применения конструкции ИТОГИ ПО для запросов, включающих в себя соединения виртуальной таблицы остатков и оборотов с другими таблицами (например, с основной таблицей регистра), необходимо учитывать влияние наличия всех возможных комбинаций значений полей связанных таблиц (удовлетворяющих условиям соединения) на вышеописанные алгоритмы расчета полей итогов. Иначе легко получить «удивительные» с прикладной точки зрения результаты запросов. Например, рассмотрим в листинге 11.82.
запрос,
текст
которого
представлен
Листинг 11.82. Пример получения остатков и оборотов регистра накопления
ВЫБРАТЬ ТоварыНаСкладахОстаткиИОбороты.Номенклатура КАК Номенклатура, ТоварыНаСкладахОстаткиИОбороты.КоличествоНачальныйОстаток КАК КоличествоНачальныйОстаток, ТоварыНаСкладахОстаткиИОбороты.КоличествоПриход КАК КоличествоПриход, ТоварыНаСкладахОстаткиИОбороты.КоличествоРасход КАК КоличествоРасход, ТоварыНаСкладахОстаткиИОбороты.КоличествоКонечныйОстаток КАК КоличествоКонечныйОстаток, ТоварыНаСкладах.ВидОперации КАК ВидОперации ИЗ РегистрНакопления.ТоварыНаСкладах.ОстаткиИОбороты КАК ТоварыНаСкладахОстаткиИОбороты ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.ТоварыНаСкладах КАК ТоварыНаСкладах ПО ТоварыНаСкладахОстаткиИОбороты.Номенклатура =ТоварыНаСкладах.Номенклатура ИТОГИ СУММА(КоличествоНачальныйОстаток), СУММА(КоличествоПриход), СУММА(КоличествоРасход), СУММА(КоличествоКонечныйОстаток) ПО Номенклатура, ВидОперации
В результате данные по остаткам и оборотам каждой номенклатурной позиции могут быть завышены в несколько раз или даже десятков тысяч раз в зависимости от того, сколько записей с этой номенклатурной позицией присутствует в таблице движений регистра и как они упорядочиваются по хронологии внутри вышестоящих группировок.
Применение отборов в запросах, использующих виртуальные таблицы регистров накопления Для обеспечения максимальной скорости выполнения запросов важно правильно применять условия отборов. Например, для получения остатков по отдельной номенклатурной позиции текст запроса может выглядеть так, как показано в листинге 11.83 или в листинге 11.84.
602
Профессиональная разработка в системе «1С:Предприятие 8»
Получение данных из регистров накопления Листинг 11.83. Пример использования отбора в виртуальной таблице
Листинг 11.86. Пример получения остатков регистра накопления
ВЫБРАТЬ ТоварыНаСкладахОстатки.Номенклатура КАК Номенклатура, ТоварыНаСкладахОстатки.Склад КАК Склад, ТоварыНаСкладахОстатки.КоличествоОстаток КАК КоличествоОстаток ИЗ РегистрНакопления.ТоварыНаСкладах.Остатки(&Период, Номенклатура = &НоменклатураОтбора) КАК ТоварыНаСкладахОстатки
ВЫБРАТЬ ТаблицаДокумента.Номенклатура, СУММА(ТаблицаДокумента.Количество) КАК Количество, ТоварыНаСкладахОстатки.КоличествоОстаток, СУММА(ТаблицаДокумента.Сумма) КАК Сумма ИЗ Документ.РеализацияТоваров.Состав КАК ТаблицаДокумента ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.ТоварыНаСкладах.Остатки( &Момент, Номенклатура В (ВЫБРАТЬ РАЗЛИЧНЫЕ РеализацияТоваровТовары.Номенклатура ИЗ Документ.РеализацияТоваров.Состав КАК РеализацияТоваровТовары ГДЕ РеализацияТоваровТовары.Ссылка = &ТекущийДокумент) И Склад = &Склад) КАК ТоварыНаСкладахОстатки ПО ТаблицаДокумента.Номенклатура = ТоварыНаСкладахОстатки.Номенклатура ГДЕ ТаблицаДокумента.Ссылка = &ТекущийДокумент СГРУППИРОВАТЬ ПО ТаблицаДокумента.Номенклатура, ТоварыНаСкладахОстатки.КоличествоОстаток
Листинг 11.84. Пример неэффективного запроса, использующего виртуальную таблицу остатков
ВЫБРАТЬ ТоварыНаСкладахОстатки.Номенклатура КАК Номенклатура, ТоварыНаСкладахОстатки.Склад КАК Склад, ТоварыНаСкладахОстатки.КоличествоОстаток КАК КоличествоОстаток ИЗ РегистрНакопления.ТоварыНаСкладах.Остатки(&Период, ) КАК ТоварыНаСкладахОстатки ГДЕ ТоварыНаСкладахОстатки.Номенклатура = &НоменклатураОтбора
По сравнению с первым вариантом второй является неэффективным по скорости исполнения, поскольку сначала по всем номенклатурным позициям будут проведены необходимые расчеты и получена виртуальная таблица остатков, а отбор будет использован уже после. Условия построения виртуальной таблицы могут реализовываться не только по равенству значений измерений, но и по вхождению их в массив или список значений (листинг 11.85). Листинг 11.85. Пример получения остатков регистра накопления
ВЫБРАТЬ ТоварыНаСкладахОстатки.Номенклатура КАК Номенклатура, ТоварыНаСкладахОстатки.Склад КАК Склад, ТоварыНаСкладахОстатки.КоличествоОстаток КАК КоличествоОстаток ИЗ РегистрНакопления.ТоварыНаСкладах.Остатки(&Период, Номенклатура В (&МассивНоменклатурныхПозиций) ) КАК ТоварыНаСкладахОстатки
Также может использоваться условие вхождения в таблицу результата вложенного запроса. Например, если при проведении документа РеализацияТоваров требуется получить данные о количестве товара в самом документе и в остатках регистра ТоварыНаСкладах на момент проведения документа, то для быстрого выполнения этой операции виртуальную таблицу остатков лучше строить только по тем номенклатурным позициям и тому складу, которые указаны в документе (листинг 11.86).
Том 1
Кроме того, условие построения виртуальной таблицы может быть по значениям полей, подчиненных полям измерений (листинг 11.87). Листинг 11.87. Пример получения остатков регистра накопления
ВЫБРАТЬ ТоварыНаСкладахОстатки.Номенклатура КАК Номенклатура, ТоварыНаСкладахОстатки.Склад КАК Склад, ТоварыНаСкладахОстатки.КоличествоОстаток КАК КоличествоОстаток ИЗ РегистрНакопления.ТоварыНаСкладах.Остатки(&Период, Номенклатура.ЗакупочнаяЦена > ПороговаяЦена ) КАК ТоварыНаСкладахОстатки
Однако необходимо учитывать, что подобные операции «разыменования» реализуются за счет неявных дополнительных соединений с соответствующими таблицами. В данном примере в момент построения виртуальной таблицы выполняется левое соединение с таблицей справочника. Наибольшего эффекта увеличения скорости построения виртуальных таблиц за счет применения параметра условия можно добиться в том случае, если условия накладываются на первые измерения, потом вторые и так далее. В принципе сам порядок описания условий не важен, важен порядок измерений, на которые эти условия накладываются. Тогда система сможет эффективно применять индексы при выполнении запроса.
603
Глава 11. Учет движения средств В вышеописанных примерах, если не применять условие отбора по первому измерению Номенклатура, а применить условие отбора по измерению Склад (листинг 11.88), для получения данных таблицы итогов система сможет применить индекс Период + Номенклатура + Склад, а из таблицы движений регистра данные будут взяты при помощи индекса Период + Регистратор + НомерСтроки. То есть произойдет отбор всех записей соответствующего периода из таблиц регистра. А уже просматривая эти записи, система сможет отсечь из рассмотрений записи по ненужным складам. Поскольку для регистра накопления обычной является ситуация, когда количество записей движений на порядок больше количества записей итогов, для повышения скорости построения виртуальной таблицы «бороться» прежде всего нужно с движениями по «лишним» складам. Листинг 11.88. Пример получения остатков регистра накопления
ВЫБРАТЬ ТоварыНаСкладахОстатки.Номенклатура КАК Номенклатура, ТоварыНаСкладахОстатки.Склад КАК Склад, ТоварыНаСкладахОстатки.КоличествоОстаток КАК КоличествоОстаток ИЗ РегистрНакопления.ТоварыНаСкладах.Остатки(&Период, Склад = &СкладОтбора) КАК ТоварыНаСкладахОстатки
Поэтому изначально, описывая данные регистра как объекта конфигурации, можно указать индексирование измерения Склад. Тогда система сможет использовать данные не только индекса Период + Регистратор + НомерСтроки, но и индекса Склад + Период + Регистратор + НомерСтроки. Необходимо заметить, что порядок применения или неприменения тех или иных индексных таблиц в каждом конкретном случае исполнения конкретного запроса берут на себя механизмы СУБД, отвечающие за доступ к информации. Однако оптимальный порядок следования измерений в структуре регистра и индексирование полей регистра помогают СУБД чаще принимать верные с точки зрения эффективности решения.
Когда следует использовать запрос вместо объектной модели обращения при получении данных регистров накопления В случаях простейших обращений к информации базы данных удобство и быстродействие использования табличной и объектной модели чтения одинаковы. Дело в том, что запрос, написанный на языке системы «1С:Предприятие», и использование соответствующего метода реализуются платформой посредством «перевода» этих обращений в язык запросов СУБД, зачастую совершенно (или почти) одинаковых. Исключение составляют ситуации использования механизма обращения к динамическим данным. Посредством этого механизма чтение информации осуществляется не полностью в момент обращения, а блоками.
604
подробнее
Раздел «Работа с регистрами при отображении динамических данных», стр. 605.
В данном же разделе обращается внимание на задачи, которые можно решить эффективно только посредством запросов. К ним относятся: ■■ гибкое применение отборов и группировок, ■■ соединение с информацией других объектов, ■■ применение разграничения доступа на уровне записей. В случае применения методов Остатки() и Обороты() возможно применение отборов для измерений на равенство неким значениям. Более сложные отборы необходимо реализовать с помощью установки значений параметров соответствующих виртуальных таблиц запросов. Это относится, например, к условию вхождения значений измерений в определенную группу; условию неравенства некоему значению; условию превышения некоего значения (например, если измерение имеет тип Дата); условию равенства двум значениям (логическое ИЛИ) и т. д. В случае необходимости соединения данных нескольких объектов применение запросов также является более эффективным. Например, задачу контроля остатка для каждой номенклатурной позиции при проведении документа реализации товаров можно решить как с использованием запроса, так и с использованием объектной модели. Если рассматривать запрос, использующий левое соединение (листинг 11.89), то результатом его работы будет таблица, содержащая колонки КоличествоВДокументе и КоличествоВОстаткеРегистра. Листинг 11.89. Пример получения остатков регистра накопления с помощью запроса
ВЫБРАТЬ ТаблицаДокумента.Номенклатура, СУММА(ТаблицаДокумента.Количество) КАК КоличествоВДокументе, ТоварыНаСкладахОстатки.КоличествоОстаток КАК КоличествоВОстаткеРегистра ИЗ Документ.РеализацияТоваров.Состав КАК ТаблицаДокумента ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.ТоварыНаСкладах.Остатки(, Номенклатура В (ВЫБРАТЬ РАЗЛИЧНЫЕ РеализацияТоваровТовары.Номенклатура ИЗ Документ.РеализацияТоваров.Состав КАК РеализацияТоваровТовары ГДЕ РеализацияТоваровТовары.Ссылка = &ТекущийДокумент) И Склад = &Склад) КАК ТоварыНаСкладахОстатки ПО ТаблицаДокумента.Номенклатура = ТоварыНаСкладахОстатки.Номенклатура ГДЕ ТаблицаДокумента.Ссылка = &ТекущийДокумент СГРУППИРОВАТЬ ПО ТаблицаДокумента.Номенклатура, ТоварыНаСкладахОстатки.КоличествоОстаток
Профессиональная разработка в системе «1С:Предприятие 8»
Отдельные вопросы использования регистров накопления В данном случае виртуальная таблица остатков будет построена только по нужным товарным позициям (указанным в табличной части Состав проводимого документа), далее полученный результат соединен с записями табличной части проводимого документа. В результирующей таблице будет произведена группировка на случай упоминания одних и тех же товарных позиций в документе более одного раза. Все эти операции будут выполнены в рамках одного запроса обращения к данным базы данных. При использовании объектной модели необходимо будет выгрузить табличную часть Состав документа в таблицу значений. Затем свернуть полученную таблицу значений по колонке Номенклатура (на случай неоднократного упоминания одного и того же товара в табличной части). После этого в цикле перебора строк полученной таблицы значений обращаться к данным регистра методом Остатки(), применяя отбор по значению конкретной номенклатурной позиции. Неэффективность данного подхода проявляется в многократных обращениях к таблицам регистра в базе данных. Модификация использования объектной модели чтения для решения данной задачи, когда метод Остатки() получается не в цикле перебора строк, а до него, также неэффективна, поскольку тогда для функциональности алгоритма придется получать остатки по всем (а не по нужным) номенклатурным позициям, а в цикле перебора товаров документа искать нужные строки в таблице значений остатков. Использование же в данной ситуации запроса позволяет получать данные из таблиц регистра только по нужным значениям измерений, причем в рамках одного обращения к базе данных. Также запросы позволяют использовать при необходимости один из двух режимов получения данных из полей базы данных: ■■ получение всех записей; ■■ получение только тех записей, на которые у пользователя есть права. Во втором случае в таблице результата запроса будут обработаны только те записи, что разрешены при использовании ограничений доступа на уровне записей. Неразрешенные записи будут проигнорированы. Объектная же техника обращения к информации базы данных выполняется только в режиме получения всех записей.
Отдельные вопросы использования регистров накопления
Работа с регистрами при отображении динамических данных Форма списка регистра накопления Для обеспечения динамического просмотра записей регистра в таблице формы предназначен объект ДинамическийСписок. Он осуществляет считывание данных из информационной базы блоками, в процессе навигации пользователя в таблице формы или в процессе обращения к ним из встроенного языка. Это уменьшает время загрузки списка и объем отводимой для него памяти, что позволяет комфортно работать даже с очень большими списками. Например, не возникает задержек при открытии формы (считывается только нужный блок, а не весь список) или при переходе в конец списка (система не обязана считывать все данные регистра, будет считан блок только с нужными) и т. д. С помощью динамического списка построены все формы списка объектов конфигурации. Динамический список формируется путем запроса к основной таблице, указанной в соответствующем свойстве реквизита типа ДинамическийСписок, или путем произвольного запроса к базе данных. Форма списка регистра накопления также содержит основной реквизит типа ДинамическийСписок, который использует систему компоновки данных и позволяет задать группировку, отбор, порядок и условное оформление списка путем установки соответствующих свойств. Обычно далеко не все поля динамического списка используются для отображения в форме. Особенность использования динамического списка в том, что запросом из базы данных считываются значения только тех реквизитов, которые отображаются в форме, причем даже в том случае, если соответствующие им колонки таблицы формы невидимы. То есть система не будет считывать «ненужные» данные из базы данных. Логика проста: если не нужно показывать, то не нужно и считывать, чтобы еще больше сократить время считывания. Но иногда возникают задачи, когда может оказаться необходимым, чтобы объект ДинамическийСписок содержал некоторые колонки, которые не отображаются в таблице формы. Например, при отображении данных регистра накопления ТоварыНаСкладах для некой последующей обработки нужно, чтобы значение поля ВидДвижения динамического списка было доступно для обращения из встроенного языка (например, Элементы.Список.ТекущиеДанные.ВидДвижения).
Том 1
605
Глава 11. Учет движения средств Этого можно добиться при помощи свойства полей динамического списка Использовать всегда. Установив это свойство, можно получить значения реквизитов объекта независимо от того, отображаются они в форме или нет (рис. 11.47).
Рис. 11.48. Форма настройки динамического списка
Работа с итогами при отображении динамических данных При работе с отображением динамических данных иногда возникает задача отображения итогов регистров по значениям измерений, взятых из этих динамических данных. Например, при отображении списка справочника Номенклатура необходимо отображать остатки по номенклатурным позициям в отдельной колонке списка. Рис. 11.47. Форма списка регистра накопления
Такого же эффекта можно добиться, если поместить поле динамического списка в состав колонок таблицы и сделать его невидимым.
Для решения данной задачи нужно установить свойство ПроизвольныйЗапрос для основного реквизита типа ДинамическийСписок формы списка номенклатуры, данные которого она отображает (рис. 11.49).
Настройка динамического списка может осуществляться не только в режиме Конфигуратор (палитра свойств Настройка списка – Открыть), но и пользователем в режиме 1С:Предприятие. Это можно реализовать посредством команды Все действия Настроить список… В окне настройки динамического списка можно установить группировку, отбор, сортировку и условное оформление списка. На закладке Сортировка изначально присутствует настройка сортировки динамического списка по возрастанию поля Период, так как платформа стандартно упорядочивает записи регистра накопления по этому полю (рис. 11.48). Рис. 11.49. Установка произвольного запроса для динамического списка
606
Профессиональная разработка в системе «1С:Предприятие 8»
Отдельные вопросы использования регистров накопления Затем, выполнив в строке Настройка списка команду Открыть, следует ввести текст запроса для получения остатков (листинг 11.90). Листинг 11.90. Запрос для определения остатков номенклатуры
ВЫБРАТЬ СправочникНоменклатура.Код, СправочникНоменклатура.Наименование, СправочникНоменклатура.ЗакупочнаяЦена, СправочникНоменклатура.ПолноеНаименование, ТоварыНаСкладахОстатки.КоличествоОстаток ИЗ Справочник.Номенклатура КАК СправочникНоменклатура ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.ТоварыНаСкладах.Остатки КАК ТоварыНаСкладахОстатки ПО (ТоварыНаСкладахОстатки.Номенклатура = СправочникНоменклатура.Ссылка)
В запросе при помощи левого соединения справочника Номенклатура с виртуальной таблицей остатков регистра ТоварыНаСкладах выбираются остатки по каждой позиции номенклатуры.
Если требуется выделять отрицательные остатки номенклатуры в форме списка, то можно воспользоваться свойством расширения поля формы ВыделятьОтрицательные. При установке этого свойства в значение Да отрицательные остатки номенклатуры стандартно будут выделены красным цветом текста. Но если нужно использовать более гибкое выделение строк списка по какому-либо условию, то можно установить свойство УсловноеОформление динамического списка. Поскольку основной реквизит формы списка имеет тип ДинамическийСписок, который использует систему компоновки данных, то можно настроить для него отбор, порядок, группировку и условное оформление. Например, открыв окно настройки динамического списка Список (палитра свойств Настройка списка – Открыть, см. рис. 11.49), зададим условное оформление списка так, чтобы строки номенклатуры с остатком меньше трех выделялись розовым цветом (рис. 11.51).
Таким образом, свойство ТекстЗапроса реквизита формы Список заполняется приведенным выше запросом, и при считывании данных из этого динамического списка платформа вместо автоматической генерации текста запроса к таблице справочника номенклатуры будет использовать указанный запрос. Остается только перенести поле КоличествоОстаток из доступных полей динамического списка в список колонок таблицы формы, отображающей данные этого списка (рис. 11.50).
Рис. 11.51. Условное оформление динамического списка
В результате список номенклатуры в режиме 1С:Предприятие будет выглядеть следующим образом (рис. 11.52).
Рис. 11.52. Форма списка справочника «Номенклатура»
Рис. 11.50. Форма списка справочника «Номенклатура»
Том 1
В режиме 1С:Предприятие пользователь может также выполнять настройку списка по своему желанию с помощью команды Все действия Настроить список…
607
Глава 11. Учет движения средств подробнее
Пример такого решения приведен в демонстрационной конфигурации «Хранение информации», которая находится на прилагаемом компактдиске.
Хотелось бы все же отметить, что в решении задач автоматического отображения остатков в отдельной колонке динамического списка быстродействие системы сильно зависит от сложности алгоритма расчета. Ведь, например, при прокрутке списка пользователем система вынуждена будет слишком часто обращаться к базе данных для расчета остатков появляющихся полей. Если быстродействие получается неприемлемым, тогда нужно рассматривать другие варианты отображения остатков, то есть изменять условия задачи. Например, нужно отображать остатки в отдельном поле в форме только для текущей строки таблицы при нажатии соответствующей кнопки. Как еще один вариант решения можно применять элементы механизма динамического просмотра данных, но с дополнительной функциональностью получения остатков. подробнее
Пример такого решения приведен в демонстрационной конфигурации «Хранение информации», которая находится на прилагаемом компактдиске.
В форму документа РеализацияТоваров помещена кнопка Подбор, при нажатии которой вызывается форма ФормаПодбораНоменклатуры справочника Номенклатура. Форма подбора номенклатуры включает в себя две таблицы: ДеревоНоменклатуры и ТаблицаПодбора. Таблица ДеревоНоменклатуры отображает данные динамического списка, выбирающего только группы справочника Номенклатура. При выборе пользователем группы в этой таблице в обработчике события Выбор таблица значений ТаблицаПодбора заполняется списком номенклатуры из выбранной группы и соответствующими остатками на складе, указанном в документе (рис. 11.53). Для реализации данной функциональности используется обработчик события Выбор таблицы ДеревоНоменклатуры. В процедуре сначала запросом собираются данные об остатках номенклатуры, входящей в выбранную группу, на нужном складе. Далее таблица, отображаемая нижней таблицей, сначала очищается, потом заполняется необходимой информацией, полученной выборкой из результата запроса (листинг 11.91).
608
Рис. 11.53. Форма подбора номенклатуры Листинг 11.91. Обработчик события «Выбор» таблицы «ДеревоНоменклатуры»
Процедура ДеревоНоменклатураВыбор(Элемент, ВыбраннаяСтрока, Колонка, СтандартнаяОбработка) // Выбрать товары группы с остатками. Запрос = Новый Запрос; Запрос.Текст = " |ВЫБРАТЬ | Товары.Код, | Товары.Ссылка КАК Номенклатура, | ТоварыНаСкладахОстатки.КоличествоОстаток КАК Остаток |ИЗ | Справочник.Номенклатура КАК Товары | ЛЕВОЕ СОЕДИНЕНИЕ | РегистрНакопления.ТоварыНаСкладах.Остатки( | , | Номенклатура В (ВЫБРАТЬ | Номенклатура.Ссылка | ИЗ | Справочник.Номенклатура КАК Номенклатура | ГДЕ | Номенклатура.Родитель = &Родитель) | И | Склад = &Склад) | КАК ТоварыНаСкладахОстатки | ПО Товары.Ссылка = ТоварыНаСкладахОстатки.Номенклатура |ГДЕ | Товары.Родитель = &Родитель | И (НЕ Товары.ЭтоГруппа)"; // Установить в качестве параметра выбранную группу. Запрос.УстановитьПараметр("Родитель", ВыбраннаяСтрока); Запрос.УстановитьПараметр("Склад", Склад);
Результат = Запрос.Выполнить();
Профессиональная разработка в системе «1С:Предприятие 8»
Отдельные вопросы использования регистров накопления
// Очистить таблицу подбора. НоменклатураДляПодбора.Очистить();
// Заполнить таблицу подбора. Выборка = Результат.Выбрать(); Пока Выборка.Следующий() Цикл
НоваяСтрока = НоменклатураДляПодбора.Добавить(); НоваяСтрока.Код = Выборка.Код; НоваяСтрока.Номенклатура = Выборка.Номенклатура; НоваяСтрока.Остаток = Выборка.Остаток;
КонецЦикла;
КонецПроцедуры
Теперь независимо от действий пользователя (например, использование полосы прокрутки), пока не будет перевыбрана группа в верхней таблице, никаких обращений к базе данных происходить не будет.
Рис. 11.54. Контроль наличия товара
подробнее
В данном примере намеренно не используется механизм динамического отображения данных. Однако обеспечивается достаточно комфортная работа пользователя.
Получение остатков при проведении документов При решении бизнес-задач зачастую возникают вопросы конкурентного управления ресурсами автоматизируемого предприятия. Сам учет ресурсов, как правило, ведется посредством регистров. Поэтому рассмотрим классическую задачу и пути ее решения. Пользователи оформляют и проводят документы ЗаказПокупателя. Данный документ связан с двумя регистрами: РезервыНоменклатуры и ТоварыНаСкладах. При проведении данного документа необходимо отложить товар в резерв (выполнить движения по регистру РезервыНоменклатуры), но перед этим выполнить контроль возможности проведения данной операции. Отложить товар в резерв можно только в том случае, если его хватает, то есть если достаточно свободного (не зарезервированного другими) остатка (рис. 11.54). Кроме того, контроль остатка нужно проводить не только при оперативном проведении. Иначе пользователи «понарезервируют» задним числом столько, сколько компания вовек не продаст. А если заставить все заказы проводить только оперативно, то первый, кто возразит против такого решения, – начальник отдела продаж. Зачастую выправление ситуаций коллизий остро конкурирующих заказов он разрешает, именно управляя хронологией заказов. Мол, «вон тот заказ поставим на вчера, а Иванов пусть следующей поставки ждет…». Таким образом, при реализации алгоритма проведения документа необходимо будет читать данные остатков регистров накопления. Том 1
Пример реализации данного алгоритма проведения реализован в модуле документа ЗаказПокупателя демонстрационной конфигурации «Хранение информации», которая находится на прилагаемом компактдиске.
Рассмотрим этот пример (листинг 11.92). Листинг 11.92. Обработчик события «ОбработкаПроведения»
Процедура ОбработкаПроведения(Отказ, РежимПроведения)
// Укажем, по каким регистрам нужно записывать движения. Движения.РезервыНоменклатуры.Записывать = Истина; // Создать менеджер временных таблиц. МенеджерВТ = Новый МенеджерВременныхТаблиц; Запрос = Новый Запрос; // Укажем, какой менеджер временных таблиц использует этот запрос. Запрос.МенеджерВременныхТаблиц = МенеджерВТ;
Запрос.Текст = "ВЫБРАТЬ | ЗаказПокупателяСостав.Номенклатура, | СУММА(ЗаказПокупателяСостав.Количество) КАК КоличествоВДокументе |ПОМЕСТИТЬ НоменклатураДокумента |ИЗ | Документ.ЗаказПокупателя.Состав КАК ЗаказПокупателяСостав |ГДЕ | ЗаказПокупателяСостав.Ссылка = &Ссылка | |СГРУППИРОВАТЬ ПО | ЗаказПокупателяСостав.Номенклатура"; Запрос.УстановитьПараметр("Ссылка", Ссылка);
609
Глава 11. Учет движения средств
Результат = Запрос.Выполнить();
Запрос2 = Новый Запрос; Запрос2.МенеджерВременныхТаблиц = МенеджерВТ; Запрос2.Текст = "ВЫБРАТЬ | НоменклатураДокумента.Номенклатура, | НоменклатураДокумента.КоличествоВДокументе |ИЗ | НоменклатураДокумента КАК НоменклатураДокумента"; // Установим необходимость блокировки данных в регистре РезервыНоменклатуры. Движения.РезервыНоменклатуры.БлокироватьДляИзменения = Истина; // Запишем пустые наборы записей, чтобы читать резервы без учета данных в документе. Движения.РезервыНоменклатуры.Записать(); Результат = Запрос2.Выполнить(); ВыборкаДетальныеЗаписи = Результат.Выбрать(); Пока ВыборкаДетальныеЗаписи.Следующий() Цикл // Сформировать движения по регистру РезервыНоменклатуры. Движение = Движения.РезервыНоменклатуры.Добавить(); Движение.ВидДвижения = ВидДвиженияНакопления.Приход; Движение.Период = Дата; Движение.Номенклатура = ВыборкаДетальныеЗаписи.Номенклатура; Движение.Количество =ВыборкаДетальныеЗаписи.КоличествоВДокументе; КонецЦикла; // Запишем движения. Движения.Записать(); // Контроль остатков. Запрос3 = Новый Запрос; Запрос3.МенеджерВременныхТаблиц = МенеджерВТ; Запрос3.Текст = "ВЫБРАТЬ | НоменклатураДокумента.Номенклатура, | ЕСТЬNULL(ТоварыНаСкладахОстатки.КоличествоОстаток, 0) КАК Остаток, | ЕСТЬNULL(РезервыНоменклатурыОстатки.КоличествоОстаток, 0) КАК Резерв |ИЗ | НоменклатураДокумента КАК НоменклатураДокумента | ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.ТоварыНаСкладах.Остатки( | &Момент, | Номенклатура В | (ВЫБРАТЬ | НоменклатураДокумента.Номенклатура | ИЗ | НоменклатураДокумента)) КАК ТоварыНаСкладахОстатки | ПО НоменклатураДокумента.Номенклатура = ТоварыНаСкладахОстатки.Номенклатура | ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.РезервыНоменклатуры.Остатки( | &Момент, | Номенклатура В | (ВЫБРАТЬ
610
| НоменклатураДокумента.Номенклатура | ИЗ | НоменклатураДокумента)) КАК РезервыНоменклатурыОстатки | ПО НоменклатураДокумента.Номенклатура = РезервыНоменклатурыОстатки.Номенклатура |ГДЕ | ЕСТЬNULL(ТоварыНаСкладахОстатки.КоличествоОстаток,0) | ЕСТЬNULL(РезервыНоменклатурыОстатки.КоличествоОстаток,0) < 0"; ГраницаПоДокумент = Новый Граница(МоментВремени(), ВидГраницы.Включая); Запрос3.УстановитьПараметр("Момент", ГраницаПоДокумент); РезультатСНехваткой = Запрос3.Выполнить(); ВыборкаРезультатаСНехваткой = РезультатСНехваткой.Выбрать(); Пока ВыборкаРезультатаСНехваткой.Следующий() Цикл Сообщение = Новый СообщениеПользователю(); Сообщение.Текст = "Не хватает " + Строка(– (ВыборкаРезультатаСНехваткой.Остаток – ВыборкаРезультатаСНехваткой.Резерв)) + "единиц товара""" + ВыборкаРезультатаСНехваткой.Номенклатура + "."; Сообщение.Сообщить(); Отказ = Истина;
КонецЦикла;
КонецПроцедуры
Краткий комментарий: сначала в обработчике ОбработкаПроведения указывается, что движения документа по регистру РезервыНоменклатуры должны быть записаны при проведении документа. Затем данные табличной части документа ЗаказПокупателя помещаются во временную таблицу. Эти данные посредством менеджера временных таблиц будут затем использованы в запросе для формирования движений документа и в запросе к регистрам накопления для контроля свободных (не зарезервированных) остатков товаров. Заметьте, что данные табличной части документа группируются по полю Номенклатура, чтобы суммировать поле Количество при наличии в документе нескольких строк с одинаковой номенклатурой. Затем данные регистра РезервыНоменклатуры блокируются путем установки свойства БлокироватьДляИзменения в значение Истина. Чтобы обеспечить чтение количества зарезервированных товаров без учета существующих движений документа, движения данного документа в регистре очищаются путем записи пустого набора данных. Далее выполняется запрос к временной таблице, содержащей перечень заказанных товаров, и в цикле выборки результата запроса формируются движения по регистру РезервыНоменклатуры. Затем движения документа в регистрах записываются в явном виде (Движения.Записать()). Профессиональная разработка в системе «1С:Предприятие 8»
Отдельные вопросы использования регистров накопления После этого выполняется контроль свободного (не зарезервированного) остатка товаров. Для этого выполняется запрос для получения отрицательных свободных остатков номенклатуры, содержащейся в табличной части проводимого документа. Запрос реализован левым соединением данных временной таблицы с данными виртуальных таблиц остатков из регистров ТоварыНаСкладах и РезервыНоменклатуры. Поскольку документу запрещено оперативное проведение (свойство документа Оперативное проведение установлено в значение Запретить), остатки номенклатуры нужно контролировать на момент времени документа, включая движения самого документа. Поэтому в качестве параметра Период при установке параметра запроса передается значение момента времени документа, включая движения самого документа (Новый Граница(МоментВремени(), ВидГраницы.Включая)). Заметьте, что виртуальные таблицы остатков получены с применением отбора только по тем номенклатурным позициям, которые входят в состав проводимого документа. Поскольку может быть ситуация, когда данные по неким номенклатурным позициям в регистре отсутствуют, для выходных полей запроса применена функция преобразования возможных Null значений в числовое значение 0. Это сделано для того, чтобы впоследствии выполнять арифметические действия с данными результата запроса без опасений, что те окажутся непригодными для подобных действий.
системой автоматически применяются блокировки на уровне таблиц базы данных. Соответственно, другая транзакция при проведении другого документа не сможет прочитать или изменить остатки в регистре накопления с того момента, как записаны движения, и до того момента, как начато чтение для контроля отрицательных остатков. В клиент-серверном варианте для максимального быстродействия системы при использовании ее большим числом пользователей обеспечивается параллельность работы пользователей. Это реализуется за счет применения блокировок не на уровне таблиц базы данных, а на уровне записей таблиц и диапазонов записей таблиц регистров. При этом для ускорения записи в регистр и увеличения параллельности проведения документов регистры стандартно используют режим разделения итогов. Механизм разделения итогов вводит в состав хранимой таблицы итогов специальное поле (Разделитель), позволяющее распараллелить обновление записей итогов. Таким образом, при записи движений документа блокироваться будут только записи с тем разделителем, который получила текущая транзакция. Но возможна ситуация, когда другая транзакция с другим разделителем изменит остатки по тем же измерениям регистра, что первая, и еще до того момента, как первая начнет чтение для контроля отрицательных остатков (рис. 11.55).
После этого выборка записей запроса обходится в цикле, и если есть такие записи, в которых количество резерва по товару в регистре РезервыНоменклатуры превосходит его остаток в регистре ТоварыНаСкладах, сообщение о них выводятся пользователю. В этом случае параметр Отказ процедуры обработчика события получает значение Истина, что приведет к откату транзакции записи документа с проведением.
Блокировка записей регистров Для «1С:Предприятия» стандартным является режим управляемых блокировок. Он задается свойством конфигурации Режим управления блокировкой данных, которое для новых конфигураций устанавливается в значение Управляемый. Блокировки данных в информационной базе выполняются менеджером блокировок «1С:Предприятия». Стандартный вариант проведения документа, при котором выполняется контроль остатков из регистров накопления остатков, предусматривает следующую последовательность действий: сначала выполняется запись движений документа, затем контролируются остатки. При записи движений регистра накопления пересчитываются также и его итоги, и при этом на таблицу движений и таблицу итогов регистра накопления накладываются управляемые блокировки. В файловом варианте работы системы при выполнении транзакции, в которую входит проведение документа, для считывания и записи данных Том 1
Рис. 11.55. Блокировки записей регистра накопления при проведении с использованием режима разделения итогов
В тот момент, когда первый документ начнет чтение остатков из регистра, записи итогов по одинаковым измерениям будут сложены, и в результате при проведении первого документа будут получены неверные остатки. Ведь при записи блокировалась только итоговая запись с разделителем
611
Глава 11. Учет движения средств «0» именно для того, чтобы параллельная транзакция могла записать свои итоги по тем же измерениям, но с другим разделителем. Чтобы избежать изменения итогов между моментом записи и моментом чтения остатков, еще до формирования и записи движений регистра свойство набора записей БлокироватьДляИзменения устанавливается в значение Истина. В этом случае в момент записи набора записей платформа отключит разделитель итогов в регистре. Таким образом, другая транзакция не сможет записать движения по тем же измерениям, что и текущая, до окончания проведения документа. В результате после записи движений будут получены правильные остатки из регистров.
Чтение данных регистра остатков при неоперативном проведении Помимо блокировок, хотелось бы еще обратить внимание на следующее: на какой момент нужно получать данные регистров при проведении документа. Для решения этого вопроса, прежде всего, важно определить, используется ли для ведения учета механизм оперативного проведения. Если механизм используется, то при получении информации остатков из регистров достаточно получать данные текущих итогов, что сильно повышает быстродействие этой операции. То есть можно применять виртуальные таблицы получения остатков без указания значения параметра Период.
Таблица 11.79. Таблица движений регистра накопления остатков Период
13.05.2010 15:00:01 23.05.2010 12:30:45 23.05.2010 12:30:45
Регистратор
Вид движения
ПоступлениеТоваров № 1 Приход 13.05.2010 15:00:01 РеализацияТоваров № 1 Расход 23.05.2010 12:30:45 РеализацияТоваров № 2 Расход 23.05.2010 12:30:45
Номенклатура
Количество
Пульт VX
7
Пульт VX
2
Пульт VX
10
Таблица 11.80. Данные документа «Заказ товаров» ЗаказПокупателя Номер: № 1 Дата: 23.05.2010 12:30:45
Номенклатура Пульт VX
Количество 3
В результате, если остатки регистра будут посчитаны на значение Дата, получим, что на складе 10 пультов (то есть документ ЗаказПокупателя можно провести, хотя это не так). Поэтому данные остатков нужно брать на момент времени проводимого документа (рис. 11.56).
подробнее
Подобный пример приведен в демонстрационной конфигурации «Хранение информации», которая находится на прилагаемом компакт-диске, при проведении документа РеализацияТоваров. Также этот пример описан в разделе «Использование механизма оперативного проведения» на стр. 515.
В приведенном выше алгоритме (см. листинг 11.92) реализована ситуация, когда по каким-то причинам не используется механизм оперативного проведения документа. Тогда для обеспечения корректности контрольных операций при проведении документов нужно будет получать не актуальные данные регистров остатков, а данные на момент времени документа посредством использования соответствующего значения для параметров виртуальных таблиц. Хочется подчеркнуть, что не на дату документа, а именно на момент времени, включая движения самого документа. Например, возможна такая ситуация. В таблице движений регистра остатков есть три записи (табл. 11.79). Проводится очередной документ ЗаказПокупателя № 1, в нем указана следующая информация (табл. 11.80). Поскольку оперативное проведение не используется, то дата документа вполне может иметь точно такое же значение, как и у предыдущего документа.
612
Рис. 11.56. Получение остатков на момент времени документа
Однако необходимо иметь в виду, что управлять положением документов внутри одной секунды возможности нет. То есть не факт, что новый документ (ЗаказПокупателя) займет на временной оси положение после уже введенных с той же датой документов (РеализацияТоваров). Но при получении данных на момент времени по крайней мере есть уверенность в однозначном порядке расположения документов на временной оси с точки зрения чтения информации регистров при проведении документов. Поэтому возможные коллизии в результате неоперативного проведения документов все же можно разрешать за счет перепроведения документов, в частности, с помощью последовательностей документов. Более подробно это описано в разделе «Последовательности документов» на стр. 533. Профессиональная разработка в системе «1С:Предприятие 8»
Диаграмма взаимодействия объектов
Глава 12. Бухгалтерский учет Эта глава нашей книги посвящена задачам бухгалтерского учета и возможностям системы «1С:Предприятие» для их решения. Говорят, что правильно поставленная задача – наполовину решенная задача. Мы считаем, что это утверждение недалеко от истины, но уделить достаточное внимание вопросам теории бухгалтерского учета не позволяет формат нашей книги. Тем не менее, мы будем стараться, где это возможно, разъяснять основные понятия и методы предметной области, задачи которой будем решать. Все примеры, рассмотренные в этой главе, содержатся в демонстрационной конфигурации «Бухгалтерский учет», которая находится на прилагаемом компакт-диске. Основная задача любой учетной системы – управление и контроль работы объектов учета. Задача бухгалтерского учета – учет операций хозяйственной деятельности всего предприятия в целом. Цель учета – контроль финансово-хозяйственной деятельности и управление всем предприятием посредством замкнутой системы показателей. Далее при рассмотрении внутреннего устройства регистра бухгалтерии (основного объекта, предназначенного для реализации задач бухгалтерского учета) мы будем проводить сравнение с другим объектом – регистром накопления. Эти объекты весьма похожи, но предназначены и оптимизированы для решения разных задач. Поэтому умение выделить задачи бухгалтерского учета и задачи оперативного учета позволит значительно оптимизировать работу конфигурации.
Диаграмма взаимодействия объектов Схему взаимодействия объектов системы «1С:Предприятие» при реализации задачи бухгалтерского учета можно представить следующим образом (рис. 12.1). Рассмотрим объекты, участвующие в схеме, и начнем это делать с плана счетов. Бухгалтерский учет ведется на счетах, каждый из которых предназначен для группировки однородных хозяйственных операций. Все счета, используемые для ведения учета на предприятии, объединяются в план счетов. Счета – это основной разрез учета. Все остальные разрезы (аналитический учет, измерения) являются вспомогательными и необязательными.
Том 1
Рис. 12.1. Схема взаимодействия объектов
613
Глава 12. Бухгалтерский учет Для хранения бухгалтерских проводок по счетам используется объект конфигурации Регистр бухгалтерии. Самый простой регистр бухгалтерии, предназначенный для ведения бухгалтерского синтетического учета, может содержать всего один ресурс (для учета средств в валюте учета, в которой будет составляться вся отчетность и формироваться баланс) и более ничего. Такой регистр бухгалтерии позволит анализировать остатки и обороты по счетам, а также и обороты между счетами. Для получения оборотов между счетами регистр должен поддерживать схему учета с поддержкой корреспонденций, при которой каждая запись обязательно включает два счета: дебетуемый и кредитуемый. Дополнительными разрезами при ведении учета являются аналитические разрезы (аналитический учет) и измерения регистра бухгалтерии (с помощью которых возможно реализовать многовалютный учет, консолидированный учет и другие). Аналитический учет описывается в системе «1С:Предприятие» с помощью понятий Вид субконто и Субконто. Под видом субконто подразумевается группа однородных объектов аналитического учета (список контрагентов, номенклатуры, статей и др.). Субконто – это один конкретный объект из этого множества (объект аналитического учета, например: контрагент, карточка товара, статья затрат и др.). Для реализации аналитического учета используется «связка» объектов План видов характеристик, План счетов, Регистр бухгалтерии. План видов характеристик, использующийся для ведения аналитического учета на выбранном плане счетов, выбирается в соответствующем свойстве плана счетов. Виды характеристик «привязываются» к счетам плана счетов, требующим ведения аналитического учета. Результат этих действий – изменяющиеся таблицы регистра бухгалтерии, которые позволят хранить остатки и обороты не только по счетам, но и по счетам в разрезе субконто. Чтобы понять, как используется план видов характеристик, можно разделить название этого объекта на две части – «план» и «видов характеристик». Получаются два уровня вложенности: план, представляющий собой совокупность видов субконто, и вид субконто. Каждый вид субконто хранит информацию о типе характеристик, являющихся объектами аналитического учета, т. е. субконто. Характеристика – это один экземпляр вида характеристик, так же как субконто – это один экземпляр вида субконто. Характеристика не является самостоятельным объектом конфигурации. Для ведения аналитического учета, как правило, используются элементы справочников, значения перечисления, ссылки на документы. Виды характеристик, как правило, имеют ссылочный тип данных (хотя возможны и другие варианты). Решение задач консолидированного, многовалютного учета, единого для всех счетов аналитического учета, и некоторых других осуществляется с использованием измерений регистра бухгалтерии, которые так же, как правило, принимают значения ссылочных типов данных.
614
Каждая запись (проводка) регистра бухгалтерии подчинена какому-то регистратору (документу) и, как правило, им же создана. При проектировании реквизитного состава документов, которые должны формировать записи в регистре бухгалтерии, как правило, используются ссылочные типы данных. Документ при проектировании задачи бухгалтерского учета – это, прежде всего, средство формирования движений в регистре бухгалтерии. А движения эти, как уже было сказано выше, содержат субконто и измерения, которые и заполняются обычно значениями реквизитов документа. Каждый документ имеет свойство Движения, представляющее собой коллекцию наборов записей тех регистров, регистратором для которых он является. Схема проведения документа по регистрам унифицирована для всех регистров – регистры сведений, накопления, расчетов, бухгалтерии. Она включает запись выбранных при проведении, измененных вручную с помощью набора записей «ручной операции» или другим способом наборов записей в регистр при записи документа интерактивно или программно. Регистр бухгалтерии с точки зрения традиционной (бумажной) бухгалтерии можно рассматривать как собрание форм бухгалтерского учета, включающее в себя как формы для хронологической (проводки), так и для систематической (итоги по счетам, по субконто, обороты между счетами) записи. Кроме записи и хранения бухгалтерских проводок и итогов по счетам, регистр бухгалтерии предоставляет ряд методов и таблиц для выполнения запросов. И те и другие предназначены для удобного и оптимального получения остатков и оборотов по счетам и аналитикам. Так как основным методом извлечения данных в системе является запрос, то именно таблицы (в первую очередь виртуальные) используются в большинстве случаев для построения бухгалтерской отчетности, являющейся главным результатом бухгалтерского учета.
План счетов и его основные свойства План счетов – центральное место любой конфигурации для ведения бухгалтерского учета. Бухгалтерский учет ведется на счетах. Все счета, входящие в один баланс, объединяются в один план счетов. По свой сути план счетов – это справочник счетов. Рассмотрим пример несложного бухгалтерского учета на небольшом предприятии. Каждое предприятие обладает каким-то имуществом (активами) и обязательствами (пассивами). Пусть у нашего предприятия будут активы: ■■ наличные деньги в кассе; ■■ деньги, которые нам должны наши покупатели за поставленные им товары; ■■ сами товары, которые мы приготовили для продажи; ■■ прочие материальные ценности для собственных нужд. Профессиональная разработка в системе «1С:Предприятие 8»
План счетов и его основные свойства Все эти активы взялись «не откуда-то», а были получены нашим предприятием или от инвестора (хозяина, владельца, которому принадлежит наше предприятие), или от сторонних по отношению к предприятию организаций и физических лиц (например, поставщиков). Таким образом, пассивы нашего предприятия складываются из обязательств перед хозяином, сторонними контрагентами и собственными сотрудниками, которые работают на нашем предприятии. Итак, наши пассивы:
Закладка Основные позволяет назначить имя, синоним и комментарий для плана счетов, а также представление объекта, представление списка и пояснение для представления плана счетов в интерфейсе «1С:Предприятия» (рис. 12.2).
■■ задолженность перед сотрудниками, ■■ задолженность перед поставщиками, ■■ задолженность перед владельцем. Таким образом, мы имеем два ряда счетов, которые обусловлены балансом нашего предприятия1. Так как активы не могли взяться из «ниоткуда» и не могут исчезнуть в «никуда», то сумма всех активов в денежном выражении будет равна сумме всех обязательств в том же денежном выражении. В нашем учете нас интересуют и остатки, и обороты по каждому виду активов и обязательств. Поэтому для каждого из них мы заведем отдельный счет в плане счетов. По свой сути каждый счет – это один (или несколько) учетный регистр (форм). От количества и назначения счетов будет зависеть весь учетный процесс, поэтому перепроектирование плана счетов почти всегда связано с существенными изменениями конфигурации. Группировка этих счетов, их порядок в плане счетов во многом зависят от традиций, стандартов и просто предпочтений бухгалтера. Если речь идет о регламентированном учете, то эти свойства плана счетов описываются в законе и стандартах. В нашем случае мы создадим план счетов сами, и он будет включать следующие счета (табл. 12.1). Таблица 12.1. Состав плана счетов Код Имя
Назначение
1 1.1 1.2 1.3 1.4 1.5 2 2.1 2.2 3
Группа счетов, объединяет все активы нашего предприятия Наличные деньги Деньги, которые нам должны наши покупатели за поставленные им товары Товары, которые мы приготовили для продажи Прочие материальные ценности для собственных нужд Взаиморасчеты с контрагентами Объединяет все обязательства перед контрагентами и сотрудниками Задолженность перед сотрудниками Задолженность перед поставщиками Задолженность перед владельцем
1
Активы Касса Покупатели Товары Материалы Контрагенты Обязательства Сотрудники Поставщики Капитал
План счетов – объект конфигурации, который позволяет описать состав счетов, используемый для ведения учета на предприятии, и их свойства. Рассмотрим план счетов для ведения нашего бухгалтерского учета.
Том 1
Рис. 12.2. Основные свойства плана счетов
Следует заметить, что в одной конфигурации может быть несколько планов счетов. Для целей регламентированного учета это не требуется, но встречаются задачи управленческого учета, требующие ведения учета по разным стандартам или ведения не только бухгалтерского учета, который фиксирует свершившиеся факты, но и бюджетного учета, который учитывает планируемые операции. Закладка Данные (рис. 12.3), кроме таких свойств, как Реквизиты и Табличные части, назначение которых – хранение дополнительной информации о счете, содержит следующие свойства (табл. 12.2). Таблица 12.2. Свойства плана счетов Свойство Длина кода Длина наименования Маска кода Автопорядок по коду Длина порядка Основное представление Признаки учета
Назначение
Максимальная длина кода счета, включая все его субсчета и знаки, используемые для отделения счета и субсчета Максимальная длина наименования счета Свойство позволяет задать правила использования символов (цифровой, буквенно-цифровой код и т. д.) и иерархичность кода счета Это свойство будет рассмотрено подробно ниже Максимальная длина дополнительного индексируемого поля, значение которого используется для сортировки счетов в форме списка плана счетов и запросах Выбор основного представления счета в полях ввода документов, отчетов и др. Обычно счет принято отображать в виде кода, но в методических целях будем использовать наименование Дополнительное свойство счета, позволяющее определить необходимость ведения на выбранном счете дополнительного вида учета (например, валютного или количественного)
615
Глава 12. Бухгалтерский учет
Рис. 12.3. Данные плана счетов
Закладка Нумерация позволяет определить правила нумерации счетов в плане счетов и мало отличается от подобных закладок других объектов (рис. 12.4). Рис. 12.5. Субконто плана счетов
Здесь устанавливается, какой из планов видов характеристик будет использоваться для хранения списка видов субконто (свойство Виды субконто), максимально возможное количество параллельных (независимых) видов субконто на любом счете плана счетов. Здесь же создаются дополнительные свойства субконто на счете – Признаки учета субконто, которые позволяют управлять необходимостью ведения того или иного вида учета для одного из видов субконто выбранного счета.
Рис. 12.4. Нумерация плана счетов
Закладка Субконто предназначена для описания общих правил ведения аналитического учета плана счетов (рис. 12.5).
616
Закладка Формы кроме настройки форм позволяет настроить способы выбора счета в диалогах в поле выбора. Здесь же указывается, по каким полям будет осуществляться ввод по строке в диалогах выбора (при наборе с клавиатуры кода счета или его наименования система будет осуществлять поиск счета в плане счетов), рис. 12.6. Закладка Прочее – последняя по порядку, но не по значимости. Кроме ввода справочной информации предназначена для изменения модуля объекта, модуля менеджера объекта, списка предопределенных счетов, справочной информации о плане счетов и т. п. (рис. 12.7).
Профессиональная разработка в системе «1С:Предприятие 8»
План счетов и его основные свойства
Коды счетов Использование кодов плана счетов во многом определяется стандартами, в соответствии с которыми ведется бухгалтерский учет. Это может быть «Закон о бухгалтерском учете» (если решается задача регламентированного учета), GAAP или другие зарубежные стандарты (при решении задачи получения бухгалтерской отчетности в соответствии с МСФО), внутренние стандарты предприятия (если необходимо ведение управленческого учета). Кроме кода, который в понимании бухгалтера «…и есть счет», необходимы и другие свойства. Эти свойства и состав счетов плана счетов позволяют определить в системе объект конфигурации План счетов.
Рис. 12.6. Формы плана счетов
Код счета предназначен для идентификации счета пользователем и, как правило, используется как основное представление объекта. Именно код счета обычно вводит пользователь при заполнении бухгалтерской проводки, код счета выводится в качестве измерений (строк и колонок) бухгалтерских отчетов. Свойство Длина кода позволяет задать максимальную длину кода, которой будет ограничено описание кодов для счетов выбранного плана счетов. При описании максимальной длины кода счета необходимо учитывать возможную иерархичность плана счетов. Для счетов одного плана счетов можно установить (и обычно устанавливается) контроль уникальности кода, который может контролировать серии кодов или во всем справочнике, или в пределах подчинения владельцу. Основное отличие от справочника здесь заключается в том, что код счета включает в себя коды всех его родителей. Поэтому при установке уникальности в пределах подчинения владельцу мы можем добавить к счету с кодом 02 субсчет с кодом 01.1, ведь там такого еще нет. Свойство Наименование счета и его длина не требуют, с нашей точки зрения, отдельного описания, т. к. свойство не отличается по своему назначению от аналогичного свойства объектов Справочник и План видов характеристик. Так же как и в перечисленных объектах, это свойство предназначено для хранения вводимого пользователем наименования элемента плана счетов (счета).
Рис. 12.7. Прочие свойства плана счетов
А теперь рассмотрим подробнее основные из перечисленных свойств счетов и их использование при решении задач бухгалтерского учета.
Том 1
Свойство Маска кода заслуживает отдельного и более подробного описания. Это свойство предназначено для ограничения использования символов в коде счета и задания иерархической структуры плана счетов. Система позволяет описывать как линейные, так и иерархические планы счетов. Каждый план счетов может включать неограниченное число счетов первого уровня, неограниченное число субсчетов к каждому счету первого уровня и т. д. Первая задача – ограничение использования символов – решается с помощью использования при заполнении маски кода счета символов, описание которых можно найти в документации, например, в описании метода Маска().
617
Глава 12. Бухгалтерский учет В строке маски допустимо использование следующих специальных символов: ■■ ! – любой введенный символ преобразуется в верхний регистр; ■■ 9 – допустимо ввести произвольный символ цифры; ■■ # – допустимо ввести произвольный символ цифры, или - (знак минус), или + (знак плюс), или пробел; ■■ N – допустимо ввести любые алфавитно-цифровые символы (буквы или цифры); ■■ U – допустимо ввести любые алфавитно-цифровые символы (буквы или цифры), и любой введенный символ преобразуется в верхний регистр; ■■ X (латинского алфавита) – допустимо ввести произвольный символ; ■■ @ – допустимо ввести любые алфавитно-цифровые символы (буквы или цифры) в верхнем регистре или пробел; ■■ и других. Таким образом, если мы зададим маску кода счета ##, в план счетов можно будет вводить счета с кодами, состоящими только из цифр, знаков минуса, плюса и пробела. Кроме того, максимальный код счета становится равным 99 (счет с кодом 100 содержит уже три символа, что не разрешается выбранной маской). Вторая задача – задание иерархической структуры плана счетов (или, точнее, кодов счетов, потому что иерархия кодов и иерархия счетов может отличаться, и об этом пойдет речь ниже) – решается за счет использования символов-разделителей в составе маски кода счета. Разделителем может выступать любой символ, не перечисленный в описании специальных символов маски. Для отделения счета верхнего уровня от субсчета, как правило, используется «.» (символ точка). Таким образом, если мы считаем, что нам будет достаточно плана счетов с двумя уровнями вложенности (счет – субсчет), нам будет достаточно задать маску кода счета ##.##, что соответствует длине кода счета, которую мы выбрали ранее (5 символов: два знака – счет, два знака – субсчет, точка-разделитель между ними). Отдельно следует остановиться на использовании символа @ в описании маски кода счета. Использование этого специального символа не только позволяет вводить любые алфавитно-цифровые символы (буквы или цифры) в верхнем регистре или пробел, как уже было отмечено выше, но и влияет на хранение кода в базе и отображение его в диалогах ввода. При использовании символа @ в маске кода счета группа знаков кода, для которой использованы символы @, при сохранении кода в базу данных упаковывается – из него вырезаются пробелы. Рассмотрим на примере нашего плана счетов, для которого мы установили в свойствах маску кода счета @@.@@, соответствующую максимальной длине кода счета. Проиллюстрируем работу маски, содержащей символы @, на примере ввода счета с кодом 1 .1 (единица, пробел, точка, единица), табл. 12.3, 12.4.
618
Таблица 12.3. Маска кода с использованием символа @ Номера символов 1
2
3
4
5
Маска Вводится Хранится Символов
@ пробел .
. . 1
@ 1 нет
@ пробел нет
@ 1 1 3
Таблица 12.4. Маска кода без использования символа @ (используется #) Номера символов 1
2
3
4
5
Маска Вводится Хранится Символов
# пробел пробел
. . .
# 1 1
# пробел пробел
# 1 1 5
Таким образом, вводится код 1 .1 (единица, пробел, точка, единица), а в базе данных сохраняется 1.1. При редактировании счета в плане счетов код счета распаковывается до вида, подходящего под маску. При записи опять упаковывается. При работе пользователя с диалогами форм, содержащими ссылки на счет плана счетов, ввод по подстроке осуществляется по «упакованному» коду. В нашем случае пользователь должен будет набрать с клавиатуры 1.1 (без пробелов, т. е. не дополняя код до вида маски).
Упорядочивание счетов в плане счетов План счетов, как и объекты Справочник и План видов характеристик, стандартно сортируется в формах списка и упорядочивается (автоупорядочивание) в запросах по основному представлению. Но, во-первых, есть вероятность, что основным представлением будет выбрано наименование (в целях управленческого учета это возможно), а упорядочить необходимо по коду. А, во-вторых, код, особенно при использовании в маске кода счета символов @, позволяющих упаковывать код счета, может не подходить для сортировки. Рассмотрим это на примере первой группы счетов плана счетов, который мы начали делать. Пользователь ввел счета со следующими кодами (табл. 12.5). Таблица 12.5. Счета, введенные пользователем Коды по порядку их ввода (как должно быть)
1.1 1.2 1.3 1.N 1.10 1.11
Счета, отсортированные по коду
1.1 1.10 1.11 1.2 1.3 1.N
Профессиональная разработка в системе «1С:Предприятие 8»
План счетов и его основные свойства Возможное решение проблемы неверной сортировки счетов – использование лидирующих нулей или пробелов при кодировании счетов в плане счетов (табл. 12.6). Таблица 12.6. Использование лидирующих нулей в коде счета Коды по порядку их ввода (как должно быть)
Счета, отсортированные по коду
01.01 01.02 01.03 01.0N 01.10 01.11
01.01 01.02 01.03 01.0N 01.10 01.11
Альтернативный вариант решения проблемы сортировки – воспользоваться свойством счета Порядок. Это поле с автоматическим индексированием, предназначенное для хранения значения, по которому будет выполняться упорядочивание счетов в форме списка и результатах запроса. В отличие от кода, который для хранения в базе данных может упаковываться, порядок хранится в базе в неизменном виде. Порядок становится доступным для использования, если его длина больше нуля. При этом платформа не разрешит записать в базу данных счет с пустым порядком. Зададим длину порядка в нашем плане счетов (5 символов), порядок зададим произвольный (рис. 12.8).
Листинг 12.1. Пример автоматического формирования порядка счета
Процедура ПередЗаписью(Отказ)
Порядок = ПолучитьПорядокКода();
КонецПроцедуры
Метод ПолучитьПорядокКода() развернет упакованный код и дополнит его «лидирующими пробелами», что позволит упорядочить план счетов правильно, без использования в коде счета лидирующих нулей (табл. 12.7). Таблица 12.7. Пример использования метода «ПолучитьПорядокКода()» Номера символов
1
2
3
4
5
Вводим код счета Маска кода счета Хранится в базе данных ПолучитьПорядокКода()
1 @ 1 пробел
пробел @ . 1
. . 1 .
1 @ нет пробел
пробел @ Нет 1
После выполнения записи всех счетов в пользовательском режиме и установки сортировки по полю Порядок план счетов приобретет следующий вид (рис. 12.9).
Рис. 12.9. Сравнение сортировки по порядку и по коду Рис. 12.8. Сравнение сортировки по коду и по порядку
На картинке видно, что при сортировке по полю Порядок счет Капитал с кодом 3 занял первое место (порядок 01), а счет Активы переместился вниз. Если в маске кода счета используются только символы @ и символыразделители, то для счетов, вводимых в пользовательском режиме, поле Порядок можно сформировать автоматически. Для этого в модуле формы счета или в модуле объекта (закладка Прочее, кнопка Модуль объекта) необходимо разместить процедуру – обработчик события (листинг 12.1).
Том 1
Мы видим, что при сортировке по полю Порядок введенный пользователем счет Новый счет с кодом 1.11 занял свое «законное» место – последним в группе Активы. Тем не менее, остается возможность отсортировать план счетов по коду. Кроме того, при вводе предопределенного счета поле Порядок автоматически не заполняется. Для автоматического заполнения поля Порядок кодом, дополненным лидирующими пробелами при вводе предопределенного счета, и для подмены сортировки по коду сортировкой по порядку используется свойство счета Автопорядок по коду. После его установки, во-первых, при вводе предопределенного счета в момент перехода с поля Код (Tab или Enter) при незаполненном порядке счета поле Порядок будет заполняться по описанным выше правилам (как при использовании
619
Глава 12. Бухгалтерский учет метода ПолучитьПорядокКода()). А во-вторых, в формах списка и запросах при указании сортировки по полю Код сортировка будет выполняться не по полю Код, а по полю Порядок, т. е. получить порядок кодов будет невозможно (рис. 12.10).
«Бесконечная иерархичность» плана счетов обеспечивается благодаря свойству Родитель счета. Это свойство может заполняться и для предопределенных счетов, и для счетов, вводимых пользователем. Это свойство содержит ссылку на родительский счет. Рассмотрим свойство Иерархичность на схеме (рис. 12.11).
Рис. 12.10. Сравнение сортировки по коду и по порядку
Две приведенные картинки отличаются между собой колонкой, по которой выполняется сортировка. Левый список отсортирован по полю Код, правый – по полю Порядок, но сортировка на обоих выполняется по полю Порядок. Это можно увидеть по положению счета 1.11, который ранее, при сортировке по полю Код, всегда занимал место после счета с кодом 1.1. Подобная же сортировка (по полю Порядок) будет выполняться и в запросах при указании в предложении УПОРЯДОЧИТЬ ПО в качестве поля сортировки Код (листинг 12.2). Листинг 12.2. Сортировка по полю «Код» в тексте запроса
УПОРЯДОЧИТЬ ПО Код
Иерархичность плана счетов Как уже было замечено выше, объект План счетов позволяет создавать иерархические планы счетов. Наш план счетов имеет два уровня вложенности – счета первого уровня Активы, Обязательства и Капитал и несколько субсчетов к счетам Активы и Обязательства. Платформа позволяет создавать неограниченное число счетов и уровней вложенности. Это свойство плана счетов позволяет детализировать учет, однако детализация эта будет иерархической и не позволит организовать фасетное (параллельное) деление итогов. Например, не удастся организовать учет товаров на складах с возможностью автоматического получения итогов по складу, по товару и по товару на складе. Т. е. иерархическая организация плана счетов не может в полной степени обеспечить ведение аналитического учета. Для ведения аналитического учета предназначены понятия Вид субконто и Субконто, о которых пойдет речь в разделе «Основы организации аналитического учета» на стр. 624.
620
Рис. 12.11. Иерархичность плана счетов
При необходимости иерархичность плана счетов всегда можно изменить, например, разделив счет Касса на два субсчета – Рублевая касса и Валютная касса. При такой иерархичности счета первого уровня (в нашем случае Активы, Обязательства и Капитал), имеющие субсчета, не теряют возможности участвовать в проводках и выполнять те же функции, что и счета конечного уровня. И, кроме того, они позволяют сгруппировать данные в отчетах, суммируя итоги со своих субсчетов. План счетов напоминает справочник, у которого установлено свойство Иерархия элементов.
Ввод проводок и формирование отчетов по счетам, содержащим подчиненные Подобная организация плана счетов позволяет перепроектировать подчинение счетов в плане счетов в процессе работы с программой. Счет, предназначенный изначально для ведения по нему учета, однажды может стать группой счетов, объединяющей в себе субсчета более низкого уровня. Рассмотрим пример на нашем плане счетов. Предположим, что до какого-то момента счета Активы и Обязательства не имели субсчетов и участвовали в проводках (рис. 12.12). Профессиональная разработка в системе «1С:Предприятие 8»
План счетов и его основные свойства в информационной базе присутствуют проводки по счетам, имеющим субсчета. Все проводки, сделанные по счету, имеющему субсчета, группируются системой и отображаются в отчете по «служебному» субсчету. При написании запросов к регистру бухгалтерии можно получить данные только по проводкам счета, имеющего субсчета (листинг 12.3). Листинг 12.3. Условие для получения данных по счету
Счет = &Счет Рис. 12.12. Документ «Операция»
Далее было принято решение разбить счета Активы и Обязательства на субсчета и не использовать их в проводках в дальнейшем. Запрет использования в проводках можно реализовать, добавив в план счетов реквизит, принимающий два значения: разрешить или запретить использовать в проводах, и проверяя его значение при выборе счета в диалоге формы документа. Итак, решение было принято, были созданы субсчета, и все дальнейшие проводки вводились пользователем по субсчетам. На рис. 12.13 приведен фрагмент отчета, который показывает состояние остатков и оборотов по счетам после того, как в базу были введены и проводки по счетам Активы и Обязательства, и проводки по их субсчетам.
В приведенном примере &Счет – это параметр типа ПланСчетовСсылка.<имя>, содержащий ссылку на счет, имеющий субсчета. Если необходимо получить в отчете данные по счету и всем его субсчетам, условие будет выглядеть иначе (листинг 12.4). При этом в итоги попадут и проводки по самому счету-группе. Листинг 12.4. Условие для получения данных по счету и всем субсчетам
Счет В ИЕРАРХИИ(&Счет)
Однако приведенный пример не является руководством к действию. Если у счета есть подчиненные субсчета, то в проводках, как правило, участвуют они. А сам счет-группа предназначен для сбора итогов по всем своим субсчетам. Приведенный пример лишь демонстрирует следующее: ■■ система корректно отрабатывает ситуации, когда существуют движения и по счету, и по подчиненным ему субсчетам; ■■ всегда существует возможность «разбить» счет на субсчета даже на этапе промышленной эксплуатации системы без необходимости вносить изменения в проводки в закрытом отчетном периоде.
Свойства счета-родителя и подчиненных ему счетов
Рис. 12.13. Отчет «Оборотно-сальдовая ведомость»
Мы видим, что в группах счетов Активы и Обязательства появились остатки и обороты по одноименным субсчетам. Подобных субсчетов нет в плане счетов. Так платформа интерпретирует в отчетах ситуацию, когда Том 1
Продолжая рассматривать иерархическую организацию плана счетов, обратим внимание на такую особенность, как возможные отличия свойств счета-родителя и подчиненных ему субсчетов. Это свойство плана счетов позволяет создать у активного счета пассивные субсчета, или использовать на счете и его субсчетах различную аналитику, или задавать коды субсчетов без учета кода счета родителя. Как можно использовать, например, различную аналитику на счете и его субсчетах? Это может иметь смысл, только если ранее использовавшийся счет был разбит на субсчета и на них потребовалась другая аналитика, или если один из субсчетов выбивается из общего правила (все субсчета имеют одну детализацию и счет-родитель ее же, а один субсчет – другую).
621
Глава 12. Бухгалтерский учет Может ли на практике счет-родитель быть активным, а его субсчета активными и пассивными? Может! Например, счет Внеоборотные активы будет, несомненно, активным (ведь это же активы!), а среди его субсчетов могут быть и активные (Первоначальная стоимость), и пассивные (Накопленная амортизация). Схожей особенностью обладает и код счета. Каждый счет в плане счетов нумеруется в соответствии с маской кода счета и включает в себя коды «предполагаемых» родителей. Подчеркнем слово «предполагаемых». Если уникальность кода не используется, то для счета возможна смена родителя. Таким образом, счет с кодом 1.1, говорящим нам, что он располагается внутри группы счетов с кодом 1, на самом деле может оказаться в группе 3 или любой другой по усмотрению пользователя (рис. 12.14).
Рис. 12.15. Отчет «Карточка счета» Листинг 12.5. Фрагмент отчета «Карточка счета» Рис. 12.14. Счет «Касса»
В результате иерархичность счетов и иерархичность кодов счетов могут отличаться, что необходимо учитывать при написании кода, как в объектной модели, так и при написании запросов. Рассмотрим возможные ошибки на примере. Задача – сделать отчет Карточка счета, который позволит пользователю получить отбор всех проводок по одному счету. Воспользуемся в качестве источника данных для этого отчета виртуальной таблицей регистра бухгалтерии ДвиженияССубконто. Таблица, которая должна получиться в результате выполнения отчета, показывает все проводки по счету (или группе счетов). Отбор осуществляется по счету (или группе счетов), выбранному в диалоге пользователем. Если выбранный пользователем счет участвует в проводке по дебету, сумму проводки необходимо отобразить в колонке СуммаДт; если по кредиту – СуммаКт (рис. 12.15). При построении отчета по группе счетов можно разными способами проверить, принадлежит ли выбранной группе дебетуемый или кредитуемый счет проводки. Первый вариант кода (листинг 12.5) выполняет проверку при обработке результатов запроса.
622
Запрос = Новый Запрос; Запрос.Текст = "ВЫБРАТЬ | ДвиженияССубконто.Период КАК Период, | ДвиженияССубконто.Регистратор, | ПРЕДСТАВЛЕНИЕ(ДвиженияССубконто.Регистратор), | ДвиженияССубконто.СчетДт, | ДвиженияССубконто.СчетКт, | ДвиженияССубконто.Сумма |ИЗ | РегистрБухгалтерии.ОсновнойРегистрБухгалтерии.ДвиженияССубконто(&НачПериода, | &КонПериода, Счет В ИЕРАРХИИ (&Счет)) | КАК ДвиженияССубконто | |УПОРЯДОЧИТЬ ПО Период"; Запрос.УстановитьПараметр("КонПериода", КонПериода); Запрос.УстановитьПараметр("НачПериода", НачПериода); Запрос.УстановитьПараметр("Счет", Счет); Результат = Запрос.Выполнить(); КодКоррСчета = Счет.Код; ОборотДт = 0; ОборотКт = 0; ВыборкаДетали = Результат.Выбрать();
Профессиональная разработка в системе «1С:Предприятие 8»
План счетов и его основные свойства Пока ВыборкаДетали.Следующий() Цикл Если Найти(ВыборкаДетали.СчетДт.Код, КодКоррСчета) > 0 Тогда ОбластьДетальныхЗаписей.Параметры.СуммаДт = ВыборкаДетали.Сумма; ОборотДт = ОборотДт + ВыборкаДетали.Сумма; КонецЕсли; Если Найти(ВыборкаДетали.СчетКт.Код, КодКоррСчета) > 0 Тогда ОбластьДетальныхЗаписей.Параметры.СуммаКт = ВыборкаДетали.Сумма; ОборотКт = ОборотКт + ВыборкаДетали.Сумма; КонецЕсли; КонецЦикла;
Этот вариант проверяет вхождение кода счета дебета или кода счета кредита (метод Найти()) в код счета, выбранного в диалоге. Не учитывается возможность несовпадения иерархии кодов и иерархии счетов. В случае несовпадения иерархии кодов и счетов отчет будет сформирован неверно. Второй вариант (листинг 12.6) выполняет сравнение в запросе, его и рекомендуется использовать. Листинг 12.6. Фрагмент отчета «Карточка счета»
Запрос = Новый Запрос; Запрос.Текст = "ВЫБРАТЬ | ДвиженияССубконто.Период КАК Период, | ДвиженияССубконто.Регистратор, | ПРЕДСТАВЛЕНИЕ(ДвиженияССубконто.Регистратор), | ВЫБОР | КОГДА ДвиженияССубконто.СчетДт В ИЕРАРХИИ (&Счет) | ТОГДА ДвиженияССубконто.Сумма | ИНАЧЕ 0 | КОНЕЦ КАК СуммаДт, | ВЫБОР | КОГДА ДвиженияССубконто.СчетКт В ИЕРАРХИИ (&Счет) | ТОГДА ДвиженияССубконто.Сумма | ИНАЧЕ 0 | КОНЕЦ КАК СуммаКт |ИЗ | РегистрБухгалтерии.ОсновнойРегистрБухгалтерии.ДвиженияССубконто(&НачПериода, | &КонПериода, Счет В ИЕРАРХИИ (&Счет)) | КАК ДвиженияССубконто | |УПОРЯДОЧИТЬ ПО | Период |ИТОГИ | СУММА(СуммаДт), | СУММА(СуммаКт) |ПО | ОБЩИЕ"; Запрос.УстановитьПараметр("КонПериода", КонПериода); Запрос.УстановитьПараметр("НачПериода", НачПериода); Запрос.УстановитьПараметр("Счет", Счет); Результат = Запрос.Выполнить();
Том 1
ВыборкаОбщийИтог = Результат.Выбрать(ОбходРезультатаЗапроса.ПоГруппировкам); ВыборкаОбщийИтог.Следующий(); // Общий итог ВыборкаДетали = ВыборкаОбщийИтог.Выбрать(); Пока ВыборкаДетали.Следующий() Цикл // … КонецЦикла;
Это не означает, что нельзя проверить принадлежность группе при обходе результатов запроса. Можно. Но нужно проверять принадлежность родителю, а не «коду».
Предопределенные и пользовательские счета План счетов может содержать счета, вводимые пользователем, и счета, введенные на этапе конфигурирования. Последние называются предопределенными и являются объектами конфигурации (имеют свое уникальное имя в рамках плана счетов). Нужно отметить, что для плана счетов, в отличие, например, от справочника, который обладает такой же возможностью, ввод счетов в режиме Конфигуратор является в большинстве случаев основным вариантом заполнения. План счетов, ну или по крайней мере его основа (счета первого уровня), создается еще на этапе конфигурирования и во многом определяет логику учета. Ввод новых счетов (субсчетов) пользователем является скорее исключением, чем правилом.
Свойства счета Предопределенные счета вводятся по кнопке Предопределенные с закладки Прочие плана счетов. При вводе для предопределенного счета есть возможность задать следующие свойства (табл. 12.8). Таблица 12.8. Свойства счета Свойство
Комментарий
Может изменяться пользователем
Имя
Имя объекта Счет-родитель Код счета в соответствии с маской Наименование счета Активный, Пассивный, Активный/ Пассивный определяет вариант подсчета остатков по счету По счету не выполняется контроль двойной записи Сортировка счетов в списке и запросах
Нет Да Да Да
Участие счета в том или ином виде учета
Нет
Родитель Код Наименование Вид счета Забалансовый Порядок Признаки учета (сколько
введено в плане счетов)
Нет Нет Да
623
Глава 12. Бухгалтерский учет Свойство Виды субконто (не более чем
определено в плане счетов) Признаки учета субконто
(сколько определено в плане счетов)
Комментарий
Может изменяться пользователем
Детализация счета в аналитическом учете
Нет*
Возможность отключить ведение того или иного вида учета для одного вида субконто на счете
Нет*
* Для предопределенных счетов в режиме 1С:Предприятие можно добавлять новые виды субконто и изменять признаки учета субконто для этих видов субконто. Но нельзя удалять виды субконто счета, введенные в конфигураторе. А также нельзя изменять признаки учета субконто для этих видов субконто.
Как мы видим, часть свойств, которые мы задаем на этапе конфигурирования, может изменяться пользователем при работе в информационной базе. По сути, задавая такие поля, как Код, Родитель, Наименование, Порядок, мы лишь указываем начальные стандартные значения. Пользователь сможет присвоить свой код, изменить наименование, переопределить родителя, установить новый порядок сортировки счетов.
Особенности написания запросов Возможность изменения этих свойств необходимо учитывать при конфигурировании. Так, например, при написании запроса для получения остатка по одному счету можно поступить следующим образом (листинг 12.7). Листинг 12.7. Пример получения остатка по счету
Запрос = Новый Запрос; Запрос.Текст = "ВЫБРАТЬ | Остатки.СуммаОстаток |ИЗ | РегистрБухгалтерии.ОсновнойРегистрБухгалтерии.Остатки(, Счет.Код = ""1.1"", | , ) КАК Остатки"; Остатки = Запрос.Выполнить().Выбрать(); Остатки.Следующий(); Остаток = Остатки.СуммаОстаток;
В этой процедуре выполняется запрос, получающий из виртуальной таблицы регистра бухгалтерии РегистрБухгалтерии.ОсновнойРегистрБухгалтерии.Остатки остаток по счету с кодом 1.1, который в нашем плане счетов называется Касса. Ну или, точнее, назывался на этапе конфигурирования. Если пользователь изменит код счета, запрос или не будет выполнен, или будет выполнен не по тому счету. Поэтому всегда имеет смысл при установке отборов по счетам использовать или ссылку (полученную, например, путем выбора в диалоге элемента из плана счетов), или неизменяемое имя предопределенного счета (рис. 12.16).
624
Рис. 12.16. Свойства предопределенного счета
ВНИМАНИЕ!
Когда мы сказали о необходимости использовать имя для получения ссылки на предопределенный счет плана счетов, имелось в виду свойство счета Имя, а не наименование счета. Имя – свойство любого объекта метаданных конфигурации, в том числе и предопределенного счета плана счетов. Имя служит для однозначной идентификации счета в плане счетов конфигурации и как следствие может использоваться для получения ссылки на объект. Листинг 12.8. Пример получения остатка по счету
Запрос = Новый Запрос; Запрос.Текст = "ВЫБРАТЬ | Остатки.СуммаОстаток |ИЗ | РегистрБухгалтерии.ОсновнойРегистрБухгалтерии.Остатки(, Счет = &Счет, , ) КАК Остатки"; Запрос.УстановитьПараметр("Счет", ПланыСчетов.ОсновнойПланСчетов.Касса); Остатки = Запрос.Выполнить().Выбрать(); Остатки.Следующий(); Остаток = Остатки.СуммаОстаток;
Основы организации аналитического учета Иерархический план счетов позволяет организовать детальный учет. И при желании можно организовать детальный аналитический учет, используя возможность организации иерархического плана счетов и ввода новых субсчетов пользователем. Однако эта детализация будет иерархической. При такой организации аналитического учета не представляется возможным получение итогов по нескольким параллельным срезам. Рассмотрим учет товаров на складах. Предположим, в нашей организации есть несколько складов, на каждом из которых множество видов номенклатурных позиций. Перед нами стоит задача обеспечить получение остатков и оборотов по каждому складу и товару в отдельности и сводно по всем. Задачу можно решить, используя субсчета счета Товары. Изменив длину кода счета (до 10 символов) и маску кода счета @@.@@.@.@@, мы можем завести к счету учета товаров необходимое количество субсчетов (рис. 12.17). Профессиональная разработка в системе «1С:Предприятие 8»
План счетов и его основные свойства ■■ список складов для учета товаров на складах; ■■ список статей затрат для учета затрат; ■■ и другие. Каждый элемент списка вида субконто представляет собой объект аналитического учета и называется Субконто. Ни субконто, ни вид субконто не имеют объектного представления в системе и существуют лишь как понятия, реализуемые с помощью других объектов. Виды субконто, как правило, бывают ссылочного типа и содержат в себе ссылку на справочник, документ или перечисление, хотя возможны и другие варианты. Если видом субконто является справочник, то субконто – один элемент этого справочника. Сами по себе виды субконто не хранят никакой информации об остатках и оборотах по счетам и являются, по сути, подключаемыми измерениями для счетов плана счетов. Рис. 12.17. План счетов «Основной план счетов»
Подобная организация аналитического учета возможна, но имеет ряд существенных недостатков. Во-первых, план счетов будет расти (и расти существенно) по мере изменения номенклатуры товаров (добавления новых позиций, отказа от старых и появления неиспользуемых). Во-вторых, он будет расти нелинейно, т. к. одна и та же позиция номенклатуры может храниться на разных складах; таким образом, количество субсчетов на каждую позицию будет равняться количеству складов. И самое главное – не представляется возможным автоматически сгруппировать данные по одной позиции номенклатуры, хранимой на разных складах.
Использование видов субконто для организации аналитического учета можно представить в виде схемы на рис. 12.18.
Организацию аналитического учета с использованием субсчетов нельзя назвать неправильной. Это вполне возможный вариант, который имеет свои ограничения (мы перечислили их выше) и свои достоинства. К достоинствам можно отнести, например, интуитивную прозрачность учета для любого бухгалтера, который ранее не сталкивался с учетом при помощи компьютерной программы, всю жизнь проработал в «бумажной бухгалтерии». Однако подавляющее большинство бухгалтеров предпочитают бухгалтерские программы с большими возможностями в части ведения аналитического учета. Для описания возможностей системы при автоматизации задач аналитического учета используются понятия Вид субконто и Субконто. Вид субконто – группа однородных объектов аналитического учета. Понятие «вид субконто» соответствует понятию бухгалтерского учета «аналитический счет». В демонстрационной конфигурации «Бухгалтерский учет», которая находится на прилагаемом компакт-диске, возможны следующие виды субконто: ■■ список контрагентов для ведения учета расчетов в разрезе контрагентов; ■■ список номенклатуры товаров; Том 1
Рис. 12.18. Использование видов субконто для организации аналитического учета
Левая часть схемы описывает наш иерархический план счетов. Каждый из счетов предназначен для ввода и хранения относительно укрупненной информации – остаток всех товаров на всех складах, долг всех покупателей, задолженность перед всеми поставщиками и др. Вместо того, чтобы развивать субсчета у названных счетов, мы открываем на них аналитический учет, используя виды субконто. Каждый счет на данной схеме можно
625
Глава 12. Бухгалтерский учет рассматривать как учетный регистр, накапливающий остатки и обороты в денежном выражении. Виды субконто позволяют добавлять измерения в эти регистры и создают новые сущности. Так, например, один и тот же справочник Контрагенты может использоваться для организации аналитического учета как на счете Покупатели, так и на счете Поставщики. Анализируя остатки и обороты по счету Покупатели в разрезе объектов аналитического учета (контрагентов), мы получим список наших покупателей, остатки (задолженность) и обороты (увеличение, погашение) по каждому из них. Возможность системы привязать к одному счету несколько самостоятельных видов субконто позволяет нам получить фасетное (параллельное) деление: например, на одном складе могут быть разные товары, один и тот же товар может быть на разных складах. Мы всегда можем получить остаток по складу, по товару и по товару на складе.
План видов характеристик для создания списка видов субконто
Рис. 12.19. Основные свойства плана видов характеристик
Для хранения списка видов субконто используется объект План видов характеристик. Получаются два уровня вложенности: план, представляющий собой совокупность видов субконто, и вид субконто. Каждый вид субконто хранит информацию о типе характеристик, являющихся объектами аналитического учета, т. е. субконто. Характеристика – это один экземпляр вида характеристик, так же как субконто – это один экземпляр вида субконто. Характеристика не является самостоятельным объектом конфигурации. Для ведения аналитического учета, как правило, используются элементы справочников, значения перечисления, ссылки на документы. Виды характеристик, как правило, имеют ссылочный тип данных (хотя возможны и другие варианты). Один план видов характеристик может использоваться для организации аналитического учета для нескольких планов счетов. Можно провести следующие параллели между понятиями системы и понятиями предметной области (табл. 12.9). Таблица 12.9. Соответствие понятий системы «1С:Предприятие» и понятий предметной области Объект
Понятие
Планы видов характеристик Все виды субконто Вид характеристики Вид субконто Характеристика Субконто
Начнем организацию аналитического учета с создания нового плана видов характеристик. Назовем его ВидыСубконто (рис. 12.19 и 12.20).
626
Рис. 12.20. Тип значения характеристик
Так как в качестве объектов аналитики могут выступать данные разных объектов (разных справочников, как в нашем случае, или справочников и документов и перечислений и др.), то тип значения характеристик устанавливается составным. Фактически в диалоге редактирования типа характеристик мы выбираем объекты конфигурации, которые будут использоваться для ведения аналитического учета. Выбираем, какого типа виды субконто мы (и пользователь) сможем создавать. Нужно отметить, что поле диалога для выбора значения субконто в документах, отчетах и других механизмах будет иметь тип Характеристика.ВидыСубконто плана видов характеристик ВидыСубконто. А тип значения поля в базе данных будет составным и будет включать все выбранные в типе значения характеристик типы. Профессиональная разработка в системе «1С:Предприятие 8»
План счетов и его основные свойства ПРИМЕЧАНИЕ
Не рекомендуется включать в тип значения характеристик какие-либо типы, кроме ссылочных. Это существенно повышает нагрузку на систему. В базе данных поле составного типа, включающего в себя только ссылочные типы данных, хранится в трех полях таблицы (фактический тип хранимого значения, номер таблицы, на которую ссылается значение, и идентификатор записи, на которую ссылается значение). При добавлении в составной тип данных примитивных типов на каждый из них добавляется новое поле в базу данных. Кроме увеличения объема базы данных, это имеет еще одну негативную сторону: система выполняет индексирование полей для хранения итогов по субконто таблиц регистра бухгалтерии, и количество полей в индексе ограничено в SQL-версии 16 полями, часть из которых уже занята под счет, период, измерения. Более подробно эта тема рассмотрена в разделе «Индексы таблиц итогов регистра бухгалтерии» на стр. 681.
Теперь пользователь сможет создать сколько угодно видов субконто, имеющих тип этого справочника, но все его объекты аналитики будут лежать «вперемешку». Чтобы предоставить пользователю возможность создавать отдельные подмножества объектов аналитики, справочник Субконто необходимо сделать подчиненным плану видов характеристик. Подчиненность справочника Субконто плану видов характеристик – обязательное условие функционирования механизма дополнительных характеристик (рис. 12.22).
Как и счета плана счетов, виды субконто могут создаваться как в режиме Конфигуратор, так и в пользовательском режиме. Если мы не считаем необходимым предоставлять пользователю возможность создавать собственные виды субконто, то настройку закладки Общая можно на этом закончить, перейти на закладку Прочее и создать предопределенные виды характеристик (рис. 12.21).
Рис. 12.21. Предопределенные виды характеристик
У пользователя все равно будет возможность создавать новые виды субконто, но только тех типов данных, которые мы выбрали в качестве возможных типов значения характеристик. Например, он сможет создать еще один вид субконто Продавцы типа СправочникСсылка.Контрагенты, но физически эти продавцы будут находиться в справочнике Контрагенты. Маловероятно, что пользователю пригодится такая возможность. Скорее всего, он предпочел бы создать новый вид субконто и хранить в нем какие-то новые объекты аналитики, для которых не предусмотрено справочника в конфигурации. Для предоставления пользователю возможности создавать собственные виды субконто предусмотрен механизм дополнительных значений характеристик. Для этого создается новый справочник в конфигурации, который мы назовем, например, Субконто. Потом включим его в тип значения характеристик и получим таким образом «местечко про запас», где пользователь сможет хранить собственные объекты аналитики. Том 1
Рис. 12.22. Владельцы справочника «Субконто»
Тем самым мы предоставили пользователю возможность создать сколько угодно новых видов субконто. Физически все они будут храниться в одном справочнике, но «перемешиваться» не будут, т. к. на каждый новый вид субконто в справочнике будет выделяться новое множество подчиненных ему элементов. А чтобы нумерация этих элементов была также независимой, имеет смысл на закладке Нумерация объекта конфигурации Справочник Субконто установить переключатель Серии кодов в значение В пределах подчинения владельцу.
627
Глава 12. Бухгалтерский учет Последний штрих – выбрать справочник Субконто в качестве дополнительных значений характеристик (рис. 12.23). Теперь вновь создаваемые пользователем виды субконто (виды характеристик) по умолчанию будут иметь тип значения СправочникСсылка.Субконто.
Рис. 12.24. Субконто плана счетов
Закладка Субконто также позволяет определить максимальное количество субконто на счете. Это число параллельных аналитических срезов (видов субконто), которое можно будет выбрать для каждого счета. И число это в большинстве случаев определяется отчетными потребностями объекта автоматизации. На рисунке выбрано значение 2, в типовом решении «Бухгалтерия предприятия» выбрано значение 3, максимально возможное поддерживаемое платформой значение 50. Рис. 12.23. Дополнительные значения характеристик
подробнее
Раздел «Использование плана видов характеристик для хранения видов характеристик», стр. 483.
Детализация счета плана счетов по видам субконто Теперь, когда созданы «аналитические счета» – виды субконто, нужно, чтобы они заработали и позволили вести аналитический учет на счетах, которые ранее были синтетическими. Для этого необходимо привязать виды субконто к счетам плана счетов. Выполняется это в объекте План счетов. Начинаем настройку с закладки Субконто. На этой закладке в свойстве Виды субконто выбираем план видов характеристик, который хранит виды субконто для этого плана счетов (рис. 12.24).
628
Выбор максимального количества субконто – важный этап в проектировании системы автоматизации бухгалтерского учета, и мы остановимся на нем отдельно в разделе «Принятие решений при организации аналитического учета» на стр. 632. Пока же установка этого свойства привела к тому, что для каждого счета плана счетов было добавлено новое свойство – специализированная табличная часть Виды субконто. И содержать эта табличная часть в нашей конфигурации может максимум две строки. Подчеркнем: именно в нашей конфигурации (где в свойствах плана счетов выбрано значение максимального количества субконто равным двум) и именно для каждого счета (разные счета могут иметь различную детализацию), рис. 12.25. Каждая из строк табличной части содержит ссылку на вид характеристики плана видов характеристик, выбранного в свойстве плана счетов Виды субконто, и дополнительные свойства. Каждая строка табличной части ВидыСубконто содержит следующие поля: ВидСубконто, Предопределенное, ТолькоОбороты и признаки учета субконто. ВидСубконто – свойство типа ПланВидовХарактеристикСсылка.<имя>,
позволяющее получить доступ к свойствам вида характеристики плана видов характеристик. Это поле задает вид субконто, в разрезе которого будет вестись аналитический учет. Кроме того, оно может быть исполь-
Профессиональная разработка в системе «1С:Предприятие 8»
План счетов и его основные свойства зовано, например, при установке типов значений для реквизитов формы или для полей построителя отчета (листинг 12.9).
Этот тип данных может быть назначен реквизиту формы и реквизиту объекта, хранимому в информационной базе. Этот тип данных является составным и включает в себя все типы данных, выбранные в свойстве Тип значения характеристик плана видов характеристик. Рассмотрим первый пример, в котором пользователь должен в документе (или справочнике) выбрать сначала в первом поле ввода вид субконто, а затем в другом – объект субконто выбранного ранее вида. Подробнее
Этот пример приведен в демонстрационной конфигурации «Бухгалтерский учет», которая находится на прилагаемом компакт-диске, в форме обработки Демонстрационная, на закладке Выбор субконто.
Для этого добавим в форму обработки два реквизита: ВидСубконто типа ПланВидовХарактеристикСсылка.ВидыСубконто и Субконто типа Характеристика.ВидыСубконто (рис. 12.26). Рис. 12.25. Виды субконто Листинг 12.9. Пример использования свойства «ВидСубконто»
Для Каждого ВидСубконто Из Счет.ВидыСубконто Цикл Вид = ВидСубконто.ВидСубконто; ТипЗначения = Вид.ТипЗначения; Наименование = Вид.Наименование; ВведенВКонфигураторе = ВидСубконто.Предопределенное; Оборотный = ВидСубконто.ТолькоОбороты; Количественный = ВидСубконто.Количественный; КонецЦикла;
В приведенном примере счет – переменная или поле ввода типа ПланСчетовСсылка.<имя>. Цикл по видам субконто счета позволит узнать их типы, наименования, были они введены в конфигураторе (предопределенный вид субконто был добавлен на счет в режиме Конфигуратор) или добавлены пользователем, узнать признаки учета субконто.
Ввод в диалоге и хранение в базе данных объектов аналитического учета С тех пор, как нами была добавлена возможность ведения аналитического учета, в нашей конфигурации должны будут произойти изменения. Теперь пользователю будет необходимо в диалогах форм отчетов, документов, а может быть и не только, выбирать объекты аналитики, соответствующие выбранному уже в том же диалоге счету. А информационной базе придется сохранять этот сделанный пользователем выбор. Для хранения выбранного пользователем объекта аналитики в конфигурации предусмотрен специальный тип данных Характеристика.<Имя>. Том 1
Рис. 12.26. Реквизиты «Субконто» и «ВидСубконто»
Если этим ограничиться, то при выборе значения субконто в диалоге формы пользователю сначала будет предлагаться выбор типа из списка типов значений характеристик Виды субконто. Следующая наша задача – ограничить выбор только типами выбранного пользователем вида субконто. Для этого в свойствах поля ввода Субконто необходимо установить свойство Связь по типу в значение, указывающее на реквизит Виды субконто. Теперь, если, например, пользователем выбран вид субконто Контрагенты (который в нашей конфигурации имеет тип
629
Глава 12. Бухгалтерский учет значения СправочникСсылка.Контрагенты), то диалог выбора типа будет содержать только те типы значений, которые может принимать данный вид субконто. Также свойство Связи параметров выбора поля ввода Субконто нужно установить как Отбор.Владелец(ВидСубконто). В результате при выборе значений субконто, содержащихся в справочнике Субконто, для выбора будут предлагаться только те значения, которые относятся к выбранному виду субконто. Диалог выбора типа данных будет предлагаться в случае, если выбранный вид субконто содержит несколько типов данных. В практике создания механизмов для ведения бухгалтерского учета чаще, однако, встречается другая ситуация, когда пользователь выбирает в диалоге формы счет и далее должен выбрать значения субконто того типа данных, который выбран для видов субконто этого счета. В таком случае в диалоге формы размещают поле ввода для реквизита Счет (тип ПланСчетовСсылка.<имя>) и устанавливают связь между полем ввода для выбора значения субконто и счетом (минуя вид субконто, который становится не нужен). Подробнее
Этот пример приведен в демонстрационной конфигурации «Бухгалтерский учет», которая находится на прилагаемом компакт-диске, в форме документа ВыборСубконтоСчета.
Создадим в документе следующие реквизиты: Счет (тип ПланСчетовСсылка.ОсновнойПланСчетов), Субконто1 (тип Характеристика.ВидыСубконто) и Субконто2 (тип Характеристика.ВидыСубконто). В свойствах нашего плана счетов выбрано максимальное количество субконто равным двум, поэтому более двух значений субконто для одного счета выбирать не потребуется. Установим свойства Связь по типу реквизитов Субконто1 и Субконто2, в которых в этот раз мы укажем реквизит Счет (рис. 12.27). Теперь диалог выбора типа в форме документа будет содержать только те типы значений, которые могут принимать виды субконто выбранного пользователем счета. Чтобы оставить только те типы (или один тип, если используется субконто не составного типа), которые нужны для выбора первого вида субконто, необходимо установить значение свойства Элемент связи по типу равным 1. Для реквизита Субконто2 это свойство будет равным 2. Свойство Элемент связи по типу позволяет указать порядковый номер вида субконто на счете, значение которого должно выбираться в соответствующем поле ввода. Следующая наша задача – избавиться от диалога выбора типа. Для этого создадим форму документа и напишем процедуру – обработчик события ПриИзменении поля ввода Счет (листинг 12.10).
630
Рис. 12.27. Реквизиты «Субконто» и «Счет» документа «ВыборСубконтоСчета» Листинг 12.10. Обработчик события «ПриИзменении» поля ввода «Счет»
&НаКлиенте Процедура СчетПриИзменении(Элемент) ВыбиратьТипСубконто(); УстановитьВидимостьСубконто(); КонецПроцедуры
При изменении счета вызывается сначала процедура ВыбиратьТипСубконто() и затем процедура УстановитьВидимостьСубконто(), листинг 12.11. Листинг 12.11. Процедура «ВыбиратьТипСубконто»
&НаСервере Процедура ВыбиратьТипСубконто() ЧислоСубконто = Объект.Счет.ВидыСубконто.Количество(); Для Сч = 1 По ЧислоСубконто Цикл ТипСубконто = Объект.Счет.ВидыСубконто[Сч - 1].ВидСубконто.ТипЗначения; Элементы["Субконто" + Сч].ВыбиратьТип = (ТипСубконто.Типы().Количество() > 1); Если ТипСубконто.ПривестиЗначение(Объект["Субконто" + Сч]) <> Объект["Субконто" + Сч] Тогда Объект["Субконто" + Сч] = ТипСубконто.ПривестиЗначение(Объект["Субконто" + Сч]); КонецЕсли; КонецЦикла; КонецПроцедуры
Профессиональная разработка в системе «1С:Предприятие 8»
План счетов и его основные свойства Прокомментируем текст этой процедуры. Процедура написана достаточно универсально и не зависит от настроек ведения аналитического учета плана счетов. Сначала мы узнаем число субконто, задействованных для ведения аналитического учета на выбранном счете. В цикле по количеству субконто на счете мы получаем описание типов субконто. Для этого обращаемся к табличной части счета ВидыСубконто и получаем из нее строку, обращаясь к ней по индексу (индексация строк этой табличной части начинается с нуля). Выбор типа из поля ввода субконто имеет смысл только для субконто составного типа (такие тоже могут быть). Мы определяем количество типов, входящих в описание типа, и, если этот тип составной (более одного), устанавливаем флажок элемента формы ВыбиратьТип.
Признаки учета субконто Признаки учета субконто будут рассмотрены нами подробнее при изучении регистра бухгалтерии в разделе «Свойство ресурса «Признак учета субконто»» на стр. 642. Пока же рассмотрим вкратце их предназначение и создание. Признаки учета субконто дополняют специализированную табличную часть Виды субконто новыми свойствами типа Булево. Каждое свойство, связанное с ресурсом регистра бухгалтерии, позволяет управлять хранением остатков и оборотов выбранного ресурса для объектов субконто выбранного счета (рис. 12.28).
Наша процедура расположена в модуле формы документа. Основной реквизит этой формы ДокументОбъект. Мы стараемся писать процедуру универсально, поэтому предусматриваем возможность ее вызова не только при изменении счета, но и, например, при открытии формы. Чтобы не устанавливать флажок модифицированности при открытии формы, мы проверяем тип значения реквизита на соответствие типу субконто и приводим тип только в том случае, если тип реквизита отличается от типа описания субконто. Последний штрих в работе этого механизма – управление видимостью полей ввода субконто и заголовками для этих полей. Это связано с тем, что не на каждом счете используются оба вида субконто, могут быть счета, где задействован только один аналитический разрез или вообще ни одного (листинг 12.12). Листинг 12.12. Процедура «УстановитьВидимостьСубконто»
Процедура УстановитьВидимостьСубконто() Для НомерСубконто = 1 по 2 Цикл Если (НомерСубконто <= Объект.Счет.ВидыСубконто.Количество()) И (НЕ Объект.Счет.Пустая()) Тогда Элементы["Субконто" + НомерСубконто].Заголовок = Строка(Объект.Счет. ВидыСубконто[НомерСубконто-1].ВидСубконто); Элементы["Субконто" + НомерСубконто].Видимость = Истина; Иначе Элементы["Субконто" + НомерСубконто].Видимость = Ложь; КонецЕсли; КонецПроцедуры
Вызов этой процедуры из обработчика события формы ПриСозданииНаСервере и обработчика события ПриИзменении поля ввода Счет позволит скрыть неиспользуемые поля ввода субконто, а для используемых полей назначить заголовки – имена видов субконто.
Том 1
Рис. 12.28. Признаки учета субконто
Приведенная выше картинка демонстрирует, что для плана счетов Основной план счетов предусмотрена возможность отключать для отдельных видов субконто ведение количественного и суммового учета. Так, например, если на счете товаров необходимо учитывать номенклатурные позиции товаров в количественном выражении в разрезе складов, а в суммовом – по предприятию в целом (без учета складов), то настройка счета будет выглядеть как на рис. 12.28.
631
Глава 12. Бухгалтерский учет Свойство Только обороты схоже по своему назначению с признаками учета субконто. Оно ограничивает хранение итогов по субконто счета только хранением оборотов, исключая из таблиц итогов остатки. Это может быть необходимо в случае, когда остатки по субконто просто не имеют смысла.
Как правило, организация аналитического учета определяется отчетными потребностями руководства, организационной структурой предприятия, необходимостью выполнения стандартов учета (международных, государственных, внутрифирменных и т. д.). Рассмотрим пример организации учета товаров.
Например, учет на счете денежных средств в разрезе статей, характеризующих виды поступления и списания средств. В таком учете остаток по статье не будет нести никакого экономического смысла. По одной статье мы получаем денежные средства, по другой – списываем. Результатом аналитического учета станут постоянно растущие и никогда не списываемые остатки по статьям, по одним из них – положительные, по другим – отрицательные.
Пользователь изъявил желание вести учет товаров в разрезе номенклатуры товаров. Желание разумное, ведь подобная организация аналитического учета позволит ему анализировать остатки и обороты по каждой номенклатурной позиции. Список товаров существенный и незакрытый (в него добавляются новые позиции, удаляются старые). Кроме кода и наименования номенклатуры необходимо хранить и другую дополнительную, но важную информацию. Ниже приводится таблица (табл. 12.10), позволяющая в конкретном случае принять решение об оптимальности использования механизма платформы.
Рассмотрим программное заполнение субконто счета и их свойств. Следующий фрагмент кода (листинг 12.13) позволяет узнать, ведется ли на счете Касса учет в разрезе субконто Сотрудники, и если нет, то добавить это субконто на счет, включив на нем признаки учета субконто – суммовой и количественный. Листинг 12.13. Пример программного заполнения субконто и их свойств
Счет = ПланыСчетов.ОсновнойПланСчетов.Касса; ВидСубконто = ПланыВидовХарактеристик.ВидыСубконто.Сотрудники; Если Счет.ВидыСубконто.Найти(ВидСубконто, "ВидСубконто") = Неопределено Тогда СчетОбъект = Счет.ПолучитьОбъект(); НовыйВид = СчетОбъект.ВидыСубконто.Добавить(); НовыйВид.ВидСубконто = ВидСубконто; НовыйВид.Суммовой = Истина; НовыйВид.Количественный = Истина; СчетОбъект.Записать(); КонецЕсли; ПРИМЕЧАНИЕ
Комментируя это процедуру, необходимо уточнить, что добавление вида субконто на счет возможно только в том случае, если табличная часть получена как свойство объекта Счет. Кроме того, нужно учитывать, что проверка на превышение максимального количества видов субконто для плана счетов будет выполняться только при записи счета.
Принятие решений при организации аналитического учета От организации плана счетов и аналитического учета во многом зависит не только функциональность, но и производительность конфигурации. Остановимся подробнее на наиболее важных моментах организации аналитического учета в конфигурации.
632
Таблица 12.10. Решение первое. Выбор: субсчета или субконто Критерий
Учет на субсчетах
Учет на субконто
Количество позиций Список позиций учета закрыт Параллельные срезы возможны
От единиц до десятков Как правило, да Только иерархический учет Кода и наименования достаточно
От десятков до бесконечности Может и будет расширяться Несколько параллельных срезов
Достаточная информативность
Есть дополнительные свойства
Принимаем решение: вести учет на счете товаров в разрезе субконто Номенклатура типа СправочникСсылка.<имя>. Следующее желание пользователя – получать дополнительные группировки и отборы в отчетах по складам, что соответствует организационной структуре предприятия, и списывать товары методом FIFO. Дополнительно потребуется группировка в отчете Остатки товаров по годам приобретения имеющихся на складе МПЗ и видам товаров. По партиям и складам, основываясь на предыдущей таблице, принимаем решение о необходимости открытия новых видов субконто Партии и Склады на счете учета товаров. По видам товаров и годам закупки МПЗ решение может быть проще (табл. 12.11). Таблица 12.11. Решение второе. Выбор: новый вид субконто или новое свойство старого Критерий
Новый вид субконто
Можно ли однозначно связать новый критерий отбора (группировки) с существующим объектом аналитического учета
Связать невозможно, Новый критерий вполне можно это параллельный срез разместить как новое свойство существующего вида аналитики
Новое свойство субконто
Принимаем решение: вид товара – это новый реквизит справочника Номенклатура, год можно получить из партии товара. Стало быть, добавления новых видов аналитики эти два критерия не потребовали. Профессиональная разработка в системе «1С:Предприятие 8»
План счетов и его основные свойства В результате пришли к выводу, что для получения затребованной информации потребуется ведение аналитического учета на счете товаров в разрезе трех независимых видов аналитики: номенклатура, склады и партии. Следующий вопрос: порядок следования видов аналитики. Более подробно об организации регистра бухгалтерии мы расскажем потом, пока же заметим, что физическая организация таблиц позволяет наиболее быстро получать развернутые отчеты по тем аналитическим срезам, которые находятся «ближе к счету» (табл. 12.12). Таблица 12.12. Решение третье. Выбор: порядок следования видов субконто Критерий
Первый на счете
По какому аналитическому срезу отчеты чаще всего будут Номенклатура «разворачиваться», по какому реже
Последний на счете
Склады
Принимаем решение: первый вид субконто на счете будет Номенклатура, второй Партии, третий Склады. Следующая наша задача – оценить возможность использования трех видов субконто на счете со стороны типового (или просто существующего) решения, которое мы адаптируем, и со стороны платформы. Любое типовое решение ориентировано, как правило, на фиксированное заданное максимальное количество субконто на счете. Так, например, конфигурация «Бухгалтерия предприятия» содержит в себе набор документов, среди которых есть универсальные, и отчетов, предназначенных для работы максимум с тремя видами субконто на счете (три поля для выбора). Кроме того, важно оценить влияние изменившейся аналитики счета на работу существующих механизмов типового решения. Любое изменение аналитики счета, задействованного в автоматических учетных схемах, может привести к существенной переделке этих схем, даже если не превышено максимальное количество субконто, установленное в свойствах плана счетов. А если к тому же требуется увеличить максимальное количество субконто, предусмотренное в плане счетов типового решения и как следствие прописанное во всех универсальных механизмах, переделка коснется и их. Формальное ограничение со стороны платформы на максимальное количество субконто составляет 50 субконто на счете. Именно формальное, так как существует особенность работы сервера базы данных при построении индексов таблиц, о которой более подробно будет рассказано в разделе «Индексы таблиц итогов регистра бухгалтерии» на стр. 681. Во многих случаях при проектировании плана счетов имеет смысл обдумать возможность вынесения отдельных разделов учета из бухгалтерии в оперативный учет, который может быть реализован с помощью регистров накопления (о регистрах см. главу 11 «Учет движения средств», стр. 545). Том 1
При принятии решения о необходимости вынесения раздела в оперативный учет имеет смысл учитывать критерии, перечисленные в табл. 12.13. Таблица 12.13. Решение четвертое. Выбор: оперативный или бухгалтерский учет Критерий
Субконто бухгалтерии
Измерения оперативного учета
Максимальное количество субконто, выбранное в плане счетов демонстрационной конфигурации
Не более двух
Максимальное количество субконто, с которыми эффективно может работать платформа Количество объектов учета Количество документов в день Измерение примитивного типа Влияние на бухгалтерский баланс
*
Нет ограничения, может быть создан регистр с нужным количеством измерений *
Десятки, сотни, тысячи ** Единицы, десятки ** Настоятельно не рекомендуется Необходимо
Десятки и сотни тысяч ** Десятки, сотни ** В принципе возможно Не рекомендуется
* Не представляется возможным дать этот критерий в количественном выражении, не увидев и не проанализировав задачу, которую необходимо решить. Можно сказать лишь, что при решении одной и той же задачи автоматизации одного раздела учета наличия и движения средств регистр накопления будет эффективнее регистра бухгалтерии. Это обусловлено универсальностью регистра бухгалтерии, платой за которую является эффективность. ** Количественные оценки очень приблизительны и неточны, и причина этого все та же: невозможно дать универсальные рекомендации. Правильное решение должно быть результатом оценки каждой конкретной задачи, и осуществляется эта оценка на этапе технического проектирования задачи после детального изучения объекта автоматизации.
Отдельно можно выделить последний критерий: влияние на бухгалтерский баланс. Разделяя учет на бухгалтерский и оперативный, в качестве критерия можно использовать необходимость включения информации с выбранной детализацией в сводные формы бухгалтерской отчетности (в первую очередь бухгалтерский баланс). Приведем пример: в бухгалтерском балансе товары входят в раздел «Оборотные активы» и отображаются там свернуто (без деления по номенклатуре, складам, партиям). Вывод: можно целиком вынести этот аналитический разрез в оперативный учет. Еще один пример: в бухгалтерском балансе задолженность контрагентов (перед контрагентами) отображается развернуто по контрагентам. Значит, ведение учета по контрагентам должно выполняться с помощью субконто плана счетов на регистре бухгалтерии, т. к. баланс должен строиться только на основании данных, введенных методом двойной записи. А если взаиморасчеты еще нужно вести в разрезе договоров? Если развернутая
633
Глава 12. Бухгалтерский учет информация по договорам или по срокам погашения задолженности, которая хранится в договоре, используется в балансе, значит, это субконто. А если нет, значит, можно вынести учет по договорам в регистры накопления. Принимаем решение: в нашем случае учет МПЗ можно было бы «вынести» в оперативный учет. Отдельно следует рассмотреть возможность использования небалансовых измерений регистра для ведения сквозного аналитического учета для всех (или большинства) счетов. Об этих возможностях платформы рассказано в разделе «Измерения регистра бухгалтерии» на стр. 643.
Предназначение регистра бухгалтерии В разрезе чего ведется бухгалтерский учет? В разрезе счетов бухгалтерского учета, управление которыми осуществляется с использованием объекта План счетов; в разрезе объектов аналитического учета, управлять списком которых позволяет объект План видов характеристик. Это как минимум. Возможны и другие разрезы. Где ведется бухгалтерский учет? Где хранятся проводки? Как эти проводки формировать и записывать? Как рассчитываются остатки и обороты по счетам и получаются бухгалтерские отчеты? На все эти вопросы отвечают свойства и методы объекта Регистр бухгалтерии. Но прежде чем приступить к их изучению, давайте договоримся, что будем иметь в виду под «бухгалтерским учетом». Можно приводить различные определения, которыми изобилуют учебники, но нам важно понять отличия этого вида учета от оперативного. У этих двух видов учета много общего: оба вида учета предназначены для решения одной и той же задачи – накопления и анализа каких-либо показателей в разрезе каких-либо измерений. Основные отличия заключаются в том, как это делается и для чего это делается. В первую очередь для чего. Задача оперативного учета – управление (часто оперативное, в реальном времени) одним (или несколькими, но не всеми) участком учета предприятия. Задача бухгалтерского учета – управление всей финансовохозяйственной деятельностью предприятия. И решение этой задачи требует использования специфических методов, в первую очередь двойной записи на счетах, которая образует замкнутую систему показателей. Итак, приведем основные отличия двух этих видов учета (табл. 12.14) и ответим на вопрос, почему нельзя обойтись только механизмами оперативного учета.
634
Таблица 12.14. Основные отличия оперативного и бухгалтерского видов учета Критерий
Оперативный учет
Бухгалтерский учет
Охват деятельности предприятия Измеритель Обязательные разрезы учета Показатели Метод учета
Один или несколько участков
Вся хозяйственная деятельность
Любой и зависит от участка Отсутствуют Независимые Произвольный
В едином денежном выражении Счета бухгалтерского учета Взаимосвязанные Двойная запись
Из отличий в видах учета вытекают и отличия в механизмах платформы, их реализующих. Необходимость учета всего множества хозяйственных операций предприятия исключает возможность задать однажды состав и структуру учетных регистров и не изменять их в процессе работы пользователя. В процессе работы возникают новые виды деятельности, новые хозяйственные операции и как результат новые учетные регистры, которые также должны попасть в баланс двойной записи. Причем возможность создавать эти новые учетные регистры предоставлена не только программисту, но и пользователю программного продукта. Достигается эта возможность за счет добавления новых счетов в план счетов и определения для них аналитики путем выбора вида субконто из списка существующих в конфигурации или добавления новых видов субконто в план видов характеристик. По своей сути регистр бухгалтерии – это «регистр регистров», совокупность регистров. Один регистр бухгалтерии содержит в себе множество учетных регистров (счетов), каждый из которых может иметь независимую аналитику (субконто), в разрезе которой и будут отражаться учетные показатели. В целях контроля все учетные регистры (счета) связаны между собой правилом двойной записи, которое образует замкнутую систему показателей: невозможно изменить значение показателя одного учетного регистра, не затронув другой, причем на ту же сумму. Счет бухгалтерского учета служит для указания, к какой области учета относится показатель, а набор субконто – измерения, в разрезе которых необходимо его учитывать. Если рассматривать только синтетическую составляющую плана счетов, который мы реализовали в нашей конфигурации, и вести учет только в денежном выражении, можно интерпретировать наш план счетов в виде совокупности регистров учета (регистров накопления). При этом каждый счет будет представлен в этой совокупности отдельным регистром учета. Дополнительно должен быть организован еще один регистр, задача которого – хранить обороты между счетами (разделами учета). Таблица Проводки (обороты) будет создана только в том случае, если используется регистр бухгалтерии с поддержкой корреспонденций (табл. 12.15).
Профессиональная разработка в системе «1С:Предприятие 8»
Предназначение регистра бухгалтерии Таблица 12.15. Перечень регистров учета Регистр
Касса Покупатели Товары Материалы Контрагенты Сотрудники Поставщики Капитал Проводки (обороты)
Измерения
Счет Дт
Таблица 12.19. Перечень ресурсов регистров учета
Ресурсы
Счет Кт
Сумма Сумма Сумма Сумма Сумма Сумма Сумма Сумма Сумма
Подобный набор регистров накопления позволит полностью реализовать бухгалтерский синтетический учет (учет в денежном выражении в валюте учета на счетах бухгалтерского учета). Пользователь сможет анализировать остатки и обороты по каждому разделу учета, а также обороты между счетами. Проводку, представленную в табл. 12.16, можно записать с помощью следующих движений в регистрах учета (табл. 12.17). Таблица 12.16. Пример проводки Дебет
Кредит
Сумма
Касса
Капитал
100
Таблица 12.17. Набор движений регистров учета Раздел учета
Касса Капитал Проводки
Вид движения
Приход Расход
Измерения
Касса
Сумма
Капитал
100 100 100
Полностью план счетов нашей конфигурации можно представить следующим образом (табл. 12.18 и табл. 12.19). Таблица 12.18. Перечень измерений и дополнительных измерений регистров учета Регистр
Касса Касса об. Покупатели Товары Материалы Контрагенты Сотрудники Поставщики Капитал Проводки об.
Том 1
Измерения
Организация Организация Организация Организация Организация Организация Организация Организация Организация Организация
Валюта Валюта
Валюта
Дополнительные измерения
Статьи Контрагенты Номенклатура Склады Контрагенты Сотрудники Контрагенты Счет Дт
Склады Номенклатура
Регистр
Ресурсы
Касса Касса об. Покупатели Товары Материалы Контрагенты Сотрудники Поставщики Капитал Проводки об.
Сумма Сумма Сумма Сумма Сумма Сумма Сумма Сумма Сумма Сумма
Вал сумма Вал сумма Количество Количество
Количество
Вал сумма
Подобный набор учетных регистров полностью повторит функциональность регистра бухгалтерии, за исключением контроля двойной записи и возможности создания новых учетных регистров (счетов) с произвольным набором дополнительных измерений (видов субконто) пользователем. Балансовое измерение регистра бухгалтерии Организация позволяет разделить учет на всех участках учета по организациям. Измерение Валюта включено только для счета Касса. Счет Касса потребовал создания двух регистров: одного для хранения остатков по счету в целом и еще одного для хранения оборотов по статьям (субконто Статьи имеет свойство Только обороты). Приведенная нами в качестве примера проводка (Дебет Касса – Кредит Капитал, см. табл. 12.16) теперь может быть интерпретирована такими движениями регистров учета (табл. 12.20). Таблица 12.20. Набор движений регистров учета Раздел учета
Вид движения Измерения
Касса Касса (об) Капитал Проводки (об)
Приход Расход
Организация Организация Организация Организация
Ресурсы
Валюта Валюта Валюта
Статья
100 руб. 100 руб. 100 руб. 100 руб.
10 у. е. 10 у. е. 10 у. е.
Подобное «раздвоение» одного счета учета на два (или более) учетных регистра применяется каждый раз, когда используются признаки учета субконто. Если представить, что на счете Товары мы решим для вида субконто Склады снять признак ведения суммового учета (это может потребоваться для выполнения правила учетной политики – расчет себестоимости должен выполняться по номенклатурному номеру без учета складов), то один счет Товары будет представлен в нашей модели двумя учетными регистрами (табл. 12.21).
Счет Кт
635
Глава 12. Бухгалтерский учет Таблица 12.21. Пример учетных регистров для счета «Товары» Регистр
Измерения
Дополнительные измерения Ресурсы
Товары Товары
Организация Организация
Номенклатура Номенклатура
Сумма Склады
Количество
Подобная организация регистров позволит получать количественные остатки каждого номенклатурного номера на каждом складе и суммовые остатки номенклатуры по предприятию в целом. Суммовые остатки и обороты по складу не ведутся. Рассмотренные нами свойства регистра бухгалтерии «накладывают отпечаток» на проектирование всей конфигурации. Многообразие хозяйственных операций и возможность расширения пользователем состава регистров учета и/или их измерений потребовали обязательного включения в конфигурацию документов-регистраторов типа «ручная операция», которые позволяют непосредственно редактировать движения регистра бухгалтерии, используя в проводках любые счета и аналитику. Кроме универсальных документов-регистраторов, потребуется учитывать особенности регистра бухгалтерии и в других документах, многие из которых должны предоставлять возможность выбора счета (одного или обоих) и/или аналитики. Необходимость анализировать остатки и обороты по новым учетным регистрам и по всем учетным регистрам, включая новые, привела к необходимости разработки в типовом решении универсальной отчетности. Эти отчеты, с одной стороны, являются универсальными и позволяют анализировать движения по любым счетам. С другой, сами формы отчетов устоялись за четыреста лет использования двойной записи и не могут быть произвольными по содержанию и расположению строк и колонок отчета: это оборотки, шахматки, ведомости, ордера, карточки и другие. Анализ таблицы, в которой мы выполнили реализацию нашего плана счетов с использованием регистров накопления, хорошо демонстрирует некоторую «неоптимальность»: слишком много пустых ячеек… Под измерение Валюта резервируется место и для тех учетных регистров, где валютный учет не ведется. Сделано это для того, чтобы пользователь мог в любой момент сам добавить новый учетный регистр и включить на нем валютный учет. Или же включить валютный учет на любом из предопределенных счетов (изменив настройки этого счета в конфигураторе). Та же ситуация и с ресурсами. Ресурсы ВалютнаяСумма и Количество задействованы не на всех счетах, а место под них резервируется в любом случае и с той же целью, что и для измерения Валюта. Для справедливости нужно заметить, что наша таблица неправильно передает способ хранения дополнительных измерений (субконто) в регистре бухгалтерии. Субконто хранятся иначе, в другой таблице
636
(более подробно о физическом строении регистра рассказано в разделе «Реальные таблицы» на стр. 655), и хранятся компактно – пустых ячеек там нет. Но в любом случае платой за универсальность регистра бухгалтерии является некоторое снижение производительности по сравнению с регистрами накопления. Поэтому при проектировании задачи бухгалтерского учета очень важно выявить и выделить в оперативный учет те разделы учета, которые требуют хранения и обработки значительного объема информации, особенно информации разнородной (ресурсы) и с большой детализацией (измерения). Если довести эту задачу почти до абсурда, то идеальной организацией бухгалтерского учета можно считать ведение синтетического (на счетах и субсчетах) учета в денежном выражении с незначительной детализацией по видам субконто, остатки по которым требуются для формирования баланса. А все остальные виды учета (многовалютный, количественный, подробный аналитический) реализовать, используя механизмы оперативного учета. Вывод: основной результат бухгалтерского учета – баланс, и все, что на него не влияет, может быть вынесено в оперативный учет. Выше нами был рассмотрен лишь один раздел науки об управлении предприятием – учет на предприятии, в котором мы выделили подвиды учета – оперативный и бухгалтерский (хочется надеяться, что выделили оптимально). Однако управление предприятием в целом намного шире и, кроме учета свершившихся фактов (чем и занимается учет) включает в себя планирование, анализ и многое другое. В этих задачах также есть место методам бухгалтерского учета и как следствие механизмам бухгалтерского учета системы «1С:Предприятие». В заключение можно сделать вывод, что любая задача, цель которой – получение взаимосвязанной системы показателей в виде баланса (в широком смысле этого слова: баланса средств и их источников, баланса оборотов и т. д.), может быть эффективно решена с использованием регистра бухгалтерии. Пример: получение прогнозного баланса в финансовом планировании, получение баланса-нетто в бухгалтерском управленческом учете и т. д.
Объект «Регистр бухгалтерии» Этот раздел будет посвящен свойствам и методам объекта Регистр бухгалтерии. Причем преимущественно тем методам, которые позволяют записывать данные в регистр. Методы объекта, предназначенные для чтения данных об остатках и оборотах по счетам, будут рассмотрены нами в разделе «Методы менеджера регистра бухгалтерии» на стр. 676, посвященном таблицам регистра бухгалтерии и извлечению данных из них.
Профессиональная разработка в системе «1С:Предприятие 8»
Объект «Регистр бухгалтерии»
Основные свойства регистра бухгалтерии Создание объекта Регистр бухгалтерии начинается с заполнения его основных свойств (рис. 12.29).
достаточно выбрать в регистре бухгалтерии план счетов, установить (или снять) признак поддержки корреспонденции и ввести в регистр одинединственный ресурс, Сумма например, в котором и будет храниться сумма проводки. В этом случае проводка будет выглядеть так, как показано на рис. 12.30.
Рис. 12.29. Основные свойства регистра бухгалтерии
На закладке Основные выбирается план счетов и признак поддержки корреспонденций. Как планов счетов, так и регистров бухгалтерии может быть несколько, но один регистр бухгалтерии содержит проводки только между счетами одного плана счетов. В то же время на одном плане счетов могут основываться два и более регистра бухгалтерии. Пример подобного использования: в разрезе счетов одного и того же плана счетов ведется учет свершившихся хозяйственных операций (один регистр бухгалтерии) и планируемых операций (бюджетных транзакций в другом регистре бухгалтерии). Наличие между ними единого связующего звена – плана счетов – позволит получить отчеты для план-фактного анализа, а различная структура регистров позволит вести каждый вид учета удобно и эффективно. Сравнивая объекты Регистр накопления (или понятие «учетный регистр») и Регистр бухгалтерии, можно сказать, что в самом простом случае регистр бухгалтерии – это регистр, который позволяет учитывать значение какого-то (или каких-то, но как минимум одного – сумма в валюте учета) ресурса в разрезе двух «предопределенных» измерений – СчетДебета и СчетКредита (или Счет и Вид движения для регистра без поддержки корреспонденций). Это скорее образное сравнение, чем демонстрация физического строения таблиц регистра, однако, по нашему мнению, вполне имеет право на жизнь. Для того чтобы получить самый простой бухгалтерский учет (синтетический: на счетах и субсчетах в денежном выражении в валюте учета), Том 1
Рис. 12.30. Реализация принципа двойной записи в регистре бухгалтерии
Если регистр поддерживает корреспонденцию, т. е. реализует привычную для России схему учета, каждая проводка включает два корреспондирующих счета (счет дебета и счет кредита) и ресурс Сумма. При такой архитектуре регистра пользователю будут доступны для анализа остатки и обороты по каждому счету и обороты между счетами. Учетная схема без поддержки корреспонденций может считаться более гибкой и в большей степени удовлетворяющей отражению экономической сути хозяйственных операций (хотя бы потому, что не приходится «укладывать» каждую операцию в «прокрустово ложе» корреспонденций счетов, разбивая движения на корреспондирующие пары счетов). Однако отсутствие корреспонденции исключает возможность анализа оборотов между счетами (табл. 12.22). Таблица 12.22. Отличия учетных схем с поддержкой корреспонденции и без поддержки корреспонденции Критерий
Поддержка корреспонденции Включена
Контроль двойной записи
В рамках проводки
Анализ остатков по счету Анализ оборотов по счету Анализ оборотов между счетами
Да Да Да
Выключена
В рамках набора движений регистратора Да Да Нет
637
Глава 12. Бухгалтерский учет ПРИМЕЧАНИЕ
Обращаем внимание: отсутствие поддержки корреспонденций не означает отсутствие контроля двойной записи. Если корреспонденция поддерживается, контроль двойной записи осуществляется в рамках каждой проводки. Если корреспонденция не поддерживается, то контроль двойной записи осуществляется в рамках всего набора записей, принадлежащих одному регистратору (рис. 12.31).
Рис. 12.32. Свойство «Балансовый»
Данные регистра бухгалтерии Рис. 12.31. Контроль двойной записи
Рассказывая о контроле двойной записи, нельзя не рассказать о свойстве ресурсов и измерений регистра бухгалтерии Балансовый. В процессе настройки регистра бухгалтерии нами был добавлен новый ресурс Сумма с установленным свойством Балансовый. Этим же свойством обладают, как видно на рис. 12.32, и измерения регистра. Счета балансовыми являются по умолчанию, но есть возможность объявить их забалансовыми. Контроль двойной записи осуществляется для балансовых счетов, балансовых измерений и балансовых ресурсов. Для регистра без поддержки корреспонденции контроль двойной записи осуществляется для балансового ресурса по балансовому измерению (всем сочетаниям балансовых измерений, если их несколько) в рамках набора записей одного регистратора.
638
Задача любого регистра – учет значений некоторых показателей (ресурсов) в разрезе некоторых измерений (счета проводки, измерения регистра и дополнительные измерения регистра – субконто) с возможностью оставить дополнительную информацию о каждой записи регистра (реквизиты). Закладка Данные регистра бухгалтерии позволяет определить все перечисленные свойства (рис. 12.33). Далее мы подробно рассмотрим свойства Измерения и Ресурсы регистра бухгалтерии. Реквизиты регистра, с нашей точки зрения, столь подробного описания не требуют. Реквизит характеризует лишь запись регистра бухгалтерии и, по сути, является дополнительной информацией, которую можно к этой записи прикрепить (рис. 12.34).
Профессиональная разработка в системе «1С:Предприятие 8»
Объект «Регистр бухгалтерии»
Ресурсы регистра бухгалтерии Если единственным обязательным разрезом ведения бухгалтерского учета являются счета и субсчета, то единственное значение, которое в этом разрезе нужно учитывать, – это сумма в валюте учета (или валюте составления баланса, можно сказать и так). Для регламентированного учета этой валютой является национальная валюта. Другими словами, для ведения регламентированного бухгалтерского учета достаточно добавить в регистр бухгалтерии один ресурс, который обычно называют Сумма, в который будут записываться значения, выраженные в рублях.
Рис. 12.33. Данные регистра бухгалтерии
Если речь идет об автоматизации нерегламентированного учета, то ничто не мешает в качестве валюты учеты выбрать любую другую. Например, в качестве валюты управленческого учета стараются выбрать наиболее устойчивую валюту или валюту той страны, в которой расположены основные деловые партнеры (учредители, инвесторы). В РФ управленческий учет чаще всего ведется в долларах США и с недавних пор в евро. Рассматривая свойства первого ресурса, который был добавлен нами для ведения бухгалтерского учета, следует остановиться на его свойствах. Ресурс регистра бухгалтерии может иметь только числовой тип, его длиной и точностью мы можем управлять.
Свойство ресурса «Балансовый»
Рис. 12.34. Реквизит «Содержание»
По значению реквизита можно получить отбор движений, но нельзя получить остаток или оборот по счету или субконто. Типичный вариант использования реквизита регистра – содержание проводки, куда пользователь сможет написать краткий комментарий к сделанной им проводке. Нужно предостеречь от использования большого числа реквизитов или реквизитов значительной длины. Несмотря на то, что таблицы итогов регистра не включают в себя реквизиты, таблицы первичных движений будут резервировать под них место и как результат увеличивать объем базы данных. Лучше оставлять всю дополнительную информацию в документерегистраторе, который сделал это движение, чем в самом движении.
Том 1
Свойство Балансовый влияет на структуру регистра бухгалтерии. Основная цель бухгалтерского учета – баланс. Основывается баланс на методе двойной записи, в соответствии с которым при движении в учете каждое учитываемое значение (в данном случае сумма в валюте учета) должно «проходить» по двум сторонам проводки: по дебету и по кредиту. При установке свойства Балансовый платформа создаст в регистре бухгалтерии с поддержкой корреспонденции одно новое свойство – Сумма. Таким образом, заполняя сумму проводки, пользователь указывает и сумму, на которую изменяется дебетуемый счет проводки, и ту (ее же), на которую изменяется кредитуемый. Каждый ресурс регистра бухгалтерии создает новый вид учета. Первый созданный нами ресурс «создал» в регистре «учет в денежном выражении в валюте учета». Добавляя новые ресурсы, мы можем увеличить функциональность нашей «бухгалтерии», расширив виды учета, которые можно здесь вести. Например, в случае необходимости ведения учета натуральных показателей в регистр бухгалтерии будет добавлен новый ресурс Количество. Добавляя новый ресурс, задумаемся о смысле этого учета. На отдельных счетах материальных ценностей пользователь хочет видеть остатки и обороты по этим счетам не только в стоимостном, но и в натуральном выражении. Само собой разумеется, что контролировать баланс двойной
639
Глава 12. Бухгалтерский учет записи по этому ресурсу смысла не имеет. Во-первых, он будет задействован не для всех счетов (какой экономический смысл ресурс Количество будет иметь для счета учета наличных денег Касса, что будет в нем учитываться – монеты, бумажки, и что будет получаться в итоге от сложения монет и бумажек?). А, во-вторых, в этом ресурсе, возможно, будут учитываться движения в различных единицах измерения (учитываться в количественном выражении будут материальные ценности, которые в программе представлены объектами аналитического учета, а они могут храниться в различных единицах измерения). Вывод: баланс не нужен. Значит, ресурс будет небалансовым. Небалансовые ресурсы предназначены для ведения вспомогательных видов учета, которые по большому счету можно было бы вообще в бухгалтерии не вести, а вести, например, в отдельных учетных регистрах оперативного учета. Но если уж мы поставили перед собой задачу все виды учета вести в регистре бухгалтерии, платформа предоставляет нам инструменты для этого (рис. 12.35).
Экономический смысл количественного учета, рассмотренный нами выше, предполагает, что пользователь должен иметь возможность для каждого счета проводки (и дебетуемого, и кредитуемого) указать свое значение ресурса Количество. При использовании регистра бухгалтерии без поддержки корреспонденций, в котором дебетуемые и кредитуемые счета располагаются в разных записях, в регистр будет добавлено новое поле Количество. Единственным отличием его от поля Сумма будет отсутствие контроля двойной записи. То есть при записи набора движений в базу данных платформа разрешит записать набор, если итог по ресурсу Количество дебетуемых записей не будет равен итогу по этой же графе кредитуемых. В регистре бухгалтерии с поддержкой корреспонденции каждая запись включает сразу два счета, положение которых в проводке (дебетуется или кредитуется) и определяет вид движения по счету. Чтобы предоставить возможность независимого заполнения ресурса для каждой из сторон проводки, платформа добавляет на каждый небалансовый ресурс два поля регистра бухгалтерии. Они отличаются постфиксами (Дт и Кт), подсказывающими, к какому счету проводки поле относится. В данном случае будут добавлены поля КоличествоДт и КоличествоКт. Следует заметить, что дополнительные виды учета можно создавать, добавляя не только небалансовые ресурсы регистра бухгалтерии, но и балансовые. Примером использования в регистре бухгалтерии более одного балансового ресурса может служить трехвалютный учет. При таком виде учета предприятие, входя в состав холдинга, вынуждено готовить отчетность в двух валютах учета, которыми, например, могут быть национальная (для РФ – рубли) и валюта учета холдинга (если руководство холдинга европейское, видимо, это евро).
Рис. 12.35. Ресурс «Количество»
Причем предоставляет возможность не только их создать, но и обеспечить пользователя возможностью добавлять новые учетные регистры, включая в них различные виды учета (универсальность регистра бухгалтерии!), например, количественный.
640
Первое решение, которое приходит в голову, – просто взять всю бухгалтерскую отчетность и пересчитать значение каждого ее показателя по курсу на сдачу отчетности. Однако на такое решение могут возникнуть замечания со стороны руководства холдинга, ведь в течение отчетного периода соотношения курсов национальной валюты и валюты холдинга менялись. И как результат необходимо пересчитывать не итоговые показатели отчетности, а сумму каждой проводки по историческому курсу (т. е. по курсу на дату проводки). Пересчитывать и где-то хранить результат, чтобы можно было быстро получить отчетность. Можно было бы пересчитывать каждый раз, а не хранить, но пересчета по историческому курсу будут требовать не только обороты за период, но и входящие остатки, т. е. считать каждый раз нужно будет с самого начала. Поэтому проще в регистр бухгалтерии добавить еще один балансовый ресурс, который, скорее всего, не будет доступен пользователю для заполнения и изменения, а будет рассчитываться при записи набора движений в регистр. И при составлении отчетности нам останется лишь обратиться к показателям остатков и оборотов по новому виду учета. Профессиональная разработка в системе «1С:Предприятие 8»
Объект «Регистр бухгалтерии»
Свойство ресурса «Признак учета» Как уже было замечено выше, количественный учет, почти как и любой другой дополнительный вид учета, имеет смысл не для всех счетов. Таким образом, может возникнуть необходимость в инструменте, который позволит запретить заполнять ресурс для тех счетов, по которым его ведение не имеет смысла. Это позволит сэкономить время пользователя и исключит ошибки в учете. Решением этой задачи занимается механизм признаков учета. Признаки учета вводятся в плане счетов на закладке Данные. Они всегда имеют тип Булево и, по сути, являются новыми свойствами (специальными реквизитами) счета плана счетов. Количество (и «качество») признаков учета в общем случае должно соответствовать количеству забалансовых ресурсов регистра бухгалтерии. Так, например, если в нашей бухгалтерии ведутся только два вида учета – Суммовой и Количественный, причем суммовой ведется по всем счетам (по нему составляется баланс), необходимо создать один признак учета Количественный (рис. 12.36). Признак учета Количественный, созданный на закладке Данные объекта План счетов, позволит отметить (и нам – предопределенные, и пользователю – те, которые он ввел в план счетов самостоятельно) счета, требующие ведения количественного учета. Пока это просто новая «галочка», новое свойство счета. Чтобы это свойство заработало, необходимо пометить ресурс регистра бухгалтерии, который зависит от этого признака учета. Для этого предназначено свойство ресурса регистра бухгалтерии Признак учета. Теперь заполнение ресурса Количество возможно только в том случае, если в проводке участвует счет, отмеченный флажком Количественный, и только по той стороне проводки регистра с поддержкой корреспонденций, в которой этот счет участвует (рис. 12.37).
Рис. 12.36. Признак учета «Количественный»
Рис. 12.37. Использование признака учета
Том 1
641
Глава 12. Бухгалтерский учет
Свойство ресурса «Признак учета субконто» Создавая аналитический учет в нашей конфигурации, мы предусмотрели, что отдельные виды учета (количественный, валютный), которые задаются в конфигурации ресурсами регистра бухгалтерии, включаются на счетах опционально с помощью признаков учета счетов. Устанавливая такой признак учета, мы (или пользователь для пользовательских счетов) тем самым предоставляем возможность заполнять тот или иной ресурс и в дальнейшем получать остатки и обороты этого ресурса. В случае, когда на счете ведется аналитический учет (один или несколько видов субконто), может возникнуть необходимость отключить для одного из видов субконто ведение одного из видов учета. Классическим примером может служить учет материально-производственных запасов на складах. Обычно запасы учитываются по цене приобретения. При списании запасов со склада оценка производится по одной из принятых в учете методик (по стоимости приобретения каждого объекта, один из вариантов расчета – средний, FIFO, LIFO). При этом если один и тот же номенклатурный номер хранится на разных складах, то при списании с любого из них стоимость списания нужно рассчитать по предприятию в целом. Можно проиллюстрировать учет графически. Рассмотрим ситуацию, когда предприятие закупает один и тот же вид материально-производственных запасов (МПЗ) по разным ценам. Выполним расчет средней стоимости отдельно по каждому складу и по предприятию в целом (рис. 12.38).
Мы видим что средняя, рассчитанная по предприятию в целом (по номенклатурному номеру), и средняя по складу отличаются. При расчете стоимости по складу для правильного ведения учета необходимо хранить информацию о суммовых и количественных (признак учета Количественный) остатках каждого вида МПЗ (аналитический разрез по субконто Номенклатура) на каждом складе (субконто Склады). При расчете стоимости по предприятию учетная схема (признак учета, аналитика) остается без изменений: нам по-прежнему необходимо видеть остатки и суммовые, и количественные по номенклатуре. И по-прежнему нужны остатки по складу, но только количественные (чтобы оценить, хватает ли номенклатуры). Если при расчете себестоимости по предприятию в целом оставить суммовой учет по складам, то в результате на них после списания всего количества будут оставаться отрицательные и положительные остатки на разницу между суммой оприходованных на склад МПЗ и списанных по средней стоимости. Учет наличия и движения средств с необходимой степенью детализации в целях расчета стоимости при списании и получение оперативной отчетности об остатках и оборотах во многих случаях имело бы смысл вынести в отдельную подсистему оперативного учета. Однако, руководствуясь особенностями учета предприятия, мы приняли решение реализовать его в регистре бухгалтерии, где предусмотрена возможность отключения отдельных видов учета с отдельных видов субконто на выбранных счетах. Рассмотрим текущую организацию аналитического учета на примере счета учета товаров (табл. 12.23). Таблица 12.23. Учетный регистр «Товары» Регистр
Измерения
Дополнительные измерения Ресурсы
Товары
Организация
Номенклатура
Склады
Сумма
Количество
Счет товаров ведется, как все счета, в разрезе балансового измерения Организация и двух видов субконто – Номенклатура и Склады. На счете ведется суммовой и количественный учет. Наша задача сводится к тому, чтобы превратить один учетный регистр Товары в два учетных регистра (табл. 12.24). Таблица 12.24. Ведение количественного учета на счете «Товары»
Рис. 12.38. Пример расчета средней себестоимости
642
Регистр
Измерения
Дополнительные измерения
Ресурсы
Товары Товары
Организация Организация
Номенклатура Номенклатура
Сумма Склады
Количество
Первый из них должен хранить остатки и обороты в суммовом выражении в разрезе номенклатуры. Второй должен хранить количественные показатели для каждого номенклатурного номера на каждом складе. Задача решается с помощью признака учета субконто. Профессиональная разработка в системе «1С:Предприятие 8»
Объект «Регистр бухгалтерии» Задача признака учета субконто – отключить ведение одного из видов учета на одном виде субконто одного счета. Признаки учета субконто создаются на закладке Субконто (рис. 12.39).
в котором он будет управлять. Когда каждый признак учета «знает» свой вид учета, можно перейти к настройке счетов. Каждый признак учета субконто дополнит специальную табличную часть Виды субконто новым свойством (колонкой), которое позволит управлять ведением учета. Именно такая настройка счета Товары (см. рис. 12.39) позволит решить поставленную задачу только количественного учета товаров на складах.
Измерения регистра бухгалтерии Все измерения регистра бухгалтерии можно условно разделить на собственно измерения (которым и посвящен этот раздел и которые создаются на закладке Данные свойств регистра бухгалтерии), дополнительные измерения (виды субконто) и обязательные измерения (встроенные, предопределенные, разделы учета – ни одно из этих понятий не является «штатным» описанием механизма, но позволяет понять суть явления), которыми для регистра бухгалтерии с поддержкой корреспонденции являются СчетДебета и СчетКредита, а для регистра без поддержки корреспонденции – Счет и Вид движения (рис. 12.40).
Рис. 12.39. Признаки учета субконто
В общем случае количество признаков учета субконто должно быть меньше или равно количеству ресурсов регистра бухгалтерии. Меньше – потому что не все виды учета, ведущиеся в ресурсах регистра, необходимо отключать. Чтобы предоставить себе и пользователю возможность отключать два вида учета (в нашем случае суммовой и количественный) для отдельных субконто, необходимо создать два признака учета субконто. Для решения нашего примера (расчет стоимости по предприятию в целом) нам было бы достаточно одного признака учета субконто Суммовой, который бы позволил нам отключить ведение суммового учета с субконто Склады. Каждый признак учета, созданный в объекте План счетов, необходимо привязать к ресурсу регистра бухгалтерии – к тому самому, учетом Том 1
Рис. 12.40. Измерения регистра бухгалтерии
643
Глава 12. Бухгалтерский учет Задачи, которые решаются с помощью измерений регистра бухгалтерии, как и сами измерения из ветки Измерения закладки Данные регистра бухгалтерии, можно разделить на две группы: ведение раздельных балансов и получение сводной отчетности (балансовые измерения) и разделение отдельных (или всех, но встречается это реже) разделов учета по какому-то признаку.
ВалютаДт и ВалютаКт. Для регистра без поддержки поле добавляется
одно, но при записи набора движений в регистр контроль двойной записи по каждому значению такого измерения не осуществляется.
Свойство измерения «Балансовый» Балансовые измерения делят весь учет (все разделы учета) на самостоятельные балансы. Баланс, как известно, – замкнутая система показателей. Поэтому если в процессе конфигурирования было добавлено балансовое измерение Организация, значит, по каждой организации (в данном случае список организаций ведется в справочнике Организации) программой будет составлен свой баланс. Это значит, что у каждой организации будут свои активы (касса, расчетные счета, склады и др.), свои обязательства (перед сотрудниками, перед поставщиками) и свой собственный капитал. Именно так и никак иначе! Наличие балансового измерения в регистре бухгалтерии совершенно исключает возможность, например, переместить товары с одной организации в другую. По каждой организации ведется свой баланс. А значит, для решения задачи перемещения товаров нужно в одной организации их списать (на какой-нибудь счет расчетов с той, другой, организацией), а в другой организации их оприходовать (со счета учета расчетов с первой организацией). К слову, в хозрасчетном учете РФ такой счет имеет код 79 и называется Внутрихозяйственные расчеты. Он предназначен для расчетов с обособленными, выделенными на отдельный баланс подразделениями. Схема проводок изображена на рис. 12.41. Мы видим, что счет расчетов закроется только в балансе всего предприятия, как правило, по результатам работы за год. По отдельным же значениям разделителя задолженность будет оставаться. Эта учетная схема – всего лишь один из вариантов ведения учета, и была приведена не как руководство к действию, а как демонстрация всей серьезности шага добавления балансового измерения в регистр бухгалтерии. Балансовое измерение добавляет новое поле во все таблицы регистра бухгалтерии. При записи набора движений в регистр осуществляется контроль двойной записи по каждому значению (сочетанию значений, если балансовых измерений несколько) балансового измерения. Небалансовое измерение по своей сути напоминает субконто. Так же как и субконто, оно делит не все разделы учета на самостоятельные балансы, а, как правило, лишь некоторые, или все разделы учета, но баланса по нему получить нельзя. Для регистра с поддержкой корреспонденции добавляются два поля – по одному на каждую сторону проводки, например,
644
Рис. 12.41. Расчеты с обособленными подразделениями
Небалансовое измерение можно сравнить с субконто, которое в обязательном порядке прикрепили ко всем счетам. Хотя хранение в физических таблицах регистра у них различное, функционально механизмы небалансовых измерений и субконто похожи (табл. 12.25). Таблица 12.25. Сравнение небалансовых измерений и субконто Критерий
Небалансовое измерение
Субконто
Компактность хранения в базе
Поле резервируется даже для счетов, где измерение не используется Любой, чаще просто ссылка на справочник
Резервируется только в том случае, если субконто на счете используется
Тип данных Возможность включить/ отключить для конкретного счета Всегда на своем месте
Да, с помощью признаков учета Да
Всегда составной, причем состав определятся для плана видов характеристик Да, при подключении вида субконто на счет Может быть любым по порядку на счете, и для пользовательских счетов порядок может быть задан произвольно пользователем
Профессиональная разработка в системе «1С:Предприятие 8»
Объект «Регистр бухгалтерии» Таким образом, можно предложить использование небалансового измерения вместо субконто в том случае, если данный признак аналитики используется на всех (или на подавляющем большинстве) счетах. Более того, в этом случае можно считать использование измерения более оптимальным, чем субконто, что связано с типом данных. Приведем пример: организации необходимо вести учет почти всех разделов учета в разрезе источников финансирования. Для решения этой задачи можно воспользоваться или добавлением субсчетов к нужным (почти всем) счетам, или добавлением на них нового вида субконто, или добавлением в регистр нового небалансового измерения. У каждого решения есть свои плюсы и минусы (табл. 12.26). Таблица 12.26. Сравнение субсчетов, субконто и небалансовых измерений Решение
Плюсы
Минусы
Субсчета
Может потребовать незначительного изменения типового решения, если оно с самого начала предусматривало возможность расширения субсчетов второго или третьего уровня Может потребовать незначительного изменения типового решения, если уложиться в максимальное число субконто для плана счетов
Сложность получения отчетности по одному источнику финансирования и сложность ведения учета изза значительного числа счетов в плане счетов Может потребовать значительных изменений, если все субконто для отдельных счетов уже заняты и нужно увеличивать максимальное число субконто. Увеличение максимального числа субконто может негативно повлиять на производительность Потребует значительных изменений типового решения
Субконто
Небалансовое измерение
Позволит разделить учет более оптимально, чем в случае субконто, и удобно подготавливать отчетность, как по значению измерения, так и сводно
Свойство измерения «Признак учета» Еще один вариант использования небалансовых измерений – добавление нового вида учета, требующего не только учета нового показателя (ресурса), но и ведения нового разреза для этого и других (например, Сумма) ресурсов. Даже если этот новый вид учета используется далеко не на всех счетах, а место под новое измерение будет все равно резервироваться для всех счетов, использование механизма небалансовых измерений оправдано необходимостью создать универсальный механизм, который сможет использовать и пользователь системы.
Том 1
Примером такого использования может служить валютный (многовалютый, мультивалютный) учет. Суть учета состоит в том, что для отдельных (не всех) счетов необходимо учитывать не только показатели в валюте учета (ресурс Сумма), но и в иностранных валютах. Если бы иностранная валюта была одна, этот вид учета ничем не отличался бы от учета количественного, который мы рассмотрели в разделе, посвященном признакам учета ресурса регистра бухгалтерии. Но валют может быть много, и по каждой из них мы хотим видеть остатки и обороты, как в валюте, так и валюте учета. Другими словами, нам необходим разрез по валютам. Развивая тему количественного учета и доводя его до абсурда, можно предложить схожее решение для задачи количественного учета в разрезе единиц измерения. В этом случае к небалансовому ресурсу Количество нам пришлось бы добавить небалансовое измерение Единица измерения и связать их признаком учета, чтобы пользователь мог одним щелчком мыши включить новый вид учета на счете. Подчеркнем еще раз – это именно пример абсурдного использования регистра бухгалтерии. Для решения задач наличия и движения средств с целью управления ими (а не предприятием в целом, как в нашем случае) существуют механизмы оперативного учета. Возвращаясь к задаче ведения валютного учета, который, как правило, является обязанностью бухгалтерии, заметим, что кроме справочника Валюты нам потребуется еще один связанный с ним объект – периодический регистр сведений Курсы валют. Регистр будет иметь измерение Валюта типа Ссылка на справочник Валюты и ресурс Курс типа Число, а если требуется вести учет в валютах с очень маленькими значениями курса, то два ресурса – Курс и Кратность, и для получения эквивалента в валюте учета валютную сумму нужно будет сначала умножить на курс, а затем разделить на кратность. Какие изменения коснутся механизмов бухгалтерии? Во-первых, необходимо добавить новый признак учета в плане счетов Валютный (рис. 12.42). Он позволит отметить те счета, которые требуют ведения валютного учета. Во-вторых, нужно добавить новый ресурс регистра бухгалтерии ВалютнаяСумма, где будет храниться сумма в валюте. И, в-третьих, добавить новое небалансовое измерение регистра бухгалтерии Валюта – ссылка на элемент справочника Валюты, по которому будет «разделен» учет отмеченного признаком счета.
645
Глава 12. Бухгалтерский учет Схему взаимодействия (рис. 12.43).
объектов
можно
изобразить
графически
Рис. 12.43. Схема взаимодействия объектов
Результат: при установке одного флажка в настройках счета для счета становятся доступными для заполнения новый ресурс и новое измерение.
Запись движений в регистр бухгалтерии Регистр бухгалтерии подчинен регистратору, и движения в регистре можно сделать, только указав в движении ссылку на документ-регистратор. Регистратором может являться любой документ системы. Выбрать документ как регистратор можно или на закладке Регистраторы регистра бухгалтерии (рис. 12.44), или на закладке Движения документа (рис. 12.45).
Рис. 12.42. Признак учета «Валютный»
646
Рис. 12.44. Регистраторы регистра бухгалтерии
Профессиональная разработка в системе «1С:Предприятие 8»
Запись движений в регистр бухгалтерии Коллекция содержит столько элементов, для скольких регистров документ является регистратором. В приведенном примере коллекция Движения документа Операция содержит всего один элемент ОсновнойРегистрБухгалтерии – это набор записей регистра бухгалтерии Основной регистр бухгалтерии. Каждый набор записей может содержать сколько угодно записей одного регистра, подчиненных документу-регистратору. Изменять набор записей регистра из коллекции Движения можно как из документа, так и из любого другого программного модуля, интерактивно или программно. В любом случае набор записей регистра позволит прочитать из базы данных существующий набор записей, изменить его и записать в базу данных одной транзакцией. Можно предложить следующие основные варианты изменения наборов записей регистра. Рис. 12.45. Движения документа
Интерактивно: ручная операция
По сути, на этих закладках разных объектов отображается одна и та же информация. Движение в регистр может быть сделано разными способами (мы рассмотрим ниже), но без ссылки на документ-регистратор сделать движение невозможно (рис. 12.46).
Одно из отличий бухгалтерского учета от оперативного состоит в том, что он охватывает все предприятие в целом. Поэтому автоматизировать все операции, алгоритмизировав формирование проводок документами, фактически невозможно. Все равно останутся операции (корреспонденции счетов), про которые забыли. Поэтому, как правило, при автоматизации бухгалтерского учета автоматизируется формирование проводок документами только для регулярно встречающихся операций, а для остальных создается документ Операция, который позволяет пользователю, по сути, редактировать регистр бухгалтерии «вручную», вводя любые проводки. Во-первых, документ нам нужен как ссылка, которая будет прописана в поле Регистратор регистра бухгалтерии. А во-вторых, мы задействуем его свойство Движения, содержащее набор записей регистра бухгалтерии, который мы хотим разрешить изменять пользователю. Подробнее
Этот пример приведен в демонстрационной конфигурации «Бухгалтерский учет», которая находится на прилагаемом компакт-диске.
Рис. 12.46. Движения документа
Документ, во-первых, требуется как «ссылка», которая будет прописана в одно из полей регистра бухгалтерии, а, во-вторых, документ обладает коллекцией наборов записей Движения, которая используется для записи движений в регистры. Коллекция Движения содержит в себе наборы записей регистров, по которым документ может делать движения. Том 1
Создадим новый документ Операция с реквизитом Организация (СправочникСсылка.Организации). В свойствах этого документа на закладке Движения мы установим следующие свойства (рис. 12.47). Документ не будет проводиться (свойство Проведение: запретить). Это означает, что при записи документа в базу данных не будет выполняться алгоритм проведения документа, расположенный в обработчике события модуля объекта Обработка проведения.
647
Глава 12. Бухгалтерский учет
■■ ■■
■■
Рис. 12.47. Движения документа «Операция»
Документ будет являться регистратором для регистра бухгалтерии. Установка этого свойства привела к тому, что в коллекции Движения появился набор записей регистра бухгалтерии ОсновнойРегистрБухгалтерии, который позволит изменять этот регистр бухгалтерии. Заполнять этот набор записей проводками можно разными способами. Поставленная нами задача создания документа Операция предполагает, что набор записей будет заполняться пользователем интерактивно, т. е. в форме документа.
■■ ■■
■■
Создавая форму документа, в окне элементов формы мы размещаем таблицу, отображающую данные Объект.Движения.ОсновнойРегистрБухгалтерии. При этом автоматически добавляем в нее колонки, соответствующие свойствам регистра бухгалтерии. Затем вручную откорректируем состав колонок таблицы движений регистра, который заполнила платформа. Удалим из таблицы колонки Период и Организация и добавим поле Активность. Часть свойств мы разместим в диалоге формы, часть будем заполнять программно, часть предоставим заполнять платформе. Рассмотрим все свойства нашего регистра подробнее. ■■ Регистратор – ссылка на документ, в нашем случае на документ Операция. Поле составного типа данных, количество типов зависит от того, сколько документов могут являться регистраторами
648
■■ ■■
для регистра. Платформа не разрешит сделать движение в регистр «по другому регистратору». Поэтому свойство не имеет смысла включать в диалог формы и заполнять программно при проведении или записи регистра, платформа сама запишет в него документ-регистратор; НомерСтроки – номер записи, нумерация начинается с 1; Активность – свойство записи должно быть одинаковым для всех записей одного регистратора, в противном случае платформа не разрешит записать набор в регистр. Записи с установленным свойством отражаются в таблицах итогов и включаются в виртуальные таблицы регистра бухгалтерии. «Неактивные» записи существуют только в таблицах первичных движений и не влияют на бухгалтерскую отчетность; Период – содержит дату периода, в итоги которого должна попасть проводка. Поле не может быть пустым и должно быть обязательно заполнено или интерактивно, или программно при записи набора в регистр. Периоды разных записей даже одного набора могут отличаться. Период записи может отличаться от даты документа регистратора. В регламентированном бухгалтерском учете возможность документа записывать проводки датой, отличной от даты документа, редко находит свое применение, однако можно предположить, что в других разделах учета, таких как управленческий учет и бюджетирование, использующих механизмы бухгалтерского учета для получения баланса, свойство может пригодиться; СчетДт, СчетКт – ссылки на счет, который выбран в свойствах регистра. Наличие двух счетов в проводке обусловлено свойством Корреспонденция; СубконтоДт1, СубконтоДт2, СубконтоКт1, СубконтоКт2 – в свойствах плана счетов установлено максимальное количество субконто равным 2. Поля составного типа данных, который определен в свойствах плана видов характеристик, выбранного в плане счетов; Организация – балансовое измерение регистра, в нашем случае предназначенное для получения отчетности в разрезе самостоятельных организаций (юридических лиц или обособленных подразделений, выделенных на отдельный баланс). Измерение является свойством каждого движения, но в нашем случае мы будем исходить из предположения, что каждая операция в бухгалтерском учете должна быть подкреплена первичным документом и на нем должна быть печать. Причем печать одной организации. Поэтому принимаем решение заполнять поле Организация одним значением (из шапки документа) для всех записей и делать это программно; ВалютаДт, ВалютаКт – небалансовое измерение регистра бухгалтерии породило два поля в регистре (для дебетовой и для кредитовой стороны проводки); Сумма, СуммаХолдинга – балансовые ресурсы, единые для обеих сторон проводки;
Профессиональная разработка в системе «1С:Предприятие 8»
Запись движений в регистр бухгалтерии ■■ КоличествоДт, КоличествоКт, ВалютнаяСуммаДт, ВалютнаяСуммаКт – небалансовые ресурсы, для каждой стороны проводки свой; ■■ Содержание – реквизит регистра. Для выбора организации в шапке документа был размещен реквизит документа Организация. Записать организацию и дату документа в соответствующие поля записи регистра бухгалтерии позволит обработчик события Перед записью формы или объекта документа. Мы воспользуемся событием объекта, чтобы обрабатывать не только интерактивную, но и программную запись документа (листинг 12.14). Листинг 12.14. Обработчик события «ПередЗаписью»
Процедура ПередЗаписью(Отказ, РежимЗаписи, РежимПроведения) Для Каждого Проводка Из Движения.ОсновнойРегистрБухгалтерии Цикл Проводка.Период = Дата; Проводка.Организация = Организация; КонецЦикла; КонецПроцедуры
Пример заполненного документа Операция представлен на рис. 12.48.
Таблицы итогов как источники данных запроса недоступны и являются (вместе с таблицами первичных движений) источниками данных при создании платформой виртуальных таблиц регистра бухгалтерии. Именно они и служат источниками данных для большинства отчетов. Виртуальные таблицы, как правило, включают только активные записи. Таким образом, активность – это свойство записи, позволяющее пользователю системы проанализировать, а что было бы, если этой проводки не было. Проводка с выключенной активностью не удаляется из базы данных. Если сравнивать удаление движения и отключение активности этого движения, то разница будет заметна в первую очередь на документах, которые формируют движения автоматически при проведении. Сделав такой документ непроведенным, удалив все движения, пользователь, конечно, сможет проанализировать данные отчетов «без этого документа». Но включение этого документа обратно в учет потребует его перепроведения, при котором движения будут сформированы заново и новые. То есть существует вероятность, что повторное исполнение алгоритма проведения в возможно изменившихся условиях приведет к формированию других движений. Если же воспользоваться свойством Активность, то повторное включение документа в учет не потребует его перепроведения. Старые проводки не были удалены, они просто были исключены из итогов. При включении активности в итоги будут включены те же проводки, которые были выключены, а не новые. Листинг 12.15 содержит процедуру, которая может быть расположена в модуле формы документа и позволяет управлять активностью записей регистра. Листинг 12.15. Пример процедуры, переключающей активность записей
&НаСервере Процедура ПереключитьАктивностьПроводок() Рис. 12.48. Документ «Операция»
Активность Активность – свойство записи регистра, влияющее на отражение этой записи
в таблицах итогов регистра. Активные записи находят свое отражение в итогах и как следствие попадают в отчеты, неактивные – нет. Физической организации таблиц регистра посвящен отдельный раздел нашей главы, пока же можно заметить, что все таблицы регистра бухгалтерии разделяются на таблицы первичных движений (собственно проводки и значения субконто этих проводок) и таблицы итогов, которые хранят информацию об остатках и оборотах на счетах и субконто, сгруппированную по месяцам. Физические таблицы могут быть использованы разработчиком для написания запросов, но используются как источник данных редко. Том 1
Документ = РеквизитФормыВЗначение("Объект"); Проводки = Документ.Движения.ОсновнойРегистрБухгалтерии; КоличествоПроводок = Проводки.Количество(); Если КоличествоПроводок > 0 Тогда Проводки.УстановитьАктивность(НЕ Проводки[0].Активность); КонецЕсли; ЗначениеВРеквизитФормы(Документ, "Объект"); КонецПроцедуры
Процедура получает активность первой записи из набора (с индексом 0), инвертирует ее (НЕ) и устанавливает полученную в результате активность для всего набора.
649
Глава 12. Бухгалтерский учет Рассмотрим еще один вариант использования этого свойства движения на примере документа Операция. Операция не хранит в себе движения, а лишь объединяет их одним регистратором, которым и является. Документ не проводится (не выполняет алгоритм проведения документа) и поэтому не может быть снят с проведения. Если установить на документ пометку на удаление, записи в регистре остаются неизмененными, т. е. даже удаленная операция продолжает участвовать в учете. Поставим задачу – удаленная операция не должна участвовать в учете, не должна попадать в отчеты. Но должна быть возможность, сняв пометку на удаление, вернуть ее в учет. Для этого воспользуемся свойством Активность движения регистра. При установке пометки удаления документа будем снимать активность записей, при снятии пометки на удаление – восстанавливать активность записей (листинг 12.16). Листинг 12.16. Управление активностью записей при установке/снятии пометки удаления документа
Процедура ПередЗаписью(Отказ, РежимЗаписи, РежимПроведения) Проводки = Движения.ОсновнойРегистрБухгалтерии; НужноСчитатьНабор = (НЕ Ссылка.Пустая() И НЕ Проводки.Модифицированность() И НЕ Проводки.Выбран()); Если НужноСчитатьНабор Тогда Проводки.Прочитать(); КонецЕсли; КоличествоПроводок = Проводки.Количество(); Если КоличествоПроводок > 0 Тогда ТекущаяАктивностьПроводок = Проводки[0].Активность; НужнаяАктивностьПроводок = НЕ ПометкаУдаления; Если ТекущаяАктивностьПроводок <> НужнаяАктивностьПроводок Тогда Проводки.УстановитьАктивность(НужнаяАктивностьПроводок); КонецЕсли; КонецЕсли; КонецПроцедуры
Прокомментируем работу процедуры. Обработчик события Перед записью объекта документа выполняется перед каждой записью документа. Отметка о проведении документа является свойством документа. После изменения этого свойства платформа производит запись документа в базу. Процедура получает в переменной Проводки набор записей регистра движений документа. Запись движений в регистр осуществляется в разных ситуациях. Это может быть интерактивная запись нового документа пользователем, запись измененного документа пользователем, удаление или снятие пометки удаления документа.
650
Документ в момент открытия формы считывает набор записей из регистра бухгалтерии. Если форму не открывали, а установка пометки удаления осуществляется без открытия формы, необходимо прочитать из информационной базы набор записей регистра. Необходимость считывать набор из регистра определяется совпадением трех условий: ■■ этот документ не новый; если он новый, то набор записей документа еще не записан в базу, а находится в документе; ■■ набор записей регистра не был изменен; если он был изменен, то считывание его из базы затрет изменения пользователя; ■■ набор еще не считывался из базы данных, что позволяет узнать метод Выбран(). Если все три условия присутствуют, считываем из регистра набор записей и выполняем действия с ним. Проверив количество движений в наборе записей, мы получаем текущую активность движений набора записей по первой записи и устанавливаем нужную активность для набора записей.
Программно при проведении документа Формирование и запись проводок в момент проведения документа можно считать основными вариантами изменения регистра бухгалтерии. В отличие от документа Операция, запись проводок при проведении позволяет описать сложный алгоритм формирования проводок, вычисление сумм и обусловленное заполнение других свойств записей и используется для автоматизации ввода часто встречающихся в практике учета операций. В этом случае заполнение набора записей регистра осуществляется в обработчике события проведения документа ОбработкаПроведения. Несложный алгоритм проведения, использующий при заполнении свойств движений преимущественно значений реквизитов документа, можно разработать с использованием конструктора движений. Рассмотрим его работу на примере документа ПриходнаяНакладная. Документ предназначен для ввода проводок закупки товаров у поставщика. Подробнее
Этот пример приведен в демонстрационной конфигурации «Бухгалтерский учет», которая находится на прилагаемом компакт-диске.
В шапке документа пользователь сможет выбрать организацию (из справочника Организации), поставщика (из справочника Контрагенты) и склад (из справочника Склады). В табличной части будут выбираться товары (из справочника Номенклатура), вводиться цена покупки, количество и сумма товара (рис. 12.49). Форма документа включает все перечисленные реквизиты. Профессиональная разработка в системе «1С:Предприятие 8»
Запись движений в регистр бухгалтерии Движение.СубконтоДт[ПланыВидовХарактеристик.ВидыСубконто. Номенклатура] = ТекСтрокаТовары.Номенклатура; Движение.СубконтоДт[ПланыВидовХарактеристик.ВидыСубконто.Склады] = Склад; Движение.СубконтоКт[ПланыВидовХарактеристик.ВидыСубконто. Контрагенты] = Поставщик; КонецЦикла; КонецПроцедуры
Рис. 12.49. Данные документа «ПриходнаяНакладная»
Конструктор движений документа Алгоритм проведения такого документа может быть полностью сформирован конструктором движений документа, вызываемым по кнопке Конструктор движений с закладки Движения свойств документа (рис. 12.50). Результатом работы конструктора (убраны только комментарии) будет процедура в модуле объекта (листинг 12.17). Листинг 12.17. Процедура «ОбработкаПроведения()»
Процедура ОбработкаПроведения(Отказ, Режим)
Движения.ОсновнойРегистрБухгалтерии.Записывать = Истина;
Для Каждого ТекСтрокаТовары Из Товары Цикл Движение = Движения.ОсновнойРегистрБухгалтерии.Добавить(); Движение.СчетДт = ПланыСчетов.ОсновнойПланСчетов.Товары; Движение.СчетКт = ПланыСчетов.ОсновнойПланСчетов.Поставщики; Движение.Период = Дата; Движение.Организация = Организация; Движение.Сумма = ТекСтрокаТовары.Сумма; Движение.КоличествоДт = ТекСтрокаТовары.Количество; Движение.Содержание = "Покупка товара";
Том 1
Рис. 12.50. Конструктор движений регистров
Сначала указываются наборы записей, содержащие движения документа по регистрам, которые должны быть записаны при проведении документа. В цикле по табличной части Товары в набор записей регистра бухгалтерии, расположенный в коллекции движений, добавляется новое движение. Далее заполняются свойства записи регистра. После выхода из обработки проведения те наборы записей, у которых свойство Записывать имеет значение Истина, будут автоматически записаны платформой. В этот типовой алгоритм, сформированный конструктором, можно было бы внести изменения. Возможен альтернативный вариант синтаксиса при заполнении субконто проводки. Вариант, используемый конструктором, является более универсальным и больше подходит для документов, где счет выбирается в диалоге пользователем (листинг 12.18).
651
Глава 12. Бухгалтерский учет Листинг 12.18. Пример установки значения субконто
Движение.СубконтоКт[ПланыВидовХарактеристик.ВидыСубконто.Контрагенты] = Поставщик;
В этой строке обращение к элементу коллекции субконто кредита проводки производится с использованием оператора «[ ]», в который в качестве параметра необходимо передать ссылку на вид характеристик. В нашем случае ссылки на элементы видов субконто получаются по предопределенным (неизменяемым) именам видов субконто, и поэтому можно было бы использовать упрощенный синтаксис (листинг 12.19).
расширения формы документа стандартно установится в значение Автоматически. Если установить свойство ИспользоватьРежимПроведения в значение Оперативный и попытаться провести документ задним числом, то пользователю будет выдано предупреждение и отказано в проведении документа (рис. 12.52).
Листинг 12.19. Пример установки значения субконто
Движение.СубконтоКт.Контрагенты = Поставщик; Рис. 12.52. Предупреждение о невозможности оперативного проведения задним числом
Оперативное и неоперативное проведение Оперативность – это свойство документа, используемое в первую очередь при решении задач оперативного учета в реальном времени. Бухгалтерия редко работает в реальном времени. Как правило, бухгалтер работает со свершившимися событиями, обрабатывая первичные документы за отчетный период. Поэтому свойство документа Оперативное проведение обычно при решении задач бухгалтерского учета устанавливают в значение Запретить. Тем не менее, практика автоматизации учета малых предприятий показывает частое использование механизмов бухгалтерского учета для решения задач учета оперативного, поэтому мы кратко рассмотрим это свойство и возможности его использования. подробнее
Раздел «Оперативный учет. Описание задач, решаемых регистрами накопления», стр. 545.
Свойство Оперативное проведение, установленное в значение Разрешить, позволит контролировать ввод документов задним числом и запретить ввод документов будущей датой. При попытке проведения документа будущей датой пользователю будет выдано предупреждение и отказано в проведении документа (рис. 12.51).
Рис. 12.51. Предупреждение о невозможности оперативного проведения будущей датой
При вводе документа задним числом платформа автоматически проведет документ неоперативно, так как свойство ИспользоватьРежимПроведения
652
Если же установить свойство ИспользоватьРежимПроведения в значение Запрашивать, то пользователю будет предложено выбрать режим проведения документа (рис. 12.53).
Рис. 12.53. Выбор режима проведения
Пользователь может изменить дату документа на текущую и провести документ оперативно, выбрав режим Оперативное проведение, или отказаться от оперативного проведения, и тогда документ будет проведен неоперативно и записан в базу с существующей датой и временем. подробнее
Раздел «Установка режима проведения», стр. 521.
При проведении документа во второй параметр процедуры ОбработкаПроведения будет передано значение системного перечисления РежимПроведенияДокумента – Оперативный или Неоперативный, которое и может анализировать разработчик конфигурации с целью принятия решения о способе проведения документа. Основная задача, которую может помочь решить разделение проведения документа на оперативное и неоперативное, – это сокращение времени на проведение документа, если документы вводятся в реальном времени и в правильной (реальной, соответствующей событиям в реальной жизни) хронологической последовательности. Время на проведение документа всегда является критичным фактором в оценке удобства эксплуатации Профессиональная разработка в системе «1С:Предприятие 8»
Запись движений в регистр бухгалтерии системы, особенно если в ней работает большое число пользователей, и особенно если они работают в реальном времени. Рассматриваемая нами в качестве примера приходная накладная вряд ли может улучшить свою работу, ведь всю необходимую для проведения информацию она содержит в себе и не обращается к другим объектам базы данных. А вот, например, расходная накладная, списывая товар, обязательно должна проверить его наличие по данным учетных регистров (в нашем случае счета Товары регистра бухгалтерии), рассчитать себестоимость и многое другое. В большинстве случаев извлечение данных из базы выполняется с помощью запроса (исключение может составлять лишь получение одного значения, тогда допускается использование метода объекта). Физическая организация таблиц регистра бухгалтерии (более подробно об этом пойдет речь ниже) позволяет наиболее быстро выполнить запрос к текущим итогам. Текущие итоги хранятся в регистре и пересчитываются при любом движении в регистре. Но в каком случае мы можем воспользоваться этими текущими итогами? Только тогда, когда уверены, что, во-первых, не вводились документы будущей датой, и, во-вторых, документ вводится с текущим временем, и, стало быть, нужно «снимать» текущие итоги. Если документ вводится задним числом, то для оценки возможности его проведения, расчета остатков и себестоимости обязательно нужно получать не текущие итоги, а итоги на момент времени документа, что увеличивает время проведения документа. Таким образом, если стоит задача учета документов в реальном времени и большинство документов вводятся в правильной хронологической последовательности, оперативное проведение может существенно сократить время на проведение и улучшить работу пользователей.
Автоматическое удаление движений Свойство документа Удаление движений устанавливается на закладке Движения и может принимать значения Удалять автоматически при отмене проведения (стандартное значение), Удалять автоматически или Не удалять автоматически. В случае значения Удалять автоматически при отмене проведения для свойства Удаление движений движения, связанные с документом, удаляются автоматически только при удалении и отмене проведения документа. При проведении документа движения не удаляются, а перезаписываются. Такое поведение является стандартным для платформы «1С:Предприятие». Используя два других значения свойства Удаление движений, разработчик может реализовывать нестандартные сценарии проведения документа. В случае значения Удалять автоматически для свойства Удаление движений платформа автоматически удаляет старые записи движений, связанных с данным документом, при повторном проведении документа перед Том 1
записью новых движений, а также при удалении и отмене проведения документа. Отключение этого режима имеет смысл, прежде всего, при решении задач оперативного учета в реальном времени. В случае же значения Не удалять автоматически для свойства Удаление движений автоматическое удаление движений для этих ситуаций производиться не будет. Один из вариантов использования документа с отключенным автоматическим удалением движений – построчное проведение документа. При решении задачи автоматизации учета продавцов товаров в реальном времени это свойство может быть актуально. Представим себе ситуацию, что два менеджера продают один и тот же товар, количество которого ограничено. Пока первый из них, удостоверившись в наличии товара на складе по данным регистра, проводит свой документ с установленным свойством Автоматическое удаление движений, второй менеджер за те мгновения, когда старые движения уже удалены, а новые еще не записаны, успевает провести свой документ. Научившись на горьком опыте, первый менеджер начинает нажимать кнопку Провести после добавления каждой строки документа. Но при проведении каждый раз удаляются все ранее сформированные записи в регистре и формируются новые. И между этими двумя событиями все равно остается временной лаг, достаточный для списания товара вторым менеджером. Решение этой проблемы – построчное проведение документа первым менеджером, при котором запись по новой строке добавляется в регистр без удаления всех ранее сделанных движений документа. В этом случае контроль удаления записей при проведении документа в целом, отмене проведения и удалении документа лежит на программисте, разрабатывающем этот документ. Мы рассмотрели последние две темы поверхностно по одной и той же причине: бухгалтерский учет почти никогда не требует работы пользователей в реальном времени.
Программно без проведения документа Документ может иметь движения в регистре, и не будучи проведенным. Для записи движений в регистр можно использовать или свойство документа Движения, содержащее коллекцию наборов записей, или набор записей регистра бухгалтерии. Этот вариант формирования движений в регистр нельзя считать основным. Его можно рекомендовать для офф-лайнового проведения документа, когда в реальном времени документ проводится в оперативном учете, а отражение операции в бухгалтерском учете выполняется в конце отчетного периода. В этом случае можно предложить один из следующих вариантов (листинг 12.20).
653
Глава 12. Бухгалтерский учет Листинг 12.20. Пример записи движений документа
Приходные = Документы.ПриходнаяНакладная.Выбрать(); Пока Приходные.Следующий() Цикл ПриходнаяОбъект = Приходные.ПолучитьОбъект(); Проводки = ПриходнаяОбъект.Движения.ОсновнойРегистрБухгалтерии;
НоваяПроводка = Проводки.Добавить(); НоваяПроводка.Период = ПриходнаяОбъект.Дата; НоваяПроводка.Организация = ПриходнаяОбъект.Организация; НоваяПроводка.СчетДт = ПланыСчетов.ОсновнойПланСчетов.Товары; НоваяПроводка.СчетКт = ПланыСчетов.ОсновнойПланСчетов.Поставщики; НоваяПроводка.Сумма = ПриходнаяОбъект.Всего;
Проводки.Записать(Ложь); КонецЦикла;
Предложенный выше код может располагаться в любой обработке. Программный код получает из базы данных выборку документов, и для каждого из них, создавая объект документа, выполняет заполнение набора записей движениями и запись его в регистр добавлением к тем записям, которые уже существуют в регистре. В приведенном примере для записи движений в регистр используется свойство документа Движения. Можно не использовать его, а воспользоваться набором записей регистра бухгалтерии. Следующий фрагмент кода выполняет ту же задачу, но с использованием объекта РегистрБухгалтерииНаборЗаписей.ОсновнойРегистрБухгалтерии (листинг 12.21).
Оба варианта кода предусматривают возможность непроведенного документа иметь движения. Необходимо, однако, учитывать, что повторное проведение документа штатным способом (интерактивно из формы или программно методом документа Записать(РежимЗаписиДокумента. Проведение)) не будет учитывать наличие добавленной нами записи. Так, например, если в свойствах документа установлено свойство автоматического удаления движения, будет удалено и дополнительное, сделанное обработкой движение. А при формировании движений из процедуры ОбработкаПроведения не будет добавлено движение, описанное в обработке.
Чтение данных регистра бухгалтерии Для чтения данных регистра бухгалтерии в системе «1С:Предприятие» предусмотрены методы объекта РегистрБухгалтерии и набор таблиц, используемых запросом как источники данных. Основным способом извлечения данных в системе является запрос. Мы полагаем, что это утверждение актуально и для регистра бухгалтерии, поэтому начнем изучение подходов к извлечению данных об остатках и оборотах на счетах с изучения таблиц регистра – источников данных запроса. Методы объекта, которые можно считать вспомогательным механизмом, будут рассмотрены позднее.
Таблицы регистра бухгалтерии Регистр бухгалтерии – сложный объект, представленный в табличной модели данных рядом таблиц (рис. 12.54).
Листинг 12.21. Пример записи движений документа
Приходные = Документы.ПриходнаяНакладная.Выбрать(); Проводки = РегистрыБухгалтерии.ОсновнойРегистрБухгалтерии.СоздатьНаборЗаписей(); Пока Приходные.Следующий() Цикл ПриходнаяСсылка = Приходные.Ссылка; Проводки.Отбор.Регистратор.Установить(ПриходнаяСсылка);
НоваяПроводка = Проводки.Добавить(); НоваяПроводка.Период = ПриходнаяСсылка.Дата; НоваяПроводка.Организация = ПриходнаяСсылка.Организация; НоваяПроводка.СчетДт = ПланыСчетов.ОсновнойПланСчетов.Товары; НоваяПроводка.СчетКт = ПланыСчетов.ОсновнойПланСчетов.Поставщики; НоваяПроводка.Сумма = ПриходнаяСсылка.Всего;
Проводки.Записать(Ложь); КонецЦикла;
При использовании набора записей регистра от документа нам нужна ссылка, чтобы по ней установить отбор в наборе записей. Затем, используя методы набора записей регистра, мы добавляем нужную запись в набор записей и записываем его с добавлением.
654
Рис. 12.54. Таблицы запросов регистра бухгалтерии
Профессиональная разработка в системе «1С:Предприятие 8»
Чтение данных регистра бухгалтерии Все таблицы регистра бухгалтерии можно разделить на две группы: реальные и виртуальные. Реальные таблицы предоставляют доступ посредством запроса к физически существующим в информационной базе таблицам. У регистра бухгалтерии таких таблиц две: основная таблица и таблица значений субконто, которая создается в информационной базе после добавления в конфигурацию механизмов аналитического учета.
Реальные таблицы Имя основной таблицы регистра бухгалтерии содержит имя регистра. И для использования ее в качестве источника данных в нашем случае необходимо написать следующее предложение (листинг 12.22). Листинг 12.22. Обращение к таблице записей регистра бухгалтерии
ИЗ
РегистрБухгалтерии.ОсновнойРегистрБухгалтерии
Основная таблица регистра бухгалтерии с поддержкой корреспонденции содержит следующие поля (табл. 12.27). Таблица 12.27. Поля основной таблицы регистра бухгалтерии Поле
Тип
Комментарий
Период
Дата
Регистратор
ДокументСсылка.<имя>
НомерСтроки
Число
Активность
Булево
СчетДт
ПланыСчетовСсылка.<имя>
СчетКт
ПланыСчетовСсылка.<имя>
<Измерение>
Определяется типом измерения
Дата движения Документ движения Номер движения в наборе записей Участвует ли запись в таблицах итогов Дебетуемый счет Кредитуемый счет Балансовое измерение регистра бухгалтерии Небалансовое измерение регистра бухгалтерии создает два поля в регистре
<Измерение>Дт Определяется типом измерения <Измерение>Кт
Определяется типом измерения
<Ресурс>
Число
<Ресурс>Дт
Число
<Ресурс>Кт
Число
Балансовый ресурс регистра бухгалтерии Небалансовый ресурс регистра бухгалтерии создает два поля в регистре
<Реквизит>
Определяется типом реквизита
Характеристика движения регистра
Основная таблица регистра бухгалтерии без поддержки корреспонденции отличается отсутствием корреспонденции счетов и отсутствием деления измерений на балансовые и небалансовые, которые в таблице регистра с поддержкой корреспонденции были представлены двумя полями – свое для дебета и свое для кредита. В регистре без поддержки корреспонденции также присутствуют поля ВидДвижения и Счет. Основная таблица хранит проводки (движения регистра бухгалтерии) без данных аналитического учета. Для хранения данных аналитического учета Том 1
предназначена вторая реальная таблица регистра бухгалтерии – таблица значений субконто. Эта таблица не содержит числовых характеристик и вряд ли может использоваться самостоятельно. В таблице хранится информация о виде и значении каждого субконто проводки. Для получения полной информации о проводке (включая данные аналитического учета) система соединяет данные таблицы движений и таблицы значений субконто по периоду, регистратору и виду движения. Субконто хранятся платформой компактно, и количество полей этой таблицы не зависит от количества субконто на счете. Чем больше субконто описано в проводке, тем больше записей будет содержать таблица значений субконто. Одной проводке из основной таблицы может соответствовать несколько записей таблицы значений субконто. Обращение к таблице значений субконто в нашем случае будет выглядеть так (листинг 12.23). Листинг 12.23. Обращение к таблице значений субконто
ИЗ
РегистрБухгалтерии.ОсновнойРегистрБухгалтерии.Субконто
Таблица значений субконто регистра бухгалтерии содержит следующие поля (табл. 12.28). Таблица 12.28. Поля таблицы значений субконто Поле
Тип
Период
Дата
Регистратор
ДокументСсылка.<имя>
НомерСтроки ВидДвижения Вид Значение
В
регистре
Комментарий
Дата движения Документ движения Число Номер движения в наборе записей ВидДвиженияБухгалтерии Дебет или Кредит ПланВидовХарактеристикСсылка.<имя> Вид субконто Характеристика.<имя> Значение субконто
ВидДвижения.
без
поддержки
корреспонденции
отсутствует
поле
Виртуальные таблицы Реальные таблицы регистра бухгалтерии малопригодны для формирования большинства бухгалтерских отчетов и являются скорее вспомогательным механизмом. Для построения отчетов и анализа данных в большинстве случаев используются виртуальные таблицы. Эти таблицы не хранятся в информационной базе и создаются системой при обращении к ним. По своей сути это вложенные запросы. Запросы выполняются системой к физическим таблицам регистра бухгалтерии, о которых мы расскажем ниже. Виртуальные таблицы параметризированы: обращаясь к ним, мы можем передать в качестве параметров условия выполнения запроса.
655
Глава 12. Бухгалтерский учет Виртуальные таблицы узкоспециализированные, предназначены для решения конкретных задач, поэтому проще изучать их исходя из задач, которые с их помощью можно решить.
Таблица остатков Для получения остатков по счетам в разрезе субконто и измерений используется таблица остатков. Эта таблица позволяет решить такие задачи, как получение количественных и суммовых остатков материальнопроизводственных запасов при их списании, определение остатка задолженности для выполнения зачета аванса, расчет амортизации и курсовых разниц и многие другие, где требуется узнать остаток какого-либо ресурса по счету, субконто или измерению, свернутый или развернутый. Таблица не отличается для регистра с поддержкой и без поддержки корреспонденции. Использование таблицы остатков в качестве источника запроса представлено в листинге 12.24. Листинг 12.24. Обращение к таблице «Остатки»
ИЗ
РегистрБухгалтерии.ОсновнойРегистрБухгалтерии.Остатки
После имени таблицы в круглых скобках могут (и в большинстве случаев будут) указываться параметры, задающие условия отбора данных из физических таблиц информационной базы. Рассмотрим поля виртуальной таблицы остатков. ■■ Счет – это поле имеет тип ПланСчетовСсылка.<имя>. Поле позволяет получить остатки, сгруппированные по счетам; ■■ Субконто – это поле имеет тип Характеристика.<имя>. Количество полей Субконто зависит от максимального количества субконто на счете плана счетов. Поле позволяет получить остатки, сгруппированные по значениям субконто; ■■ <Измерение> – тип этого поля задается при создании измерения регистра. Количество полей зависит от количества измерений, объявленных в регистре бухгалтерии. На поле не влияет свойство измерения Балансовый. Поле позволяет получить остатки, сгруппированные по измерениям регистра; ■■ <Ресурс>Остаток – это поле имеет тип Число. Абсолютный остаток (как он хранится в физических таблицах информационной базы) без учета вида счета: дебетовый остаток показывается положительным числом, кредитовый – отрицательным; ■■ <Ресурс>ОстатокДт – это поле имеет тип Число. Дебетовый остаток с учетом вида счета. Если счет пассивный, значение этого поля всегда равно нулю. Если счет активный, значение поля равно значению поля
656
Остаток. Если счет активно-пассивный, значение поля равно значению поля Остаток, если Остаток больше или равен нулю. Если Остаток
меньше нуля, значит – ноль; ■■ <Ресурс>ОстатокКт – это поле имеет тип Число. Кредитовый остаток с учетом вида счета. Если счет активный, значение этого поля всегда равно нулю. Если счет пассивный, равно «- Остаток». Если счет активно-пассивный, значение поля равно нулю, если значение поля Остаток больше или равно нулю. Если значение поля Остаток меньше нуля, значение этого поля равно «- Остаток»; ■■ <Ресурс>РазвернутыйОстатокДт – это поле имеет тип Число. Развернутый дебетовый остаток. Имеет смысл только при использовании в запросе итогов. Для детальной записи значение этого поля равно значению поля ОстатокДт. Для итоговой записи равно сумме дебетовых остатков всех детальных записей; ■■ <Ресурс>РазвернутыйОстатокКт – это поле имеет тип Число. Развернутый кредитовый остаток. Имеет смысл только при использовании в запросе итогов. Для детальной записи значение этого поля равно значению поля ОстатокКт. Для итоговой записи равно сумме кредитовых остатков всех детальных записей. В физических таблицах регистра хранится абсолютный остаток (поле <Ресурс>Остаток), все остальные рассчитываются при формировании системой виртуальной таблицы остатков. Алгоритм расчета полей ОстатокДт и ОстатокКт можно представить в виде схемы (рис. 12.55).
Рис. 12.55. Алгоритм расчета полей «ОстатокДт» и «ОстатокКт»
При обращении к полям ОстатокДт или ОстатокКт система в первую очередь проверяет наличие в запросе группировки (или отбора) по счету. Профессиональная разработка в системе «1С:Предприятие 8»
Чтение данных регистра бухгалтерии Если такой разрез в запросе есть и этот счет один, вычисление полей зависит от вида счета. Если используемый в запросе счет активный, система отображает в поле ОстатокДт значение поля Остаток, кредитовый остаток для активного счета всегда равен нулю. Если используемый в запросе счет пассивный, значение поля ОстатокКт будет равно значению поля Остаток с обратным знаком («- Остаток»), дебетовый остаток для пассивного счета всегда равен нулю. При расчете полей остатков активно-пассивного счета система дополнительно будет анализировать знак остатка. Если поле Остаток содержит положительное число, остаток будет интерпретирован системой как ОстатокДт; если отрицательное – как ОстатокКт. В случае, если в запросе нет разреза по счету или в качестве условия используется отбор по списку счетов, поля ОстатокДт и ОстатокКт рассчитываются по правилам активно-пассивного счета. Алгоритм формирования развернутых остатков счета мы рассмотрим более подробно ниже. Параметры виртуальной таблицы остатков позволяют задать условие отбора данных из информационной базы. Параметры следует задавать строго в порядке их описания. ■■ Период – имеет тип значения Дата, МоментВремени или Граница. На этот момент будут рассчитаны остатки виртуальной таблицы. Если параметр не задан, будут получены актуальные остатки, включающие движения последнего проведенного документа. Физическая организация таблиц позволяет максимально быстро получить остатки за месяц (на начало следующего месяца) и актуальные остатки; ■■ УсловиеСчета – содержит конструкцию языка запросов. Позволяет установить фильтр по счету или счетам. Как правило, содержит следующие условия: Счет = (В ИЕРАРХИИ, В) &Счет; ■■ Субконто – имеет тип ПланВидовХарактеристикСсылка.<имя> или содержит массив значений типа ПланВидовХарактеристикСсылка.<имя>. В этот параметр таблицы можно передать ссылку на вид субконто для получения отбора по этому виду или массив видов для установки отбора и упорядочивания видов субконто в результате запроса; ■■ Условие – содержит конструкцию языка запросов. Позволяет устанавливать отбор данных виртуальной таблицей по значениям субконто и измерений регистра бухгалтерии. Рассмотрим примеры построения запросов к таблице остатков регистра бухгалтерии. При необходимости получить количественный остаток конкретного товара со счета товаров можно использовать следующий код (листинг 12.25). Том 1
Листинг 12.25. Пример получения остатка товара
ВЫБРАТЬ Остатки.КоличествоОстаток ИЗ РегистрБухгалтерии.ОсновнойРегистрБухгалтерии.Остатки(&Момент, Счет = &СчетТоваров, , Организация = &Организация И Субконто1 = &Номенклатура) КАК Остатки
В приведенном тексте запроса используются параметры: ■■ Момент – Дата, МоментВремени или Граница, на которую необходимо получить остаток; ■■ СчетТоваров – ПланСчетовСсылка.<имя>. Ссылку для предопределенного счета можно получить по имени, например: СчетТоваров = ПланыСчетов.ОсновнойПланСчетов.Товары; ■■ Организация – ссылка на элемент справочника Организации, который используется как измерение регистра; ■■ Номенклатура – ссылка на элемент справочника Номенклатура, который используется на счете товаров как первый вид субконто. Результат запроса будет содержать одну строку в одном поле: абсолютный остаток по ресурсу регистра Количество. Следующий запрос позволяет отобрать остатки по всем счетам, по которым ведется валютный учет, и в разрезе валют проанализировать остатки в валюте сделки и в валюте учета (листинг 12.26). Листинг 12.26. Пример получения остатков регистра бухгалтерии
ВЫБРАТЬ Остатки.Счет, Остатки.Валюта, Остатки.ВалютнаяСуммаОстаток, Остатки.СуммаОстаток ИЗ РегистрБухгалтерии.ОсновнойРегистрБухгалтерии.Остатки(, Счет.Валютный = ИСТИНА, , ) КАК Остатки
В результате выполнения этого запроса будет получена, например, следующая таблица (табл. 12.29). Таблица 12.29. Результат выполнения запроса Счет
Валюта
ВалютнаяСуммаОстаток
СуммаОстаток
Касса Касса Касса Новый счет
Рубль Доллар Евро Доллар
100 100 100 10
470 2850 3500 285
657
Глава 12. Бухгалтерский учет
Таблица оборотов Для получения оборотов по счету, по счету в разрезе субконто и измерений и оборотов счета с корреспондирующими счетами (как дебетуемыми, так и кредитуемыми) используется таблица оборотов. Таблица присутствует как у регистра с поддержкой, так и без поддержки корреспонденции, хотя и с небольшими отличиями. Таблица оборотов может быть использована при решении задач получения оборотных показателей таких отчетов, как анализ счета/субконто/по датам и др., журнальный ордер, ведомость по счету. Использование таблицы оборотов в качестве источника запроса представлено в листинге 12.27. Листинг 12.27. Обращение к таблице «Обороты»
ИЗ
РегистрБухгалтерии.ОсновнойРегистрБухгалтерии.Обороты
После имени таблицы в круглых скобках могут (и в большинстве случаев будут) указываться параметры, задающие условия отбора данных из физических таблиц информационной базы. Рассмотрим поля виртуальной таблицы оборотов. ■■ Счет – это поле имеет тип ПланСчетовСсылка.<имя>. Поле позволяет получить обороты выбранного счета; ■■ КорСчет – это поле имеет тип ПланСчетовСсылка.<имя>. Поле позволяет получить обороты выбранного счета, указанного в параметре Счет с выбранным корреспондирующим счетом; ■■ Субконто – это поле имеет тип Характеристика.<имя>. Количество полей Субконто зависит от максимального количества субконто на счете плана счетов. Поле позволяет получить обороты, сгруппированные по значениям субконто; ■■ КорСубконто – это поле имеет тип Характеристика.<имя>. Количество полей КорСубконто зависит от максимального количества субконто на счете плана счетов. Поле позволяет получить обороты, сгруппированные по значениям субконто корреспондирующего счета; ■■ <Измерение> – тип поля задается при создании измерения регистра. Количество полей зависит от количества измерений, объявленных в регистре бухгалтерии. Поле существует как для балансовых, так и для небалансовых измерений; ■■ <Измерение>Кор – тип поля задается при создании измерения регистра. Количество полей зависит от количества измерений, объявленных в регистре бухгалтерии. Поле создается только для небалансовых измерений; ■■ Период – тип Дата, Регистратор – тип ДокументСсылка.<имя>, НомерСтроки – тип Число. Поля создаются в том случае, если в параметрах виртуальной таблицы задана периодичность и она отличается от значения Период;
658
■■ <Ресурс>Оборот – это поле имеет тип Число. Разница оборотов выбранного счета (дебетовый оборот минус кредитовый оборот); ■■ <Ресурс>ОборотДт – это поле имеет тип Число. Дебетовый оборот счета; ■■ <Ресурс>ОборотКт – это поле имеет тип Число. Кредитовый оборот счета; ■■ <Ресурс>КорОборот – это поле имеет тип Число. Содержит разницу оборотов (кор. оборот дебета минус кор. оборот кредита) для небалансового ресурса корреспондирующего счета; ■■ <Ресурс>КорОборотДт – это поле имеет тип Число. Дебетовый оборот для небалансового ресурса корреспондирующего счета; ■■ <Ресурс>КорОборотКт – это поле имеет тип Число. Кредитовый оборот для небалансового ресурса корреспондирующего счета. Параметры виртуальной таблицы оборотов позволяют задать условие отбора данных из информационной базы. Параметры следует задавать строго в порядке их описания. ■■ НачалоПериода, КонецПериода – имеет тип Дата, МоментВремени или Граница. Период времени, за который будут получены обороты; ■■ Периодичность – содержит конструкцию языка запросов. Позволяет задать дополнительную группировку данных по стандартным периодам. Возможные значения: Период, Год, Полугодие, Квартал, Месяц, Декада, Неделя, День, Час, Минута, Секунда, Регистратор, Запись. Если периодичность не задана или задана как Период, дополнительная группировка не выполняется; ■■ УсловиеСчета – содержит конструкцию языка запросов. Позволяет установить фильтр по счету или счетам. Как правило, содержит следующие условия: Счет = (В ИЕРАРХИИ, В) &Счет; ■■ Субконто – имеет тип ПланВидовХарактеристикСсылка.<имя> или содержит массив значений типа ПланВидовХарактеристикСсылка.<имя>. В этот параметр таблицы можно передать ссылку на вид субконто для получения отбора по этому виду или массив видов для установки отбора и упорядочивания видов субконто в результате запроса; ■■ Условие – содержит конструкцию языка запросов. Позволяет устанавливать отбор данных виртуальной таблицей по значениям субконто и измерений регистра бухгалтерии; ■■ УсловиеКорСчета – содержит конструкцию языка запросов. Позволяет установить фильтр по корреспондирующему счету или счетам. Как правило, содержит следующие условия: КорСчет = (В ИЕРАРХИИ, В) &КорСчет; ■■ КорСубконто – имеет тип ПланВидовХарактеристикСсылка.<имя> или содержит массив значений типа ПланВидовХарактеристикСсылка.<имя>. В этот параметр таблицы можно передать ссылку на вид Профессиональная разработка в системе «1С:Предприятие 8»
Чтение данных регистра бухгалтерии субконто для получения отбора по этому виду или массив видов для установки отбора и упорядочивания видов субконто в результате запроса. Рассмотрим примеры построения запросов к таблице оборотов регистра бухгалтерии. Все запросы обращаются к итогам за весь период, который есть в регистре (не указываются параметры НачалоПериода и КонецПериода). Во всех запросах в качестве параметра передается условие по счету, где СчетТоваров –ссылка на счет Товары плана счетов. Запрос, который покажет, сколько было куплено и списано товаров разных видов в количественном выражении, представлен в листинге 12.28. Листинг 12.28. Пример использования таблицы «Обороты»
ВЫБРАТЬ Обороты.Субконто1, Обороты.КоличествоОборотДт, Обороты.КоличествоОборотКт ИЗ РегистрБухгалтерии.ОсновнойРегистрБухгалтерии.Обороты(, , , Счет = &СчетТоваров, , , , ) КАК Обороты
Результат такого запроса представлен в табл. 12.30. Таблица 12.30. Результат запроса Субконто1
КоличествоОборотДт
Комплект Паркер Школьная Цветной
1 15 10 3
КоличествоОборотКт
10
Таблица 12.31. Результат запроса Субконто1
КорСчет
КорСубконто1
КоличествоОборотДт
Комплект Паркер Паркер Школьная Школьная Цветной
Товары Поставщики Поставщики Сотрудники Поставщики Поставщики
Паркер СтройТоргВсе Дисконт центр Иванов Дисконт центр МонтажДоставка
1 10 5 5 5 3
Таблица демонстрирует, какой именно товар (Субконто1), с какого корреспондирующего счета (КорСчет), от какого контрагента (первое субконто корреспондирующего счета) и в каком количестве был получен. Как мы видим, большинство товаров было получено со счета Поставщики, от разных контрагентов. Однако есть и такие, которые были получены со счета Сотрудники и счета Товары. Именно эта корреспонденция может нас заинтересовать. Количество является небалансовым ресурсом регистра бухгалтерии.
Регистр, который мы рассматриваем, поддерживает корреспонденцию, поэтому для каждого небалансового ресурса создаются два поля в таблице записей регистра бухгалтерии. Таким образом, допускается ситуация, когда корреспондируют два счета, поддерживающих вид учета, ведущийся в небалансовом ресурсе (в нашем случае Количество), и эти счета будут иметь различные обороты. То есть дебетовый оборот счета дебета проводки не будет равен кредитовому обороту счета кредита проводки. Как пример можно привести комплектацию (рис. 12.56).
Таблица показывает, какие из товаров в каком количестве были оприходованы (КоличествоОборотДт) и списаны (КоличествоОборотКт). Если требуется узнать, с какого корреспондирующего счета (субконто корреспондирующего счета) были получены те или иные товары, необходимо воспользоваться полями таблицы оборотов КорСчет и КорСубконто (листинг 12.29). Листинг 12.29. Пример использования таблицы «Обороты»
ВЫБРАТЬ Обороты.Субконто1, Обороты.КорСчет, Обороты.КорСубконто1, Обороты.КоличествоОборотДт ИЗ РегистрБухгалтерии.ОсновнойРегистрБухгалтерии.Обороты(, , , Счет = &СчетТоваров, , , , ) КАК Обороты
Результат запроса представлен в табл. 12.31. Том 1
Рис. 12.56. Комплектация
В приведенном примере дебетуется счет Товары с аналитикой Комплект и кредитуется счет Товары с другой аналитикой (Паркер). При этом ресурс Сумма балансирует (балансовый ресурс регистра бухгалтерии), а количество дебета и кредита отличается: было списано десять «Паркеров», и оприходован один «Комплект». Воспользовавшись полем ОборотДт виртуальной таблицы оборотов, мы сможем проанализировать, сколько Комплектов было оприходовано
659
Глава 12. Бухгалтерский учет на счет Товары в количественном (КоличествоОборотДт) и суммовом выражении (СуммаОборотДт). Для балансового ресурса этой информации более чем достаточно. Ресурс небалансовый, как мы убедились, может быть заполнен для основного и для корреспондирующего счета проводки и заполнен независимо. Если потребуется проанализировать, из какого количества авторучек Паркер какое количество Комплектов было собрано, нам пригодится поле с постфиксом КорОборот. Напишем запрос, в котором для виртуальной таблицы оборотов установим фильтр по полям Счет и КорСчет и получим таким образом в качестве итогов обороты по всем проводкам, где корреспондировали между собой счет Товары и счет Товары (листинг 12.30). Листинг 12.30. Пример использования таблицы «Обороты»
ВЫБРАТЬ Обороты.Субконто1, Обороты.КоличествоОборотДт, Обороты.КорСубконто1, Обороты.КоличествоКорОборотДт ИЗ РегистрБухгалтерии.ОсновнойРегистрБухгалтерии.Обороты(, , , Счет = &СчетТоваров, , , КорСчет = &СчетТоваров, ) КАК Обороты
Результат запроса приведен в табл. 12.32. Таблица 12.32. Результат запроса Субконто1
КоличествоОборотДт
КорСубконто1 КоличествоКорОборотДт
Комплект
1
Паркер
10
Аналогичное назначение имеет поле виртуальной таблицы оборотов <Измерение>Кор, которое позволит сгруппировать или отобрать данные, например, по валюте корреспондирующего счета. Таблица оборотов регистра без поддержки корреспонденции отличается отсутствием в ней полей, содержащих слово Кор.
Таблица остатков и оборотов Основное предназначение таблицы остатков и оборотов – формирование оборотно-сальдовых ведомостей, отчетов, где для каждой строки необходимо показать остаток на начало периода, обороты за период и остаток на конец периода. Нужно сразу заметить, что функционально таблица остатков и оборотов не является соединением таблицы остатков с таблицей оборотов (табл. 12.33).
660
Таблица 12.33. Сравнение функциональности таблиц регистра бухгалтерии Функциональность
Соединение таблицы остатков и таблицы оборотов
Таблица остатков и оборотов
Получить остатки Обороты по счету (субконто, измерению счета) Обороты счета с корреспондирующими (счетами, субконто, измерениями)
Да Да Да
Да Да Нет
Как видно из таблицы, таблица остатков и оборотов позволяет получить обороты по счету аналогично таблице оборотов, однако не предоставляет возможности анализировать обороты с корреспондирующими счетами, субконто, измерениями. По этой причине, например, не представляется возможным использовать ее для получения отчета Анализ счета. Использование таблицы в качестве источника запроса потребует следующего обращения (листинг 12.31). Листинг 12.31. Обращение к таблице остатков и оборотов
ИЗ
РегистрБухгалтерии.ОсновнойРегистрБухгалтерии.ОстаткиИОбороты
Рассмотрим поля виртуальной таблицы остатков и оборотов: ■■ Счет – это поле имеет тип ПланыСчетовСсылка.<имя>. Поле содержит счет, для которого получены остатки и обороты; ■■ Субконто – это поле имеет тип Характеристика.<имя>, тип этого поля определяется типом субконто. Количество таких полей зависит от максимального количества субконто на счете плана счетов. Поле позволяет получить остатки и обороты, сгруппированные по значениям субконто; ■■ <Измерение> – тип этого поля определяется типом измерения регистра накопления. Количество таких полей зависит от количества измерений, объявленных в регистре бухгалтерии. Поле существует как для балансовых, так и для небалансовых измерений; ■■ Период, Регистратор, НомерСтроки – эти поля имеют тип соответственно Дата, ДокументСсылка.<имя> и Число. Поля создаются в том случае, если в параметрах виртуальной таблицы задана периодичность и она отличается от Период; ■■ <Ресурс>Оборот, <Ресурс>ОборотДт, <Ресурс>ОборотКт – эти поля имеют тип Число. Поля аналогичны полям таблицы оборотов. Подробнее можно прочитать в разделе «Таблица оборотов» на стр. 658; ■■ <Ресурс>НачальныйОстаток, <Ресурс>НачальныйОстатокДт, Ресурс>НачальныйОстатокКт, <Ресурс>НачальныйРазвернутыйОстаток Дт, <Ресурс>НачальныйРазвернутыйОстатокКт – эти поля имеют тип Число. Поля аналогичны полям таблицы остатков (подробнее можно Профессиональная разработка в системе «1С:Предприятие 8»
Чтение данных регистра бухгалтерии прочитать в разделе «Таблица остатков» на стр. 656), рассчитываются на дату начала интервала, указанного в параметре таблицы остатков и оборотов НачалоПериода; ■■ <Ресурс>КонечныйОстаток, <Ресурс>КонечныйОстатокДт, <Ресурс>КонечныйОстатокКт, <Ресурс>КонечныйРазвернутыйОстатокДт, <Ресурс>КонечныйРазвернутыйОстатокКт – эти поля имеют тип Число. Поля аналогичны полям таблицы остатков (подробнее можно прочитать в разделе «Таблица остатков» на стр. 656), рассчитываются на дату окончания интервала, указанного в параметре таблицы остатков и оборотов КонецПериода. Параметры виртуальной таблицы остатков и оборотов позволяют задать условие отбора данных из информационной базы. Параметры следует задавать строго в порядке их описания: ■■ НачалоПериода, КонецПериода – эти параметры имеют тип соответственно Дата, МоментВремени и Граница. Период времени, за который будут получены обороты; ■■ Периодичность – этот параметр содержит конструкцию языка запросов. Позволяет задать дополнительную группировку данных по стандартным периодам. Возможные значения: Период, Год, Полугодие, Квартал, Месяц, Декада, Неделя, День, Час, Минута, Секунда, Регистратор или Запись. Если периодичность не задана или задана как Период, то дополнительная группировка не выполняется; ■■ МетодДополнения – этот параметр содержит конструкцию языка запросов. Возможны два значения: Движения или ДвиженияИГраницыПериода. Управляет включением в отчет периодов, не имеющих оборотов, но имеющих остатки; ■■ УсловиеСчета – этот параметр содержит конструкцию языка запросов. Позволяет установить фильтр по счету или счетам. Как правило, содержит следующие условия: Счет = (В ИЕРАРХИИ, В) &Счет; ■■ Субконто – этот параметр имеет тип ПланВидовХарактеристикСсылка.<имя> или может содержать массив значений типа ПланВидовХарактеристикСсылка.<имя>. В этот параметр таблицы можно передать ссылку на вид субконто для получения отбора по этому виду или массив видов для установки отбора и упорядочивания видов субконто в результате запроса; ■■ Условие – этот параметр содержит конструкцию языка запросов. Позволяет устанавливать отбор данных виртуальной таблицей по значениям субконто и измерений регистра бухгалтерии. Примером использования таблицы может быть отчет «Оборотно-сальдовая ведомость», текст которого приведен в листинге 12.32.
Листинг 12.32. Пример отчета «Оборотно-сальдовая ведомость»
ВЫБРАТЬ ОстаткиИОбороты.Счет КАК Счет, ПРЕДСТАВЛЕНИЕ(ОстаткиИОбороты.Счет), ОстаткиИОбороты.СуммаНачальныйОстатокДт КАК НачОстДт, ОстаткиИОбороты.СуммаНачальныйОстатокКт КАК НачОстКт, ОстаткиИОбороты.СуммаОборотДт КАК ОборотДт, ОстаткиИОбороты.СуммаОборотКт КАК ОборотКт, ОстаткиИОбороты.СуммаКонечныйОстатокДт КАК КонОстДт, ОстаткиИОбороты.СуммаКонечныйОстатокКт КАК КонОстКт ИЗ РегистрБухгалтерии.ОсновнойРегистрБухгалтерии.ОстаткиИОбороты(&НачПериода, &КонПериода, , , , , ) КАК ОстаткиИОбороты УПОРЯДОЧИТЬ ПО ОстаткиИОбороты.Счет.Код ИТОГИ СУММА(НачОстДт), СУММА(НачОстКт), СУММА(ОборотДт), СУММА(ОборотКт), СУММА(КонОстДт), СУММА(КонОстКт) ПО Счет ИЕРАРХИЯ
В результате выполнения этого запроса будут получены данные, представленные в табл. 12.34. Таблица 12.34. Результат выполнения запроса Счет
НачОстДт
НачОстКт
ОборотДт
ОборотКт
КонОстДт
КонОстКт
Активы Активы Касса Покупатели Товары Материалы
8804 100 6961 95 350 1000
7511 6903 490 100
1293 100 58 -395 250 1000
13
18
Контрагенты
5
Обязательства Обязательства Сотрудники Поставщики
2 2
1352 100 50 1202
1350 100 48 1202
Капитал
6810
6753
-57
Подробнее
Пример такого отчета приведен в демонстрационной конфигурации «Бухгалтерский учет», которая находится на прилагаемом компактдиске, – Оборотно-сальдовая ведомость.
Том 1
661
Глава 12. Бухгалтерский учет Другой пример использования таблицы остатков и оборотов – получение детальных аналитических отчетов схожей структуры, т. е. содержащих колонки Остаток на начало периода, Обороты за период, Остаток на конец периода (листинг 12.33). Листинг 12.33. Пример отчета «Оборотно-сальдовая ведомость по счету товаров»
ВЫБРАТЬ ОстаткиИОбороты.Субконто1 КАК Товар, ОстаткиИОбороты.КоличествоНачальныйОстаток КАК НачОст, ОстаткиИОбороты.КоличествоОборотДт КАК Приход, ОстаткиИОбороты.КоличествоОборотКт КАК Расход, ОстаткиИОбороты.КоличествоКонечныйОстаток КАК КонОст ИЗ РегистрБухгалтерии.ОсновнойРегистрБухгалтерии.ОстаткиИОбороты(&НачПериода, &КонПериода, , , Счет = &СчетТоваров, , ) КАК ОстаткиИОбороты
В данном случае запрос выполняется к таблице остатков и оборотов с фильтром за интервал дат и только по одному счету – счету учета товаров, на котором в качестве первого субконто используется Номенклатура товаров. Результатом запроса будет таблица, демонстрирующая количественные остатки и обороты каждой позиции номенклатуры (табл. 12.35). Таблица 12.35. Результат выполнения запроса Товар
НачОст
Комплект Паркер Школьная Цветной
Приход
1 15 10 3
Расход
10
КонОст
1 5 10 3
ВНИМАНИЕ!
Не нужно считать таблицу остатков и оборотов панацеей и использовать для построения всех отчетов. Таблица универсальна и содержит поля, необходимые во многих отчетах. Однако платой за универсальность всегда является производительность. Использование таблицы имеет смысл только в случаях, когда в одной группировке отчета требуется получение и остатков на начало, и оборотов, и остатков на конец периода. Если требуются только остатки, или только обороты, или все три составляющие, но в разных группировках строках отчета, стоит задуматься о возможности написания нескольких запросов к таблице остатков и таблице оборотов.
Таблица движений с субконто Для получения отборов проводок используется таблица движений с субконто. Таблица включает в себя все поля основной таблицы и таблицы значений субконто и получается их соединением. Поэтому таблица отличается для регистра с поддержкой и без поддержки корреспонденции.
662
Таблицу можно использовать для решения задач формирования отчетов Карточка счета/субконто, Отчет по проводкам. Таблица является виртуальной, но получается соединением двух реальных таблиц (основная таблица и таблица значений субконто), поэтому одна из отличительных особенностей этой таблицы состоит в том, что в нее попадают неактивные записи. Другая отличительная особенность таблицы – несовпадение полей таблицы, которые можно использовать для группировки данных, и полей, на которые можно ставить условие в параметре виртуальной таблицы. Таблица движений с субконто регистра с поддержкой корреспонденций содержит следующие поля (табл. 12.36). Таблица 12.36. Поля виртуальной таблицы движений с субконто Поле
Тип
Комментарий
Дата движения Документ движения МоментВремени МоментВремени Момент времени документа Число НомерСтроки Номер движения в наборе записей Булево Активность Участвует ли запись в таблицах итогов ПланСчетовСсылка.<имя> СчетДт Дебетуемый счет ПланСчетовСсылка.<имя> СчетКт Кредитуемый счет <Измерение> Определяется типом измерения регистра Балансовое измерение бухгалтерии регистра бухгалтерии <Измерение>Дт Небалансовое измерение регистра <Измерение>Кт бухгалтерии создает два поля в регистре Число <Ресурс> Балансовый ресурс регистра бухгалтерии <Ресурс>Дт Небалансовый ресурс регистра бухгалтерии <Ресурс>Кт создает два поля в регистре <Реквизит> Определяется типом реквизита регистра Характеристика бухгалтерии движения регистра ВидСубконтоДт ПланВидовХарактеристикСсылка.<имя> Количество полей зависит от настройки ВидСубконтоКт плана счетов СубконтоДт Определяется типом субконто Количество полей зависит от настройки СубконтоКт плана счетов Период
Дата
Регистратор
ДокументСсылка.<имя>
Виртуальная таблица движений с субконто имеет следующие параметры: ■■ НачалоПериода, КонецПериода – эти параметры имеют тип Дата, МоментВремени или Граница. Период времени, за который будут отобраны проводки; Профессиональная разработка в системе «1С:Предприятие 8»
Чтение данных регистра бухгалтерии ■■ Условие – этот параметр содержит конструкцию языка запросов. Конструкция позволяет установить условие на любое поле виртуальной таблицы; ■■ Порядок – этот параметр содержит конструкцию языка запросов. Конструкция позволяет задать упорядочивание проводок; ■■ Первые – этот параметр имеет тип Число. С его помощью задается ограничение максимального количества записей. Ниже приводятся два рисунка, демонстрирующие поля виртуальной таблицы «Движения с субконто» демонстрационной конфигурации «Бухгалтерский учет», которая находится на прилагаемом компактдиске. Рис. 12.57 показывает поля таблицы, доступные для группировки. Рис. 12.58 – поля таблицы, доступные для установки на них условия в параметре Условие.
Рис. 12.58. Поля, доступные для использования в параметре «Условие»
Таблица оборотов Дт Кт Рис. 12.57. Поля, доступные для группировки
Видно, что перечень полей, на которые можно устанавливать условия, существенно шире. Если для включения в отчет нам доступны только физически существующие поля, полученные виртуальной таблицей из реальных таблиц первичных движений, то для выполнения отборов доступны также и виртуальные поля, такие как Счет (без указания стороны проводки), Субконто, ВидСубконто, КорСчет, <Ресурс>Кор. Пример запроса, использующий таблицу движений с субконто, приводится в разделе «Свойства счета-родителя и подчиненных ему счетов» на стр. 621.
Том 1
Таблица оборотов Дт Кт предназначена для получения оборотов между корреспондирующими счетами. Таблица присутствует только у регистра с поддержкой корреспонденции и позволяет узнать оборот в дебет счета с кредита счета (субконто, измерения). Если рассматривать таблицу с точки зрения ее возможного использования при разработке отчетов, то, вероятнее всего, это будут отчеты «Шахматный баланс (шахматка)» и «Сводные проводки». Основное отличие таблицы оборотов Дт Кт от таблицы оборотов состоит в том, что таблица оборотов Дт Кт позволяет анализировать обороты между счетами, где заранее известно, какой счет дебетуется, а какой кредитуется. В то время как таблица оборотов, кроме того что позволяет анализировать обороты по счету (без указания второго), позволяет анализировать обороты между счетом и корсчетом. При этом одним обращением к таблице можно получить как дебетовые, так и кредитовые корреспонденции. Рассмотрим поля этой виртуальной таблицы (табл. 12.37).
663
Глава 12. Бухгалтерский учет Таблица 12.37. Поля виртуальной таблицы оборотов Дт Кт Поле
Тип
Комментарий
Период Регистратор НомерСтроки
Дата ДокументСсылка.<имя> Число
СчетДт
ПланыСчетовСсылка.<имя>
Поля существуют в таблице, только если значение параметра Периодичность задано и отличается от Период Дебетуемый счет Кредитуемый счет Балансовое измерение регистра бухгалтерии Небалансовое измерение регистра бухгалтерии создает два поля в таблице Количество полей зависит от настройки плана счетов
СчетКт <Измерение>
Определяется типом измерения регистра бухгалтерии
<Измерение>Дт <Измерение>Кт СубконтоДт
Определяется типом субконто
СубконтоКт <Ресурс>Оборот
Число
<Ресурс>ОборотДт
Число
<Ресурс>ОборотКт
Оборот балансового ресурса регистра бухгалтерии Обороты небалансового ресурса регистра бухгалтерии
Виртуальная таблица оборотов Дт Кт использует следующие параметры: ■■ НачалоПериода, КонецПериода – эти параметры имеют тип Дата, Момент времени или Граница. Период времени, за который будут отобраны обороты; ■■ Периодичность – этот параметр содержит конструкцию языка запросов. Позволяет задать дополнительную группировку данных по стандартным периодам. Возможные значения: Период, Год, Полугодие, Квартал, Месяц, Декада, Неделя, День, Час, Минута, Секунда, Регистратор, Запись. Если периодичность не задана или задана как Период, то дополнительная группировка не выполняется; ■■ УсловиеСчетаДт – этот параметр содержит конструкцию языка запросов. Отбор по дебетуемому счету, как правило, содержит следующие условия: СчетДт = (В ИЕРАРХИИ, В) &СчетДт; ■■ СубконтоДт – этот параметр имеет тип ПланВидовХарактеристикСсылка.<имя> или содержит массив значений типа ПланВидовХарактеристикСсылка.<имя>. В этот параметр таблицы можно передать ссылку на вид субконто для получения отбора по этому виду для дебетовых оборотов или массив видов для установки отбора и упорядочивания видов субконто в результате запроса; ■■ УсловиеСчетаКт – этот параметр содержит конструкцию языка запросов. Отбор по дебетуемому счету, как правило, содержит следующие условия: СчетКт = (В ИЕРАРХИИ, В) &СчетКт; ■■ СубконтоКт – этот параметр имеет тип ПланВидовХарактеристикСсылка.<имя> или содержит массив значений типа ПланВидовХарактеристикСсылка.<имя>. В этот параметр таблицы можно передать ссылку
664
на вид субконто для получения отбора по этому виду для кредитовых оборотов или массив видов для установки отбора и упорядочивания видов субконто в результате запроса; ■■ Условие – этот параметр содержит конструкцию языка запросов. Конструкция позволяет установить условие на субконто и измерения. Примером отчета, который может быть построен с использованием таблицы оборотов Дт Кт, может послужить отчет «Сводные проводки», показывающий сводные обороты между дебетуемыми и кредитуемыми счетами. Простейший запрос, который позволяет получить этот отчет, приводится в листинге 12.34. Листинг 12.34. Пример отчета «Сводные проводки»
ВЫБРАТЬ ОборотыДтКт.СчетДт, ОборотыДтКт.СчетКт, ОборотыДтКт.СуммаОборот ИЗ РегистрБухгалтерии.ОсновнойРегистрБухгалтерии.ОборотыДтКт КАК ОборотыДтКт
При выполнении этого запроса будет получен следующий результат (табл. 12.38). Таблица 12.38. Результат выполнения запроса СчетДт
СчетКт
СуммаОборот
Товары Касса Товары Новый счет Материалы Сотрудники Контрагенты Покупатели Активы Товары Касса Покупатели Касса Капитал
Товары Покупатели Поставщики Капитал Поставщики Поставщики Касса Касса Обязательства Сотрудники Капитал Капитал Контрагенты Касса
100 490 200 285 1000 2 13 80 100 50 6453 15 18 6810
Разницу между таблицей оборотов и таблицей оборотов Дт Кт может показать следующий пример. Решим задачу: необходимо получить оборот между счетами, свидетельствующий об объеме выручки, полученной в кассу от покупателей. Другими словами, нам необходимо получить обороты за период в дебет счета Касса с кредита счета Покупатели в разрезе контрагентов (субконто Контрагенты привязано к счету Покупатели плана Профессиональная разработка в системе «1С:Предприятие 8»
Чтение данных регистра бухгалтерии счетов). Во всех приведенных ниже запросах используются следующие параметры (табл. 12.39). Таблица 12.39. Параметры запросов Параметр запроса
Тип
Значение
НачПериода
Дата
КонПериода
Дата
СчетКассы
ПланыСчетовСсылка.<имя>
СчетПокупателей
ПланыСчетовСсылка.<имя>
Начало интервала отбора итогов Конец интервала отбора итогов Счет Касса Счет Покупатели
Решим эту задачу, используя таблицу оборотов Дт Кт (листинг 12.35). Листинг 12.35. Пример запроса, использующего таблицу оборотов Дт Кт
ВЫБРАТЬ ОборотыДтКт.СубконтоКт1 КАК Покупатель, ОборотыДтКт.СуммаОборот КАК Выручка ИЗ РегистрБухгалтерии.ОсновнойРегистрБухгалтерии.ОборотыДтКт(&НачПериода, &КонПериода, , СчетДт = &СчетКассы, , СчетКт = &СчетПокупателей, , ) КАК ОборотыДтКт ИТОГИ СУММА(Выручка) ПО ОБЩИЕ
В результате выполнения этого запроса будут получены следующие данные (табл. 12.40). Таблица 12.40. Результат выполнения запроса Покупатель
Выручка
СтройТоргВсе МонтажДоставка Дисконт центр Итог
200 150 100 450
Эта же таблица отчета может быть получена с помощью таблицы оборотов следующим способом (листинг 12.36). Листинг 12.36. Пример запроса, использующего таблицу оборотов
ВЫБРАТЬ Обороты.КорСубконто1 КАК Покупатель, Обороты.СуммаОборотДт КАК Выручка ИЗ РегистрБухгалтерии.ОсновнойРегистрБухгалтерии.Обороты(&НачПериода, &КонПериода, , Счет = &СчетКассы, , ,КорСчет = &СчетПокупателей, ) КАК Обороты ИТОГИ СУММА(Выручка) ПО ОБЩИЕ
Том 1
В приведенном примере выполняется запрос с отбором по счетам Касса (основной счет) и Покупатели (корреспондирующий счет). Нужно сразу отметить, что можно сделать и наоборот: основным счетом запроса сделать счет Покупатели, а корреспондирующим – счет Касса. При этом данные группируются по первому субконто корреспондирующего счета. Отчетом анализируется дебетовый оборот (дебетовый относительно основного счета запроса, т. е. относительно счета Касса, оборот в дебет счета Касса). Теперь усложним задачу. Необходимо узнать не только, сколько было получено денег от покупателей в кассу за выбранный период, но и сумму возвращенных покупателям средств и разницу между выручкой и возвратами. Для получения прямой и обратной корреспонденции в одном запросе с использованием в качестве источника данных таблицы остатков и оборотов придется обратиться к источнику дважды: для получения оборота в дебет счета Касса с кредита Покупатели и в дебет Покупатели с кредита счета Касса. С помощью таблицы оборотов эта же задача может быть решена с однократным обращением к таблице (листинг 12.37). Листинг 12.37. Пример запроса, использующего таблицу оборотов
ВЫБРАТЬ Обороты.КорСубконто1 КАК Покупатель, Обороты.СуммаОборотДт КАК Выручка, Обороты.СуммаОборотКт КАК Возвраты, Обороты.СуммаОборотДт - Обороты.СуммаОборотКт КАК Результат ИЗ РегистрБухгалтерии.ОсновнойРегистрБухгалтерии.Обороты(&НачПериода, &КонПериода, , Счет = &СчетКассы, , , КорСчет = &СчетПокупателей, ) КАК Обороты ИТОГИ СУММА(Выручка), СУММА(Возвраты), СУММА(Результат) ПО ОБЩИЕ
Результат выполнения запроса приведен в табл. 12.41. Таблица 12.41. Результат выполнения запроса Покупатель
Выручка
Возвраты
Результат
СтройТоргВсе МонтажДоставка Дисконт центр Итог
200 150 100 450
80 80
200 150 20 370
665
Глава 12. Бухгалтерский учет
Общие приемы работы с виртуальными таблицами
Параметр
Все рассмотренные виртуальные таблицы имеют ряд общих параметров, полей и просто подходов, которые не имеет смысла описывать для каждой таблицы.
ВидСубконтоДт/Кт
Таблица Таблица Таблица Таблица Таблица оборотов оборотов остатков остатков движений Дт Кт и оборотов с субконто
Для начала сгруппируем параметры, которые используются в виртуальных таблицах (табл. 12.42).
<Ресурс> Дт/Кт
Таблица 12.42. Параметры виртуальных таблиц регистра бухгалтерии
<Ресурс>РазвернутыйОстатокДт/Кт
Параметр
Да Да Да
<Ресурс>
Да Да Да
<Ресурс>Остаток <Ресурс>ОстатокДт/Кт <Ресурс>Оборот
Да Да Да Да
Да Да
Да** Да** Да** Да Да
Таблица оборотов
Таблица оборотов Дт Кт
Таблица Таблица остатков остатков и оборотов
Таблица движений с субконто
Период, НачалоПериода, КонецПериода
Да
Да
Да
Да
Да
Условие
Да Да
Да Да
Да Да
Да Да
Да
Субконто, КорСубконто, СубконтоДт, СубконтоКт
Да
Да
Да
Да
* Поля присутствуют в таблице при установленном значении параметра Периодичность; поле НомерСтроки доступно, если периодичность равна Запись; поле Регистратор доступно, если периодичность равна Запись или Регистратор. ** В таблице присутствуют поля для получения остатков на начало и конец периода, заданного в параметрах таблицы.
Периодичность
Да
Да
Да Да
Теперь перейдем к рассмотрению отдельных полей и параметров таблиц.
УсловиеСчета, УсловиеКорСчета, УсловиеСчетаДт, УсловиеСчетаКт
МетодДополнения
Поля, используемые в виртуальных таблицах регистра бухгалтерии, представлены в табл. 12.43. Таблица 12.43. Поля виртуальных таблиц регистра бухгалтерии Параметр
Таблица Таблица Таблица Таблица Таблица оборотов оборотов остатков остатков движений Дт Кт и оборотов с субконто
Счет
Да Да
КорСчет Счет Дт/Кт <Измерение> <Измерение>Кор
Да Да
КорСубконто
Да Да
СубконтоДт/Кт Период Регистратор НомерСтроки МоментВремени Активность <Реквизит>
666
Да
Да
Да
Да
Да
Да
<Измерение>Дт/Кт Субконто
Да Да
Да
Да* Да* Да*
Да Да* Да* Да*
<Ресурс>КорОборот <Ресурс>КорОборотДт/Кт
Параметр «Субконто»: отбор и упорядочивание по виду субконто В этом разделе пойдет речь о параметрах виртуальных таблиц (остатков, оборотов, оборотов Дт Кт, остатков и оборотов) типа ПланыВидовХарактеристикСсылка.<имя>. В разных таблицах параметр называется по-разному (табл. 12.44). Таблица 12.44. Параметры различных таблиц
Да Да Да
Да* Да* Да*
<Ресурс>ОборотДт/Кт
Да Да Да Да Да Да Да
Таблица
Имя параметра
Оборотов Оборотов Дт Кт Остатков Остатков и оборотов
Субконто, КорСубконто СубконтоДт, СубконтоКт Субконто Субконто
Все перечисленные параметры могут принимать значения ПланыВидовХарактеристикСсылка.<имя> или содержать массив, состоящий из значений указанного типа данных. Назначение этих параметров для всех таблиц схоже. Рассмотрим возможные варианты использования этих параметров на примере таблицы остатков. Начнем с того, что это не субконто в том смысле слова, который мы обычно вкладываем в него. В этом параметре можно передать Профессиональная разработка в системе «1С:Предприятие 8»
Чтение данных регистра бухгалтерии не значение субконто, а значение вида субконто или массив видов субконто. Следует заметить, что для отбора по значению субконто используется другой параметр виртуальных таблиц. Для всех таблиц он называется Условие. В нем же можно устанавливать отбор по измерению регистра. Какое же назначение у параметра Субконто? Их как минимум два: ■■ отбор итогов по виду субконто; ■■ упорядочивание субконто в результате запроса (в особенности, если запрос выполняется по нескольким счетам). Рассмотрим подробнее каждый из перечисленных вариантов. Задача отбора по виду субконто может быть сформулирована следующим образом: необходимо получить отчет по остаткам товарно-материальных запасов. При этом в одной строке отчета нужно показать сумму стоимостных остатков одного вида номенклатуры со всех счетов учета материальных ценностей. Такая постановка вопроса, разумеется, возможна только при условии, что на всех счетах учета материальных ценностей в качестве аналитики используется один и тот же вид субконто. Применительно к демонстрационной конфигурации «Бухгалтерский учет», которая находится на прилагаемом компакт-диске, можно уточнить задачу. В конфигурации два счета учета материальных ценностей: Товары и Материалы. Предположим, что на обоих счетах первым субконто привязан вид субконто Номенклатура типа СправочникСсылка.Номенклатура. Для получения отчета, приведенного ниже, потребуется написать следующий код (листинг 12.38). Листинг 12.38. Пример получения остатков регистра бухгалтерии
Запрос = Новый Запрос; Запрос.Текст = "ВЫБРАТЬ | Остатки.Субконто1 КАК Товар, | Остатки.СуммаОстаток КАК Остаток |ИЗ | РегистрБухгалтерии.ОсновнойРегистрБухгалтерии.Остатки(&Дата, , &ВидСубконто,) КАК Остатки |ИТОГИ | СУММА(Остаток) |ПО | ОБЩИЕ"; Запрос.УстановитьПараметр("ВидСубконто", ПланыВидовХарактеристик.ВидыСубконто.Номенклатура); Запрос.УстановитьПараметр("Дата", Дата);
В параметр ВидСубконто запроса передается ссылка на вид характеристик Номенклатура. Результатом подобного запроса может быть таблица, представленная в табл. 12.45.
Таблица 12.45. Результат выполнения запроса Товар
Итог Комплект Паркер Школьная Цветной
Остаток
1250 100 1050 75 25
В колонке Остаток будет отображаться сумма остатков со счетов Товары и Материалы, т. к. только на этих счетах нашей конфигурации используется субконто Номенклатура. При желании в запрос можно добавить и отбор по списку счетов. При необходимости разделить отчет по счетам (Товары и Материалы) запрос может быть видоизменен (листинг 12.39). Листинг 12.39. Пример получения остатков регистра бухгалтерии
Запрос = Новый Запрос; Запрос.Текст = "ВЫБРАТЬ | Остатки.Субконто1 КАК Товар, | Остатки.Счет, | Остатки.СуммаОстаток КАК Остаток |ИЗ | РегистрБухгалтерии.ОсновнойРегистрБухгалтерии.Остатки(&Дата, , &ВидСубконто,) КАК Остатки |ИТОГИ | СУММА(Остаток) |ПО | ОБЩИЕ, | Товар"; Запрос.УстановитьПараметр("ВидСубконто", ПланыВидовХарактеристик.ВидыСубконто.Номенклатура); Запрос.УстановитьПараметр("Дата", Дата);
В запрос было добавлено еще одно группировочное поле Счет, а по субконто был подведен итог. Результатом запроса будет таблица, позволяющая увидеть итоговый остаток по виду номенклатуры не только в целом по всем счетам, но и по каждому в отдельности (табл. 12.46). Таблица 12.46. Результат выполнения запроса Товар
Счет
Итог Комплект Товары Паркер Товары Материалы Школьная Товары Цветной Товары
Том 1
Остаток
1250 100 100 1050 50 1000 75 75 25 25
667
Глава 12. Бухгалтерский учет При необходимости отчету можно придать «шахматный» вид, переведя вторую группировку (счета) в колонки отчета. Если мы еще усложним задачу, то нам может понадобиться второе назначение параметра Субконто – упорядочивание по виду субконто. Аналитика счетов Товары и Материалы настроена следующим образом (табл. 12.47).
материалов на 1000, а, во-вторых, что этот самый Филиал (субконто Склады) является первым субконто счета, который мы и анализируем нашим запросом. Если добавить в виртуальную таблицу регистра источник запроса, параметр Субконто и передать туда ссылку на вид субконто Номенклатура, ситуация будет исправлена (листинг 12.41).
Таблица 12.47. Аналитика счетов «Товары» и «Материалы»
Листинг 12.41. Пример получения остатков регистра бухгалтерии
Код
Счет
Субконто1
Субконто2
1.3 1.4
Товары Номенклатура Склады Материалы Склады Номенклатура
Задача остается той же: получить в одной строке отчета остаток с двух счетов, причем строками отчета должны быть номенклатурные позиции. Если при подобной настройке плана счетов мы выполним запрос без указания параметра Субконто, но с отбором по списку счетов в параметре таблицы УсловиеСчета (листинг 12.40), то результат выполнения этого запроса будет таким, как показано в табл. 12.48. Листинг 12.40. Пример получения остатков регистра бухгалтерии
Запрос = Новый Запрос; Запрос.Текст = "ВЫБРАТЬ | Остатки.Субконто1 КАК Товар, | Остатки.СуммаОстаток КАК Остаток |ИЗ | РегистрБухгалтерии.ОсновнойРегистрБухгалтерии.Остатки(&Дата, | Счет В (&СчетТоваров, &СчетМатериалов), ,) | КАК Остатки |ИТОГИ | СУММА(Остаток) |ПО | ОБЩИЕ"; Запрос.УстановитьПараметр("Дата", Дата); Запрос.УстановитьПараметр("СчетТоваров", ПланыСчетов.ОсновнойПланСчетов.Товары); Запрос.УстановитьПараметр("СчетМатериалов", ПланыСчетов.ОсновнойПланСчетов.Материалы); Таблица 12.48. Результат выполнения запроса Товар
Остаток
Итог Комплект Паркер Школьная Цветной Филиал
1250 100 50 75 25 1000
Обратите внимание на последнюю строку отчета «Филиал = 1000». Она говорит нам, во-первых, о том, что на складе Филиал есть остаток
668
Запрос = Новый Запрос; Запрос.Текст = "ВЫБРАТЬ | Остатки.Субконто1 КАК Товар, | Остатки.СуммаОстаток КАК Остаток |ИЗ | РегистрБухгалтерии.ОсновнойРегистрБухгалтерии.Остатки(&Дата, | Счет В (&СчетТоваров, &СчетМатериалов), | &ВидыСубконто,) КАК Остатки |ИТОГИ | СУММА(Остаток) |ПО | ОБЩИЕ"; Запрос.УстановитьПараметр("Дата", Дата); Запрос.УстановитьПараметр("СчетТоваров", ПланыСчетов.ОсновнойПланСчетов.Товары); Запрос.УстановитьПараметр("СчетМатериалов", ПланыСчетов.ОсновнойПланСчетов.Материалы); Запрос.УстановитьПараметр("ВидыСубконто", ПланыВидовХарактеристик.ВидыСубконто.Номенклатура);
Продолжим усложнять задачу. Предположим, нужно включить в отчет две группировки по субконто: сначала пользователь хочет увидеть итоги по номенклатуре, а потом детализацию по складам, на каком сколько числится. Решение будет напоминать ранее сделанное решение для группировки по счетам, проблема только в настройке плана счетов: субконто Номенклатура прикреплено первым на счет товаров и вторым на счет материалов. А обращаемся мы к ним в запросе именно по номеру (Субконто1, Субконто2). Чтобы добиться в результате запроса нужного порядка следования субконто на счетах (без изменения настройки плана счетов), необходимо воспользоваться все тем же параметром Субконто (листинг 12.42). Листинг 12.42. Пример получения остатков регистра бухгалтерии
Запрос = Новый Запрос; Запрос.Текст = "ВЫБРАТЬ | ОсновнойРегистрБухгалтерииОстатки.Субконто1 КАК Товар, | ОсновнойРегистрБухгалтерииОстатки.Субконто2 КАК Склад, | ОсновнойРегистрБухгалтерииОстатки.СуммаОстаток КАК СуммаОстаток |ИЗ | РегистрБухгалтерии.ОсновнойРегистрБухгалтерии.Остатки(&Дата, Счет В (&СчетТоваров, | &СчетМатериалов), &ВидыСубконто, ) КАК ОсновнойРегистрБухгалтерииОстатки |ИТОГИ
Профессиональная разработка в системе «1С:Предприятие 8»
Чтение данных регистра бухгалтерии | |ПО | | |
СУММА(СуммаОстаток) ОБЩИЕ, Товар, Склад";
Запрос.УстановитьПараметр("Дата", Дата); Запрос.УстановитьПараметр("СчетТоваров", ПланыСчетов.ОсновнойПланСчетов.Товары); Запрос.УстановитьПараметр("СчетМатериалов", ПланыСчетов.ОсновнойПланСчетов.Материалы); мВидыСубконто = Новый Массив; мВидыСубконто.Добавить(ПланыВидовХарактеристик.ВидыСубконто.Номенклатура); мВидыСубконто.Добавить(ПланыВидовХарактеристик.ВидыСубконто.Склады); Запрос.УстановитьПараметр("ВидыСубконто", мВидыСубконто);
Результатом выполнения этого запроса будет следующая таблица (табл. 12.49). Таблица 12.49. Результат выполнения запроса Товар
Склад
Итог Комплект Офис Паркер Офис Филиал Школьная Офис Цветной Офис Филиал
СуммаОстаток
1250 100 100 1050 -50 1100 75 75 25 10 15
Таким образом, нам удалось «расставить субконто по местам»: первым субконто в нашем запросе является Номенклатура, вторым – Склады. Причем если мы хотим изменить последовательность группировок в запросе (сначала группировать по складам, потом внутри склада – по номенклатурным позициям), нам достаточно изменить порядок следования элементов массива, который передается в параметр виртуальной таблицы Субконто.
Параметры «Период», «НачалоПериода» и «КонецПериода» Все виртуальные таблицы регистра позволяют устанавливать отбор итогов или на момент времени, или за период. Для установки такого отбора итогов можно использовать значения типа Дата, МоментВремени или Граница. Использование в запросе параметра типа МоментВремени в большинстве случаев ограничивается обработками проведения документов, когда Том 1
важно получить итоги с точностью «до ссылки». Этот объект, предназначенный для получения и хранения момента времени для объекта в базе данных, можно считать самым точным указанием для отбора итогов. Рассмотрим использование этих объектов в параметре Период виртуальной таблицы остатков. Исходная ситуация будет описана нами в виде журнала проводок. Было сделано несколько проводок разными датами по счету Касса. Мы рассматриваем период за июнь 2010 года. Входящий остаток составил 15 рублей, и было сделано четыре проводки за первое и второе июня по 10 рублей каждая. Исходящий остаток – 55 рублей (табл. 12.50). Таблица 12.50. Проводки Период
Остаток 31.05.2010 01.06.2010 12:00:00 01.06.2010 23:59:59 Остаток 01.06.2010 02.06.2010 0:00:00 02.06.2010 12:00:00 Остаток 02.06.2010
Счет дебета
Счет кредита
Сумма
Касса Касса
Покупатели Покупатели
10,00 10,00
Касса Касса
Покупатели Покупатели
10,00 10,00
Текущий остаток
15,00 25,00 35,00 35,00 45,00 55,00 55,00
Для анализа остатка мы воспользуемся следующим несложным запросом (листинг 12.43). Листинг 12.43. Пример получения остатков регистра бухгалтерии
Запрос = Новый Запрос; Запрос.Текст = "ВЫБРАТЬ | Остатки.СуммаОстаток |ИЗ | РегистрБухгалтерии.ОсновнойРегистрБухгалтерии.Остатки(&Момент, Счет = &Счет, | , КАК Остатки"; Запрос.УстановитьПараметр("Момент", Момент); Запрос.УстановитьПараметр("Счет", ПланыСчетов.ОсновнойПланСчетов.Касса); Результат = Запрос.Выполнить(); Если Результат.Пустой() Тогда Возврат 0; КонецЕсли; Остатки = Результат.Выбрать(); Остатки.Следующий(); Возврат Остатки.СуммаОстаток;
Запрос будет получать остаток по счету Касса на тот момент времени, который будет передан ему в качестве параметра. А передавать мы туда будем разные значения. Наша задача – получить остаток на счете Касса, который там сформировался к концу 1 июня (или, другими словами, к началу дня 2 июня).
669
Глава 12. Бухгалтерский учет Вариант первый (листинг 12.44).
Листинг 12.47. Четвертый вариант установки параметра запроса
Момент = Дата(2010, 6, 1);
Дата = Дата(2010, 6, 1); КонДня = КонецДня(Дата); Момент = Новый Граница(КонДня, ВидГраницы.Включая);
Полученный результат представлен в табл. 12.51.
Полученный результат представлен в табл. 12.54.
Листинг 12.44. Первый вариант установки параметра запроса
Таблица 12.51. Полученный результат и комментарий Момент равен
Остаток равен
Комментарий
01.06.10 0:00:00
15,00
Не было учтено время, получили остаток на начало дня
Вариант второй (листинг 12.45). Листинг 12.45. Второй вариант установки параметра запроса
Таблица 12.54. Полученный результат и комментарий Момент равен
Остаток равен
Комментарий
Граница
35,00
Правильно!
Подведем итоги (табл. 12.55). Таблица 12.55. Сводная таблица полученных результатов
Дата = Дата(2010, 6, 1); Момент = КонецДня(Дата);
№
Полученный результат представлен в табл. 12.52.
2 3 4
Метод
Момент
Остаток
Комментарий
01.06.10 0:00:00
15,00
Конец текущего дня
01.06.10 23:59:59
25,00
Начало следующего дня Граница (включая)
02.06.10 0:00:00 Граница
35,00 35,00
Не было учтено время, получили остаток на начало дня Получили остаток на конец дня, но в остатки не попала последняя проводка, сделанная в 23:59:59 Правильно! Правильно!
1
Таблица 12.52. Полученный результат и комментарий Момент равен
Остаток равен
Комментарий
01.06.10 23:59:59
25,00
Получили остаток на конец дня, но в остатки не попала последняя проводка, сделанная в 23:59:59
ВНИМАНИЕ!
В бухгалтерском учете проводка в 23:59:59 не редкость. Для счета Касса такая проводка маловероятна, но все счета, по которым выполняются регламентные операции, попадают в группу риска, ведь, например, закрытие месяца наверняка будет выполнено именно последним документом в этой дате.
Вариант третий (листинг 12.46). Листинг 12.46. Третий вариант установки параметра запроса
Дата = Дата(2010, 6, 1); ОдинДень = 60 * 60 * 24; Момент = НачалоДня(Дата + ОдинДень);
Полученный результат представлен в табл. 12.53. Таблица 12.53. Полученный результат и комментарий Момент равен
Остаток равен
Комментарий
02.01.06 0:00:00
35,00
Правильно!
Итак, правильные результаты были получены в третьем и четвертом вариантах. Для получения правильного остатка на конец периода, включающего все операции, необходимо или получать остатки на начало следующего периода, или использовать объект Граница с параметром ВидГраницы.Включая. Теперь рассмотрим этот же пример для таблицы оборотов (табл. 12.56). Таблица 12.56. Проводки Период
Счет дебета
Счет кредита
Сумма
01.06.2010 12:00:00 01.06.2010 23:59:59 Оборот за 01.06.2010 02.06.2010 0:00:00 02.06.2010 12:00:00 Оборот за 02.06.2010
Касса Касса
Покупатели Покупатели
Касса Касса
Покупатели Покупатели
10,00 10,00 20,00 10,00 10,00 20,00
Ниже приведен (листинг 12.48).
запрос,
который
будет
анализировать
обороты
Вариант четвертый (листинг 12.47).
670
Профессиональная разработка в системе «1С:Предприятие 8»
Чтение данных регистра бухгалтерии Листинг 12.48. Пример получения оборотов регистра бухгалтерии
Периодичность «оборотных» таблиц
Запрос = Новый Запрос; Запрос.Текст = "ВЫБРАТЬ | Обороты.СуммаОборот |ИЗ | РегистрБухгалтерии.ОсновнойРегистрБухгалтерии.Обороты(&НачПериода, &КонПериода, | , Счет = &Счет, , , , ) КАК Обороты";
Таблица оборотов, таблица оборотов и остатков и таблица оборотов Дт Кт содержат параметр Периодичность. Этот параметр позволяет задать дополнительную группировку данных таблицей – по стандартным периодам. Параметр может принимать одно из значений (табл. 12.57). Таблица 12.57. Значения, которые может принимать параметр «Периодичность»
Запрос.УстановитьПараметр("НачПериода", НачПериода); Запрос.УстановитьПараметр("КонПериода", КонПериода); Запрос.УстановитьПараметр("Счет", ПланыСчетов.ОсновнойПланСчетов.Касса);
Период
Комментарий
Период или пусто
Результат = Запрос.Выполнить(); Если Результат.Пустой() Тогда Возврат 0; КонецЕсли;
Полугодие
Обороты = Результат.Выбрать(); Обороты.Следующий(); Оборот = Обороты.СуммаОборот;
Неделя
Дополнительная группировка данных не выполняется Все проводки за год Все проводки за полгода Все проводки за квартал Все проводки за календарный месяц Все проводки за декаду Все проводки за неделю Все проводки за день Все проводки за час Все проводки за минуту Все проводки за секунду Все проводки одного документа (регистратора) группируются Движение регистра
Запрос получает обороты по счету Касса за период с НачПериода по КонПериода. С оборотами все проще. Нам достаточно использовать функции НачалоДня() и КонецДня(), чтобы получить все обороты за указанный интервал, включая указанные дни (листинг 12.49). Листинг 12.49. Пример установки начала и конца периода при получении оборотов
Дата = Дата(2010, 6, 1); НачПериода = НачалоДня(Дата); КонПериода = КонецДня(Дата);
Результатом работы функции будет значение 20, соответствующее обороту за первое июня 2010 года. Таблица остатков и оборотов рассчитывает исходящий остаток на основании входящего и оборотов (более подробно о работе виртуальных таблиц с данными информационной базы рассказано в разделе «Построение виртуальных таблиц регистра бухгалтерии» на стр. 684), поэтому особенного внимания к себе не требует. Для получения корректных остатков и оборотов за 1 июня 2010 года достаточно передать в качестве параметров даты начала и конца дня. Параметры виртуальной таблицы не являются обязательными. Если момент или период отбора итогов не будет указан, результат запроса вернет текущие итоги. Более подробно об этом рассказано в разделе «Механизм текущих итогов» на стр. 684. Пока же упомянем лишь, что в таблицах итогов регистра бухгалтерии хранятся не только рассчитанные итоги по месяцам, но и текущие итоги с учетом последнего проведенного документа. Том 1
Год Квартал Месяц Декада День Час Минута Секунда Регистратор Запись
Значение по умолчанию, если параметр не заполнен, – Период. При установке в параметре Периодичность виртуальной таблицы значения, отличного от Период, в таблице появляются новые поля, по которым можно сгруппировать данные. Покажем это на примере таблицы остатков и оборотов и таблицы оборотов Дт Кт регистра бухгалтерии демонстрационной конфигурации «Бухгалтерский учет», которая находится на прилагаемом компакт-диске. Колонки таблицы – значения параметра Периодичность. В таблице перечислены поля, добавляемые к тем, которые существуют по умолчанию (когда значение параметра Периодичность равно Период), табл. 12.58. Таблица 12.58. Поля, добавляемые в виртуальную таблицу остатков Дт Кт Период
Секунда и более
Регистратор
Запись
Период
Период Регистратор
Период Регистратор НомерСтроки
Как мы видим, по мере того как мы задаем большую детализацию в параметре таблицы, появляются новые поля таблицы. В случае, если периодичность равна Секунда или больше (Секунда – Год), появляется возможность группировать данные по периодам. Поле Период будет содержать дату начала периода. Например, если выбрана периодичность Год,
671
Глава 12. Бухгалтерский учет то все обороты за 2010 год будут сгруппированы в период 01.01.2010 00:00:00; если выбрана периодичность Месяц, то в таблице появятся первые числа всех месяцев, за которые были обороты.
Если периодичность сделать равной Запись (отчет Сводные проводки с периодичностью – Запись), каждая строка отчета будет отображать свою проводку, ее дату и время (рис. 12.60).
Если периодичность равна Регистратор, то кроме периода появляется возможность получить доступ к документу, сделавшему движения в регистре. Если периодичность равна Запись, мы получаем доступ к еще одному полю таблицы – НомерСтроки, номеру записи в наборе. Ниже приведен текст запроса, с помощью которого система компоновки данных извлекает данные из таблицы оборотов Дт Кт для отчета Сводные проводки с периодичностью – Месяц (листинг 12.50). Листинг 12.50. Пример отчета «Сводные проводки периодичностью Месяц»
ВЫБРАТЬ ОборотыДтКт.СчетДт, ОборотыДтКт.СчетКт, ОборотыДтКт.СуммаОборот, ОборотыДтКт.Период ИЗ РегистрБухгалтерии.ОсновнойРегистрБухгалтерии.ОборотыДтКт(, , Месяц, , , , , ) КАК ОборотыДтКт
Перед формированием отчета задается отчетный период (данные берутся на конец дня конца периода) и отбор по корреспондирующим счетам дебета и кредита. При периодичности запроса Месяц поле Период будет содержать дату начала каждого месяца. Как мы видим на рисунке внизу, часть проводок по корреспондирующим счетам Касса и Покупатели сделаны в мае 2010 года на сумму 450, а часть – в июне 2010 года на сумму 40 (рис. 12.59).
Рис. 12.59. Результат отчета при периодичности «Месяц»
672
Рис. 12.60. Результат отчета при периодичности «Запись»
В результате более детального отчета выяснится, например, что 40 рублей первого отчета состояли из четырех проводок по 10 рублей каждая, сделанных первого и второго июня 2010 года. Таким же образом устроена таблица оборотов. А вот таблица остатков и оборотов имеет свою особенность. Как видно из приведенных выше отчетов, в запрос попадают только те периоды, которые содержали обороты, соответствующие отборам, установленным в других параметрах таблицы. В нашем случае были фильтры на счет дебета и счет кредита, но в отчет попали только те периоды, где обороты между выбранными счетами были. Иначе говоря, в первый отчет не попал апрель 2010 года, потому что в нем не было никаких проводок, а во второй отчет не попало 3 июня по той же причине. Таблица остатков и оборотов позволяет в одной группировке запроса получить и остатки (входящие и исходящие), и обороты. Поэтому в таблице присутствует еще один параметр, позволяющий указывать, будут ли включены в результат отчета периоды, которые имели обороты или еще и границы интервала, если на эти даты были остатки. Параметр МетодДополнения может принимать два значения: ДвиженияИГраницыПериода (по умолчанию) и Движения. Рассмотрим отличия на примере запроса, приведенного ниже (листинг 12.51).
Профессиональная разработка в системе «1С:Предприятие 8»
Чтение данных регистра бухгалтерии Листинг 12.51. Пример получения остатков и оборотов регистра бухгалтерии
ВЫБРАТЬ ОсновнойРегистрБухгалтерииОстаткиИОбороты.Период, ОсновнойРегистрБухгалтерииОстаткиИОбороты.СуммаНачальныйОстаток КАК НачальныйОстаток, ОсновнойРегистрБухгалтерииОстаткиИОбороты.СуммаОборотДт КАК ОборотДт, ОсновнойРегистрБухгалтерииОстаткиИОбороты.СуммаОборотКт КАК ОборотКт, ОсновнойРегистрБухгалтерииОстаткиИОбороты.СуммаКонечныйОстаток КАК КонечныйОстаток ИЗ РегистрБухгалтерии.ОсновнойРегистрБухгалтерии.ОстаткиИОбороты(, , День, ДвиженияИГраницыПериода, Счет В ИЕРАРХИИ (&Счет), , ) КАК ОсновнойРегистрБухгалтерииОстаткиИОбороты
Отчет Остатки и обороты (движения и границы) формируется с помощью системы компоновки данных. Перед формированием отчета задается отчетный период (данные берутся на конец дня конца периода) и отбор по счету (в нашем примере – по счету Товары). Параметр Периодичность в запросе установлен в значение День, а параметр МетодДополнения – в значение ДвиженияИГраницыПериода. Исходные данные: существуют проводки по счету Товары, сделанные до 1 июня 2010 года, 23 и 25 июня 2010 года. Запрос выполняется по счету Товары за интервал с 01.06.2010 по 30.06.2010 года с периодичностью День. Результат выполнения запроса показан на рис. 12.61.
Рис. 12.62. Результат выполнения запроса
ВНИМАНИЕ!
Наличие в таблице остатков и оборотов наиболее часто встречающихся показателей (остатки на начало и конец интервала и обороты) и возможность формирования ее с периодичностью до проводки включительно не должны приводить к ее использованию для решения любых задач. Таблица остатков и оборотов является виртуальной, т. е. одна не хранится в базе данных и формируется системой при обращении к ней. Формирование таблицы может включать в себя выполнение до трех запросов. По каждому периоду (мы рассматриваем сейчас использование таблицы с заполненным параметром Периодичность) будут рассчитаны и обороты, и входящие остатки, и исходящие остатки. Если поставленная задача не требует получения всех этих показателей по каждой группировке (строке) отчета (например, отчет «Карточка счета»), то использование таблицы можно считать неоптимальным. Поэтому стоит обдумать возможность использования для решения другой таблицы (например, таблицы движений с субконто) для получения отбора проводок и таблицы остатков для получения остатков на начало периода.
Развернутые остатки Рис. 12.61. Результат выполнения запроса
Если параметр МетодДополнения принимает значение ДвиженияИГраницыПериода или если он не задан, то в отчет включается дата начала интервала отбора итогов (01.06.2010, так как на эту дату был входящий остаток) и дата конца интервала (30.06.2010, по той же причине), см. рис. 12.61. Если бы параметр МетодДополнения принимал значения Движения, в отчет попали только те даты, за которые были обороты по счету Товары (рис. 12.62). Том 1
Мы знаем, что все счета бухгалтерского учета делятся на активные, пассивные и активно-пассивные (в стандартах учета, принятых в РФ). Активные счета предназначены для группировки операций о движении средств (имущества, активов) предприятия. Остатки по активным счетам всегда дебетовые и показывают, каким имуществом обладает предприятие. Пассивные счета предназначены для группировки операций об изменении источников средств (пассивов) организации. Остатки по пассивным счетам всегда кредитовые и демонстрируют, откуда было получено имущество предприятия. Самые простые примеры активных счетов – счета учета денежных средств (касса, банк) и материальных запасов (товары,
673
Глава 12. Бухгалтерский учет материалы). Пример пассивных счетов – капитал собственника (т. е. задолженность перед хозяином предприятия) и расчеты с поставщиками. Таким образом, если на счете учитываются операции расчетов с тем, кто должен нам (например, с покупателями за поставленный им товар), то такой счет является активным (долг нам является нашим имуществом), и остаток по счету должен быть всегда дебетовым (дебиторская задолженность). Если на счете учитываются операции расчетов с тем, кому должны мы (например, с поставщиками за поставленный нам товар), то такой счет является пассивным (мы должны), и остаток будет всегда кредитовым (кредиторская задолженность). Сложившаяся в РФ теория и практика учета предусматривают и третий вид счетов – активно-пассивные. Это счета расчетов, на которых группируются операции с прочими контрагентами, как внутренними (по отношению к предприятию), так и внешними. Такой прочий контрагент, с которым могут совершаться самые разные операции, может оказаться как дебитором, так и кредитором. Пример такого счета в хозрасчетной бухгалтерии коммерческой организации РФ – расчеты с прочими дебиторами и кредиторами (счет 76). Рассмотрим несложный пример учета расчетов с прочими контрагентами. В методических целях будем использовать для учета расчетов счет «Прочие контрагенты» (имя счета – Контрагенты). В методических целях мы сократим количество возможных операций по этому счету до двух: мы будем отдавать им деньги и получать от них деньги. В реальной практике учета есть вероятность, что среди прочих дебиторов и кредиторов окажутся контрагенты, которым мы продаем товар, от которых мы получаем внеоборотные активы, и многие другие. Но нам сейчас интересен учет остатков, и то, какие обороты сформировали эти остатки, нам не принципиально. Итак, предположим, что у нас есть один Прочий контрагент, которому мы выдали 10 рублей (табл. 12.59). Таблица 12.59. Первая проводка №
Счет дт
Аналитика
Счет Кт
Контрагенты
Иванов
Касса
Аналитика
Сумма
10
Кроме этого, есть еще один контрагент, который решил дать нам 10 рублей (табл. 12.60). Таблица 12.60. Вторая проводка №
Счет Дт
Касса
Аналитика
Счет Кт
Аналитика
Контрагенты Петров
Сумма
10
Если на счете Контрагенты не ведется аналитический учет, то, анализируя остаток по счету Контрагенты, можно прийти к выводу: никто никому
674
ничего не должен (рис. 12.63), хотя контрагенты между собой о взаимозачете не договаривались.
Рис. 12.63. Анализ счета «Контрагенты»
Поэтому на счете Контрагенты будем вести учет в разрезе списка контрагентов. Тогда на каждого контрагента будет открыт свой маленький аналитический счет (рис. 12.64).
Рис. 12.64. Обороты по аналитическим счетам
Теперь, когда мы открыли на счете Контрагенты аналитический учет по контрагентам, с одной стороны, можем вести учет расчетов и анализировать задолженности по каждому контрагенту, что очень удобно. С другой стороны, мы получаем возможность видеть развернутый остаток по счету Контрагенты. Теперь у счета Контрагенты есть два типа остатков: свернутый (синтетический) остаток, который в нашем примере равен нулю, и развернутый (аналитический), который в нашем примере равен 10 руб. по дебету и 10 руб. по кредиту. Если свернутый (синтетический или просто остаток) остаток у счета всегда один, зависит от типа счета (активный, пассивный или активнопассивный) и рассчитывается системой (и в теории бухгалтерского учета) по правилам, которые мы рассматривали в разделе «Таблица остатков» на стр. 656, то развернутый остаток может быть и дебетовый, и кредитовый одновременно. В приведенном выше простом примере развернутый остаток счета соответствует оборотам счета, т. к. отсутствует входящий остаток. На самом деле они могут отличаться и наверняка отличаются. Рассмотрим более сложную ситуацию. Добавим для счета Контрагенты входящие остатки. Иванов был нашим кредитором, и мы были ему должны 8 рублей. В текущем отчетом периоде мы заплатили ему 10 рублей. Переплатили 2 рубля, и теперь он наш дебитор (он нам должен 2 рубля), рис. 12.65. Профессиональная разработка в системе «1С:Предприятие 8»
Чтение данных регистра бухгалтерии и другие варианты, например, развернутые остатки счета-группы с разворотом по субсчетам.
Рис. 12.65. Остатки и обороты на аналитических счетах
Петров, наоборот, был дебитором (был нам должен 3 рубля), в текущем отчетном периоде он сделал платеж на 10 рублей. Переплатил нам 7 рублей. Теперь мы ему должны 7 рублей. Мы видим, что при подсчете остатков по синтетическому счету Контрагенты мы учитываем входящее (свернутое) сальдо (5 рублей) и обороты по счету в целом (рис. 12.66).
Наиболее часто развернутые остатки требуется получать именно по активно-пассивным счетам, счетам расчетов и, чаще всего, при составлении баланса. По стандартам учета расчеты при включении в баланс не должны «сворачиваться»: в активе баланса нужно показать полную сумму дебиторской задолженности, а в пассиве – кредиторской. Возвращаясь к нашему примеру, правильно показать в активе баланса 2 рубля, а в пассиве – 7 рублей. Неправильно показать в пассиве 5 рублей. В системе «1С:Предприятие» для подсчета развернутых остатков используются специальные поля виртуальных таблиц. В таблице остатков это поля: ■■ <Ресурс>РазвернутыйОстатокДт, ■■ <Ресурс>РазвернутыйОстатокКт. В таблице остатков и оборотов такими полями являются следующие поля:
Рис. 12.66. Синтетический счет «Контрагенты»
При расчете развернутого сальдо по счету в разрезе аналитики (рис. 12.67) мы делаем следующее: ■■ выполняем расчет по каждому объему аналитики; ■■ по каждому объекту аналитики получаем входящее (развернутое) сальдо; ■■ по каждому объекту аналитики подсчитываем обороты; ■■ по каждому объекту аналитики рассчитываем исходящее сальдо; ■■ суммируем отдельно по всем объектам аналитики остатки дебетовые и отдельно кредитовые; ■■ получаем развернутый дебетовый остаток и развернутый кредитовый остаток по счету.
■■ ■■ ■■ ■■
<Ресурс>НачальныйРазвернутыйОстатокДт, <Ресурс>КонечныйРазвернутыйОстатокДт, <Ресурс>НачальныйРазвернутыйОстатокКт, <Ресурс>КонечныйРазвернутыйОстатокКт.
Реализуем в конфигурации описанный выше пример учета на счете Контрагенты и напишем запрос для анализа развернутого остатка по счету. При решении задачи получения развернутых остатков всегда нужно исходить из формулы: Остаток по <Итог> развернутый по <ПоляДетальнойВыборки>.
Поля развернутых остатков, присутствующие в виртуальных таблицах в детальной выборке запроса, полностью повторяют содержимое полей остатков (свернутых). Развернутые остатки имеют смысл только при наличии в запросе итогов. Построим несколько элементарных запросов к таблице остатков. Во все запросы будем передавать только один параметр Счет, который равен ссылке на счет Контрагенты. Первый запрос получит все остатки с отбором по счету (листинг 12.52). Листинг 12.52. Пример получения остатков регистра бухгалтерии
Рис. 12.67. Аналитический счет «Контрагенты»
Развернутый остаток не имеет смысла без критерия, по которому он будет «разворачиваться». В практике учета чаще всего получают развернутые остатки счета с разворотом по аналитике этого счета. Хотя возможны Том 1
ВЫБРАТЬ Остатки.Счет, Остатки.СуммаОстатокДт КАК СвернутыйДт, Остатки.СуммаОстатокКт КАК СвернутыйКт, Остатки.СуммаРазвернутыйОстатокДт КАК РазвернутыйДт, Остатки.СуммаРазвернутыйОстатокКт КАК РазвернутыйКт ИЗ РегистрБухгалтерии.ОсновнойРегистрБухгалтерии.Остатки(, Счет = &Счет, , ) КАК Остатки
675
Глава 12. Бухгалтерский учет Результат этого запроса – одна строка. Свернутые и развернутые остатки равны. Причина: мы не указали, по какому полю разворачивать (табл. 12.61). Таблица 12.61. Результат выполнения запроса Счет
СвернутыйДт
СвернутыйКт
РазвернутыйДт
РазвернутыйКт
Контрагенты
5
5
ПО
СУММА(СвернутыйКт), СУММА(РазвернутыйДт), СУММА(РазвернутыйКт) Счет
Результат выполнения этого запроса представлен в табл. 12.63. Таблица 12.63. Результат выполнения запроса
Изменим запрос, включим в поля выборки новое поле Субконто1, т. е. контрагента (листинг 12.53). Листинг 12.53. Пример получения остатков регистра бухгалтерии
Счет
Контрагент
СвернутыйДт
СвернутыйКт
РазвернутыйДт
РазвернутыйКт
Контрагенты
Иванов Петров
2
5 7
2 2
7 7
ВЫБРАТЬ Остатки.Счет, Остатки.Субконто1 КАК Контрагент, Остатки.СуммаОстатокДт КАК СвернутыйДт, Остатки.СуммаОстатокКт КАК СвернутыйКт, Остатки.СуммаРазвернутыйОстатокДт КАК РазвернутыйДт, Остатки.СуммаРазвернутыйОстатокКт КАК РазвернутыйКт ИЗ РегистрБухгалтерии.ОсновнойРегистрБухгалтерии.Остатки(, Счет = &Счет, , ) КАК Остатки
Мы получили свернутые и развернутые остатки по счету. При подведении итогов поля <Ресурс>ОстатокДт и <Ресурс>ОстатокКт сворачиваются по правилам, которые определяет вид счета (активный, пассивный, активно-пассивный), а поля <Ресурс>РазвернутыйОстатокДт и <Ресурс>РазвернутыйОстатокКт суммируются раздельно: отдельно подводится итог по элементам выборки, имеющим дебетовый остаток, отдельно по элементам, имеющим кредитовый остаток.
Результатом запроса будет таблица из двух строк: счет повторяется, но остатки мы получили по каждому контрагенту. Свернутые остатки и развернутые по-прежнему равны (табл. 12.62).
Можно ли было в нашем случае не включать в запрос поле Счет? Да, можно. Мы могли бы ограничиться включением в детальную выборку поля Субконто1 и подвести общие итоги.
Таблица 12.62. Результат выполнения запроса Счет
Контрагент СвернутыйДт СвернутыйКт
РазвернутыйДт
РазвернутыйКт
Контрагенты Контрагенты
Иванов Петров
2
7
2
7
Однако в этом запросе мы уже видим, что если подвести итоги по колонкам, мы получим тот самый развернутый остаток по счету, который нас и интересует. Давайте это сделаем. Подводим итоги по счету, суммируя все числовые поля (листинг 12.54). Листинг 12.54. Пример получения остатков регистра бухгалтерии
ВЫБРАТЬ Остатки.Счет КАК Счет, Остатки.Субконто1 КАК Контрагент, Остатки.СуммаОстатокДт КАК СвернутыйДт, Остатки.СуммаОстатокКт КАК СвернутыйКт, Остатки.СуммаРазвернутыйОстатокДт КАК РазвернутыйДт, Остатки.СуммаРазвернутыйОстатокКт КАК РазвернутыйКт ИЗ РегистрБухгалтерии.ОсновнойРегистрБухгалтерии.Остатки(, Счет = &Счет, , ) КАК Остатки ИТОГИ СУММА(СвернутыйДт),
676
Таким образом, итоги разворачиваются по всем полям детальной выборки (в нашем примере по двум – Счет и Субконто1) и рассчитываются по итоговому полю.
Методы менеджера регистра бухгалтерии Основным способом чтения данных в системе является запрос, и это оправданно. Однако для извлечения данных может применяться и объектная техника. Менеджер регистра бухгалтерии имеет три метода, позволяющих получать остатки и обороты. Необходимо сразу же оговориться, что при обращении к этим методам система все равно выполнит запрос. Разница между использованием запроса к виртуальным таблицам регистра бухгалтерии и использованием методов объекта лишь в синтаксисе. У менеджера регистра бухгалтерии существует три метода извлечения остатков и оборотов: ■■ ■■ ■■
Остатки(), Обороты(), ОборотыДтКт().
Каждый из них по своему назначению и функциональности похож на одноименную виртуальную таблицу. Профессиональная разработка в системе «1С:Предприятие 8»
Чтение данных регистра бухгалтерии Результат, возвращаемый этими методами, – таблица значений, содержащая затребованные при выполнении метода поля выборки. Такой же результат может быть получен с помощью запроса и последующей выгрузки результата запроса в таблицу значений (листинг 12.55). Листинг 12.55. Выполнение запроса и выгрузка результата запроса в таблицу значений
Таблица = Запрос.Выполнить().Выгрузить();
Рассмотрим работу метода Остатки(). Задача – получить остаток одного товара на выбранную пользователем дату. Пользователь выбирает в диалоге формы следующие параметры: ■■ Дата, ■■ Организация, ■■ Товар. Решим сначала задачу с помощью запроса (листинг 12.56). Листинг 12.56. Получение остатков с помощью запроса
Момент = Новый Граница(КонецДня(Дата), ВидГраницы.Включая); СчетТоваров = ПланыСчетов.ОсновнойПланСчетов.Товары; Запрос = Новый Запрос; Запрос.Текст = "ВЫБРАТЬ | Остатки.КоличествоОстатокДт |ИЗ | РегистрБухгалтерии.ОсновнойРегистрБухгалтерии.Остатки(&Момент, Счет = &Счет, , | Субконто1 = &Субконто1 | И | Организация = &Организация) | КАК Остатки"; Запрос.УстановитьПараметр("Момент", Момент); Запрос.УстановитьПараметр("Счет", СчетТоваров); Запрос.УстановитьПараметр("Субконто1", Товар); Запрос.УстановитьПараметр("Организация", Организация); Результат = Запрос.Выполнить(); Остатки = Результат.Выбрать(); Остатки.Следующий(); ОстатокТовара = Остатки.КоличествоОстатокДт;
Эта же задача с помощью метода Остатки() менеджера регистра бухгалтерии может быть решена следующим образом (листинг 12.57). Листинг 12.57. Получение остатков с помощью метода «Остатки()»
Сравним параметры виртуальной таблицы остатков регистра бухгалтерии и параметры метода Остатки(), табл. 12.64. Таблица 12.64. Сравнение параметров таблицы остатков и метода «Остатки()» Метод Остатки()
Запрос к виртуальной таблице остатков
№
Параметр
№
1 2 3
МоментВремени
4 5
Измерения
Период 1 Субконто 3 УсловиеСчета 2 Условие 4 Выбранные поля-измерения запроса Выбранные поля-ресурсы запроса
ВидыСубконто Отбор
Ресурсы
Параметр
Первый параметр метода – МоментВремени – по своему назначению и использованию полностью идентичен первому параметру Период виртуальной таблицы остатков. Второй параметр – ВидыСубконто – позволяет установить отбор по виду субконто или упорядочить поля Субконто запроса, в точности как параметр Субконто виртуальной таблицы. Более подробно о назначении параметра можно посмотреть в разделе «Параметр «Субконто»: отбор и упорядочивание по виду субконто» на стр. 666. Третий параметр метода – Отбор – имеет тип Структура. Каждый элемент структуры описывает одно условие отбора. В этом элементе ключ соответствует полю, по которому можно выполнить отбор в виртуальной таблице (Счет, Субконто, <Измерение>). А значение элемента – это значение, по которому нужно отобрать. Этот параметр объединяет в себе второй (УсловиеСчета) и четвертый (Условие) параметры виртуальной таблицы. Четвертый (Измерения) и пятый (Ресурсы) параметры метода позволяют указать в виде строки одно или несколько (через запятую) полей таблицы, которые будут включены в детальную выборку запроса. Как измерения могут быть указаны поля Счет, Субконто, <Измерение>. В качестве ресурсов указываются имена ресурсов регистра бухгалтерии. Ниже приводится пример использования параметров метода для получения таблицы остатков товаров (листинг 12.58). Листинг 12.58. Пример получения остатков регистра бухгалтерии
Момент = Новый Граница(КонецДня(Дата), ВидГраницы.Включая); СчетТоваров = ПланыСчетов.ОсновнойПланСчетов.Товары; Регистр = РегистрыБухгалтерии.ОсновнойРегистрБухгалтерии; Отбор = Новый Структура("Счет, Субконто1, Организация", СчетТоваров, Товар, Организация);
Момент = Новый Граница(КонецДня(Дата), ВидГраницы.Включая); СчетТоваров = ПланыСчетов.ОсновнойПланСчетов.Товары; Регистр = РегистрыБухгалтерии.ОсновнойРегистрБухгалтерии; Отбор = Новый Структура("Счет, Организация", СчетТоваров, Организация); ТаблицаРезультат = Регистр.Остатки(Момент, , Отбор, "Субконто1, Субконто2", "Количество, Сумма");
ТаблицаРезультат = Регистр.Остатки(Момент, ,Отбор, "" , "Количество"); ОстатокТовара = ТаблицаРезультат.Итог("КоличествоОстатокДт");
Результат исполнения кода приведен в табл. 12.65.
Том 1
Остатки()
677
Глава 12. Бухгалтерский учет
Физические таблицы регистра бухгалтерии
Таблица 12.65. Результат выполнения запроса Субконто1
Субконто2 Количество ОстатокДт
Количество ОстатокКт
Сумма ОстатокДт
Сумма ОстатокКт
Комплект Паркер Паркер Школьная Цветной Цветной
Офис Офис Филиал Офис Офис Филиал
100 -50 100 75 10 15
1 -5 10 10 3
Все физические таблицы регистра бухгалтерии можно разделить на две группы: таблицы первичных движений и таблицы итогов (рис. 12.68).
Такой же результат может быть получен с помощью запроса (листинг 12.59). Листинг 12.59. Пример получения остатков регистра бухгалтерии
Момент = Новый Граница(КонецДня(Дата), ВидГраницы.Включая); СчетТоваров = ПланыСчетов.ОсновнойПланСчетов.Товары; Запрос = Новый Запрос; Запрос.Текст = "ВЫБРАТЬ | Остатки.Субконто1, | Остатки.Субконто2, | Остатки.КоличествоОстатокДт, | Остатки.КоличествоОстатокКт, | Остатки.СуммаОстатокДт, | Остатки.СуммаОстатокКт |ИЗ | РегистрБухгалтерии.ОсновнойРегистрБухгалтерии.Остатки(&Момент, Счет = &Счет, , | Организация = &Организация | ) КАК Остатки"; Запрос.УстановитьПараметр("Момент", Момент); Запрос.УстановитьПараметр("Счет", СчетТоваров); Запрос.УстановитьПараметр("Организация", Организация); Результат = Запрос.Выполнить(); ТаблицаРезультат = Результат.Выгрузить();
Вопросы производительности регистра бухгалтерии Этот раздел посвящен внутреннему устройству объекта Регистр бухгалтерии и предназначен для более глубокого понимания работы системы и более оптимального написания запросов к виртуальным таблицам регистра. Авторы не рекомендуют использовать знание физической организации таблиц для непосредственного доступа к таблицам. Все примеры и вопросы, рассмотренные в разделе, подразумевают использование системы «1С:Предприятие» в клиент-серверном варианте работы, при котором информационная база хранится в формате таблиц SQL Server.
678
Рис. 12.68. Физические таблицы регистра бухгалтерии
Таблицы первичных движений доступны для выполнения запроса и поэтому знакомы нам – это основная таблица и таблица значений субконто. Эти две таблицы хранят полную информацию о проводке. Таблицы итогов скрыты от прикладного разработчика и не могут выступать как источники запроса. И таблицы первичных движений, и таблицы итогов служат источниками данных для виртуальных таблиц регистра, которые по своей сути являются вложенными запросами. Таблицы первичных движений рассмотрены в разделе «Реальные таблицы» на стр. 655, поэтому перейдем сразу к описанию таблиц итогов.
Остатки и обороты по счетам Физическая таблица остатков и оборотов по счетам имеет следующую структуру (табл. 12.66). Таблица 12.66. Структура таблицы остатков и оборотов по счетам Период Счет
<Измерения>
<Ресурсы>
Остаток
ОборотДт
ОборотКт
Профессиональная разработка в системе «1С:Предприятие 8»
Вопросы производительности регистра бухгалтерии Рассмотрим подробнее поля этой таблицы (табл. 12.67). Таблица 12.67. Поля таблицы остатков и оборотов по счетам
Период
Комментарий
Период
Итоги хранятся помесячно, поле содержит дату (первое число месяца) Ссылка на счет плана счетов Количество полей зависит от измерений, которые созданы в регистре бухгалтерии Для каждого ресурса регистра бухгалтерии создаются три поля таблицы итогов: Остаток, ОборотДт, ОборотКт Хранит абсолютный остаток (дебет-кредит) на начало месяца, за который рассчитаны итоги (т. е. на конец прошлого месяца). При построении виртуальных таблиц служит основой для расчета полей ОстатокДт, ОстатокКт, РазвернутыйОстатокДт, РазвернутыйОстатокКт и зависит от вида счета (активный, пассивный, активно-пассивный) Дебетовый оборот счета за рассчитанный месяц Кредитовый оборот счета за рассчитанный месяц Общий оборот счета за рассчитанный месяц Разделитель итогов (для обеспечения параллельности проведения документов)
<Измерения> <Ресурсы> Остаток
ОборотДт ОборотКт Оборот Разделитель
Таблица хранит итоги по всем счетам. И при любом движении в регистре бухгалтерии эта таблица обновляется.
Наличие этой таблицы – одно из оснований, позволяющих утверждать, что регистры накопления более производительны по сравнению с регистрами бухгалтерии. По своей сути регистр бухгалтерии – это «регистр регистров», где каждый счет можно сравнить с регистром накопления. Однако таблица остатков и оборотов по счетам одна на все счета, и изменяется при записи любого документа, делающего движение по любым счетам.
Таблицы остатков и оборотов по счетам и субконто Физические таблицы остатков и оборотов по счетам и субконто появляются, когда хотя бы на один счет плана счетов был добавлен хотя бы один вид субконто. Количество таблиц соответствует максимальному количеству субконто, используемых на счетах. Структура таблиц напоминает структуру физической таблицы остатков и оборотов по счетам. В случае, если на счетах задействовано только два вида субконто, будет создано две таблицы (табл. 12.68 и табл. 12.69). Таблица 12.68. Структура первой таблицы остатков и оборотов по счетам и субконто при использовании двух видов субконто Счет
<Измерения> <Субконто>
Субконто1
Том 1
<Измерения> <Субконто>
<Ресурсы>
Ск2
Остаток
ОборотДт
ОборотКт
Если мы увеличим максимальное количество субконто и добавим хотя бы на один счет третье субконто, в базу данных будет добавлена еще одна таблица (табл. 12.70). Таблица 12.70. Структура третьей таблицы остатков и оборотов по счетам и субконто при использовании трех видов субконто Период
Счет
<Измерения> <Субконто>
Ск1
<Ресурсы>
Ск2
Ск3
Остаток
ОборотДт
ОборотКт
При записи движения в регистр изменяется только одна из этих таблиц (для регистра без поддержки корреспонденций). Для регистра с поддержкой корреспонденций может потребоваться изменение двух таблиц (для счета дебета и счета кредита проводки, если на них различное количество субконто). Запись производится лишь в ту таблицу, количество субконто которой соответствует количеству субконто счета проводки. Например, пусть записывается проводка, представленная в табл. 12.71.
ВНИМАНИЕ!
Период
Счет
Ск1
Поле Счет
Таблица 12.69. Структура второй таблицы остатков и оборотов по счетам и субконто при использовании двух видов субконто
<Ресурсы>
Остаток
ОборотДт
Таблица 12.71. Пример проводки №
Счет Дт
1
Поставщики
Субконто 1
Счет Кт
Субконто 2
Иванов
Субконто 1
Сумма
Субконто 2
Касса
10
В этом случае будет внесено изменение в одну из таблиц остатков и оборотов по счетам и субконто. В ту из них, где остатки и обороты учитываются в разрезе одного субконто (и по счету Поставщики, и по счету Касса), будет сделана запись в таблицу, которая хранит итоги в разрезе Субконто1. Теперь рассмотрим другую проводку (табл. 12.72). Таблица 12.72. Пример проводки №
Счет Дт
Субконто 1
Счет Кт
Субконто 2
2
Товары
Авторучка Склад № 1
Субконто 1
Сумма
Субконто 2
Поставщики
Иванов
10
ОборотКт
679
Глава 12. Бухгалтерский учет В этом случае будут изменены две таблицы: по счету Поставщики будет сделана запись в таблицу, которая хранит итоги в разрезе Субконто1; по счету Товары будет сделана запись в таблицу, которая хранит итоги в разрезе Субконто 1 и Субконто 2. Кроме того, для двух проводок для каждого счета будут сделаны записи в физическую таблицу остатков и оборотов по счетам, рассмотренную нами в разделе «Остатки и обороты по счетам» на стр. 678.
Строка в таблице итогов имеет период – 01.07.2010 и хранит остатки на начало июля 2010 года и обороты за июль. Расчет итогов можно выполнить программно, используя метод регистра бухгалтерии УстановитьПериодРассчитанныхИтогов(), листинг 12.60. Листинг 12.60. Пример использования метода «УстановитьПериодРассчитанныхИтогов()»
РегистрыБухгалтерии.ОсновнойРегистрБухгалтерии.УстановитьПериодРассчитанныхИтогов(Дата);
Обороты между счетами Для регистра с поддержкой корреспонденций создается физическая таблица для хранения оборотов в разрезе корреспондирующих счетов (таблица оборотов между счетами), табл. 12.73.
В качестве параметра в метод передается дата месяца, за который необходимо выполнить расчет итогов. ВНИМАНИЕ!
Расчет итогов не является обязательным, но представляется нам очень желательным. Рассчитанные итоги влияют на скорость получения остатков и оборотов по счетам: при построении виртуальных таблиц система всегда, когда есть возможность, обращается к таблицам итогов. Если затребованных данных в таблицах итогов нет, система обращается к таблицам первичных движений.
Таблица 12.73. Структура таблицы оборотов между счетами Период
СчетДт
СчетКт
<Измерения>
<Ресурсы>
Оборот
Таблица хранит обороты между счетами без детализации по субконто. Поэтому для извлечения любых оборотов между субконто используются физические таблицы первичных движений.
Управление итогами Управление итогами регистра бухгалтерии осуществляется интерактивно с помощью системной команды Управление итогами. Для этого нужно вызвать стандартную функцию Управление итогами (Все функции Стандартные) и переключить ее в режим Полные возможности (рис. 12.69).
Рис. 12.69. Диалог управления итогами
Период рассчитанных итогов – месяц. На рисунке видно, что последний рассчитанный месяц итогов регистров бухгалтерии – июль 2010 года.
680
Рассмотрим структуру физической таблицы остатков и оборотов по счетам, соответствующей приведенному выше диалогу расчета итогов (итоги рассчитаны по 31.07.2010 года), табл. 12.74. Таблица 12.74. Структура таблицы остатков и оборотов по счетам Период
Счет
01.02.2010 <Счет> 00:00:00
<Измерения>
<Измерения>
01.03.2006 <Счет> 00:00:00
<Измерения>
01.04.2006 <Счет> 00:00:00
<Измерения>
01.05.2006 <Счет> 00:00:00
<Измерения>
01.06.2006 <Счет> 00:00:00
<Измерения>
01.07.2006 <Счет> 00:00:00
<Измерения>
01.11.3999 00:00:00
<Измерения>
<Счет>
<Ресурсы>
Остаток на начало Дебетовый февраля (на конец оборот за января 2010 года) февраль 2010 года Остаток на начало Дебетовый марта (конец оборот за март февраля) 2010 2010 года года Остаток на начало Дебетовый апреля (конец оборот за марта) 2010 года апрель 2010 года Остаток на начало Дебетовый мая (конец апреля) оборот за май 2010 года 2010 года Остаток на начало Дебетовый июня (конец мая) оборот за июнь 2010 года 2010 года Остаток на начало Дебетовый июля (конец июня) оборот за июль 2010 года 2010 года Актуальный 0 остаток с учетом всех движений регистра
Кредитовый оборот за февраль 2010 года Кредитовый оборот за март 2010 года Кредитовый оборот за апрель 2010 года Кредитовый оборот за май 2010 года Кредитовый оборот за июнь 2010 года Кредитовый оборот за июль 2010 года 0
Профессиональная разработка в системе «1С:Предприятие 8»
Вопросы производительности регистра бухгалтерии Таким образом, каждая строка таблицы итогов регистра бухгалтерии как указание месяца итогов хранит дату начала месяца. Хранится счет и измерения, и для каждого ресурса регистра бухгалтерии хранится абсолютный остаток (дебетовый остаток минус кредитовый остаток) на начало рассчитанного месяца (т. е. на конец прошлого месяца) и обороты за месяц. Дополнительно создается строка, маркированная периодом 01.11.3999, предназначенная для хранения текущих итогов регистра с учетом всех его записей. подробнее
Получение данных из таблиц итогов рассмотрено в разделе «Виртуальные таблицы» на стр. 655.
Режим разделения итогов Использование режима разделения итогов обеспечивает более высокую параллельность работы при записи в регистр, что позволяет ускорить запись в регистр и избежать блокировок в тех случаях, когда разные пользователи записывают данные с одинаковым набором значений полей (Период + Счет + Измерение). При использовании режима разделения итогов система при одновременной записи движений несколькими сеансами не будет обновлять одни и те же записи итогов, а будет записывать изменения итогов в отдельные записи. При получении итогов эти данные складываются. Таким образом обеспечивается и поддержание в актуальном состоянии итогов (например, для быстрого получения отчетов), и параллельность записи движений. Как уже говорилось, при записи движений в регистр записи в таблице итогов автоматически пересчитываются. Считываемые записи таблицы итогов в момент пересчета блокируются. Таким образом, документы, содержащие движения по одинаковым комбинациям значений полей (Период + Счет + Измерение), не могут быть проведены параллельно. Механизм разделения итогов вводит в состав хранимой таблицы итогов специальное поле (Разделитель), позволяющее распараллелить обновление записей итогов. Новые записи (с новым разделителем) с уже существующими комбинациями значений полей (Период + Счет + Измерение) создаются системой только в том случае, если параллельно выполняются две и более транзакции. Таким образом, увеличение количества записей итогов зависит от количества одновременно выполняемых транзакций. При получении итогов регистра бухгалтерии или при пересчете итогов записи сворачиваются по комбинациям измерений. Чтобы управлять работой данного механизма, предусмотрены две возможности. В конфигурации для регистров введено свойство Разрешить разделение итогов. Для новых регистров бухгалтерии, создаваемых в конфигурации, Том 1
это свойство стандартно установлено. Установка этого свойства позволяет включить или отключить возможность разделения итогов для конкретного регистра. Отключение свойства полностью исключает влияние данного механизма на работу регистра, так как само поле, используемое для разделения итогов, не включается в структуру регистра. Отключение данной возможности полезно, например, для регистров, которые не используются при параллельной работе пользователей (например, для регистров, всегда заполняемых специальными регламентными обработками). Признак использования разделения итогов для регистров (для которых разделение итогов разрешено в конфигурации) может быть получен и установлен программно методами менеджера регистра бухгалтерии ПолучитьРежимРазделенияИтогов() и УстановитьРежимРазделенияИтогов(), а также в стандартной функции управления итогами (Все функции Стандартные Управление итогами Полные возможности Разделение итогов Включить разделение итогов/Выключить разделение итогов). Такая возможность позволяет включать или выключать режим
разделения итогов в зависимости от условий работы пользователей в конкретной организации. Например, при интенсивном параллельном вводе информации этот режим может быть полезен. Но если с системой работает небольшое количество пользователей, то выигрыш от его применения будет небольшой, а некоторое замедление при получении отчетов и лишние записи в таблицах итогов фактически будут лишними (неоправданными). подробнее
В целом механизм разделения итогов для регистров бухгалтерии аналогичен такому же механизму для регистров накопления остатков. Подробно он описан в разделе «Режим разделения итогов» на стр. 681.
Индексы таблиц итогов регистра бухгалтерии Для ускорения поиска нужных записей в физических таблицах создаются индексы. Система создает индексы автоматически в соответствии со свойствами объектов. Нас интересует количество и состав полей в индексах, их зависимость от свойств объектов и их влияние на производительность системы. Так как производительность подсистемы бухгалтерского учета во многом определяется эффективностью хранения и получения данных из таблиц итогов регистра бухгалтерии, мы уделим им особое внимание. В индекс таблиц итогов регистра бухгалтерии входят следующие поля: Период + Счет + Измерение1 + [Измерение2…] + ЗначениеСубконто1 + [ЗначениеСубконто2…]
Индексы, создаваемые платформой для физических таблиц итогов регистра бухгалтерии, влияют на производительность системы с двух сторон: влияние на скорость записи движений при проведении документа и влияние на скорость получения данных при обращении к итогам (табл. 12.75).
681
Глава 12. Бухгалтерский учет Таблица 12.75. Влияние индексов на производительность Критерий
Влияние на производительность
Количество индексов
Обновление индексов при записи движений. Чем Да больше индексов создано для таблиц регистра, тем дольше они будут обновляться в момент записи движений в таблицы регистра, что существенно увеличит время проведения документа Чем больше полей попало в индекс, тем точнее Да будет выполнен захват строк (диапазона строк) таблицы итогов, который нужно обновить при записи движений в регистр Поля, не включенные в индекс, увеличат диапазон строк таблиц итогов на количество всех возможных комбинаций этих полей. Поиск нужных строк в этой выборке будет осуществляться перебором
Количество полей в индексе
Запись
Чтение Ограничение
Не более 128 индексов для таблицы
Несложно представить, к чему приведет увеличение максимального количества субконто до трех или включение еще одного примитивного типа данных (например, Булево) в состав составного типа данных значения субконто. СОВЕТ
Не более 16 полей в индексе Да
Рассмотрим подробнее перечисленные критерии.
Тип значения субконто и его влияние на количество индексов Количество индексов существенно зависит от типов полей, которые были использованы при создании измерений и/или субконто регистра. Рассмотрим несложный пример: в плане счетов установлено максимальное количество субконто, равное «2». Используются субконто примитивного типа данных (Дата и Строка).
Категорически не рекомендуется включать в составной тип данных плана видов характеристик, используемого в качестве видов субконто, примитивные типы данных.
Количество полей в индексе SQL Server имеет ограничение на количество полей в индексе, равное 16. Поиск по полям, участвующим в индексе, осуществляется системой быстро. Если есть поля, которые должны были бы участвовать в индексе (измерения, значения субконто), но не были включены в него по причине ограничения длины, система сможет быстро получить выборку, включающую в себя поля, участвующие в индексе, и все сочетания полей, не вошедших в индекс. Полученная выборка будет обрабатываться построчно с целью поиска нужной строки итогов. Рассмотрим это на примере физической таблицы остатков и оборотов по счетам и субконто регистра бухгалтерии демонстрационной конфигурации «Бухгалтерский учет», которая находится на прилагаемом компакт-диске (рис. 12.71).
При использовании примитивных типов данных для каждого включенного примитивного типа в составной тип данных значения субконто создается свое поле в информационной базе (рис. 12.70).
Рис. 12.70. Поля записи
Индекс будет создан на каждое сочетание полей (табл. 12.76). Таблица 12.76. Создаваемые индексы Номер индекса
Поля в индексе
1 2 3 4
… + Субконто1 (Дата) + Субконто2 (Дата) … + Субконто1 (Дата) + Субконто2 (Строка) … + Субконто1 (Строка) + Субконто2 (Дата) … + Субконто1 (Строка) + Субконто2 (Строка)
682
Рис. 12.71. Свойства, влияющие на количество полей в индексе
Индекс будет включать следующие поля (табл. 12.77). Профессиональная разработка в системе «1С:Предприятие 8»
Вопросы производительности регистра бухгалтерии до четырех. При таком максимальном количестве субконто мы как раз «укладываемся» в 16 полей индекса.
Таблица 12.77. Поля, входящие в индекс № Поле
Комментарий
1 2 3
Период Счет Организация
4
Валюта
5 6 7 8 9 10
Субконто1 Субконто1 Субконто1 Субконто2 Субконто2 Субконто2
Тип Таблица Запись Тип Таблица Запись
Прокомментируем
Дата начала месяца периода итогов (Дата) Счет плана счетов (ПланСчетовСсылка.<имя>) Измерение регистра бухгалтерии Организация (СправочникСсылка.<имя>) Измерение регистра бухгалтерии Валюта (СправочникСсылка.<имя>) Фактический тип значения поля составного типа Тип ссылки Значение ссылки Фактический тип значения поля составного типа Тип ссылки Значение ссылки
таблицу:
хранения
Рассмотрим особенности функционирования демонстрационной конфигурации «Бухгалтерский учет» в случае увеличения максимального количества субконто на счете до пяти (табл. 12.78). Таблица 12.78. Поля, входящие в индекс
значений типа Дата, система создает одно поле в таблице базы данных, и, следовательно, каждое из них занимает одно поле в индексе.
№ поля
Для описания субконто используется составной тип данных. В демонстрационной конфигурации «Бухгалтерский учет», которая находится на прилагаемом компакт-диске, и в типовой конфигурации для описания составного типа данных, определяющего тип значения характеристик ВидыСубконто, применяются только ссылочные типы данных. Для хранения одного значения составного типа данных (содержащего только ссылки) системой используются три поля базы данных: фактический тип значения, имя таблицы и идентификатор записи в этой таблице. Если включить в составной тип данных примитивные, то кроме опасностей, описанных в разделе «Тип значения субконто и его влияние на количество индексов» на стр. 682, возникает еще одна: для хранения каждого примитивного типа данных (Число, Дата, Строка, Булево) в таблицу базы данных будет добавлено еще одно поле. Другими словами, если добавить в составной тип данных все четыре примитивных типа, то для хранения одного значения субконто будет использоваться семь полей (из них три для ссылки). И как следствие при той же максимальной длине индекса (16 полей) в него попадут только период, счет, измерение и первое субконто.
4
Валюта
5, 6, 7 8, 9, 10 11, 12, 13 14, 15, 16
Субконто1 Субконто2 Субконто3 Субконто4 Субконто5
ПланСчетовСсылка.<имя>,
для
Увеличение количества субконто в нашей конфигурации более чем до четырех приведет к тому, что последнее субконто не будет участвовать в индексе. Конфигурация с такой настройкой регистра бухгалтерии и аналитического учета может и будет функционировать, но теряется производительность как при записи движений в регистр, так и при формировании отчетов.
СправочникСсылка.<имя>
1 2 3
Поле Период Счет Организация
Комментарий
Обязательное поле Счет плана счетов (ПланСчетовСсылка.<имя>) Измерение регистра бухгалтерии Организация (СправочникСсылка.<имя>) Измерение регистра бухгалтерии Валюта (СправочникСсылка.<имя>) Три поля для хранения составного типа данных (только ссылки) Три поля для хранения составного типа данных (только ссылки) Три поля для хранения составного типа данных (только ссылки) Три поля для хранения составного типа данных (только ссылки) Три поля для хранения составного типа данных (только ссылки)
Мы видим, что последнее субконто не включается в индекс таблицы. К чему это приведет? Давайте сравним работу таблицы итогов для демонстрационной конфигурации «Бухгалтерский учет», которая находится на прилагаемом компакт-диске, с максимальным количеством субконто, равным четырем и пяти. Итак, работа таблиц итогов, если все поля помещаются в индекс, представлена на рис. 12.72.
подробнее
Приложение «Хранение данных», раздел «Хранение значений полей составного типа».
Продолжая рассматривать физическую таблицу остатков и оборотов по счетам и субконто регистра бухгалтерии демонстрационной конфигурации «Бухгалтерский учет», мы можем сделать вывод, что все десять полей помещаются в индексе. Мы можем увеличить максимальное количество субконто на счете, не рискуя потерять производительность, Том 1
Рис. 12.72. Получение итогов при четырех субконто
683
Глава 12. Бухгалтерский учет Когда система осуществляет поиск в таблице итогов, она обращается к индексу и получает точное указание на строку, которая хранит затребованные остатки и обороты. При увеличении количества субконто до пяти последний вид субконто не попадает в индекс, и работа системы изменяется (рис. 12.73).
СОВЕТ
Если анализ поставленной задачи учета выявляет необходимость создания регистра, количество полей таблиц итогов которого больше, чем может включить в себя индекс, имеет смысл переосмыслить выбор объекта системы «1С:Предприятие» для решения этой задачи. Можно предположить, что ее решение с помощью регистров накопления будет рациональнее. Подходы к отнесению учетной задачи к бухгалтерскому или оперативному учету приводятся в разделе «Принятие решений при организации аналитического учета» на стр. 632. Если же постановка задачи исключает возможность решить ее с помощью объекта Регистр накопления, следует располагать субконто с малой селективностью (обладающие малым количеством значений и редко используемые для отбора в отчетах) последними на счетах. Это сократит диапазон полученных по индексу строк и время на поиск в нем нужной строки.
Построение виртуальных таблиц регистра бухгалтерии Как уже не раз говорились, виртуальные таблицы регистра представляют собой запросы, которые собирают данные из физических таблиц регистра бухгалтерии. Рассмотрим правила построения виртуальных таблиц. Рис. 12.73. Получение итогов при пяти субконто
На приведенной выше схеме видно, что в индексе участвуют только первые четыре субконто. Как результат система при поиске итогов по затребованному набору полей получает не одну строку, а диапазон строк, содержащий строки со всеми хранимыми вариантами (в нашем примере ВидN – Вид3). Далее поиск строки с нужным видом осуществляется перебором. Получение диапазона строк вместо одной строки итогов, во-первых, увеличит время формирования отчетов, в которых требуется получить отбор по последнему (не включенному в индекс) виду субконто, а во-вторых, увеличит время записи и объем блокируемых транзакцией строк таблицы во время записи движений в регистр. Во время записи движений в регистр блокируются строки таблицы итогов для внесения в них изменений. Если индекс охватывает все поля регистра, блокируется одна изменяемая и соседние (блокировка соседних строк связана с особенностями работы SQL) строки. Пока выполняется транзакция, другие пользователи не могут выполнять запись движений с таким же набором полей (Период + Счет + Измерение + Субконто). Если вместо одной строки итогов был получен диапазон строк, блокируется весь диапазон (плюс соседние строки). Вероятность того, что пользователи «столкнутся» при проведении документов, увеличивается.
684
Механизм текущих итогов При описании физических таблиц итогов регистра мы упоминали, что итоги хранятся помесячно. Подобная организация физических таблиц позволяет быстро получать остатки на первое число месяца и обороты за календарный месяц. Хранение итогов помесячно обосновано особенностью ведения учета: как правило, стандартными бухгалтерскими интервалами для составления отчетности являются месяц, квартал и месяц и квартал нарастающим итогом с начала года. Бухгалтерский учет «историчен» – как правило, обрабатываются документы, свидетельствующие об уже свершившихся фактах хозяйственной деятельности, после ввода всех документов за стандартный бухгалтерский интервал формируется отчетность. Однако существуют и задачи учета в реальном времени. Тогда необходимо получать данные по еще не закрытому отчетному периоду, «на сейчас», т. е. с учетом последней записанной в информационную базу проводки. Для быстрого получения актуальных на текущий момент времени данных и предназначен механизм текущих итогов. Рассмотрим несложный пример работы механизма для одного счета. В методических целях будем считать, что: ■■ ведется только синтетический учет (нет учета по субконто); ■■ только в валюте учета; Профессиональная разработка в системе «1С:Предприятие 8»
Вопросы производительности регистра бухгалтерии ■■ без измерений; ■■ нет входящих остатков. Итак, были (табл. 12.79).
сделаны
Можно представить также этот журнал проводок в виде оборотной ведомости по счету «Касса» в разрезе календарных месяцев (табл. 12.81).
следующие
проводки
в
таблице
записей
Таблица 12.79. Записи таблицы записей регистра бухгалтерии Период
Счет Дт
Счет Кт
Сумма
01.01.2010 12.01.2010 18.01.2010 05.02.2010 13.02.2010 20.02.2010 01.03.2010 08.03.2010 16.03.2010 01.04.2010 10.04.2010 20.04.2010
Касса Касса Сотрудники Касса Поставщики Касса Касса Сотрудники Касса Касса Касса Сотрудники
Капитал Покупатели Касса Покупатели Касса Сотрудники Покупатели Касса Покупатели Сотрудники Покупатели Касса
10 5 3 8 6 1 7 9 4 2 1 2
Период
Остаток на начало
Оборот Дт Оборот Кт Остаток на конец
Январь 2010 Февраль 2010 Март 2010 Апрель 2010
0 12 15 17
15 9 11 3
3 6 9 2
12 15 17 18
Итоги рассчитаны за январь и февраль. Ячейки, выделенные серым цветом, в физической таблице итогов не хранятся. Это остатки на конец месяца и еще не рассчитанные месяцы: пользователи уже начали вводить операции за апрель, однако и март, и апрель еще не рассчитаны. Чтобы не использовать физические таблицы первичных движений каждый раз, когда требуется узнать последние (текущие) итоги по счету с учетом всех движений (включая проводки за март и апрель), в физических таблицах итогов создается еще одна строка для хранения текущих итогов.
Можно представить также этот журнал проводок в виде оборотной ведомости по счету касса в разрезе дней (табл. 12.80). Это пригодится нам в дальнейшем. Таблица 12.80. Представление журнала проводок в виде оборотной ведомости по счету Период
Счет Дт
Счет Кт
Сумма Остаток на начало
Оборот Дт
Оборот Кт
Остаток на конец
01.01.2010 12.01.2010 18.01.2010 05.02.2010 13.02.2010 20.02.2010 01.03.2010 08.03.2010 16.03.2010 01.04.2010 10.04.2010 20.04.2010
Касса Касса Сотрудники Касса Поставщики Касса Касса Сотрудники Касса Касса Касса Сотрудники
Капитал Покупатели Касса Покупатели Касса Сотрудники Покупатели Касса Покупатели Сотрудники Покупатели Касса
10 5 3 8 6 1 7 9 4 2 1 2
10 5 0 8 0 1 7 0 4 2 1 0
0 0 3 0 6 0 0 9 0 0 0 2
10 15 12 20 14 15 22 13 17 19 20 18
0 10 15 12 20 14 15 22 13 17 19 20
О расчете итогов рассказывается в разделе «Управление итогами» на стр. 680. Результатом расчета итогов стали физическая таблица остатков и оборотов по счетам и физическая таблица оборотов между счетами за эти же два месяца, но в нашем примере мы не будем ее учитывать. Том 1
Таблица 12.81. Представление журнала проводок в виде оборотной ведомости по счету в разрезе месяцев
Поэтому на самом деле физическая таблица остатков и оборотов по счетам хранит не два (январь и февраль), а три «месяца» (январь, февраль, текущие итоги) и выглядит следующим образом (табл. 12.82). Таблица 12.82. Таблица остатков и оборотов по счетам Период
Счет
Остаток
Оборот Дт
Оборот Кт
01.01.2010 01.02.2010 01.11.3999
Касса Касса Касса
0 12 18
15 9 0
3 6 0
На 01.11.3999 года хранятся текущие итоги. Эти итоги учитывают все активные движения регистра. Дату 01.11.3999 можно увидеть, например, сформировав запрос к виртуальной таблице остатков и оборотов без указания интервала дат с периодичностью Месяц или более детально. Используя шкалу времени, можно представить хранение итогов в виде схемы, приведенной на рис. 12.74. Пример формирования запроса без указания интервала дат был приведен не случайно. Именно в случае, если обращение к виртуальной таблице остатков производится без указания интервала дат, система обращается непосредственно к строкам, где хранятся текущие итоги. Текущие итоги используются и при обращении к итогам на произвольную дату месяца, который не был рассчитан (на схеме – март и апрель). В нижней части схемы изображены различные варианты получения остатков и оборотов. Актуальному остатку соответствует элемент схемы «Остаток 5». Остальные элементы (варианты) будут рассмотрены ниже.
685
Глава 12. Бухгалтерский учет Вариант 1. При обращении к виртуальной таблице остатков указан момент времени, соответствующий началу календарного месяца, и этот месяц рассчитан. На приведенной схеме (рис. 12.74, вариант Остаток 1) это может быть начало января 2010 года (01.01.2010 0:00:00 или граница от конца дня 31.12.2009, включая последнюю секунду) или начало февраля 2010 года. В этом варианте система обращается к физической таблице итогов и получает готовый остаток. Такой запрос будет выполнен максимально быстро. Вариант 2. Требуется получить остаток на произвольный момент времени месяца. Важные замечания: этот месяц рассчитан, и этот месяц не последний рассчитанный, т. е. существует следующий рассчитанный месяц, и, таким образом, есть остаток на конец того месяца, за произвольную дату которого нужно получить остаток. В нашем случае (рис. 12.74, вариант Остаток 2) это может быть любая дата января (на рис. 12.74 – 15 января). Итоги рассчитаны за февраль, т. е. в физических таблицах итогов есть строка на 01.02.2010 с остатком на начало февраля (конец января). Система получит остаток на начало следующего месяца (начало февраля) из физической таблицы итогов и вычтет из него «проводки» с 15.01.2010 (включительно) по 31.01.2010 (включительно). Остаток на 15.01.2010 = Итоги остаток (01.02.2010)
– Проводки (15.01.2010 - 31.01.2010)
В нашем примере это будет: остаток на 15.01.2010 = 12 руб. - (-3 руб.) = 15 руб. Рис. 12.74. Схема хранения итогов
В нашем примере, чтобы получить актуальный остаток по счету Касса, необходимо выполнить запрос к виртуальной таблице остатков без указания первого параметра таблицы Момент. Или воспользоваться методом менеджера регистра бухгалтерии Остатки(), передав в качестве первого параметра метода значение Неопределено.
Таблица остатков Источниками данных виртуальной таблицы остатков в базе данных являются физическая таблица остатков и оборотов по счетам, физическая таблица остатков и оборотов по счетам и субконто и, в ситуациях, когда физические таблицы итогов использовать невозможно, физическая таблица движений. Рассмотрим все возможные варианты работы виртуальной таблицы остатков. В первую очередь рассмотрим варианты выбора системой источника данных: физические таблицы итогов или физические таблицы первичных движений. Критерием выбора в данном случае является момент времени, на который затребован остаток.
686
Вариант 3. Требуется получить остаток на произвольный момент последнего рассчитанного месяца. В физических таблицах итогов нет следующей строки со следующим рассчитанным месяцем, где бы хранились остатки на конец выбранного нами месяца. На рис. 12.74, вариант Остаток 3, это 15 февраля (итоги рассчитаны по февраль включительно). Система получит итоги на начало февраля из физических таблиц итогов, далее из той же строки физической таблицы итогов получит дебетовый и кредитовый оборот и, таким образом, сможет быстро получить остаток на конец февраля (начало марта). Получив этот остаток, она вычтет из него «проводки» с 15.02.2010 (включительно) по 28.02.2010 (включительно). Остаток на 15.02.2010 = Итоги остаток (01.02.2010)
+ Итоги дебетовый оборот (01.02.2010 - 28.02.2010)
- Итоги кредитовый оборот (01.02.2010 - 28.02.2010)
- Проводки (15.02.2010 - 28.02.2010)
В нашем примере это будет: 12 руб. + 9 руб. - 6 руб. - 1 руб. = 14 руб. Вариант 4. Требуется получить остаток на произвольный момент времени любого не рассчитанного месяца. В нашем примере (рис. 12.74, вариант Профессиональная разработка в системе «1С:Предприятие 8»
Вопросы производительности регистра бухгалтерии Остаток 4) это могут быть и 15 марта, и 15 апреля. В этом случае система
воспользуется готовыми текущими итогами и отнимет от них проводки за интервал дат с 15 марта (15 апреля) до последней записи. Остаток на 15.03.2010 = Итоги остаток (актуальный)
- Проводки (15.03.2010 - последняя проводка).
В нашем примере это будет: 18 руб. - (7 руб. - 2 руб.) = 13 руб. Вариант 5. Требуется получить актуальный остаток. Момент времени при обращении к виртуальной таблице не указывается, система получает актуальный остаток из физических таблиц итогов (рис. 12.74, вариант Остаток 5). Актуальный остаток = Итоги остаток (актуальный).
В нашем примере это будет: 18 руб.
Рис. 12.75. Алгоритм использования физических таблиц при построении виртуальной таблицы оборотов
Если первым критерием, влияющим на выбор источника запроса для виртуальной таблицы (физическая таблица итогов или физическая таблица проводок), можно считать момент времени, то вторым – были ли затребованы в отборах или списке выбранных полей субконто. Если аналитика встречалась, в качестве физической таблицы итогов (их может быть несколько, если запрос выполняется по нескольким счетам) будет использоваться физическая таблица остатков и оборотов по счетам и субконто. Если требуются только синтетические остатки – физическая таблица остатков и оборотов по счетам.
Вариант 2. Требуется получить оборот с 20.12.2009 по 20.02.2010 (рис. 12.74, вариант Оборот 2).
Таблица оборотов
В нашем примере это будет: оборот Дт = 15 руб. + 0 + 9 руб. = 24 руб.
В основе построения виртуальной таблицы оборотов лежит тот же принцип: если данные можно взять из физических таблиц итогов, используются они. То, что из физических таблиц итогов взять нельзя, получается из физических таблиц первичных движений.
Вариант 3. Так же поступит система и в случае, если требуется получить оборот за период, в котором есть не рассчитанные интервалы (рис. 12.74, вариант Оборот 3). Рассчитанные, полностью включенные в период запроса календарные месяцы будут взяты из таблиц итогов, а оставшиеся «куски» дат будут собраны системой по таблицам проводок.
Но у виртуальной таблицы оборотов есть и свои особенности. Если при обращении к виртуальной таблице параметр Периодичность установлен меньше месяца или используются поля, содержащие в своем название Кор, виртуальная таблица строится только на основании физических таблиц первичных движений. Во всех остальных случаях обороты за календарные месяцы виртуальная таблица получает из физических таблиц итогов (рис. 12.75). Рассмотрим возможные варианты. Вариант 1. Затребован оборот за рассчитанный календарный месяц с 01.01.2010 по 31.01.2010 (рис. 12.74, вариант Оборот 1).
Система получит готовые обороты за январь, как в предыдущем случае, а интервалы дат с 20.12.2009 по 01.01.2010 и с 01.02.2010 по 20.02.2010 рассчитает по данным физической таблицы записей. Оборот за произвольный период (20.12.2009 - 20.02.2010 включительно) = Оборот Дт = Итоги оборот Дт (январь) + Проводки (20.12.2009 - 31.12.2009)
+ Проводки (01.02.2010 - 20.02.2010).
Отдельно следует упомянуть про расчет полей с постфиксом Оборот. Поля виртуальной таблицы оборотов <имя>ОборотДт и <имя>ОборотКт рассчитываются таблицей «в один приход» – такие поля есть в физических таблицах итогов, и достаточно одного «прохода» по физической таблице записей. Поля виртуальной таблицы <имя>Оборот рассчитываются «в два прохода» – сначала рассчитывается дебетовый оборот, потом из него вычитается кредитовый оборот (рис. 12.76).
Система обратится к строке физической таблицы итогов, маркированной периодом «01.01.2010», и получит дебетовый или кредитовый оборот. Оборот за календарный месяц Январь = Итоги оборот Дт / Кт (01.01.2010 - 31.12.2010).
В нашем примере это будет: оборот Дт = 15 руб., оборот Кт = 3 руб. Том 1
Рис. 12.76. Алгоритм расчета полей оборотов
687
Глава 12. Бухгалтерский учет
Таблица остатков и оборотов Формирование виртуальной таблицы остатков и оборотов можно представить в виде следующий схемы (рис. 12.77).
Рис. 12.78. Алгоритм построения таблицы оборотов Дт Кт
При условии, что периодичность не меньше месяца (как и в виртуальной таблице оборотов) и в запросе не упоминается аналитика (физическая таблица оборотов между счетами не хранит информацию в разрезе субконто), используется физическая таблица итогов, в противном случае запрос выполняется к физическим таблицам первичных движений. Рис. 12.77. Алгоритм формирования таблицы остатков и оборотов
Виртуальную таблицу остатков и оборотов система получает в несколько проходов. Остатки на начало периода рассчитываются по той же схеме, по которой рассчитывается виртуальная таблица остатков. Обороты за период рассчитываются как виртуальная таблица оборотов с условием, что в ней не используются фильтры и группировки по <…>Кор полям. Далее система самостоятельно (не используя ресурсы SQL-сервера) подсчитывает остатки на конец периода.
Физическая таблица оборотов между счетами хранит ресурс Оборот, поэтому получение этого ресурса не требует двух проходов (как в виртуальной таблице оборотов).
Таблица движений с субконто Виртуальная таблица движений с субконто формируется системой с использованием только физических таблиц первичных движений, чем и обусловлена возможность получения этой виртуальной таблицей неактивных записей (рис. 12.79).
Если используется параметр Периодичность, то результаты запросов по остаткам на начало и оборотам помещаются во временную таблицу на сервер, к которой и выполняется запрос для получения виртуальной таблицы остатков и оборотов.
Таблица оборотов Дт Кт Построение виртуальной таблицы оборотов Дт Кт выполняется системой по алгоритму, напоминающему виртуальную таблицу оборотов. Отличия есть, и они являются следствием физической таблицы итогов (физическая таблица оборотов между счетами), которая может использоваться при построении виртуальной таблицы (рис. 12.78).
688
Рис. 12.79. Алгоритм формирования виртуальной таблицы движений с субконто
Профессиональная разработка в системе «1С:Предприятие 8»
Вопросы производительности регистра бухгалтерии
Использование текущих итогов Чтобы поддерживать текущие итоги в актуальном состоянии, при записи набора активных записей в таблице движений всегда рассчитываются и перезаписываются текущие итоги в таблице итогов, если у регистра установлен признак использования итогов.
в запросе для фильтра или группировки), на втором – два вида субконто (один из них тот же), а на третьем – три, источниками данных запроса будут три физические таблицы остатков и оборотов по счетам и субконто регистра бухгалтерии (рис. 12.80).
Однако пересчет текущих итогов при параллельной записи движений несколькими пользователями может быть неэффективным. Например, если период рассчитанных итогов регулярно устанавливается обработкой и есть уверенность в хранении посчитанных итогов на начало каждого месяца, может быть выгоднее «досчитывать» остатки от хранимых итогов. В таком случае можно не устанавливать использование текущих итогов для регистра бухгалтерии – УстановитьИспользованиеТекущихИтогов(Ложь). Если использование текущих итогов выключено, то расчет актуальных остатков будет производиться следующим образом: сначала будут получены остатки на самые поздние хранимые итоги, а потом по движениям за оставшийся период будут получены актуальные остатки. Данный подход позволяет увеличить параллельность при записи наборов записей данного регистра, так как не требуется обновления текущих итогов. Получить признак использования текущих итогов из встроенного языка можно методом менеджера регистра бухгалтерии ПолучитьИспользованиеТекущихИтогов(). Включить или выключить использование текущих итогов можно методом УстановитьИспользованиеТекущихИтогов(Истина/ Ложь), а также в стандартной функции управления итогами (Все функции Стандартные Управление итогами Полные возможности Текущие итоги Включить использование текущих итогов/Выключить использование текущих итогов).
Зависимость производительности от настроек субконто счета Производительность системы при формировании виртуальных таблиц зависит от многих факторов. Часть из них мы перечислили, описывая индексирование таблиц, часть – при описании конкретных виртуальных таблиц. Остались те, которые влияют на работу всех таблиц и которые, мы считаем, необходимо учитывать при проектировании плана счетов и написании запросов. Во всех виртуальных таблицах отбор по полю Счет (СчетДт, СчетКт, КорСчет) вынесен в отдельное поле. Сделано это не случайно. При формировании таблицы система анализирует настройку видов субконто для каждого счета и выбирает соответствующую физическую таблицу итогов для получения остатков и оборотов.
Рис. 12.80. Пример использования физических таблиц
Еще один вопрос, связанный с аналитикой и производительностью при работе виртуальных таблиц, – это порядок, в котором «прикреплены» субконто к счету. Наиболее быстро система сможет получить итоги по тем субконто, которые прикреплены к счету первыми. Можно порекомендовать располагать субконто на счете с учетом следующего правила: ■■ те из них, по которым наиболее часто нужно выполнять отбор, имеет смысл располагать «ближе к счету»; ■■ те, которые реже участвуют в отборе и чаще предназначены для группировки, имеет смысл поместить «в конец» (рис. 12.81). Также на производительность влияет и то, в каком порядке привязаны на разные счета одни и те же виды субконто, если запрос выполняется сразу по нескольким счетам. Возможность упорядочить виды субконто в запросе, используя параметр виртуальной таблицы Субконто, описана в разделе «Параметр «Субконто»: отбор и упорядочивание по виду субконто» на стр. 666.
Например, если запрос выполняется сразу по трем счетам и на первом из них подключен один вид субконто (значение которого используется Том 1
689
Глава 12. Бухгалтерский учет Если один и тот же субконто прикреплен к разным счетам в различном порядке (на одном счете он первый, на другом – второй), виртуальная таблица для сбора данных по этому субконто выполнит два подзапроса (рис. 12.82).
Рис. 12.81. Пример зависимости скорости выполнения запроса от расположения субконто
690
Рис. 12.82. Схема формирования виртуальной таблицы
Профессиональная разработка в системе «1С:Предприятие 8»