Габец А.П., Козырев Д.В., Кухлевский Д.С., Хрусталева Е.Ю. Реализация прикладных задач в системе "1С:Предприятие 8.2" Электронная книга в формате pdf; ISBN 978-5-9677-2063-5. Электронный аналог печатного издания «Реализация прикладных задач в системе "1С:Предприятие 8.2"» (ISBN 978-5-9677-1387-3, М.: ООО «1С-Паблишинг», 2010; артикул печатной книги по прайс-листу фирмы «1С»: 4601546080479; по вопросам приобретения печатных изданий издательства «1С-Паблишинг» обращайтесь к партнеру «1С», обслуживающему вашу организацию, или к другим партнерам фирмы «1С», в магазины «1С Интерес», а также в книжные и интернет-магазины). Книга посвящена углубленному изучению вопросов создания и модификации прикладных решений на платформе "1С:Предприятие 8.2". В книгу включены материалы, которые описывают основные прикладные механизмы платформы, позволяющие решать задачи оперативного, бухгалтерского учета и расчета заработной платы. Рассматривается структура и реализация этих механизмов, значительное внимание уделяется организации хранения данных. Все рассматриваемые в книге примеры адаптированы для использования с версией платформы "1С:Предприятие 8.2" в режиме управляемого приложения. Кроме этого, описание механизмов дополнено новыми возможностями, появившимися в версиях платформы 8.1 и 8.2. Пособие ориентировано на разработчиков, работающих в системе "1С:Предприятие", IT-специалистов, желающие получить представление о возможностях системы "1С:Предприятие", студентов и преподавателей технических вузов и факультетов, слушателей учебных курсов по "1С", специалистов по внедрению и сопровождению программ "1С". Дополнительные материалы Приложение к книге включает демонстрационные конфигурации, иллюстрирующие примеры, рассматриваемые в книге. Таким образом, можно самостоятельно воспроизвести или доработать любой пример из книги, используя имеющиеся готовые решения. Демонстрационные конфигурации можно установить на коммерческую или учебную версию 1С:Предприятия. Скачайте материалы и учебную версию на странице http://its.1c.ru/book_demo/, раскройте архив и следуйте инструкциям по установке. Интернет-конференция для начинающих разработчиков http://devtrainingforum.v8.1c.ru/forum. Оглавление Введение.................................................................................................................7 Что находится на компакт-диске.....................................................................................................8 Глава 1. Хранение информации..........................................................................9 Задачи хранения информации........................................................................................................9 Варианты подходов к решению задач хранения информации...................................................15 Хранение информации, общей для информационной базы..................................................15 Хранение единичных значений условно-постоянной информации.......................................18 Использование предопределенных элементов.......................................................................25 Хранение информации объектных и необъектных сущностей..............................................27 Хранение информации в самих объектах или в других объектах..........................................29 Хранение иерархической информации....................................................................................35 Хранение иерархии данных одной сущности..........................................................................38 Хранение подчиненных данных в составе объекта................................................................42 Хранение информации, имеющей привязку ко времени........................................................50 Использование объекта «ХранилищеЗначения»....................................................................52 Хранение информации в регистрах сведений.............................................................................54 Уникальность записей регистра сведений...............................................................................54 Периодические регистры сведений..........................................................................................57 Подчинение записей регистратору...........................................................................................59 Структура регистра сведений....................................................................................................63 Создание, изменение, удаление записей регистра сведений................................................69 Получение данных из регистров сведений..............................................................................86 Проектирование структуры регистров сведений...................................................................107 Реализация прикладных задач в системе «1С:Предприятие 8.2» Хранение дополнительных характеристик.................................................................................109 Хранение дополнительных характеристик определенного типа.......................................... 110 Хранение дополнительных характеристик произвольного типа ......................................... 114 Место документов в концепции системы «1С:Предприятие»...................................................139 Глава 2. Документы и последовательности.................................................139 Документы.....................................................................................................................................142 Функциональность документов...............................................................................................142 Состав документов...................................................................................................................157 Отдельные вопросы типового использования документов..................................................162 Запись документов...................................................................................................................169 Специальные случаи использования документов. Ручная операция..................................214 Журналы документов...................................................................................................................219 Состав журналов......................................................................................................................221 Последовательности документов...............................................................................................224 Устройство последовательностей..........................................................................................228 Работа с последовательностями............................................................................................230 Параллельный ввод документов, участвующих в последовательности.............................246 Оперативный учет. Описание задач, решаемых регистрами накопления..............................249 Глава 3. Реализация задач учета движения средств..................................249 Структура регистра накопления..................................................................................................254 Механизмы заполнения таблиц регистров накопления в базе данных...................................262 Запись данных в таблицу движений регистра накопления...................................................264 Свойство «Движения» объекта документа ...........................................................................266 Запись набора записей регистра без использования свойства «Движения».....................283 Механизмы заполнения таблицы итогов регистра накопления...........................................289 Получение данных из регистров накопления ...........................................................................299 Получение движений регистров накопления.........................................................................300 Получение остатков.................................................................................................................310 Получение оборотов................................................................................................................326 Получение остатков и оборотов в одной таблице.................................................................350 Применение отборов в запросах, использующих виртуальные таблицы регистров накопления . .............................................................................................................................374 Когда следует использовать запрос вместо объектной модели обращения при получении данных регистров накопления.......................................................................377 Отдельные вопросы использования регистров накопления....................................................379 Работа с регистрами при отображении динамических данных............................................379 Получение остатков при проведении документов.................................................................387 Глава 4. Реализация задач бухгалтерского учета........................................397 Диаграмма взаимодействия объектов . .....................................................................................398 План счетов и его основные свойства........................................................................................400 Коды счетов..............................................................................................................................406 Упорядочивание счетов в плане счетов.................................................................................409 Иерархичность плана счетов..................................................................................................413 Предопределенные и пользовательские счета.....................................................................420 Оглавление Основы организации аналитического учета..........................................................................422 Принятие решений при организации аналитического учета.................................................439 Предназначение регистра бухгалтерии......................................................................................442 Объект «Регистр бухгалтерии»...................................................................................................448 Основные свойства регистра бухгалтерии............................................................................449 Данные регистра бухгалтерии.................................................................................................453 Запись движений в регистр бухгалтерии....................................................................................469 Интерактивно: ручная операция.............................................................................................471 Программно при проведении документа................................................................................477 Программно без проведения документа................................................................................484 Чтение данных регистра бухгалтерии........................................................................................486 Таблицы регистра бухгалтерии...............................................................................................486 Вопросы производительности регистра бухгалтерии...............................................................536 Физические таблицы регистра бухгалтерии...........................................................................536 Индексы таблиц итогов регистра бухгалтерии......................................................................543 Построение виртуальных таблиц регистра бухгалтерии......................................................550 Зависимость производительности от настроек субконто счета...........................................560 Глава 5. Реализация сложных периодических расчетов...........................563 Технология реализации расчетных задач..................................................................................564 Основные понятия....................................................................................................................564 Планы видов расчета...................................................................................................................577 Назначение планов видов расчета.........................................................................................577 Свойства планов видов расчета.............................................................................................578 Структура планов видов расчета............................................................................................580 Проверки, выполняемые при записи вида расчета...............................................................583 Структура таблиц базы данных..............................................................................................586 Регистры расчета.........................................................................................................................588 Назначение регистров расчета...............................................................................................588 Свойства регистров расчета...................................................................................................589 Структура регистров расчета..................................................................................................593 Структура таблиц базы данных..............................................................................................600 Настройка протяженных во времени расчетов..........................................................................602 Использование механизма вытеснения.................................................................................602 Использование графиков.........................................................................................................605 Сторнирование.........................................................................................................................612 Настройка зависимости по базовому периоду...........................................................................616 Настройка планов видов расчета и регистров расчета........................................................616 Технология формирования и расчета записей регистров расчета..........................................626 Формирование записей регистра расчета..............................................................................626 Настройка алгоритмов расчета...............................................................................................628 Расчет записей регистра расчета...........................................................................................633 Перерасчет записей регистров расчета.....................................................................................646 Объект конфигурации «Перерасчет».....................................................................................646 Измерения перерасчета..........................................................................................................648 Реализация прикладных задач в системе «1С:Предприятие 8.2» Автоматическое формирование записей перерасчета при вводе вытесняющих расчетов..........................................................................................650 Автоматическое формирование записей перерасчета при вводе прочих расчетов..........650 Особенности использования таблицы вытесняющих видов расчета..................................652 Формирование записей перерасчета средствами встроенного языка................................654 Автоматическое удаление записей перерасчета..................................................................656 Анализ данных таблицы перерасчета....................................................................................656 Реализация перерасчета записей регистров расчета..........................................................660 Размещение данных системы «1С:Предприятие»....................................................................665 Приложение. Хранение данных......................................................................665 Информационные базы...........................................................................................................667 Профайлы.................................................................................................................................678 Другие вспомогательные данные...........................................................................................680 Временные данные..................................................................................................................683 Поля таблиц базы данных...........................................................................................................684 Хранение значений полей примитивных и ссылочных типов...............................................685 Хранение значений полей составного типа...........................................................................686 Индексы таблиц базы данных.....................................................................................................697 Справочник...............................................................................................................................698 Документ...................................................................................................................................701 Журнал документов..................................................................................................................702 План видов характеристик.......................................................................................................702 План счетов..............................................................................................................................702 План видов расчета.................................................................................................................703 План обмена.............................................................................................................................704 Табличная часть.......................................................................................................................704 Регистр сведений.....................................................................................................................704 Регистр накопления.................................................................................................................706 Агрегаты регистра накопления................................................................................................707 Регистр бухгалтерии................................................................................................................708 Регистр расчета........................................................................................................................709 Последовательность................................................................................................................710 Перечисление...........................................................................................................................710 Бизнес-процесс.........................................................................................................................710 Задача....................................................................................................................................... 711 Таблицы регистрации изменений...........................................................................................712 Таблица списка пользователей..............................................................................................713 Таблица истории работы пользователей...............................................................................713 Таблица хранилища системных настроек . ...........................................................................713 Таблица хранилища настроек отчетов . ................................................................................713 Таблица хранилища настроек вариантов отчетов................................................................713 Таблица хранилища общих настроек.....................................................................................714 Таблица хранилища настроек данных форм.........................................................................714 Введение Идея этой книги заключается в том, чтобы собрать вместе и систематизировать наиболее важную информацию, которая может понадобиться разработчику прикладных решений «1С:Предприятия 8.2». Уровень изложения материала предполагает, с одной стороны, что разработчик уже знаком с системой «1С:Предприятие 8.2», а с другой стороны, что в этой книге он сможет найти ответ даже на довольно сложные вопросы, возникающие в процессе разработки. В одной книге невозможно рассмотреть абсолютно все ситуации, которые могут возникнуть при разработке прикладных решений. Однако на подавляющее большинство вопросов, возникающих перед разработчиками, книга дает ответы. Причем книга будет одинаково интересна как начинающим разработчикам, так и более «продвинутым». Как правило, прикладные разработчики имеют достаточно четко определенную специализацию, сосредотачивая свои усилия на решении задач одной предметной области. Вместе с этим довольно часто возникают ситуации, когда приходится осваивать смежные прикладные области для того, чтобы внести небольшие исправления в существующее решение или, наоборот, создать новую подсистему. Поэтому книга, помимо собственно глубокого изложения прикладных механизмов, содержит общие сведения как о самих механизмах, так и об автоматизируемой предметной области. Благодаря этому разработчик, хорошо знакомый с системой, но специализирующийся, Реализация прикладных задач в системе «1С:Предприятие 8.2» например, на решении задач оперативного учета, всегда сможет разобраться с задачами начисления заработной платы и понять работу механизмов, которые используются для решения этих задач. При написании этой книги мы стремились, чтобы она стала «серьезным инструментом для серьезных разработчиков», книгой, к которой всегда можно обратиться в случае затруднений и которую просто интересно прочитать, чтобы узнать что-то новое о хорошо известной предметной области или познакомиться с новым взглядом на привычные вещи. При подготовке материала этой книги был использованы самые различные источники информации: ■ опыт преподавания на учебных курсах по платформе и прикладным решениям «1С:Предприятия 8»; ■ опыт внедрения прикладных решений; ■ опыт, накопленный разработчиками фирмы «1С»; ■ материалы информационно-технологической поддержки (ИТС); ■ материалы форума партнеров-разработчиков на http://partners.v8.1c.ru; ■ общение на партнерских семинарах, проводимых фирмой «1С». Что находится на компакт-диске К книге прилагается компакт-диск, который содержит материалы, предназначенные для самостоятельного изучения и использования. Прежде всего, это три демонстрационные конфигурации, которые используются в ходе изложения различных глав книги: ■ «Хранение информации и учет движения средств»; ■ «Бухгалтерский учет»; ■ «Сложные периодические расчеты». Все демонстрационные конфигурации содержатся на компакт-диске в виде дистрибутивов. После запуска исполняемого файла шаблоны конфигураций устанавливаются в текущий каталог шаблонов. Конфигурации созданы в версии «1С:Предприятия» 8.2.12.87. Глава 1. Хранение информации Задачи хранения информации При создании любых решений в области автоматизации практически всегда приходится решать задачи хранения информации. При этом поднимаются вопросы собственно предназначения хранимой информации и многочисленные технологические вопросы. К технологическим вопросам можно отнести те, которые приходится решать для достижения оптимального соотношения таких показателей, как: ■ объем, ■ надежность, ■ функциональность, ■ быстродействие. Причем на всех этапах жизненного цикла информации: ■ ■ ■ ■ запись информации, хранение информации, получение информации, удаление информации. 10 Реализация прикладных задач в системе «1С:Предприятие 8.2» При создании бизнес-приложений сложность решений этих задач обусловлена наличием противоречий между: ■ необходимостью обеспечения удобства представления логики взаимодействия сущностей в информационной модели; ■ необходимостью хранения больших объемов информации; ■ повышенными требованиями к широкой функциональности и высокой производительности доступа к этим данным. Например, чем больше объем, тем в общем случае сложнее с обеспечением скорости доступа к информации (рис. 1.1). Рис. 1.1. Схема противоречий между требованиями к хранимой информации И в результате очевидные прямые решения одних вопросов ухудшают возможности решения других. Например, хранение информации о происходящих в жизни автоматизируемого предприятия событиях в виде набора неструктурированных текстов – идеальное решение с точки зрения простоты и скорости регистрации. Однако последующая обработка этой информации для составления каких бы то ни было аналитических отчетов в таком случае будет сопряжена с колоссальными временными затратами. Потому что как для решения задачи поиска информации обо всех продажах предприятия, так и для поиска информации о продажах одному покупателю необходимо будет пересмотреть данные всех текстов. И чем больше функциональных возможностей потребуется на этапе получения информации, тем дольше будут работать соответствующие обработки, зачастую по нескольку раз просматривая одну и ту же информацию, но уже с разными целями. Глава 1. Хранение информации 11 Объектно-реляционная парадигма системы «1С:Предприятие» позволяет решить проблему соотношения удобства представления и манипулирования объектами, отражающими прикладные сущности, с должной надежностью и эффективностью обработки больших объемов информации этих объектов в базе данных. Объекты и процессы прикладной области отражаются в решении посредством объектов конфигурации. Таким образом, объекты конфигурации обеспечивают удобство манипулирования данными, характеризующими прикладные объекты и процессы. Но сами данные объектов хранятся в реляционной базе данных (в виде таблиц, полей, индексов), при этом обеспечиваются вопросы оптимального быстродействия при больших объемах информации (рис. 1.2). Рис. 1.2. Схема представления и манипулирования данными в системе «1С:Предприятие» В системе «1С:Предприятие» все возможные к применению в решениях прикладные объекты прототипированы. Каждый прототип отвечает за отражение в прикладном решении определенной совокупности объектов или процессов прикладной области, имеющих схожие поведенческие характеристики и схожую роль в общей картине решения. Примерами прототипов являются справочники, документы, регистры различных видов и так далее. В рамках средств платформы для каждого прототипа уже предопределены: ■ оптимальная для большинства задач структура хранения информации в реляционной базе данных; ■ набор средств встроенного языка для манипулирования этой информацией; ■ методы, свойства, события и типовые для решаемых задач операции; ■ способы отображения и редактирования; ■ средства регулирования прав доступа и т. д. 12 Реализация прикладных задач в системе «1С:Предприятие 8.2» Рис. 1.3. Пример представления и манипулирования данными Таким образом, облегчается работа разработчика конкретного прикладного решения. С точки зрения эффективного хранения информации вместо решения задач «низкого» уровня он занят решением вопросов: ■ выбора нужного прототипа; ■ создания в рамках прототипов объектов с наиболее подходящим составом для отражения прикладных сущностей; ■ обеспечения обмена информацией и взаимодействия между созданными объектами. Обеспечение же всей остальной необходимой функциональности берет на себя платформа. Но и в этих вопросах, при необходимости, у разработчиков достаточно широкие возможности «подправить» поведение программы. В частности, при решении задач, связанных с вводом и получением информации для последующего анализа. Например, при отображении динамических списков система считывает из базы данных содержимое только видимых полей и полей, необходимых «для технологических нужд». Если же разработчику необходимо сделать так, чтобы данные некоего поля, не отображаясь, тем не менее, считывались из базы данных вместе с остальными, он может этого добиться. Глава 1. Хранение информации 13 Итак, вернемся к общим вопросам, связанным с обеспечением эффективного хранения информации. Прежде всего, они не являются самоцелью. К выбору прототипов объектов для использования в рамках решения необходимо подходить с точки зрения обеспечения целей автоматизации и областей применимости прототипов. А вот если одинаковая функциональность может быть достигнута различными альтернативными с точки зрения организации хранения информации путями, то выбор оптимального варианта построения конфигурации как раз и будет определяться оптимальностью решения вопросов хранения информации. Причем разработчику необходимо решать эти вопросы в комплексе. Потому что все объекты будут тесно связаны между собой логическими, информационными, интерфейсными и прочими связями в интересах преследования общих целей автоматизации. В общем виде взаимосвязь и предназначение объектов, относящихся к соответствующим прототипам, могут быть описаны следующим образом (рис. 1.4). Рис. 1.4. Взаимосвязь различных групп объектов Если требуется хранить в базе данных информацию, которая изменяется достаточно редко и работа с которой строится по принципу «ввели один раз, но используется много раз», то для хранения такой информации наиболее удобны объекты из блока Условно-постоянная информация. То есть справочники, перечисления, константы, планы видов характеристик – при решении практически любых задач. Планы счетов, планы видов расчетов и т. п. – при решении специфичных задач, сопряженных с использованием принципа «двойной записи», использованием механизмов сложных периодических расчетов и т. д. 14 Реализация прикладных задач в системе «1С:Предприятие 8.2» Если требуется хранить информацию о происходящих в жизни автоматизируемого предприятия действиях (событиях и выполняемых операциях), то есть информацию, для которой важна привязка ко времени, то наиболее удобно использовать документы. На схеме к этой же группе относятся и другие объекты, которые используются для решения вопросов дополнительной функциональности системы при обслуживании этой информации: ■ журналы – средства визуального группирования информации разных документов; ■ последовательности – средства логического группирования информации разных документов; ■ нумераторы – средства группирования разных документов для ведения единой нумерации. Если требуется хранить информацию о состоянии показателей, учитываемых в системе, то более удобны для решения этих задач объекты из группы регистры. Причем показатели могут иметь привязку ко времени или не иметь ее, быть наиболее общими или достаточно специфичными, предназначенными к использованию в специальных моделях учета (те же «двойная запись», «сложные периодические расчеты» и т. д.). Чаще всего модель обмена информацией между объектами вышеописанных прототипов обслуживает следующую модель автоматизации бизнес-решений: ■ Требуемые аналитические и информационные материалы о различных аспектах состояния дел на автоматизируемом предприятии получаются пользователями посредством отчетов и обработок (объектов, специально предназначенных для обеспечения вывода информации в удобном для пользователя виде). ■ Для обеспечения максимального быстродействия формирования отчетной информации о состоянии учитываемых в системе показателей алгоритмы представления этой информации берут ее в уже готовом или почти готовом виде, с последующей «дообработкой», из регистров. ■ Стандартная методика использования регистров заключается в том, что изменение состояния учитываемых показателей в регистрах производится не произвольным образом, а при наличии «документального подтверждения». То есть информация регистров вторична, она заполняется на основании данных документов. Ведь именно документы, как правило, служат для обеспечения регистрации происходящих в жизни автоматизируемого предприятия событий. В то же время платформа не ограничивает разработчика жесткими рамками стандартной методики и позволяет изменять данные регистров и другими произвольными способами, например, напрямую из процедур встроенного языка. Глава 1. Хранение информации 15 ■ Однозначность толкования вводимой в документы информации обеспечивается заполнением документов посредством выбора элементов объектов хранения условно-постоянной информации, отражающих объекты прикладной области. Однако, как уже было замечено выше, разработчик не обязан слепо следовать предлагаемой логике. В ситуациях, когда это окажется оправданным, можно применять приемы, упрощающие или даже полностью отвергающие ее. Например, в платформе «1С:Предприятие» есть возможности и средства прямого интерактивного ввода информации в регистры, формирования отчетов на основании данных первичных документов, заполнения справочников посредством обработок и так далее. Более того, рассмотрение и оценка возможных вариантов выбора прототипов и объектов будут производиться фактически каждый раз заново, для данной конкретной ситуации данного конкретного решения. Потому что даже в рамках преследования одинаковых целей автоматизации, но для разных условий функционирования, эффективная композиция структуры объектов в рамках решения может оказаться разной. Например, ситуации для предприятия, заключающего в течение года сто сделок по десять миллионов рублей, и для предприятия, заключающего в год десять миллионов сделок по сто рублей, с точки зрения оптимизации хранения информации различаются. Поэтому цель данного раздела не навязать единственно верную структурную технологию решения задач хранения информации (тем более что такой не существует), а показать возможности решения вопросов хранения информации. И зачастую – в сравнении плюсов и минусов альтернативных вариантов использования для этих решений различных видов объектов системы «1С:Предприятие». Варианты подходов к решению задач хранения информации Хранение информации, общей для информационной базы При решении вопросов хранения общей информации есть возможности организовать решения в рамках работы с конфигурацией или с базой данных. 16 Реализация прикладных задач в системе «1С:Предприятие 8.2» Использование общих картинок Например, картинки с логотипами юридических лиц компании могут храниться в составе общих картинок конфигурации, а могут в составе реквизитов справочника (например, справочника Организации), рис. 1.5. Рис. 1.5. Пример хранения картинок в составе конфигурации С точки зрения надежности хранения информации успешность обращения к картинке в первом случае «гарантируется» неизменностью конфигурации, во втором – мерами разграничения прав доступа пользователей к объектам базы данных (то есть при неудачном стечении обстоятельств при обращении к картинке может выясниться, что она удалена или модифицирована пользователем). Глава 1. Хранение информации 17 Использование макетов Если предпочтение отдается хранению информации на уровне конфигурации, то кроме картинок возможно использование макетов – общих макетов и макетов объектов конфигурации. При этом могут быть использованы следующие виды макетов: ■ ■ ■ ■ ■ ■ ■ ■ ■ макет текстового документа, макет табличного документа, макет двоичных данных, макет Active document, макет HTML-документа, макет географической схемы, макет графической схемы, макет схемы компоновки данных, макет оформления компоновки данных. Рис. 1.6. Пример хранения макета Active document 18 Реализация прикладных задач в системе «1С:Предприятие 8.2» Чаще всего макеты используются для хранения данных шаблонов нужных типов. Например, когда в конфигурации нужно хранить «красивый» шаблон приглашения, разработанный в Microsoft Word, с целью его автоматического заполнения при выполнении соответствующей задачи работы пользователя (рис. 1.6). При этом можно загружать макеты из файлов, а можно создавать пустые макеты нужного вида (рис. 1.7). Рис. 1.7. Создание макета Но, кроме того, могут использоваться, например, макеты специального типа (макет схемы компоновки данных) для хранения схемы компоновки данных отчета. В ней описываются источники данных для отчета, связи между ними, параметры получения данных отчета и его настройки: структура отчета, список полей, отбор, сортировка, условное оформление и др. (рис. 1.8). Хранение единичных значений . условно-постоянной информации Зачастую при решении задач необходимо реализовывать хранение данных неких единичных значений, которые меняются крайне редко. Использование констант Константы – классические объекты для хранения таких данных. Добавлять новые константы или удалять старые можно только в режиме Конфигуратор, но вот заполнение и модификация значений обычно производятся пользователями (если не ограничен доступ). Глава 1. Хранение информации 19 Рис. 1.8. Хранение схемы компоновки данных отчета в макете При решении прикладных задач посредством констант обычно запоминаются общие для всей информационной базы значения. Можно привести примеры таких констант, как ОсновнаяБазоваяВалюта или ОсновнаяОрганизация. Также в константах могут храниться значения по умолчанию для поддержания работы алгоритмов, критичных к пустым значениям. Такими константами являются, например, константы НачалоРабочегоДня, ОкончаниеРабочегоДня. Кроме этого, благодаря тому, что значения, хранящиеся в константе, общие для всех, с помощью констант можно организовать информирование пользовательских сеансов работы с программой. Например, пользователь с административными правами имеет право устанавливать для булевой константы ЗавершениеРаботыПользователей значение Истина. А соответствующая обработка ожидания проверяет значение этой константы и, в случае необходимости, завершает пользовательский сеанс. Пример данного механизма реализован в составе демонстрационной конфигурации «Хранение информации и учет движения средств», которая находится на прилагаемом компакт-диске. 20 Реализация прикладных задач в системе «1С:Предприятие 8.2» Необходимая функциональность реализуется в рамках модуля управляемого приложения (листинг 1.1). Листинг 1.1. Фрагмент модуля управляемого приложения Перем ЗавершитьРаботу; Процедура ПриНачалеРаботыСистемы() КонтрольРежимаЗавершенияРаботыПользователей(); ПодключитьОбработчикОжидания("КонтрольРежимаЗавершенияРаботыПользователей", 180); КонецПроцедуры Процедура КонтрольРежимаЗавершенияРаботыПользователей() Экспорт // Определить текущее значение константы Завершение = ХранениеИнформации.ЗавершитьРаботуПользователей(); Если Завершение Тогда Если ЗавершитьРаботу Тогда // Завершить работу окончательно ЗавершитьРаботуСистемы(); Иначе // Предупредить пользователя и приготовиться завершить работу в следующий раз ТекстПредупреждения = "Работа системы будет автоматически завершена через 3 минуты!"; Предупреждение(ТекстПредупреждения, 30, "Завершение работы"); ЗавершитьРаботу = Истина; КонецЕсли; КонецЕсли; КонецПроцедуры //----------------// Выполнить начальную инициацию флага завершения работы ЗавершитьРаботу = Ложь; Функция для получения значения константы ЗавершениеРаботыПользователей располагается в общем модуле ХранениеИнформации, исполняющемся на сервере (в свойствах модуля должен быть установлен флажок ВызовСервера), листинг 1.2. Листинг 1.2. Функция общего модуля «ХранениеИнформации» Функция ЗавершитьРаботуПользователей() Экспорт Возврат Константы.ЗавершениеРаботыПользователей.Получить(); КонецФункции Глава 1. Хранение информации 21 Использование регистров сведений В случае, когда необходимо хранить информацию общую для базы данных, но используемую для отдельных направлений учета или отдельных подсистем конфигурации, может оказаться оправданным хранение единичных условнопостоянных значений не посредством констант, а посредством ресурсов регистра сведений. Рассмотрим, например, непериодический независимый регистр сведений УчетнаяПолитика (рис. 1.9). Рис. 1.9. Структура регистра «УчетнаяПолитика» Возможности пользователей по модификации значений будут определяться средствами разграничения прав доступа. Обратите внимание: в данном регистре не подразумевалось использование измерений, а значит, разрезов учета значений ресурсов. То есть данные регистра могут использоваться как общие для всей базы данных. Подробнее о регистрах сведений можно прочитать в разделе «Хранение информации в регистрах сведений» на стр. 54. Использование перечислений Если необходимо хранить уже не единичные значения, а некие конечные наборы значений, и при этом не подразумевается их модификация пользователями, то для решения задач возможно применение перечислений. Все операции по добавлению, изменению, удалению значений перечислений производятся только в режиме работы Конфигуратор. 22 Реализация прикладных задач в системе «1С:Предприятие 8.2» Само же хранение информации перечислений реализуется в соответствующих таблицах базы данных (по одной для каждого перечисления), рис. 1.10. Рис. 1.10. Хранение значений перечислений Обращение для чтения этой информации возможно как средствами табличной модели (запросы), так и объектными методами. Если, например, в ходе обработки необходимо использовать заранее известное значение перечисления, то его можно получить, указав его имя через точку после имени перечисления (в данном примере используется объектная модель доступа к данным), листинг 1.3. Листинг 1.3. Пример получения значения перечисления ЗаполняемоеЗначениеВидаКонтрагента = Перечисления.ВидыКонтрагентов.ЧастноеЛицо; Еще раз подчеркнем: при использовании такого кода разработчик уверен, что данное значение перечисления не может быть удалено или изменено пользователем, поскольку модификация этих данных возможна только в режиме Конфигуратор. Кроме того, многие «типовые операции», связанные с использованием перечислений, уже реализованы средствами платформы. Например, в ходе некоей обработки нужно предложить пользователю выбрать значение перечисления ВидыКонтрагентов. Задача может быть решена следующим образом (в данном примере используется табличная модель доступа к данным), листинг 1.4, 1.5. Глава 1. Хранение информации 23 Листинг 1.4. Обработчик команды для организации интерактивного выбора значения перечисления &НаКлиенте Процедура ВыбратьЗначениеПеречисления(Команда) СписокЗначенийПеречисления = ПолучитьЗначенияПеречисления(); // Предложить пользователю выбрать значение ВыбранноеЗначение = СписокЗначенийПеречисления.ВыбратьЭлемент("Выберите вид контрагента"); КонецПроцедуры Листинг 1.5. Получение списка значений перечисления &НаСервереБезКонтекста Функция ПолучитьЗначенияПеречисления() СписокЗначенийПеречисления = Новый СписокЗначений; // Прочитать значения перечисления из базы данных Запрос = Новый Запрос; Запрос.Текст = " |ВЫБРАТЬ | ВидыКонтрагентов.Ссылка КАК Значение, | ПРЕДСТАВЛЕНИЕ(ВидыКонтрагентов.Ссылка) КАК ПредставлениеЗначения |ИЗ | Перечисление.ВидыКонтрагентов КАК ВидыКонтрагентов"; Результат = Запрос.Выполнить(); Выборка = Результат.Выбрать(); Пока Выборка.Следующий() Цикл // Заполнить значения списка СписокЗначенийПеречисления.Добавить(Выборка.Значение, Выборка.ПредставлениеЗначения); КонецЦикла; Возврат СписокЗначенийПеречисления; КонецФункции Краткий комментарий: в функции ПолучитьЗначенияПеречисления(), выполняющейся на сервере, запросом из таблицы перечисления ВидыКонтрагентов считываются значения и представления для каждой записи. В цикле выборки из результата запроса заполняются значения и представления списка значений СписокЗначенийПеречисления. Этот список возвращается в обработчик команды, в котором пользователю предлагается выбрать значение из списка СписокЗначенийПеречисления. 24 Реализация прикладных задач в системе «1С:Предприятие 8.2» Однако если бы выбор значения перечисления нужен был для заполнения поля, имеющего визуальное представление (например, в форме контрагента), то данный код писать не пришлось бы вообще. Достаточно было бы установить соответствующий тип значения поля ввода (ПеречислениеСсылка.ВидыКонтрагентов), рис. 1.11. Рис. 1.11. Тип значения поля ввода Дальнейшая функциональность была бы реализована платформой автоматически (рис. 1.12). Рис. 1.12. Выбор значения перечисления в поле ввода Глава 1. Хранение информации 25 Использование предопределенных элементов Если требуется сочетать гарантии наличия информации с гибкими возможностями модификации этой информации, интересные возможности предоставляет использование предопределенных элементов справочников, планов видов характеристик, планов счетов и т. п. Благодаря тому, что добавление и удаление предопределенных элементов возможны только в режиме работы Конфигуратор, разработчик может быть уверен в их сохранности при любых действиях пользователей. Кроме этого, каждый предопределенный элемент обладает уникальным именем, что позволяет создавать алгоритмы, использующие, например, предопределенные виды контактной информации, предопределенные вычеты НДФЛ, предопределенные счета налогового учета и так далее. Таким образом, предопределенные элементы не «обезличены» для конфигурации, и конфигурация имеет возможность отличить один предопределенный элемент от другого (рис. 1.13). Рис. 1.13. Пример предопределенного элемента справочника 26 Реализация прикладных задач в системе «1С:Предприятие 8.2» К предопределенному элементу справочника можно обратиться, указав его имя через точку после имени справочника (например, Справочники.ВидыСобытий.Семинар). Например, если при создании документа Событие необходимо заполнить значение реквизита ВидСобытия (тип значения: СправочникСсылка.ВидыСобытий) предопределенным элементом справочника, это может выглядеть так (листинг 1.6, 1.7). Листинг 1.6. Обработчик команды для создания события с предопределенным элементом справочника &НаКлиенте Процедура СоздатьСобытиеСеминар(Команда) СсылкаНаДокумент = СоздатьНовоеСобытие(ДатаПроведения); ОткрытьЗначение(СсылкаНаДокумент); КонецПроцедуры Листинг 1.7. Пример использования предопределенного элемента справочника &НаСервереБезКонтекста Функция СоздатьНовоеСобытие(ДатаПроведения) // Создать новый документ НовоеСобытие = Документы.Событие.СоздатьДокумент(); // Заполнить поля НовоеСобытие.Дата = ДатаПроведения; // Заполнить значением предопределенного элемента НовоеСобытие.ВидСобытия = Справочники.ВидыСобытий.Семинар; // ... // Записать документ НовоеСобытие.Записать(); Возврат НовоеСобытие.Ссылка; КонецФункции Однако обращение к менеджерам объектов (например, Справочники.<Имя справочника>) на клиенте недоступно. Для получения ссылки на предопределенное значение на клиенте следует использовать метод глобального контекста ПредопределенноеЗначение() (например, ПредопределенноеЗначение("Справочник.ВидыСобытий.Семинар")). Например, требуется открыть форму предопределенного элемента справочника. Это можно сделать с помощью следующего кода (листинг 1.8). Глава 1. Хранение информации 27 Листинг 1.8. Обработчик команды для открытия формы предопределенного элемента справочника &НаКлиенте Процедура СоздатьСобытиеСеминар(Команда) ВидСобытия = ПредопределенноеЗначение("Справочник.ВидыСобытий.Семинар"); ОткрытьЗначение(ВидСобытия); КонецПроцедуры При работе с объектами встроенного языка предопределенные элементы отличаются от «обычных» лишь значением свойства Предопределенный (у обычных – Ложь, у предопределенных – Истина). Работа пользователя с предопределенными элементами, по сравнению с обычными, ограничивается лишь невозможностью удалить их. Все остальные способы модификации предопределенных элементов следует ограничивать правами доступа или с помощью прикладных алгоритмов. Это означает, что пользователь, при необходимости, может изменить наименование предопределенного элемента, код, пометить на удаление и т. д. При этом для системы этот предопределенный элемент остается тем же самым предопределенным элементом, т. к. его внутренний идентификатор не меняется. Хранение информации . объектных и необъектных сущностей При выборе прототипов объектов для хранения информации одним из типичных вопросов, возникающих при неочевидных случаях, является выбор между объектными и необъектными данными. Например, между регистром сведений и справочником. К объектным данным относятся данные справочников, документов, планов видов характеристик, планов счетов, планов видов расчета, бизнес-процессов, задач, планов обмена. К необъектным данным относятся данные регистров сведений, регистров накопления, регистров бухгалтерии, регистров расчета, перерасчетов, последовательностей и констант. В рамках текущей темы ограничимся лишь вопросами выбора этих данных для различных задач хранения информации. 28 Реализация прикладных задач в системе «1С:Предприятие 8.2» Для принятия решения рекомендуется обращать внимание на природу данных предметной области. Если они обладают некоей «самостью», несмотря на смену значений отдельных свойств этого объекта, то предпочтение следует отдавать определению этих данных как объектных. Например, сотрудник может сменить фамилию, имя, паспорт, цвет глаз и т. д., однако при этом он останется все тем же сотрудником. Таким образом, мы рассмотрели типичный пример идентификации сотрудников предприятия как данных объектных и подлежащих учету посредством справочника. Однако следует учитывать, что выбор вида объекта конфигурации не должен производиться для каждой сущности отдельно. Необходимо анализировать наличие и остальных сущностей в комплексе всей прикладной задачи. Причем желательно не только на текущий момент, но и с учетом развития задачи в будущем. Например, как определились выше, состав сотрудников предприятия целесообразно хранить посредством объекта конфигурации Справочник (рис. 1.14). Однако если взглянуть на проблему шире, может оказаться, что на самом деле тут смешиваются две сущности: ■ «Физические лица» как отражение реальных людей, с которыми предстоит иметь дело в рамках решения; ■ «Сотрудники подразделений предприятия», причем один и тот же человек может быть сотрудником нескольких подразделений предприятия, выполняя в них различные задачи (должности, круг обязанностей и проч.). Причем вторая сущность как объект нигде не фигурирует, просто нужно помнить «кто есть кто». Тогда хранение сотрудников подразделений может быть реализовано посредством регистра сведений (рис. 1.15). Рис. 1.14. Таблица справочника «Сотрудники» Рис. 1.15. Связь таблицы справочника и таблицы регистра сведений Глава 1. Хранение информации 29 Если аналогичным образом рассматривать хранение данных о сотрудниках и их трудовых договорах, то можно также выделить две сущности: ■ «Физическое лицо»; ■ «Сотрудник – трудовой договор» как отражение юридических отношений данного лица с организацией, имеющее при этом объектную природу, поскольку впоследствии ссылка на трудовой договор будет фигурировать во многих документах и регламентированных отчетах. В этом случае для хранения данных следует использовать два справочника, один из которых (справочник ТрудовыеДоговораСотрудников) будет подчинен другому (справочник ФизическиеЛица), рис. 1.16. Рис. 1.16. Связь таблиц справочников Таким образом, выбор каждого из вариантов хранения информации определяется тем, какую сущность предметной области будет отражать тот или иной объект. При этом разработчикам рекомендуется также и имя объекта определять так, чтобы оно максимально отражало описываемую сущность. Это позволит впоследствии обеспечить правильное восприятие и использование объекта. Хранение информации в самих объектах . или в других объектах Необходимо помнить, что любой объект – это единая сущность с точки зрения манипулирования данными. То есть при любых операциях с объектом (чтение, запись, модификация) происходит обращение к информации базы данных, касающейся всего объекта. Например, справочник ДоговорыКонтрагентов имеет подчиненные объекты: два реквизита (ДатаПоставки и ВидДоговора) и табличную часть Спецификация. В свою очередь, в состав табличной части тоже входит ряд реквизитов (рис. 1.17). 30 Реализация прикладных задач в системе «1С:Предприятие 8.2» Рис. 1.17. Структура справочника «ДоговорыКонтрагентов» Хранение этой информации в базе данных будет реализовано системой следующим образом: ■ В основной таблице справочника будет храниться информация в следующих полях: □ Ссылка, □ Код, □ Наименование, □ Пометка удаления, □ Предопределенный, □ Родитель, □ Владелец, □ ЭтоГруппа, □ ДатаПоставки, □ ВидДоговора. ■ Информация табличной части Спецификация – в отдельной таблице, содержащей следующие поля: □ Ссылка (значение этого поля равно значению поля Ссылка основной таблицы справочника); □ НомерСтроки; □ Номенклатура; □ Количество; □ Цена; □ Сумма. Любое обращение к объекту документа приведет к тому, что из базы данных будет считана информация, соответствующая данному объекту, из обеих таблиц. Глава 1. Хранение информации 31 При этом не важно, как именно выполнялось обращение: посредством метода ПолучитьОбъект() из ссылки (листинг 1.9) или при открытии формы, основным реквизитом которой является объект договора (рис. 1.18). Листинг 1.9. Пример получения объекта справочника из ссылки ОбъектДоговора = СсылкаНаДоговор.ПолучитьОбъект(); Рис. 1.18. Открытие формы объекта, отображающей табличную часть В последнем случае, кстати, не важно, будут отображаться на форме данные табличной части элемента или нет (рис. 1.19). Рис. 1.19. Открытие формы объекта, в которой табличная часть не отображается 32 Реализация прикладных задач в системе «1С:Предприятие 8.2» Объект в любом случае считывается целиком, поскольку при открытии формы платформа также создает объект справочника, обеспечивая тем самым целостность изменений, вносимых в данные объекта как интерактивно, так и программно, в модуле формы. Данную особенность нужно иметь в виду для сущностей, при работе с которыми часто необходим доступ именно к объектам, а не ссылкам (например, объекты, которые часто модифицируются пользователями). При чтении объекта или его модификации данные будут считываться и записываться по объекту целиком. Таким образом, чем меньше этих данных будет, тем быстрее будут выполняться операции, меньше будет продолжительность блокировок и т. д. Из этого можно сделать вывод, что информацию, которую предполагается хранить в объектах, следует анализировать на предмет разделения на активно используемую и неактивно используемую. Активно используемую информацию можно хранить в реквизитах самого объекта или его табличных частей. Неактивно используемую информацию об объекте можно хранить не в самом объекте, а посредством других информационных структур. Однако при этом придется самостоятельно заботиться о поддержании целостности изменений при модификации данных объекта. Для вышеприведенного примера, если информацию спецификаций можно считать «неактивно используемой», ее хранение можно организовать посредством, например, регистра сведений СпецификацииДоговоров или подчиненного справочника СпецификацииДоговоров. И в том и в другом случае при считывании объекта договора обращение к информации спецификации выполняться не будет (рис. 1.20). Рис. 1.20. Открытие формы объекта Глава 1. Хранение информации 33 Однако при необходимости выполнить такое обращение это будет легко сделать, например, с помощью запроса (листинг 1.10). Листинг 1.10. Пример получения данных подчиненного справочника запросом Запрос = Новый Запрос; Запрос.Текст = "ВЫБРАТЬ | СпецификацииДоговоров.Код, | СпецификацииДоговоров.Наименование, | СпецификацииДоговоров.Номенклатура, | СпецификацииДоговоров.Количество, | СпецификацииДоговоров.Цена, | СпецификацииДоговоров.Сумма |ИЗ | Справочник.СпецификацииДоговоров КАК СпецификацииДоговоров |ГДЕ | СпецификацииДоговоров.Владелец = &Владелец"; Запрос.УстановитьПараметр("Владелец", Договор); Результат = Запрос.Выполнить(); Выборка = Результат.Выбрать(); Пока Выборка.Следующий() Цикл // Выполнить действия с информацией строки спецификации //... КонецЦикла; В этом случае из базы данных будет считана лишь нужная информация спецификаций, относящаяся к договору, ссылка на который содержится в переменной Договор. Обратиться к данным подчиненного справочника можно и с помощью объектной модели работы с данными (листинг 1.11). Листинг 1.11. Получение данных подчиненного справочника с помощью объектной модели работы с данными СсылкаНаВладельца = Договор; Выборка = Справочники.СпецификацииДоговоров.Выбрать( ,СсылкаНаВладельца); Пока Выборка.Следующий() Цикл // Выполнить действия с информацией строки спецификации //... КонецЦикла; В этом случае, в отличие от табличной модели работы с данными, будут считаны целиком объекты элементов подчиненного справочника. 34 Реализация прикладных задач в системе «1С:Предприятие 8.2» При выборе того или иного варианта хранения, кроме разницы между «хранением необъектных данных» и «хранением объектных данных» (рассмотренной в разделе «Хранение информации объектных и необъектных сущностей» на стр. 27), можно еще учесть требования к уникальности информации, накладываемые используемыми объектами системы «1С:Предприятие». Если необходимо обеспечить жесткую уникальность понятия «номенклатурная позиция спецификации договора» (то есть одна и та же номенклатурная позиция не может быть указана более одного раза в спецификации одного договора), тогда предпочтительнее вариант с использованием регистра сведений. Он как раз позволяет хранить только уникальную с точки зрения ключевых полей информацию (в данном случае – измерений Договор и Номенклатура). Для подчиненного же справочника таких ограничений по уникальности нет. Если необходимо хранить информацию в виде простой таблицы, то вариант с использованием подчиненного справочника будет предпочтительнее. Аналогична цепочка рассуждений, если в ходе решения некоей прикладной задачи на этапе конфигурирования для объекта необходимо ввести много признаков или особых свойств. Одно дело, если эти свойства и признаки касаются всех элементов данной сущности и активно используются при работе с объектами, им соответствующими. Тогда информацию данных свойств уместно хранить в виде реквизитов объекта. Например, реквизит Услуга булевого типа для справочника Номенклатура. Очень многие прикладные механизмы, работающие с элементами справочника Номенклатура, должны быстро различать ситуации работы с услугами или материальными номенклатурными позициями. Другое дело, если этот признак касается лишь некоторых элементов и используется лишь в отдельных механизмах. Тогда для хранения этой информации нерационально использовать реквизиты, а можно использовать другие объекты. Например, информацию о том, какие из физических лиц являются пользователями, уместнее хранить в отдельном справочнике (с реквизитом ФизЛицо) или в соответствующем регистре сведений. Кроме того, возможна ситуация, когда необходимо, чтобы новые признаки и характеристики могли вводиться не только на этапе конфигурирования (разработчиками), но и в режиме работы «1С:Предприятие» – пользователями. Для реализации этой возможности удобна организация хранения информации с использованием объекта План видов характеристик. Более подробно этой теме посвящен раздел «Хранение дополнительных Глава 1. Хранение информации 35 характеристик произвольного типа. Использование плана видов характеристик» на стр. 114. В ситуации, когда требуется с помощью специальных свойств выделить только один элемент, использование реквизитов объектов вообще является неверным. Например, введение булевого реквизита БазоваяВалюта в состав справочника Валюты нерационально, как с точки зрения хранения информации (поле будет существовать для всех элементов, хотя значение Истина с прикладной точки зрения уместно только у одного элемента), так и с точки зрения быстродействия. Для корректного разрешения подобных ситуаций уместно считать элементы, обладающие такими специальными свойствами, данными, общими для всей базы данных, и организовывать хранение информации об этом посредством констант или регистров сведений. Так же осторожно нужно подходить к использованию строковых реквизитов неограниченной длины. Крайне не рекомендуется использовать их для хранения информации, объем которой может быть достаточно большим или непрогнозируемым. Примером такого некорректного использования реквизита может служить сохранение в реквизите значения, получаемого функцией ЗначениеВСтрокуВнутр() (например, для таблицы значений, содержащей большое количество строк). Не рекомендуется хранить в реквизитах активно используемых объектов картинки и образы файлов (использование полей типа ХранилищеЗначения), если заранее известно, что размер их будет велик. Для сохранения подобной информации следует использовать альтернативные методы. Хранение иерархической информации Иерархическими принято считать структуры, у которых четко прослеживаются отношения «один ко многим». Например, «один руководитель – много подчиненных» (рис. 1.21). Рис. 1.21. Пример одноуровневой иерархии Кроме того, уровней иерархии может быть больше одного: «один руководитель, в подчинении которого находятся руководители подразделений, в подчинении которых находятся подчиненные» – пример трехуровневой иерархической структуры (рис. 1.22). Ну а в общем случае уровней может быть значительно больше. 36 Реализация прикладных задач в системе «1С:Предприятие 8.2» Рис. 1.22. Пример многоуровневой иерархии Необходимо отметить, что в прикладных задачах в любом случае используется не бесконечное количество уровней иерархии. Например, хотя и говорят, что бюрократия бесконечна, но, составляя организационно-штатную структуру любой организации, всегда приходим к конечному количеству уровней подчинения, ответственности и т. д. В данном разделе мы не будем обсуждать достоинства и недостатки использования иерархических структур в области их применения. Сосредоточимся на возможностях организации хранения иерархической информации средствами системы «1С:Предприятие». Для «экономного» хранения информации об иерархичности хранимых данных достаточно, если каждый из нижестоящих элементов будет помнить ссылку на непосредственно стоящий над ним элемент. Таким образом, информацию об иерархии можно хранить не только в виде схем, но и в виде таблиц. Например, информация о вышеприведенной схеме может храниться так, как показано в табл. 1.1. Таблица 1.1. Пример хранения иерархической информации Сотрудник Руководитель Директор Руководитель отдела закупок Менеджер по закупкам Товаровед Руководитель отдела продаж Менеджер по продажам Продавец Секретарь Директор Руководитель отдела закупок Руководитель отдела закупок Директор Руководитель отдела продаж Руководитель отдела продаж Директор Каждая строка таблицы содержит информацию по одной персоне. Для каждой строки таблицы упоминание некоей персоны в поле Руководитель означает, что данный сотрудник непосредственно подчинен именно этому руководи- Глава 1. Хранение информации 37 телю (а в информации по этому руководителю будет указано, кому он, в свою очередь, подчинен). В строке, отражающей информацию по директору, поле Руководитель пустое. Это значит, что в данной схеме у директора нет руководителей. Еще говорят «директор находится на корневом уровне иерархии». Данный прием применяется при хранении иерархической информации объектов прикладной области на уровне объектов базы данных системы «1С:Предприятие». То есть «нижестоящие» элементы должны помнить ссылку на «вышестоящие» элементы иерархии. Однако это не значит, что разработчик в каждом отдельно взятом случае должен «доводить» выполнение этого приема до уровня таблиц базы данных. В типовых ситуациях эту работу берет на себя сама платформа. Разберем, что же это за ситуации. При разработке бизнес-решений разработчику чаще всего приходится иметь дело с иерархическими структурами при организации хранения условнопостоянной информации (справочники, планы видов характеристик), реже – при работе с регистрацией событий. В отношении хранения условно-постоянной информации учтены следующие ситуации: ■ иерархия объектных данных одной сущности (рассматривается в разделе «Хранение иерархии данных одной сущности» на стр. 38); ■ иерархия объектных данных разных сущностей (рассматривается в разделе «Хранение иерархии данных разных сущностей» на стр. 48); ■ хранение иерархии необъектных данных внутри объекта (рассматривается в разделе «Хранение подчиненных данных в составе объекта» на стр. 42); ■ хранение иерархии необъектных данных вне объекта (рассматривается в разделе «Хранение подчиненных данных вне объекта» на стр. 48). В остальных же случаях или для реализации ситуаций иерархии событий разработчик всегда может реализовать свою иерархическую схему посредством добавления реквизита к «подчиненным» объектам, значением которого должна являться ссылка на объект-владелец. Например, в рамках некоторого договора был оформлен документ ЗаказПокупателя. На основании документа ЗаказПокупателя был введен документ РеализацияТоваров. На основании документа РеализацияТоваров были введены документы СчетФактура и ПриходныйКассовыйОрдер. Впоследствии часть товара была возвращена, то есть на основании документа РеализацияТоваров был введен документ ВозвратТоваровОтПокупателя. Аналогичная цепочка документов может быть оформлена в отношении другого документа ЗаказПокупателя (рис. 1.23). 38 Реализация прикладных задач в системе «1С:Предприятие 8.2» Рис. 1.23. Структура документов, введенных на основании Необходимо хранить информацию о том, что все эти документы находятся в иерархии конкретного договора с покупателем. Решается данная задача включением в состав всех объектов, которые могут подчиняться договору, реквизита, например, Основание, ссылающегося на данный договор. Этот пример более широко (в отношении вопросов ввода на основании, отображения иерархии подчинения договору) рассмотрен в разделе «Ввод на основании», на стр. 204 и приведен в составе демонстрационной конфигурации «Хранение информации и учет движения средств», которая находится на прилагаемом компакт-диске. Хранение иерархии данных одной сущности Выше (см. табл. 1.1) обсуждалась схема организационно-штатной структуры компании (рис. 1.24). Рис. 1.24. Организационно-штатная структура компании Глава 1. Хранение информации 39 Допустим, при проектировании принято решение, что персоналии, отраженные в схеме, относятся к одной сущности прикладной области – пользователи программы, и являются примерами данных объектного типа. Как информация об этой иерархии может быть отражена средствами платформы «1С:Предприятие»? Для этого при разработке следует произвести настройку свойств объекта конфигурации – справочника Пользователи, касающихся иерархии справочника. А именно: справочник – Иерархический, вид иерархии – Иерархия элементов (то есть нижестоящие элементы справочника иерархически подчиняются вышестоящим – именно элементам справочника), количество уровней иерархии ограничено – только три (рис. 1.25). Рис. 1.25. Настройка иерархии справочника «Пользователи» Дальнейшую работу возьмет на себя платформа. В состав основной таблицы справочника Пользователи будет добавлено поле Родитель для хранения в записях иерархически подчиненных элементов ссылок на элементы, которым они непосредственно иерархически подчиняются. Обращение к этому предопределенному полю будет возможно посредством соответствующих объектов встроенного языка для манипулирования данными справочника или посредством запросов. Кроме того, при записи и модификации данных в справочнике Пользователи платформа будет отслеживать ограничение по количеству уровней иерархии, не позволяя реализовать попытки их превышения, выдавая соответствующие предупреждения. 40 Реализация прикладных задач в системе «1С:Предприятие 8.2» Помимо этого, в расширения соответствующих форм и элементов форм будут включены средства, облегчающие решение задач отображения информации справочника в иерархическом виде. Например, возможность отображения списка справочника в виде дерева или иерархического списка (рис. 1.26). Рис. 1.26. Отображение справочника «Пользователи» в виде иерархического списка Пример реализации подобной схемы приведен в демонстрационной конфигурации «Хранение информации и учет движения средств» (справочник Пользователи), которая находится на прилагаемом компакт-диске. Рассмотренный выше пример касался случая иерархии элементов. Однако могут встречаться задачи, когда иерархия используется лишь для логического упорядочивания хранения и отображения данных объектных сущностей. Например, данные справочника Номенклатура удобнее представлять в виде упорядочивания по товарным группам (рис. 1.27). Рис. 1.27. Отображение справочника «Номенклатура» в виде дерева Глава 1. Хранение информации 41 Обратите внимание: каждый конечный элемент обладает конкретной закупочной ценой. Однако говорить о значении закупочной цены родителя этих элементов – нонсенс с прикладной точки зрения. Таким образом, свойства элементов и свойства их родителей отличаются друг от друга. Для реализации решений подобных задач используется вид иерархии Иерархия групп и элементов. С точки зрения хранения данных в базе данных для двух видов иерархии большой разницы нет, но для прикладной и интерфейсной функциональности возможности отличаются сильно. Каждый реквизит объекта справочника или плана вида характеристик, если используется иерархия групп и элементов, может иметь следующие значения свойства Использование: ■ Для элемента, ■ Для группы, ■ Для группы и элемента. Это позволяет легче решать задачи, для которых необходимо выделять свойства, присущие нужным уровням иерархии. Например, значение реквизита ОтветственныйМенеджер присуще только группам справочника Контрагенты. Считается, что все элементы нижестоящих уровней данной группы закреплены за этим менеджером (рис. 1.28). В этом случае для реквизита ОтветственныйМенеджер значение свойства Использование указывается – Для группы. Рис. 1.28. Группы и элементы справочника «Контрагенты» 42 Реализация прикладных задач в системе «1С:Предприятие 8.2» Выгоды использования такого решения проявятся, например, при решении задачи «перезакрепления» контрагентов за другим менеджером. Чтобы «перезакрепить» все элементы, входящие в группу, не обязательно будет указывать каждому контрагенту его нового ответственного менеджера, достаточно лишь указать другое значение реквизита ОтветственныйМенеджер для этой группы. С другой стороны, реквизит ОтветственныйМенеджер можно сделать используемым и группами, и элементами. Тогда предложенная выше схема закрепления сможет учитывать ситуации, когда контрагент находится в группе, закрепленной за одним менеджером, но сам закреплен за другим менеджером. Для интерфейсных задач при использовании данного вида иерархии платформа опять же берет на себя решения большинства вопросов различного поведения групп и элементов: ■ «разделение» форм на основную форму элемента и основную форму группы для операций заполнения и просмотра данных объектов; ■ «разделение» на форму выбора и форму выбора группы для реализации операций выбора; ■ определение того, в каких ситуациях правомерен выбор групп, а в каких нет (по умолчанию, например, реквизиты документов интерактивно могут заполняться только значениями элементов); ■ использование отбора динамического списка, содержащего таблицу справочника (ЭтоГруппа = Истина/Ложь), позволяющего просматривать (в зависимости от необходимости) только элементы, только группы или элементы и группы; ■ и так далее. Хранение подчиненных данных в составе объекта Практически все объекты системы «1С:Предприятие», предназначенные для хранения данных объектных сущностей (справочники, документы, планы видов характеристик, планы видов расчета и т. д.), имеют возможность хранить свою информацию не только в виде значений реквизитов, но и в составе подчиненных табличных частей. Подобным образом также может решаться задача хранения информации «один ко многим», рассмотренная ранее в разделе «Хранение иерархической информации» на стр. 35. В качестве примера возьмем все ту же организационно-штатную структуру компании (см. рис. 1.24). Допустим, на ее основе необходимо реализовать хранение информации об объектной сущности «Руководители». Решение может быть реализовано в виде справочника Руководители так, чтобы руководители были элементами Глава 1. Хранение информации 43 справочника, а рядовые сотрудники указывались в строках табличной части ПодчиненныеРядовыеСотрудники как ссылки на элементы справочника ФизическиеЛица (рис. 1.29). Рис. 1.29. Схема хранения данных справочника «Руководители» В результате в системе будет реализовано хранение информации об объектных сущностях – «Руководителях», с указанием подчиненных в качестве их описания. Однако необходимо иметь в виду, что информация строк подчиненной табличной части не имеет своей объектной сущности. То есть при данном способе хранения информации нельзя будет сослаться ни на одного «рядового подчиненного некоего руководителя». В составе документов можно будет создавать реквизиты с типом значения СправочникСсылка.Руководители, но нельзя будет создать реквизиты, ссылающиеся на строки табличной части ПодчиненныеРядовыеСотрудники. Для задач, когда ссылка на такие сведения смысла не имеет, хранение множества подчиненных данных, характеризующих данный объект, внутри самого объекта может быть весьма удобным. Классическим примером являются документы с такими табличными частями, как ПоступлениеТоваров, Состав, Событие, СторонниеЛица и т. д. Схемы, когда подчиненная информация сама имеет иерархический вид, также могут быть реализованы внутри объекта, если это покажется удобным. Например, при оформлении заказа покупателя необходимо дать возможность пользователю вводить не только информацию о том, какие номенклатурные позиции, в каком количестве и по какой цене желает приобрести покупатель, 44 Реализация прикладных задач в системе «1С:Предприятие 8.2» но и еще произвольное количество дополнительных пожеланий по любой номенклатурной позиции в свободной форме, с возможностью отметки, насколько эти пожелания действительно важны. Представление информации в этом случае может быть отображено следующей таблицей (табл. 1.2). Таблица 1.2. Схема представления информации Заказ Заказ № 3 от 12.02.10 Номенклатура Количество Цена Сумма Лазерный принтер 2 Canon LBP-810 200 400 Телефон LG W7200 30 300 10 Пожелания Белого цвета Дополнительно упаковать в гофро-тару Без гарнитуры Доставку приурочить к 8 марта Цвет любой, только не черный Поскольку речь идет о регистрации события «Заказ покупателя», то для хранения информации логично использовать объект – документ ЗаказПокупателя. Таким образом, получаем три уровня иерархии: ■ документ; ■ указание номенклатурных позиций документа с количественно-суммовыми характеристиками; ■ указание дополнительных пожеланий к номенклатурным позициям. Реализация хранения этой информации может быть организована следующим образом. Для хранения информации о заказанных товарах с количественносуммовыми характеристиками можно использовать табличную часть Состав. Но дополнительные пожелания будет неудобно хранить в рамках этой табличной части. Как показано в таблице выше, к одной номенклатурной позиции может предъявляться более одного требования и форма информации этих требований более «свободная», нежели указание цены, количества и суммы. В этом случае для хранения информации о дополнительных пожеланиях покупателя, если эту информацию нужно хранить внутри объекта, можно использовать еще одну табличную часть ДополнительныеТребования. Реквизитами табличной части ДополнительныеТребования будут Требование, Важно и Номенклатура (рис. 1.30). Соответствие с информацией табличной части Состав будет организованно именно по номенклатурным позициям. Дополнительный сервис для пользователя может касаться вопроса подбора номенклатурных позиций в табличную часть ДополнительныеТребования только из перечисленных в табличной части Состав. Глава 1. Хранение информации 45 Рис. 1.30. Структура документа «ЗаказПокупателя» В демонстрационной конфигурации «Хранение информации и учет движения средств», которая находится на прилагаемом компакт-диске, в форме документа – ЗаказПокупателя приведен один из вариантов решения этой задачи. В форме документа расположена многостраничная группа с двумя закладками – Состав и Дополнительные требования (рис. 1.31). Рис. 1.31. Форма документа «ЗаказПокупателя» Поскольку для выполнения операций заполнения дополнительных требований пользователь сначала должен будет открыть соответствующую закладку, у многостраничной группы Страницы обработчик события смены страницы реализован в виде следующей процедуры (листинг 1.12). 46 Реализация прикладных задач в системе «1С:Предприятие 8.2» Листинг 1.12. Обработчик события «ПриСменеСтраницы» &НаКлиенте Процедура СтраницыПриСменеСтраницы(Элемент, ТекущаяСтраница) // Проверить, активизирована ли закладка "Дополнительные требования" Если ТекущаяСтраница.Имя = "ГруппаДополнительныеТребования" Тогда // Заполнить список выбора у колонки "Номенклатура" таблицы формы // "Дополнительные требования" // списком номенклатурных позиций, использованных в табличной части "Состав" ПолучитьСоставНоменклатуры(); КонецЕсли; КонецПроцедуры В процедуре обработки события ПриСменеСтраницы, если имя текущей страницы – ГруппаДополнительныеТребования, вызывается серверная процедура ПолучитьСоставНоменклатуры(), в которой происходит заполнение списка выбора у колонки Номенклатура таблицы формы ДополнительныеТребования списком номенклатурных позиций, использованных в табличной части Состав (листинг 1.13). Листинг 1.13. Процедура «ПолучитьСоставНоменклатуры()» &НаСервере Процедура ПолучитьСоставНоменклатуры() // Очистить список выбора у колонки "Номенклатура" таблицы формы "Дополнительные требования" Элементы.ДополнительныеТребованияНоменклатура.СписокВыбора.Очистить(); // Выгрузить список номенклатурных позиций, использованных в табличной части "Состав", // в таблицу значений ТЗСоставНоменклатуры = Объект.Состав.Выгрузить(,"Номенклатура"); Для Каждого СтрокаТЗ ИЗ ТЗСоставНоменклатуры Цикл Элементы.ДополнительныеТребованияНоменклатура .СписокВыбора.Добавить(СтрокаТЗ.Номенклатура); КонецЦикла КонецПроцедуры Таким образом, возможности выбора номенклатурных позиций на странице ДополнительныеТребования будут ограничены списком номенклатурных позиций, использованных в табличной части Состав. Для этого необходимо включить свойство РежимВыбораИзСписка у колонки Номенклатура таблицы формы ДополнительныеТребования (рис. 1.32). Глава 1. Хранение информации 47 Рис. 1.32. Свойства колонки «Номенклатура» таблицы формы «ДополнительныеТребования» Необходимо заметить, что в данном примере иерархических данных не реализована связь «один ко многим» в чистом виде. Ведь информация «номенклатурная позиция заказа покупателя» не относится к объектным данным. В общем случае одна и та же номенклатурная позиция может быть указана сколько угодно раз в табличном поле Состав. И значит, невозможно установить, к какой именно строке состава (с этой номенклатурной позицией) относятся пожелания покупателя, описанные в табличной части ДополнительныеТребования. Однако в постановке задачи это и не требовалось. То есть либо такие ситуации не критичны для логики работы разрабатываемого решения, либо пользователь сам может описать, что имелось в виду, в строковом реквизите Требование. В ситуациях же, когда поддержание однозначности связей «один ко многим» критично, разработчику необходимо будет решать этот вопрос. Для этого следует либо дополнительно обеспечивать уникальность значений реквизитов или комбинаций значений реквизитов в самом объекте, либо «выносить» хранение этой информации в другие объекты, специально предназначенные для обеспечения уникальности комбинаций значений сущностей, – регистры сведений. 48 Реализация прикладных задач в системе «1С:Предприятие 8.2» Хранение иерархии данных разных сущностей Допустим, необходимо организовать хранение информации по предыдущей трудовой деятельности каждого сотрудника компании. Сами сотрудники признаны сущностями объектного типа, и для хранения их информации в рамках решения создан справочник Сотрудники. Как решить задачу? С одной стороны, данная информация непосредственно связана с сотрудником и могла бы быть реализована посредством включения табличной части ТрудоваяДеятельность в состав объектов справочника Сотрудники. Но к выбору такого варианта нужно подходить осторожно. Как обсуждалось в разделе «Хранение подчиненных данных в составе объекта» (см. стр. 42), подчиненные табличные части предназначены для учета только необъектных сущностей. То есть при таком решении в других объектах системы невозможно будет использовать поля или реквизиты, соответствующие понятию «место предыдущей работы конкретного сотрудника». Если же необходимость в такой объектной сущности есть или может появиться, то решение видится в использовании подчиненного справочника ТрудоваяДеятельность. В его элементах можно хранить информацию о должности, месте работы, дате начала деятельности, дате окончания деятельности по каждому эпизоду предыдущей работы сотрудника. Впоследствии эта сущность может быть использована, например, для организации структуры регистра накопления СтажРаботы или для заполнения реквизитов соответствующих документов. Хранение подчиненных данных вне объекта Для хранения необъектных данных, соответствующих определенным комбинациям значений измерений, предназначены регистры сведений. Более подробно устройство и функциональность регистров сведений рассмотрены в разделе «Хранение информации в регистрах сведений» на стр. 54. Сейчас же рассмотрим лишь один пример. В торговой компании покупатели закреплены за менеджерами, их обслуживающими. Сами менеджеры компании, в свою очередь, относятся к тому или иному департаменту. Необходимо иметь представление, кто за кем закреплен на каждый момент времени. В данном случае вариант хранения информации в регистре сведений предпочтителен тем, что автоматически будет обеспечена уникальность значений измерений. То есть в регистре ЗакреплениеПокупателей невозможно будет создать две записи с одним и тем же покупателем (соответственно, невозможно одного покупателя закрепить за несколькими менеджерами). Аналогично в отношении регистра ЗакреплениеМенеджеров. Глава 1. Хранение информации 49 Кроме того, регистры сведений позволяют хранить не только статические варианты иерархических структур, но и изменяющиеся во времени. Если указанные регистры сведений сделать периодическими, то впоследствии можно будет легко хранить динамику картины отношений, то есть отражать в системе все изменения, касающиеся закреплений (например, менеджер со всей своей клиентской базой передан другому департаменту). И так же легко получать информацию о состоянии модели закреплений на любой момент времени. Также для ситуаций, когда в готовое (и эксплуатируемое) решение приходится вводить новые сущности, добавление новых измерений к регистру сведений позволяет легко решать задачи усложнения «взаимоотношений» данных. Например, начиная с какого-то момента, закрепление покупателей за менеджерами продолжает оставаться однозначным, но только в рамках конкретных проектов. То есть в основном проекте Торговля за обслуживание некоего покупателя по-прежнему отвечает тот же менеджер, но в проекте Информационное сопровождение – совсем другой (да еще и из другого департамента). С точки зрения классификации ситуации хранения данных такое изменение «революционно», отдельные его части можно даже рассматривать как переход от схемы «один ко многим» к схеме «многие ко многим». Однако сама реализация подобного «поворота событий» очень проста. В состав регистра ЗакреплениеПокупателей достаточно добавить измерение Проект. И поскольку система обеспечивает в регистре сведений уникальность комбинаций значений измерений, задача уже фактически решена. Остается лишь согласовать с пользователями, будет ли в регистре сведений ЗакреплениеПокупателей пустая ссылка на проект (для старых данных) с прикладной точки зрения восприниматься проектом основной деятельности предприятия – Торговля, либо необходимо произвести соответствующую обработку для заполнения этих данных. Так же легко в состав регистра сведений может быть введена дополнительная информация, характеризующая конкретные комбинации значений измерений. Это реализуется посредством добавления ресурсов. Например, для регистра ЗакреплениеПокупателей могут быть введены такие ресурсы, как Лояльность, ЧастотаКонтактов, СуммаКвотыПродаж и так далее. Для регистра ЗакреплениеМенеджеров могут быть введены такие ресурсы, как БазовыйОклад, ПроцентПремии, Эффективность и тому подобное. 50 Реализация прикладных задач в системе «1С:Предприятие 8.2» Хранение информации, имеющей привязку ко времени Практически все объекты, поддерживающие возможность добавления новых полей (значений, реквизитов), могут работать с данными типа Дата. Но зачастую предметом хранения является не информация о датах, а другая информация, которая просто должна храниться в привязке ко времени. Например, необходимо помнить, начиная с какого момента времени для таких-то номенклатурных позиций действуют такие-то цены. Информацию, хранящуюся в привязке ко времени, чаще всего разделяют на содержащую: ■ объектные данные, ■ необъектные данные. Использование документов В задачах хранения объектных данных, привязанных ко времени, речь обычно идет о регистрации неких событий и всего, что с ними связано, например, в хозяйственной жизни предприятия. Чаще всего для хранения такой информации выбираются объекты Документ. В нашем примере (с хранением информации о ценах), если необходимо в привязке ко времени фиксировать, как (и вследствие какого события) произошло изменение цен, то для хранения этой информации можно использовать документ ИзменениеЦенКомпании (рис. 1.33). Рис. 1.33. Документ «ИзменениеЦенКомпании» Глава 1. Хранение информации 51 В пользу такого решения говорит функциональность объектов документов, поддерживаемая на уровне платформы «1С:Предприятие»: ■ заполнение, ■ запись, ■ проведение, ■ формирование движений по регистрам, ■ расположение на оси времени, ■ пометка на удаление, ■ удаление. Кроме этого, положительным моментом является возможность решения (средствами платформы) вопросов отображения списков документов, группирования разных видов документов в единой хронологии для общего отображения или для общей обработки и так далее. Подробно эти вопросы освещены в главе «Документы и последовательности» на стр. 139. Использование периодических регистров сведений Как рассуждали выше, в разделе «Задачи хранения информации» на стр. 9, для решения учетных и аналитических задач кроме учета событий важно, чтобы система в определенных ситуациях учитывала показатели, которые изменяются или при обработке вышеуказанных событий, или вследствие других действий пользователя. Возможно, в нашем примере будет необходимо быстро получить ответ, для какого товара в такой-то момент времени действует такая-то цена. Получение этой информации из документов может оказаться неудобным или длительным по времени, потому что данные разных документов могут противоречить друг другу и для определения истины разработчику придется прописать некие алгоритмы. Использование периодических регистров сведений позволяет в данной ситуации (и подобных ей) достаточно быстро создать решение, большую часть функциональности которого поддерживает сама платформа (рис. 1.34). Рис. 1.34. Структура регистра накопления «ЦеныНоменклатуры» 52 Реализация прикладных задач в системе «1С:Предприятие 8.2» Например, получение информации об актуальных значениях цен на некоторый момент времени (рис. 1.35). Рис. 1.35. Схема получения актуальных цен Подробно вопросы состава и функциональности регистров сведений рассмотрены ниже, в разделе «Хранение информации в регистрах сведений» на стр. 54. При этом хотелось бы заметить, что в рассмотренном нами примере оба варианта (и использование документов, и использование периодических регистров сведений) для хранения данных, имеющих привязку ко времени, не противоречат друг другу. Они могут «мирно уживаться» в одном решении и обеспечивать каждый свою функциональность. И даже более того, помогают друг другу. Данный пример полностью приведен в составе демонстрационной конфигурации «Хранение информации и учет движения средств», которая находится на прилагаемом компакт-диске. Использование объекта «ХранилищеЗначения» При решении вопросов хранения информации желательно различать информацию, обеспечивающую основную бизнес-логику решения и другую, вспомогательную информацию. Данные основной бизнес-логики активно используются в учетных и аналитических механизмах. Для них важны такие вопросы, как индексирование, упорядочивание в запросах и выборках, суммирование, поиск и т. п. Вопросам обеспечения хранения этих данных, по сути, посвящена большая часть данной главы. Данные же вспомогательной информации нужно просто хранить. Все возможное манипулирование этой информацией сводится к операциям записи Глава 1. Хранение информации 53 и чтения. Вопросам организации хранения такой информации посвящен текущий раздел. Итак, платформа системы «1С:Предприятие» предоставляет возможность хранения некоторой вспомогательной информации в базе данных посредством полей типа ХранилищеЗначения. Особенностью использования таких полей является то, что база данных «не обязана ничего знать» о природе хранимой там информации. Это могут быть картинки, файлы, таблицы, данные примитивных типов, да что угодно. База данных отвечает лишь за хранение этой информации, не обеспечивая больше никакой функциональности. При этом еще говорят, что тип значения ХранилищеЗначения позволяет хранить значения различных типов в сериализованном виде, то есть в виде, который позволяет записывать данные и восстанавливать их. ПРИМЕЧАНИЕ Для всех объектов, чьи данные сериализуются, в описании встроенного языка данная возможность указывается отметкой «Сериализуется». Важной особенностью хранилища значений является возможность хранения данных в сжатом виде. Это позволяет существенно сократить размеры базы данных при необходимости хранения больших объемов информации. С прикладной точки зрения в полях типа ХранилищеЗначения можно хранить, например, значения каких-то вспомогательных настроек пользователей, фотографии, изображения, образы файлов и так далее. Например, фотографии сотрудников или файлы с аудиозаписью важных переговоров (то есть данные типа Картинка или ДвоичныеДанные). При этом, хотя в системе не существует явного ограничения на размер данных, хранящихся в полях типа ХранилищеЗначения, следует все-таки осмотрительно подходить к решению, что именно требуется хранить в базе данных. Большой объем хранимой вспомогательной информации может привести к тому, что административные операции (например, создание резервной копии базы данных) выполняются медленно из-за большого объема базы данных. А большой объем обусловлен не требованиями обеспечения основной бизнес-логики, а тем, что кто-то из сотрудников решил хранить в базе данных любимые фильмы. Особенно аккуратно нужно относиться к возможности использования полей типа ХранилищеЗначения в составе объектов (например, справочников, документов), активно использующихся при реализации основной бизнеслогики. Ведь данные объектов считываются целиком при обращении к ним. Поэтому, например, вопрос хранения тех же фотографий лучше решать не в составе справочника Сотрудники, а в отдельном подчиненном справочнике или регистре сведений. Тогда будет сохранена возможность идентификации 54 Реализация прикладных задач в системе «1С:Предприятие 8.2» соответствия изображений сотрудникам, к которым они относятся. И в то же время при использовании объектов справочника Сотрудники для решения других задач выполняемые операции не будут замедляться из-за необходимости считывания из базы данных больших объемов информации. Хранение информации в регистрах сведений Удобным средством для реализации задач хранения информации необъектных данных, развернутой в некоторых разрезах, является использование регистров сведений. Для решения таких задач регистры сведений обладают функциональностью, которая включает в себя: ■ уникальность записей в разрезах ключей записей; ■ периодичность; ■ подчинение записей регистратору. Разберем использование этой функциональности на примерах. Уникальность записей регистра сведений Одним из основных показаний для использования именно регистров сведений для хранения данных является то, что регистры сведений обеспечивают уникальность хранимой информации для конкретных комбинаций значений разрезов ее хранения. То есть набор значений разрезов является уникальным ключом каждой записи регистра. Сама информация в регистре хранится в виде значений ресурсов. А разрезы хранения информации реализуются посредством измерений регистра. Рассмотрим следующий пример. Для хранения значения метода списания себестоимости, действующего на автоматизируемом предприятии, может использоваться непериодический регистр сведений УчетнаяПолитикаПредприятия. В случае отсутствия измерений (разрезов хранения информации) состав регистра будет выглядеть следующим образом (рис. 1.36). Рис. 1.36. Структура регистра «УчетнаяПолитикаПредприятия» Глава 1. Хранение информации 55 В таком регистре можно хранить только одно значение метода списания себестоимости (табл. 1.3). Таблица 1.3. Значение, хранимое в регистре МетодСписанияСебестоимости FIFO Запись другого значения в данный регистр обязательно должна сопровождаться замещением предыдущего (табл. 1.4). Два значения одновременно храниться не могут. Таблица 1.4. Значение, хранимое в регистре МетодСписанияСебестоимости Средневзвешенный Это соответствует требованиям прикладной области. Ведь действительно, если для решения ряда учетных задач потребуется получать значение используемого на предприятии метода списания себестоимости, то важно, чтобы он был одним и тем же. Если же автоматизируемое предприятие, например, представляет собой ряд самостоятельных юридических лиц (организаций), то для хранения информации об учетной политике каждой организации в рассмотренный регистр сведений можно ввести измерение Организация (рис. 1.37). В результате данные в регистре смогут храниться в разрезе организаций. Рис. 1.37. Структура регистра «УчетнаяПолитикаПредприятия» По каждой конкретной организации в регистре сможет присутствовать только одна запись. Значение метода списания себестоимости в этой записи будет «персональным» для этой организации. И ключом этой записи будет значение организации (табл. 1.5). Таблица 1.5. Пример хранения данных в регистре «УчетнаяПолитикаПредприятия» Организация МетодСписанияСебестоимости ООО «АвтоматикаСвязьПроект» FIFO ООО «Информационные системы» Средневзвешенный ООО «Мультимедиа Плюс» Средневзвешенный 56 Реализация прикладных задач в системе «1С:Предприятие 8.2» Таким образом, важно понимать, что регистр сведений не является простой таблицей для хранения произвольной информации. Требование уникальности записей по ключевым полям обязательно. И оно отслеживается системой автоматически, при любых попытках модификации данных или модификации состава регистра сведений. Если в вышеприведенном примере после заполнения данных регистра информацией об организациях попытаться удалить измерение Организация из регистра как объекта конфигурации, то система не позволит внести эти изменения в конфигурацию базы данных (рис. 1.38). Рис. 1.38. Сообщения при реорганизации базы данных Количество используемых в составе регистра сведений измерений и ресурсов определяется задачами, которые решаются посредством этого регистра. Например, если стоит задача хранения информации о «персональных» для покупателей ценах на товары, она может быть решена посредством регистра сведений со следующим составом (рис. 1.39). Рис. 1.39. Структура регистра сведений Однако впоследствии любые расширения этой задачи не приводят к необходимости серьезной структурной перестройки в вопросах организации хранения информации и достаточно легко реализуются. Например, если впоследствии необходимо будет ввести понятие «Договор», когда по одному договору с покупателем на товары одни цены, а по другому могут быть совсем другие. Или если по каждой поставляемой номенклатурной позиции понадобится хранить не просто информацию о ценах продажи, но и учет сезонной скидки, условия доставки, процент предоплаты, срок отсрочки платежа и т. д. Все эти требования могут быть реализованы в рамках все того же регистра за счет добавления соответствующих ресурсов и измерений (рис. 1.40). Глава 1. Хранение информации 57 Рис. 1.40. Структура регистра сведений Важно лишь то, что в данном случае «ключом уникальности» записей регистра будет уже номенклатурная позиция конкретного договора с покупателем. ВНИМАНИЕ! Хотелось бы обратить внимание на то, что возможность расширения функциональности регистра за счет добавления новых ресурсов не является обязательной к использованию. В некоторых случаях лучше добавлять не ресурсы, а новые регистры сведений. Подробно этот вопрос рассматривается в разделе «Проектирование структуры регистров сведений» на стр. 107. Периодические регистры сведений Одной из возможностей регистра сведений является хранение данных не только в разрезе указанных измерений, но и в хронологическом разрезе. Разработчик может создавать периодические регистры сведений, указывая минимальную периодичность хранения данных. Например, для реализации хранения информации в регистре сведений УчетнаяПолитикаПредприятия не только в разрезе организаций, но и в разрезе лет (в действительности учетная политика предприятия принимается сроком на год), в состав объекта конфигурации можно внести следующее изменение – указать периодичность хранения информации регистра В пределах года (рис. 1.41). В результате в структуру хранения данных регистра будет добавлено поле Период. Причем оно будет включено в состав ключа записей регистра. То есть, по сути, является еще одним разрезом хранения информации. Теперь в регистре УчетнаяПолитикаПредприятия (см. рис. 1.37) смогут храниться, например, такие данные (табл. 1.6). 58 Реализация прикладных задач в системе «1С:Предприятие 8.2» Рис. 1.41. Периодичность регистра сведений Таблица 1.6. Пример хранения данных в регистре «УчетнаяПолитикаПредприятия» Период Организация МетодСписанияСебестоимости 2009 г. ООО «АвтоматикаСвязь Проект» FIFO 2009 г. ООО «Информационные системы» Средневзвешенный 2009 г. ООО «Мультимедиа Плюс» Средневзвешенный 2010 г. ООО «АвтоматикаСвязь Проект» Средневзвешенный 2010 г. ООО «Мультимедиа Плюс» LIFO Таким образом, в регистре сведений можно хранить не просто статические данные, но и историю изменений этих данных. При такой организации хранения информации появляются возможности: ■ получения информации, актуальной на тот или иной временной момент; ■ получения информации о значениях данных, вступающих в силу после некоего временного момента; ■ получения картины динамики изменения данных за некоторый период; ■ решения других прикладных задач, связанных с хранением информации в привязке ко времени. Глава 1. Хранение информации 59 Например, периодический регистр сведений ПерсонифицированныйПрайс сможет не только хранить информацию о том, какова цена на определенную номенклатуру сейчас (или была в прошлом), но и о том, как она будет изменяться в будущем (если эти изменения будут заранее планироваться). Более подробно вопросы получения информации из периодического регистра рассмотрены в разделе «Получение данных из периодических регистров сведений» на стр. 93. Подчинение записей регистратору В ряде прикладных задач возникает необходимость обеспечения обоснования хранимой в регистрах сведений информации наличием документов, зарегистрировавших изменения этой информации. Например, изменение отпускных цен компании может производиться только определенным кругом лиц, и каждое такое изменение должно сопровождаться оформлением соответствующего документа. То есть данные регистра сведений должны четко «помнить», в связи с каким именно документом они там оказались (рис. 1.42). Рис. 1.42. Хранение данных в регистре сведений, подчиненном регистратору Чаще всего при этом необходимо обеспечивать гранулярность записи или модификации данных регистра сведений. В качестве такой «гранулы» используется набор записей, подчиненных документу-регистратору. Например, при проведении документа-регистратора его набор записей целиком перезаписывается. Для того чтобы разработчику не пришлось решать массу вопросов обеспечения данной функциональности собственными силами, он может воспользоваться штатными возможностями платформы. 60 Реализация прикладных задач в системе «1С:Предприятие 8.2» Для этого достаточно установить значение Подчинение регистратору свойству Режим записи регистра сведений как объекта конфигурации (рис. 1.43). Рис. 1.43. Свойства регистра сведений «ЦеныНоменклатуры» С точки зрения хранения данных в регистре установка значения Подчинение регистратору свойства Режим записи приводит к включению в состав регистра полей Регистратор, НомерСтроки и Активность. ПРИМЕЧАНИЕ Обратите внимание на то, что поле Активность по умолчанию не включается в форму списка, сгенерированную платформой. Поэтому если вы захотите увидеть, какие новые поля появились у регистра, и для этого откроете форму списка, то вы не увидите там поля Активность. Но при необходимости его можно добавить вручную в форму списка. Далее требуется указать, какие именно документы могут быть регистраторами записей регистра (рис. 1.44). Это можно сделать как при редактировании самого регистра как объекта конфигурации, так и при редактировании документа-регистратора как объекта конфигурации. Глава 1. Хранение информации 61 Рис. 1.44. Регистраторы регистра сведений Благодаря этому облегчается труд разработчика, которому необходимо сформировать или модифицировать набор (наборы) записей регистра (регистров), подчиненных некоему документу. Подробно этот вопрос освещен в разделе «Создание, изменение, удаление записей регистра сведений» на стр. 69. Платформа во многих механизмах будет сама использовать обращение к данным свойствам объектов конфигурации. Поэтому при удалении документов или отмене проведения (если свойство Удаление движений установлено в значение, отличное от Не удалять) система производит поиск движений этого документа в таблицах всех регистров, для которых данный документ может быть регистратором, и удаляет их. Хотелось бы обратить внимание, что поле Регистратор обеспечивает привязку к документу, но не всегда входит в разряд ключевых полей. 62 Реализация прикладных задач в системе «1С:Предприятие 8.2» Для того чтобы поле Регистратор стало ключевым, необходимо для такого регистра сведений (с режимом записи Подчинение регистратору) установить для свойства Периодичность значение По позиции регистратора. С прикладной точки зрения это означает возможность хранения в регистре сведений данных с привязкой к временной оси с дробностью до момента времени. То есть фактически каждый регистратор может делать движения по любым комбинациям измерений (при этом не будет конфликтовать по поводу уникальности с другими документами). А значения ресурсов можно получать не только на определенный период, но и на момент времени документа (рис. 1.45). Рис. 1.45. Получение значений ресурсов на момент времени документа Однако необходимо понимать, что с точки зрения решения реальных бизнесзадач точность записи хронологии изменений информации больше секунды вряд ли требуется. Таким образом, исходя из области применения, если требуется поместить действия двух событий в определенном хронологическом порядке, то их нужно помещать в разные периоды. То есть если записи движений формируются так, что поле Период заполняется значением Дата документа, то нужно менять дату документа (рис. 1.46). Хронология записей регистра сведений с периодичностью По позиции регистратора внутри секунды однозначна с точки зрения чтения информации, но не управляема разработчиком с точки зрения записи информации. Например, при отображении движений регистра внутри секунды они упорядочиваются системой по ссылкам на регистраторы, то есть по внутренним идентификаторам документов. И такой порядок неизменен при любом обращении на чтение информации, однако нет возможности произвольно изменить его (внутри секунды). Глава 1. Хранение информации 63 Рис. 1.46. Запись движений документов с точностью до даты Структура регистра сведений В состав регистра сведений как объекта конфигурации включаются: ■ измерения, ■ ресурсы, ■ реквизиты. Как уже было рассмотрено выше, в разделе «Уникальность записей регистра сведений» на стр. 54: ■ ресурсы хранят данные регистра, то есть ту информацию, ради хранения которой регистр, собственно, создавался и с которой работает функциональность регистра; ■ измерения используются для обеспечения разрезов хранения этой информации. Кроме того, для ситуаций, когда необходимо кроме данных хранить дополнительную информацию собственно о записях регистра, возможно использование реквизитов. Хотелось бы особо отметить, что деление информации регистра на реквизиты и ресурсы – элемент общего подхода. И хотя технологически хранение информации ресурсов и реквизитов регистра сведений существенно не различается, правильное отнесение разработчиком данных к ресурсам или реквизитам позволяет впоследствии быстро отличить, что является «функцией» регистра, а что просто комментирует запись. Строго говоря, это один из ключевых моментов организации разработки в «1С:Предприятии» – деление структуры метаданных по ролям, исполняемым конкретными объектами в прикладном решении, а не только по их технологическому устройству. 64 Реализация прикладных задач в системе «1С:Предприятие 8.2» Например, регистр сведений ЦеныНоменклатуры хранит информацию о ценах в разрезах номенклатурных позиций и типов цен. Эта информация впоследствии используется для работы механизмов ценообразования. Но, кроме того, для вопросов контроля над изменением цен в составе регистра есть реквизит Ответственный, в котором для каждой записи регистра указывается ссылка на пользователя, ответственного за ввод данной записи (рис. 1.47). Рис. 1.47. Структура регистра сведений «ЦеныНоменклатуры» Рис. 1.48. Основные свойства регистра сведений «ЦеныНоменклатуры» Глава 1. Хранение информации 65 Далее, как было рассмотрено выше, регистры сведений могут иметь режим записи Подчинение регистратору, вследствие чего в состав таблиц регистра добавляется поле Регистратор. И регистр сведений может быть периодическим, вследствие чего в состав его таблиц добавляется поле Период (рис. 1.48). Данные каждого регистра сведений хранятся в отдельной таблице базы данных. Каждая такая таблица имеет следующий состав колонок: ■ Период – дата записи. Определяет положение данной записи на временной оси. Это поле существует только для периодических регистров. Регистратор – содержит ссылку на документ, которому подчинена данная запись. Это поле существует только для регистров с режимом записи Подчинение регистратору. ■ НомерСтроки – уникальный номер данной записи в наборе записей регистра, подчиненных документу, указанному в поле Регистратор. Это поле существует только для регистров с режимом записи Подчинение регистратору. ■ Активность – имеет тип Булево. Содержит признак влияния записи на получение информации из регистра. Записи, для которых значение данного свойства установлено в Ложь, не будут учитываться при получении «первых» или «последних» записей регистра, а также при получении сведений на определенный момент времени. Это поле существует только для регистров с режимом записи Подчинение регистратору. ■ Ключ – короткий ключ записи регистра. Поле присутствует у непериодических регистров, имеющих хотя бы одно измерение. ■ <Измерение> – содержит значение измерения. Количество таких полей равно количеству измерений, определенных для регистра как объекта конфигурации. ■ <Ресурс> – значение ресурса. Количество таких полей равно количеству ресурсов, определенных для регистра как объекта конфигурации. ■ <Реквизит> – значение реквизита. Количество таких полей равно количеству реквизитов, определенных для регистра как объекта конфигурации. Таким образом, для регистра ЦеныНоменклатуры с режимом записи Подчинение регистратору и периодичностью По позиции регистратора пример заполнения таблицы базы данных будет следующим (темным фоном выделены ключевые поля записей), табл. 1.7. ■ 18.04.2010 20:49:26 18.04.2010 20:49:26 18.04.2010 20:49:26 18.04.2010 20:49:26 16.04.2010 21:54:41 16.04.2010 21:54:41 16.04.2010 21:54:41 16.04.2010 21:54:41 16.04.2010 21:54:41 Период Изменение цен компании 000000001 от 16.04.2010 21:54:41 Изменение цен компании 000000001 от 16.04.2010 21:54:41 Изменение цен компании 000000001 от 16.04.2010 21:54:41 Изменение цен компании 000000001 от 16.04.2010 21:54:41 Изменение цен компании 000000001 от 16.04.2010 21:54:41 Изменение цен компании 000000002 от 18.04.2010 20:49:26 Изменение цен компании 000000002 от 18.04.2010 20:49:26 Изменение цен компании 000000002 от 18.04.2010 20:49:26 Изменение цен компании 000000002 от 18.04.2010 20:49:26 Регистратор истина истина истина истина истина истина истина истина истина 2 3 4 5 1 2 3 4 Пульт VH Пульт PX Пульт PX Пульт PX Пульт VH Пульт VH Пульт PX Пульт PX Пульт PX Мелкооптовая Розничная Мелкооптовая Оптовая Мелкооптовая Оптовая Розничная Мелкооптовая Оптовая Активность Номенклатура ТипЦены 1 Номер строки Таблица 1.7. Пример заполнения регистра сведений «ЦеныНоменклатуры» Ответственный Семенов 100,00 Иванов 220,00 Иванов 190,00 Иванов 170,00 Иванов 90,00 100,00 Семенов 200,00 Семенов 170,00 Семенов 150,00 Семенов Цена 66 Реализация прикладных задач в системе «1С:Предприятие 8.2» Глава 1. Хранение информации 67 Теперь рассмотрим непериодический регистр сведений Сотрудники с независимым режимом записи (рис. 1.49). Рис. 1.49. Структура регистра «Сотрудники» Таблица регистра Сотрудники, хранящая информацию в базе данных, может быть заполнена следующим образом (темным фоном выделены ключевые поля записей), табл. 1.8. Таблица 1.8. Пример заполнения регистра сведений «Сотрудники» Физическое лицо Подразделение Должность Иванов Иван Сергеевич Отдел продаж Руководитель Семенов Сергей Петрович Отдел продаж Менеджер Семенов Сергей Петрович Отдел закупок Руководитель Петровский Семен Иванович Руководство компании Руководитель Петровская Ирина Ивановна Бухгалтерия Бухгалтер Конечно же, функциональность регистра сведений с независимым режимом записи и регистра сведений с режимом записи Подчинение регистратору различается. Также различается функциональность использования периодических и непериодических регистров сведений. Поэтому для поддержания должного быстродействия при обращении к данным информационной базы для таблиц регистров сведений в зависимости от вида регистра создаются, например, следующие индексы: ■ Для регистра сведений с периодичностью По позиции регистратора: □ Период + Регистратор + НомерСтроки. □ Регистратор + НомерСтроки. □ Измерение1 + [Измерение2 + …] + Период + Регистратор + НомерСтроки – если для данного регистра есть хоть одно измерение. В данный индекс включаются все измерения в том порядке, в котором они заданы в составе регистра как объекта конфигурации, поле Период, поле Регистратор и поле НомерСтроки. 68 □ Реализация прикладных задач в системе «1С:Предприятие 8.2» Измерение + Период + Регистратор + НомерСтроки – если для данного измерения свойство Индексировать установлено в значение Индексировать. □ Ресурс + Период + Регистратор + НомерСтроки – если для данного ресурса свойство Индексировать установлено в значение Индексировать. □ Реквизит + Период + Регистратор + НомерСтроки – если для данного реквизита свойство Индексировать установлено в значение Индексировать. ■ Для непериодического регистра сведений: □ Измерение1 + [Измерение2 +…] – если для данного регистра есть хоть одно измерение. В данный индекс включаются все измерения в том порядке, в котором они заданы в составе регистра как объекта конфигурации. □ ИзмерениеN + Измерение1 + [Измерение2 +…] – если для измерения ИзмерениеN задано свойство Индексировать или свойство Ведущее, и при этом это не первое и не единственное измерение. В данный индекс включаются ИзмерениеN и затем все остальные измерения в том порядке, в котором они заданы в составе регистра как объекта конфигурации. □ Реквизит + Измерение1 + [Измерение2 +…] – если для данного реквизита свойство Индексировать установлено в значение Индексировать. В данный индекс включается поле Реквизит и затем все измерения в том порядке, в котором они заданы в составе регистра как объекта конфигурации. □ Ресурс + Измерение1 + [Измерение2 +…] – если для данного ресурса свойство Индексировать установлено в значение Индексировать. В данный индекс включается поле Ресурс и затем все измерения в том порядке, в котором они заданы в составе регистра как объекта конфигурации. □ Ключ. Использование индексов позволяет сократить время выполнения операций с данными регистра. Вышеприведенное описание структуры индексов позволяет утверждать, что в общем случае порядок расстановки измерений регистра сведений имеет важное значение. Измерения, к значениям которых необходим быстрый доступ (например, при реализации отборов), следует располагать первыми, далее – в порядке убывания «популярности в отборах». Таким образом будет обеспечиваться возможность эффективного применения индексов при реализации задач чтения информации из таблицы регистра. Глава 1. Хранение информации 69 Также необходимо иметь в виду, что, например, SQL Server накладывает определенное ограничение – не более 16 полей в индексе. Поэтому работа с регистрами, имеющими очень большое количество измерений, может быть неэффективна по скорости из-за невозможности использования индексов. Более подробно об индексировании физических таблиц регистра сведений можно прочитать в разделе «Индексы таблиц базы данных» на стр. 697. Создание, изменение, удаление записей регистра сведений В общем случае в таблицу регистра сведений записи могут вводиться пользователем вручную, генерироваться в процессе выполнения обработок либо при поведении документов. Для понимания работы механизмов формирования или модификации записей в таблице регистра сведений необходимо прежде всего исходить из следующих положений: ■ все записи в регистрах уникальны с точки зрения комбинации значений в ключевых полях; ■ добавление, изменение, удаление информации в регистрах производятся «гранулами», представляющими собой наборы записей. Поясним эти положения на примерах. Для регистра сведений ЦеныНоменклатуры с режимом записи Подчинение регистратору ключевыми полями являются Период, Регистратор, Номенклатура, ТипЦены. Гранулой обмена информации с базой данных является набор записей, подчиненных одному регистратору (табл. 1.9). Разным фоном в таблице выделены наборы записей. Согласно постулату об уникальности записей по значениям ключевых полей невозможно, например, записать одновременно две записи с одинаковыми значениями полей Номенклатура, ТипЦены, Период, Регистратор (табл. 1.10). При подобной попытке система выдаст соответствующее предупреждение и не выполнит запись. Это обосновывается требованиями прикладной области, поскольку невозможно одновременно установить для одного и того же товара две разные оптовые цены. В то же время положение о «гранулярности» модификации информации регистра облегчает реализацию операций удаления или модификации данных. Потому что с прикладной точки зрения: ■ удаление документа Изменение цен компании № 1 должно повлечь за собой удаление всех записей регистра, подчиненных данному документу; ■ изменение в данных документа при его перепроведении должно повлечь создание нового набора записей (движений документа), который должен полностью заместить старые записи регистра, подчиненные этому документу. 18.04.2010 20:49:26 18.04.2010 20:49:26 18.04.2010 20:49:26 18.04.2010 20:49:26 16.04.2010 21:54:41 16.04.2010 21:54:41 16.04.2010 21:54:41 16.04.2010 21:54:41 16.04.2010 21:54:41 Период Изменение цен компании 000000001 от 16.04.2010 21:54:41 Изменение цен компании 000000001 от 16.04.2010 21:54:41 Изменение цен компании 000000001 от 16.04.2010 21:54:41 Изменение цен компании 000000001 от 16.04.2010 21:54:41 Изменение цен компании 000000001 от 16.04.2010 21:54:41 Изменение цен компании 000000002 от 18.04.2010 20:49:26 Изменение цен компании 000000002 от 18.04.2010 20:49:26 Изменение цен компании 000000002 от 18.04.2010 20:49:26 Изменение цен компании 000000002 от 18.04.2010 20:49:26 Регистратор 4 3 2 1 5 4 3 2 1 Номер строки истина истина истина истина истина истина истина истина истина Пульт VH Пульт PX Пульт PX Пульт PX Пульт VH Пульт VH Пульт PX Пульт PX Пульт PX Активность Номенклатура Таблица 1.9. Пример заполнения регистра сведений «ЦеныНоменклатуры» Мелкооптовая Розничная Мелкооптовая Оптовая Мелкооптовая Оптовая Розничная Мелкооптовая Оптовая ТипЦены Ответственный Семенов 100,00 Иванов 220,00 Иванов 190,00 Иванов 170,00 Иванов 90,00 100,00 Семенов 200,00 Семенов 170,00 Семенов 150,00 Семенов Цена 70 Реализация прикладных задач в системе «1С:Предприятие 8.2» Глава 1. Хранение информации 71 16.04.2010 21:54:41 16.04.2010 21:54:41 Изменение цен компании 000000001 1 истина от 16.04.2010 21:54:41 Изменение цен компании 000000001 2 истина от 16.04.2010 21:54:41 Ответственный Цена ТипЦены Номенклатура Активность Номер строки Регистратор Период Таблица 1.10. Пример заполнения регистра сведений «ЦеныНоменклатуры» Пульт PX Оптовая 150,00 Семенов Пульт PX Оптовая 155,00 Петров Приемы добавления, удаления и модификации движений регистров с режимом записи Подчинение регистратору универсальны. То есть они одинаковы что для подчиненных регистров сведений, что для других видов регистров (накопления, бухгалтерии, расчетов). ПРИМЕЧАНИЕ Нужно помнить о различии ключей записей регистров накопления и регистров сведений. В регистре накопления номер строки входит в ключ записи, поэтому одним документом можно писать одинаковые значения в разные записи. В регистре сведений номер записи не входит в ключ, поэтому одинаковые значения измерений и даты одним документом писать нельзя! Подробно примеры подобных действий описаны в разделах «Свойство объекта документа «Движения»» и «Запись набора записей регистра без использования свойства «Движения»» главы «Реализация задач учета движения средств». В отношении регистров сведений с независимым режимом записи гранулами обмена с базой данных будут наборы записей с установленными отборами по значениям ключевых полей регистра. Кроме того, для некоторых прикладных задач может понадобиться реализация обмена информацией независимых регистров сведений в рамках распределенных баз данных. В таких ситуациях в гранулы обмена между базами данных будут включаться комбинации значений измерений с установленным свойством Основной отбор. Также в основной отбор может включаться поле Период для периодических регистров (рис. 1.50). 72 Реализация прикладных задач в системе «1С:Предприятие 8.2» Рис. 1.50. Свойство «Основной отбор» Например, в состав демонстрационной конфигурации «Хранение информации и учет движения средств», которая находится на прилагаемом компактдиске, входит ПерсонифицированныйПрайс – регистр сведений с независимым режимом записи и периодичностью В пределах дня (рис. 1.51). Рис. 1.51. Структура регистра сведений «ПерсонифицированныйПрайс» С прикладной точки зрения посредством этого регистра руководство компании может указывать информацию об исключительных условиях ценообразования для отдельных покупателей. Причем режим редактирования позволяет заполнять данные этого регистра и вручную, и программно (например, посредством обработки РаспоряжениеНаУстановкуЦенПокупателя). Ключевыми полями для этого регистра будут Период, Покупатель, Номенклатура. Поэтому гранулой модификации может считаться любая комбинация значений этих полей. Глава 1. Хранение информации 73 Например, если для решения некоей задачи нам необходимо устанавливать или менять на определенный период для определенного покупателя цены на все номенклатурные позиции сразу, гранулами модификации будут наборы записей, соответствующие комбинациям значений полей Период, Покупатель. Таким образом, данные, хранимые в регистре, можно представить следующим образом (серым фоном в таблице выделены ключевые поля), табл. 1.11. Таблица 1.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 Компания "Риона" 290,00 Компания "Риона" Монитор 17’ Philips 107S20 Монитор 19’ Hitachi CM715ET Монитор LCD 22’ M8537ZM/A Ялта-Лтд Мышь 3D-Sensor 4,00 Компания "Риона" 290,00 350,00 В результате такого гранулирования данные каждой гранулы, то есть наборы записей, соответствующие каждой грануле, можно удалять или замещать целиком. Рис. 1.52. Форма обработки «РаспоряжениеНаУстановкуЦенПокупателя» 74 Реализация прикладных задач в системе «1С:Предприятие 8.2» Именно это и реализуется посредством обработки РаспоряжениеНаУстановкуЦенПокупателя, входящей в состав демонстрационной конфигурации «Хранение информации и учет движения средств», которая находится на прилагаемом компакт-диске. В форме обработки посредством полей ввода пользователь заполняет реквизиты формы ВыбранныйПокупатель и ДатаУстановки. А посредством таблицы Товары, находящейся в форме обработки, можно ввести информацию о том, какие цены, для каких номенклатурных позиций нужно назначить выбранному покупателю на дату установки (рис. 1.52). Текст процедуры, вызываемой обработчиком нажатия кнопки Выполнить, представлен в листинге 1.14. Листинг 1.14. Обработчик события нажатия кнопки «Выполнить» &НаКлиенте Процедура ВыполнитьЗаписьВРегистр(Команда) НепосредственнаяЗаписьВРегистр(); КонецПроцедуры Из этого обработчика вызывается серверная процедура НепосредственнаяЗаписьВРегистр() (листинг 1.15). Листинг 1.15. Процедура «НепосредственнаяЗаписьВРегистр» &НаСервере Процедура НепосредственнаяЗаписьВРегистр() // Создать набор записей, соответствующий грануле "Период – Покупатель" НаборЗаписей = РегистрыСведений.ПерсонифицированныйПрайс.СоздатьНаборЗаписей(); НаборЗаписей.Отбор.Период.Установить(ДатаУстановки); НаборЗаписей.Отбор.Покупатель.Установить(ВыбранныйПокупатель); // Добавить записи в созданный набор записей Для Каждого СтрокаТовара Из Товары Цикл НоваяЗапись = НаборЗаписей.Добавить(); НоваяЗапись.Период = ДатаУстановки; НоваяЗапись.Покупатель = ВыбранныйПокупатель; НоваяЗапись.Номенклатура = СтрокаТовара.Номенклатура; НоваяЗапись.Цена = СтрокаТовара.Цена; КонецЦикла; // Записать набор записей с замещением старого, соответствующего той же грануле НаборЗаписей.Записать(); КонецПроцедуры Глава 1. Хранение информации 75 В процедуре сначала создается набор записей с установкой значений отбора по ключевым полям, то есть по полю Период и по измерению Покупатель. Далее в цикле перебора строк таблицы Товары происходит заполнение записей в созданном наборе записей. После этого сформированный набор записей записывается с замещением старого набора записей регистра, соответствующего той же грануле (у параметра Замещать метода набора записей Записать() значение по умолчанию – Истина). В результате выполнения обработки (исходные данные см. рис. 1.52) таблица регистра будет содержать следующие данные (табл. 1.12). Таблица 1.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 300,00 ЦветМетМаш Пульт VH 120,00 Компания "Риона" Компания "Риона" Ялта-Лтд Монитор 17’ Philips 107S20 Монитор�������� 15’ LG Studioworks 575N Мышь 3D-Sensor 295,00 300,00 4,00 Как видите, информация, соответствующая грануле «11.01.2010 – Компания "Риона"», заместилась согласно данным таблицы Товары формы обработки. Необходимо иметь в виду, что для независимого регистра сведений подобное «гранулирование» умозрительное, виртуальное. То есть посредством него можем получить совершенно любой набор записей (главное, чтобы отбор устанавливался по всем ключевым полям или ни по одному из них, и только на равенство). Но не всегда можно будет записать любой набор, т. к. если в отбор включены не все ключевые поля и выполняется добавление, то можно пересечься с существующими значениями ключевых полей. Конечно, выполнение записи набора записей с замещением просто очистит старые записи, с которыми пересекаемся. Но иногда на практике возникают задачи, когда необходимо запретить такое замещение. Допустим, в рассмотренном нами примере обработка РаспоряжениеНаУстановкуЦенПокупателя не должна позволять устанавливать новые цены для покупателя на определенный период по тем номенклатурным позициям, по которым цены уже были установлены ранее. 76 Реализация прикладных задач в системе «1С:Предприятие 8.2» Такое требование достаточно легко реализуемо. Достаточно лишь в той же процедуре установить значение Ложь параметру Замещать метода Записать() набора записей регистра (листинг 1.16). Листинг 1.16. Фрагмент кода // Записать набор записей с замещением старого, // соответствующего той же грануле НаборЗаписей.Записать(Ложь); При попытке выполнения обработки для условий, отображенных выше (см. рис. 1.52), система выдаст предупреждение о том, что запись с такими ключевыми полями уже существует (табл. 1.13), и запись нового набора записей не состоится. Таблица 1.13. Запись с дублирующими значениями ключевых полей Период Покупатель Номенклатура 11.01.2010 Компания "Риона" Монитор 17’ Philips 107S20 Для ситуаций, когда необходимо замещать все записи независимого регистра сведений новым набором записей, гранулой можно считать весь регистр. Для этого достаточно вообще не устанавливать отбор. То есть для этого в обработке, подобной вышеприведенной, не нужно указывать установки отборов (листинг 1.17). Листинг 1.17. Пример записи набора записей без установки отбора &НаСервере Процедура НепосредственнаяЗаписьВРегистр() // Создать набор записей НаборЗаписей = РегистрыСведений.ПерсонифицированныйПрайс.СоздатьНаборЗаписей(); // Добавить записи в созданный набор записей Для Каждого СтрокаТовара Из Товары Цикл НоваяЗапись = НаборЗаписей.Добавить(); НоваяЗапись.Период = ДатаУстановки; НоваяЗапись.Покупатель = ВыбранныйПокупатель; НоваяЗапись.Номенклатура = СтрокаТовара.Номенклатура; НоваяЗапись.Цена = СтрокаТовара.Цена; КонецЦикла; // Записать набор записей с замещением старого, соответствующего той же грануле НаборЗаписей.Записать(); КонецПроцедуры Глава 1. Хранение информации 77 Тогда при записи нового набора записей с замещением будут замещены все записи регистра. Для некоторых задач необходимо, чтобы таблица независимого регистра сведений просто полностью очищалась. Такого результата легко добиться следующим образом (листинг 1.18). Листинг 1.18. Пример очистки регистра сведений НаборЗаписей = РегистрыСведений.ПерсонифицированныйПрайс.СоздатьНаборЗаписей(); НаборЗаписей.Записать(); В некоторых задачах бывает необходимо модифицировать записи, соответствующие неким сложным условиям, причем модификации будут подвергаться и значения ключевых полей. Например, в регистре ПерсонифицированныйПрайс нужно повысить на 20 % цены на все номенклатурные позиции, входящие в группы, в названиях которых упоминаются слово «принтеры», если они стоят меньше 300, и переопределить их на некоего выделенного покупателя. То есть для остальных покупателей таких цен больше быть не должно. Пример реализации такой задачи с использованием объекта МенеджерЗаписи регистра сведений приведен в обработке ДействияСДаннымиРегистраСведений демонстрационной конфигурации «Хранение информации и учет движения средств», которая находится на прилагаемом компакт-диске (листинг 1.19). Листинг 1.19. Обработчик события нажатия кнопки «Переопределить на выбранного покупателя цены» &НаКлиенте Процедура ПовыситьЦены(Команда) ПереопределитьЦеныВРегистре(ВыделенныйПокупатель); КонецПроцедуры Из обработчика события нажатия кнопки Переопределить на выбранного покупателя цены вызывается серверная процедура ПереопределитьЦеныВРегистре() (листинг 1.20). Краткий комментарий: сначала готовится объект манипулирования данными одной записи регистра сведений – менеджер записи. Далее посредством запроса из основной таблицы регистра получаются записи, соответствующие условиям. Обратите внимание: условие по наименованию позволяет получить значения, в которых в любом месте наименования встречается сочетание символов «принтер». 78 Реализация прикладных задач в системе «1С:Предприятие 8.2» Листинг 1.20. Процедура «ПереопределитьЦеныВРегистре» &НаСервереБезКонтекста Процедура ПереопределитьЦеныВРегистре(ВыделенныйПокупатель) // Подготовить менеджер записи Запись = РегистрыСведений.ПерсонифицированныйПрайс.СоздатьМенеджерЗаписи(); // Получить данные записей, соответствующих условиям Запрос = Новый Запрос; Запрос.Текст = " |ВЫБРАТЬ | ПерсонифицированныйПрайс.Период, | ПерсонифицированныйПрайс.Покупатель, | ПерсонифицированныйПрайс.Номенклатура, | ПерсонифицированныйПрайс.Цена |ИЗ | РегистрСведений.ПерсонифицированныйПрайс КАК ПерсонифицированныйПрайс |ГДЕ | ПерсонифицированныйПрайс.Номенклатура.Наименование ПОДОБНО ""%принтер%" | И ПерсонифицированныйПрайс.Цена < 300"; Результат = Запрос.Выполнить(); Выборка = Результат.Выбрать(); Пока Выборка.Следующий() Цикл // Установить ключевые поля менеджера записи Запись.Период = Выборка.Период; Запись.Покупатель = Выборка.Покупатель; Запись.Номенклатура = Выборка.Номенклатура; // Прочитать запись из базы данных Запись.Прочитать(); // Убедиться, что запись все еще есть в базе данных Если Запись.Выбран() Тогда // Переопределить покупателя Запись.Покупатель = ВыделенныйПокупатель; // Установить новую цену Запись.Цена = Выборка.Цена * 1.2; // Записать модифицированную запись в базу данных Запись.Записать(); КонецЕсли; КонецЦикла; КонецПроцедуры Глава 1. Хранение информации 79 В цикле перебора выборки результата запроса устанавливаются значения ключевых полей менеджера записи и производится чтение записи из базы данных. Далее изменяется значение покупателя в записи, а цена в нее устанавливается как увеличенное на 20 % значение цены из выборки. После этого методом Записать() менеджера записи производится непосредственная запись в таблицу базы данных с замещением. Хотелось бы отметить, что в данном примере было рассмотрено использование менеджера записи для программной работы, но объект РегистрСведенийМенеджерЗаписи.<имя> предназначен еще и для обеспечения интерактивной работы с записью регистра сведений. Обязательное условие – регистру сведений в конфигурации должен быть установлен режим записи Независимый (рис. 1.53). Рис. 1.53. Схема использования менеджера записи регистра сведений Обратите внимание: на схеме отображено, что непосредственные операции обмена информацией с базой данных менеджер записи реализует посредством все тех же объектов манипулирования данными – наборов записей регистра. Их два. Один набор записей – пустой. Он используется для удаления записи со старыми ключевыми значениями. А второй набор записей содержит одну запись – ту, которую нужно записать в регистр. При необходимости у разработчика есть возможность «вмешиваться» в процесс модификации данных регистра посредством использования обработчиков событий. 80 Реализация прикладных задач в системе «1С:Предприятие 8.2» В случае записи новой записи (то есть записи с такими ключевыми полями еще не было) из формы записи регистра сведений последовательность, с которой задействованы обработчики событий, следующая (рис. 1.54). Рис. 1.54. Последовательность событий, вызываемая при записи из формы новой записи регистра сведений Обратите внимание: ряд событий, выделенных темным фоном, выполняется в одной транзакции. Вследствие этого, если в рамках любого из обработчиков этих событий установить параметру Отказ значение Истина, транзакция будет отменена. То есть новая запись не запишется, да и любые другие изменения в базе данных не выполнятся (ведь в рамках этих обработчиков событий разработчик мог пытаться менять что-то еще). Это важно с точки зрения обеспечения непротиворечивости изменений в информации объектов, связанных единой прикладной задачей. В случае модификации уже существующей записи регистра посредством менеджера записи могут быть изменены значения ключевых полей. А значит, запись набора с новыми ключевыми полями сама по себе не заместит «старый» набор. Поэтому здесь система работает в два этапа: сначала удаляет «старый» набор записей (состоящий из одной «старой» записи), потом уже записывает «новый» (состоящий из «новой» записи), рис. 1.55. Глава 1. Хранение информации 81 Рис. 1.55. Последовательность событий, вызываемая при записи из формы существующей записи регистра сведений Как видно на схеме, удаление «старого» набора записей производится посредством записи пустого набора записей. При этом получается, что обработчики событий (ПередЗаписью и ПриЗаписи) модуля набора записей будут вызываться дважды. Итак, подробно рассмотрены возможности работы посредством менеджера записи. Однако нужно заметить, что и с набором записей также возможна работа в интерактивном режиме (рис. 1.56). Пример организации интерактивного ввода приведен в обработке РаспоряжениеНаУстановкуЦенПокупателя, на закладке Посредством формы набора записей. Эта обработка входит в состав демонстрационной конфигурации «Хранение информации и учет движения средств», которая находится на прилагаемом компакт-диске. 82 Реализация прикладных задач в системе «1С:Предприятие 8.2» Рис. 1.56. Схема использования набора записей регистра сведений Пользователь заполняет посредством соответствующих полей ввода реквизиты формы ВыбранныйПокупатель и ДатаУстановки. Далее по нажатию кнопки Открыть форму набора записей форма набора записей регистра сведений открывается с отбором по значениям этих реквизитов (листинг 1.21). Листинг 1.21. Обработчик события нажатия кнопки «Открыть форму набора записей» &НаКлиенте Процедура ОткрытьФормуНабораЗаписей(Команда) // Открыть форму набора записей с отбором по покупателю и дате установки цен ЗначениеОтбора = Новый Структура("Покупатель, Период", ВыбранныйПокупатель, ДатаУстановки); ПараметрыФормы = Новый Структура("Отбор", ЗначениеОтбора); ОткрытьФорму("РегистрСведений.ПерсонифицированныйПрайс.Форма.ФормаНабораЗаписей" , ПараметрыФормы) КонецПроцедуры Краткий комментарий: сначала создается структура отбора ЗначениеОтбора со значениями реквизитов формы ВыбранныйПокупатель и ДатаУстановки, затем она добавляется в структуру параметров формы ПараметрыФормы. Эти параметры передаются в форму набора записей регистра сведений ПерсонифицированныйПрайс, и форма открывается с отбором по полям регистра Период и Покупатель, указанным в форме обработки РаспоряжениеНаУстановкуЦенПокупателя. Заметим, что поскольку форма набора записей не является основной формой регистра сведений, она должна быть заранее создана в конфигураторе. Реализацию дальнейших действий пользователя можно доверить самой платформе, поскольку расширения формы набора записей реализуют всю основную функциональность, которая может потребоваться при модификации данных регистра (рис. 1.57). Глава 1. Хранение информации 83 Рис. 1.57. Использование формы обработки «РаспоряжениеНаУстановкуЦенПокупателя» Если разработчику необходимо изменить эту функциональность, то это возможно сделать за счет использования соответствующих обработчиков событий (рис. 1.58). Рис. 1.58. Последовательность событий при записи в форме набора записей регистра сведений 84 Реализация прикладных задач в системе «1С:Предприятие 8.2» При работе с формой набора записей регистра сведений порядок, в котором задействованы обработчики событий, не различается для записи нового набора записей и для записи уже существовавшего, но модифицированного набора записей. Дополнительная функциональность при создании и удалении записей регистра сведений Кроме рассмотренных выше основных вопросов организации заполнения и модификации информации регистров сведений хотелось бы еще разобрать ряд вспомогательных, но не менее важных вопросов для организации решения некоторых прикладных задач. Так, для ряда задач важно не допустить записи данных с пустыми значениями разрезов учета. В рассмотренном выше примере регистра сведений ПерсонифицированныйПрайс с прикладной точки зрения удивительна, например, следующая запись (табл. 1.14). Трактовать ее данные не предоставляется возможным. Таблица 1.14. Пример записи в регистре сведений «ПерсонифицированныйПрайс» Период Покупатель 20.04.2010 Компания "Риона" Номенклатура Цена 300,00 Для того чтобы не допустить записи подобной информации в регистр, можно, конечно, выполнять соответствующую проверку в обработчике события ПередЗаписью. Однако, поскольку подобная задача в практике может встречаться не раз, данная проверка добавлена к функциональности платформы. Для того чтобы задействовать ее автоматически, достаточно лишь установить свойство Запрет незаполненных значений у измерения Номенклатура (рис. 1.59). Хотелось бы обратить внимание, что данная проверка выполняется именно в момент попытки записи данных в регистр. Если, например, сначала свойство установлено не было и регистр уже заполнился данными записей (среди которых встречаются и записи с пустыми значениями номенклатуры), а потом в конфигурации данное свойство установили, то при реструктуризации базы данных это действие никак не отрабатывается. Запрет касается именно момента и только момента записи данных в регистр. В отношении поля Период для периодических регистров сведений и в отношении поля Регистратор регистра сведений с подчиненным режимом записи подобная проверка выполняется всегда (рис. 1.60). Глава 1. Хранение информации 85 Рис. 1.59. Свойства измерения «Номенклатура» Рис. 1.60. Сообщение об ошибке при попытке записи «пустого значения» поля «Период» Другая особенность связана с удалением информации из базы данных. Платформа «1С:Предприятие» допускает непосредственное удаление объектов без контроля ссылочной целостности. Если в результате такой операции будут удалены, например, элементы справочника Номенклатура, ссылки на которые использованы в записях регистра сведений, то информация регистра сведений с прикладной точки зрения может стать некорректной (табл. 1.15). Таблица 1.15. Пример ссылки на отсутствующий объект базы данных Период Покупатель Номенклатура Цена 20.04.2010 Компания "Риона" <Объект не найден> 300,00 Если разработчик хочет, чтобы подобные ситуации корректно отрабатывались средствами самой платформы, то достаточно для измерения Номенклатура при конфигурировании установить свойство Ведущее. 86 Реализация прикладных задач в системе «1С:Предприятие 8.2» В результате при удалении элемента справочника платформа автоматически удалит все записи регистра сведений, связанные с этим элементом. Кроме того, если для измерения регистра сведений установлено свойство Ведущее, то платформа автоматически поместит команду перехода к списку записей регистра в группу Перейти, в панель навигации формы объекта, соответствующего типу измерения (рис. 1.61). Данная функциональность опять же облегчает быструю разработку прикладных решений. Рис. 1.61. Автоматическое формирование команды перехода к подчиненной информации в группе «Перейти» в панели навигации формы элемента справочника «Номенклатура» Получение данных из регистров сведений Только хранение информации как таковое вряд ли требуется при решении прикладных задач. Конечно же, при необходимости всегда подразумевается возможность получения хранимой информации. Можно выделить два больших круга задач, касающихся получения информации из регистров сведений: ■ получение информации о записях регистра для технологических целей (обычно касающихся именно хранения этой информации); ■ получение информации «функции» регистра (обычно для решения вопросов, ради которых регистр создавали). Таким образом, например, из рассмотренного выше регистра ПерсонифицированныйПрайс, хранящего цены продажи в разрезах покупателей и номенклатурных позиций, может понадобиться получить информацию Глава 1. Хранение информации 87 для проведения операций манипулирования с этими ценами. Например, повысить на отдельные товары цены на определенный процент. А может понадобиться проведение сравнительного анализа: насколько персональные цены в среднем ниже общефирменных, и как это влияет на вал продаж по отдельным номенклатурным позициям. Получение данных из непериодических регистров сведений В случае работы с регистрами сведений, у которых отсутствует привязка данных ко времени (непериодические регистры), решение задач обоих типов выполняется непосредственным обращением к записям таблицы базы данных, отвечающей за хранение информации регистра. В зависимости от сложности условий отборов, применяемых при этом, от необходимости соединения информации регистра с информацией других источников, от необходимости использования механизма динамического чтения данных используют или объектную модель представления информации (чтение посредством методов объектов, отвечающих за манипулирование данных регистров), или табличную модель представления информации (обращение к данным посредством запросов, написанных на языке запросов «1С:Предприятия»). И тот и другой способ обращения выполняется впоследствии за счет одних и тех же запросов СУБД к таблице регистра сведений. Однако, исходя из функциональных возможностей, можно различить ситуации, когда уместнее применять работу с той или иной моделью: Объектная модель обычно применяется: ■ Для чтения данных с простейшими отборами (обязательно только на равенство значению; более того, применяя метод Выбрать(), отбор можно строить только по одному полю). ■ В случае необходимости применения механизма динамического чтения данных. Посредством этого механизма чтение данных осуществляется по блокам, а не целиком сразу всех. Табличная модель применима во всех случаях, когда не требуется использование механизма динамического чтения данных. Таким образом, посредством запросов можно выбирать данные с отборами какой угодно сложности (как по измерениям, так и по любым другим полям или по подчиненным полям полей записей регистра). Кроме того, при необходимости в том же запросе информацию регистра можно тут же соединять с информацией других источников и/или выполнять дополнительную обработку полученных данных. 88 Реализация прикладных задач в системе «1С:Предприятие 8.2» Рассмотрим несколько примеров, приведенных в обработке ДействияСДаннымиРегистраСведений, в демонстрационной конфигурации «Хранение информации и учет движения средств», которая находится на прилагаемом компакт-диске. Для непериодического независимого регистра сведений Сотрудники, все поля которого – ссылки на элементы соответствующих справочников (рис. 1.62), задача перебора всех записей регистра может быть решена так, как показано в листинге 1.22. Рис. 1.62. Структура регистра «Сотрудники» Листинг 1.22. Пример перебора всех записей регистра ВыборкаЗаписей = РегистрыСведений.Сотрудники.Выбрать(); Пока ВыборкаЗаписей.Следующий() Цикл // Выполнить действие с очередной записью //... КонецЦикла; Хотелось бы отметить, что по умолчанию дополнительное упорядочивание записей при работе с выборкой не производится (табл. 1.16). Таблица 1.16. Пример результата работы с выборкой Физическое лицо Подразделение Должность Иванов Иван Сергеевич Семенов Сергей Петрович Семенов Сергей Петрович Петровский Семен Иванович Петровская Ирина Ивановна Отдел продаж Отдел продаж Отдел закупок Руководство компании Бухгалтерия Руководитель Менеджер Руководитель Руководитель Бухгалтер На таблице выше по сотруднику «Семенов» видно, что ссылка на отдел продаж указана раньше ссылки на отдел закупок. Хотя порядок мог быть и каким-то другим. Теперь рассмотрим задачу получения должности определенного физического лица в определенном подразделении. Это пример задачи на функцию регистра сведений. В качестве параметров передаем значения физического Глава 1. Хранение информации 89 лица и подразделения, в качестве результата функции ожидаем значение должности (листинг 1.23). Листинг 1.23. Пример получения должности физического лица // Подготовить структуру отбора по измерениям СтруктураОтбора = Новый Структура; СтруктураОтбора.Вставить("ФизическоеЛицо", ПроверяемоеЛицо); СтруктураОтбора.Вставить("Подразделение", ВыбранноеПодразделение); // Получить структуру с данными ресурсов записи СтруктураРесурсов = РегистрыСведений.Сотрудники.Получить(СтруктураОтбора); // Сообщить занимаемую должность Должность = СтруктураРесурсов.Должность; Сообщение = Новый СообщениеПользователю; Если Должность.Пустая() Тогда Сообщение.Текст = "В этом подразделении не работает"; Иначе Сообщение.Текст = Должность.Наименование; КонецЕсли; Сообщение.Сообщить(); Обратите внимание: для метода Получить() обязательна передача параметра, содержащего структуру отбора значений по всем измерениям непериодического регистра. Результатом применения метода является структура, в которой для каждого элемента ключом будет название ресурса регистра, а значением – значение ресурса из найденной записи регистра. Следующая задача – проверить, работает ли в компании определенное физическое лицо. И если работает, выполнить некоторые действия с записью по этому сотруднику. Допустим, ссылка на проверяемое физическое лицо будет в переменной ПроверяемоеЛицо. Тогда решение можно реализовать следующим образом (листинг 1.24). Листинг 1.24. Пример проверки наличия записи по физическому лицу в регистре сведений // Подготовить структуру отбора по измерению "ФизическоеЛицо" СтруктураОтбора = Новый Структура("ФизическоеЛицо", ПроверяемоеЛицо); // Получить выборку с отбором ВыборкаЗаписей = РегистрыСведений.Сотрудники.Выбрать(СтруктураОтбора); // Выполнить действия Пока ВыборкаЗаписей.Следующий() Цикл // Выполнить действия с записью //... КонецЦикла; 90 Реализация прикладных задач в системе «1С:Предприятие 8.2» В данном примере применялся отбор по значению измерения регистра. Вообще в качестве полей для отбора могут использоваться измерения или реквизиты регистра, для которых в конфигураторе установлен признак индексирования в значение Индексировать или установлен признак Ведущее. Но необходимо помнить, что отбор при этом возможен только на равенство и только по одному полю. Рассмотренные задачи также могли быть решены и посредством соответствующих запросов. Рассмотрим ряд задач, когда применение запросов более уместно, нежели применение объектной модели. Доступ к информации таблицы регистра в базе данных осуществляется посредством основной таблицы регистра сведений. Состав ее полей соответствует составу полей таблицы регистра сведений в базе данных (можно посмотреть в разделе «Структура регистра сведений» на стр. 63). Допустим, требуется сообщить наименования физических лиц, упомянутых в записях регистра сведений Сотрудники. Условие – в наименовании должностей этих лиц должно быть слово «Руководитель». Эта задача может быть решена следующим образом (листинг 1.25). Листинг 1.25. Пример получения физических лиц, в наименовании должностей которых присутствует слово «Руководитель» // Получить перечень нужных физических лиц Запрос = Новый Запрос; Запрос.Текст = "ВЫБРАТЬ РАЗЛИЧНЫЕ | Сотрудники.ФизическоеЛицо.Наименование КАК ФизЛицо |ИЗ | РегистрСведений.Сотрудники КАК Сотрудники |ГДЕ | Сотрудники.Должность.Наименование ПОДОБНО ""%Руководитель%"""; // Перебрать и сообщить полученный список Результат = Запрос.Выполнить(); Выборка = Результат.Выбрать(); Пока Выборка.Следующий() Цикл Сообщение = Новый СообщениеПользователю; Сообщение.Текст = Выборка.ФизЛицо; Сообщение.Сообщить(); КонецЦикла; Краткий комментарий: в запросе выбираем неповторяющиеся наименования всех физических лиц из таблицы регистра, если наименования должностей в этих записях содержат набор символов «Руководитель» (в любом месте наименования). Далее выборка результата запроса перебирается, и в цикле сообщается полученная информация. Глава 1. Хранение информации 91 Попытка решения этой задачи посредством выборки была бы грубой методической ошибкой: ■ Во-первых, выборка не может строиться с отбором по значениям ресурсов. То есть перебирать пришлось бы все записи регистра. ■ Во-вторых, условие отбора устанавливается не по значению поля Должность, а по наличию в наименовании этой должности сочетания символов «Руководитель». То есть такая проверка в цикле перебора записей регистра привела бы к необходимости применения запроса СУБД к таблице данных справочника Должности. И это на каждом шаге цикла! ■ В-третьих, сообщать нужно наименования физических лиц. То есть при выполнении условия проверки для каждой подходящей записи регистра системе пришлось бы еще обращаться посредством запроса СУБД к таблице справочника ФизическиеЛица для считывания наименования элемента, соответствующего нужной ссылке. Таким образом, решение посредством объектной модели привело бы к многочисленным обращениям к таблицам базы данных (на каждом шаге цикла перебора всех записей регистра). Решение же посредством запроса будет реализовано системой за счет левых соединений таблиц регистра и двух справочников, но за одно обращение к базе данных. Не говоря уже о том, что выборка результата запроса будет меньше выборки всех записей регистра. Следующая задача – сообщить, сколько подразделений компании задействовано в регистре Сотрудники. Эта задача может быть решена посредством следующего запроса (листинг 1.26). Листинг 1.26. Пример получения количества задействованных подразделений // Установить исходно, что подразделений нет КоличествоПодразделений = 0; // Посчитать количество "непустых" подразделений в записях регистра Запрос = Новый Запрос; Запрос.Текст = "ВЫБРАТЬ | КОЛИЧЕСТВО(РАЗЛИЧНЫЕ Сотрудники.Подразделение) КАК КоличествоПодразделений |ИЗ | РегистрСведений.Сотрудники КАК Сотрудники |ГДЕ | Сотрудники.Подразделение <> &ПустоеПодразделение"; Запрос.УстановитьПараметр("ПустоеПодразделение", Справочники.Подразделения.ПустаяСсылка()); Результат = Запрос.Выполнить(); Выборка = Результат.Выбрать(); Если Выборка.Следующий() Тогда КоличествоПодразделений = Выборка.КоличествоПодразделений; КонецЕсли; 92 Реализация прикладных задач в системе «1С:Предприятие 8.2» // Сообщить полученные результаты Сообщение = Новый СообщениеПользователю; Сообщение.Текст = Строка(КоличествоПодразделений); Сообщение.Сообщить(); В данном случае применен запрос, вычисляющий количество упоминаний различных подразделений в соответствующем поле записей регистра. При этом записи с незаполненным полем Подразделение не учитываются. Если выборка запроса будет непустой (есть записи), то исходное нулевое количество подразделений заменяется на определенное в запросе. В данном случае продемонстрирована возможность применения агрегатных функций (КОЛИЧЕСТВО()) при чтении информации регистра запросом. Следующая задача – получить список «внутренних совместителей» с предоставлением информации, в каких отделах, на каких должностях они работают. Внутренними совместителями называются физические лица, занимающие несколько должностей или в одном, или в различных подразделениях предприятия. Данная задача может быть решена посредством применения запроса со следующим текстом (листинг 1.27). Листинг 1.27. Пример получения списка внутренних совместителей Запрос = Новый Запрос; Запрос.Текст = "ВЫБРАТЬ | Сотрудники.ФизическоеЛицо.Наименование КАК ФизЛицо, | Сотрудники.Подразделение КАК Подразделение, | Сотрудники.Должность КАК Должность |ИЗ | РегистрСведений.Сотрудники КАК Сотрудники |ГДЕ | Сотрудники.ФизическоеЛицо В | (ВЫБРАТЬ | Сотрудники.ФизическоеЛицо КАК ФизЛицо | ИЗ | РегистрСведений.Сотрудники КАК Сотрудники | СГРУППИРОВАТЬ ПО | Сотрудники.ФизическоеЛицо | ИМЕЮЩИЕ | КОЛИЧЕСТВО(Сотрудники.ФизическоеЛицо) > 1)"; Результат = Запрос.Выполнить(); Выборка = Результат.Выбрать(); Пока Выборка.Следующий() Цикл Сообщение = Новый СообщениеПользователю; Сообщение.Текст = Выборка.ФизЛицо + " " + Выборка.Подразделение + " " + Выборка.Должность; Сообщение.Сообщить(); КонецЦикла; Глава 1. Хранение информации 93 В запросе выбирается информация по всем записям регистра, где упоминаются физические лица, соответствующие условию. Условие проверяет вхождения физических лиц в перечень, полученный вложенным запросом. Во вложенном запросе применяется группирование с применением агрегатной функции КОЛИЧЕСТВО() по полю ФизическоеЛицо, при этом условием будут отсечены те физлица, которые упоминались только один раз. Получение данных из периодических регистров сведений Для периодических регистров сведений задачи получения информации для технологических вопросов решаются так же, как и было рассмотрено выше для непериодических регистров. Поэтому все примеры, рассмотренные в разделе «Получение данных из непериодических регистров сведений» (см. стр. 87), будут уместны и в этом случае. Единственное отличие в том, что к перечню ключевых полей добавляется поле Период, которое можно использовать в отборах. Так, метод Выбрать() для случая периодического регистра позволяет работать не только с отбором по значению измерения, но и с отбором по временному интервалу, в который могут попадать значения поля Период. Рассмотрим примеры получения информации из периодического (периодичность – В пределах дня) независимого регистра сведений ПерсонифицированныйПрайс (рис. 1.63). Рис. 1.63. Структура регистра «ПерсонифицированныйПрайс» Для получения выборки всех записей регистра в интервале дат между значениями, содержащимися в переменных НачалоИнтервала и КонецИнтервала, с отбором по номенклатурной позиции (содержится в переменной ВыбранныйТовар) можно использовать следующий фрагмент кода (листинг 1.28). Листинг 1.28. Пример получения записей периодического регистра сведений // Подготовить структуру отбора по измерению "Номенклатура" СтруктураОтбора = Новый Структура("Номенклатура", ВыбранныйТовар); // Получить выборку записей ВыборкаЗаписей = РегистрыСведений.ПерсонифицированныйПрайс.Выбрать(НачалоИнтервала, КонецИнтервала, СтруктураОтбора); 94 Реализация прикладных задач в системе «1С:Предприятие 8.2» Пока ВыборкаЗаписей.Следующий() Цикл // Выполнить действие с очередной записью //... КонецЦикла; Необходимо помнить, что отбор при этом возможен только по одному полю и в качестве полей для отбора могут использоваться измерения или реквизиты регистра, для которых в конфигураторе установлен признак индексирования в значение Индексировать или установлен признак Ведущее. Кроме того, для реализации необходимости включения/выключения записей «граничных периодов» нужно иметь в виду следующее: ■ В параметр НачалоИнтервала передается начало интервала, в котором будут выбираться записи периодического регистра. Он может задаваться значениями типа Дата, МоментВремени, Граница. Если значение данного параметра не указано, то будут выбираться записи с самой ранней включительно. ■ В параметр КонецИнтервала передается конец интервала, в котором будут выбираться записи периодического регистра. Он также может задаваться значениями типа Дата, МоментВремени, Граница. Если значение данного параметра не указано, то будут выбираться записи по самую последнюю включительно. В результате при передаче значений типа Дата или МоментВремени в выборку получим записи, включая значения НачалоИнтервала и КонецИнтервала (рис. 1.64). Рис. 1.64. Получение записей, включая граничные значения Если же требуется получить записи, исключая граничные, то необходимо использовать объект Граница. Например, получение выборки в интервале дат, исключая границы, может быть выполнено следующим образом (листинг 1.29). Глава 1. Хранение информации 95 Листинг 1.29. Пример получения записей регистра сведений // Установить значения границ ГраницаНачалаИнтервала = Новый Граница(НачалоИнтервала, ВидГраницы.Исключая); ГраницаКонцаИнтервала = Новый Граница(КонецИнтервала, ВидГраницы.Исключая); // Подготовить структуру отбора по измерению "Номенклатура" СтруктураОтбора = Новый Структура("Номенклатура", ВыбранныйТовар); // Получить выборку записей ВыборкаЗаписей = РегистрыСведений.ПерсонифицированныйПрайс.Выбрать(ГраницаНачалаИнтервала, ГраницаКонцаИнтервала, СтруктураОтбора); Пока ВыборкаЗаписей.Следующий() Цикл // Выполнить действие с очередной записью //... КонецЦикла; Получение данных в этом случае можно проиллюстрировать следующей схемой (рис. 1.65). Рис. 1.65. Получение записей, исключая граничные значения Кроме того, если периодичность регистра меньше чем день (В пределах секунды или По позиции регистратора), то необходимо помнить, что дата в системе «1С:Предприятие» включает в себя и время. Даже если время не указано явно, оно принимает значение 00:00:00. То есть если в качестве параметра НачалоИнтервала передать значение «1 декабря 2009 года» (данное значение может быть получено так: '20091201'), а в качестве параметра КонецИнтервала передать «31 декабря 2009 года» ('20091231'), то в результате выборка будет построена с даты «01.12.2009 00:00:00» по дату «31.12.2009 00:00:00». То есть в результат, по сути, не войдут данные 31 декабря (рис. 1.66). Для предотвращения возможных недоразумений по этому поводу удобно использовать функцию КонецДня(). Эта функция возвращает значение последней секунды дня указанной в качестве параметра даты (листинг 1.30). 96 Реализация прикладных задач в системе «1С:Предприятие 8.2» Рис. 1.66. Пример получения данных регистра сведений, когда интервал задан без явного указания времени Листинг 1.30. Пример использования функции «КонецДня()» // Определить конец дня "правой" границы КонецДняИнтервала = КонецДня(КонецИнтервала); // Получить выборку записей ВыборкаЗаписей = РегистрыСведений.ЦеныНоменклатуры.Выбрать(НачалоИнтервала,КонецДняИнтервала); Пока ВыборкаЗаписей.Следующий() Цикл // Выполнить действие с очередной записью //... КонецЦикла; В результате будут получены записи с даты «01.12.2009 00:00:00» по дату «31.12.2009 23:59:59» включительно. При использовании запроса можно реализовывать не только перечисленные выше, но и гораздо более сложные условия, в том числе и по полю Период. Например, задача получения выборки данных всех записей регистра ПерсонифицированныйПрайс, которые датированы выходными днями (субботами и воскресениями), может быть решена посредством следующего запроса (листинг 1.31). Листинг 1.31. Пример запроса ВЫБРАТЬ ПерсонифицированныйПрайс.Период, ПерсонифицированныйПрайс.Покупатель, ПерсонифицированныйПрайс.Номенклатура, ПерсонифицированныйПрайс.Цена ИЗ РегистрСведений.ПерсонифицированныйПрайс КАК ПерсонифицированныйПрайс ГДЕ ДЕНЬНЕДЕЛИ(ПерсонифицированныйПрайс.Период) > 5 Глава 1. Хранение информации 97 В запросе было применено условие с использованием функции работы с датами языка запросов – ДЕНЬНЕДЕЛИ(). Данная функция возвращает порядковые номера дней недели по переданному параметру. Рассмотрим примеры задач получения информации из периодического регистра сведений не в технологических целях, а для обслуживания задач учетных или аналитических механизмов. Если необходимо получить информацию значений ресурсов одной записи регистра, соответствующей указанным в параметрах значениям всех измерений и периода, объектная модель получения информации также позволяет использовать метод Получить(). Например, нужно сообщить, какую цену установили для покупателя Покупатель по номенклатурной позиции Товар, начиная с ДатаУстановки (листинг 1.32). Листинг 1.32. Пример получения цен по номенклатурной позиции // Подготовить структуру отбора по измерениям СтруктураОтбора = Новый Структура; СтруктураОтбора.Вставить("Покупатель", Покупатель); СтруктураОтбора.Вставить("Номенклатура", Товар); // Получить структуру с данными ресурсов записи СтруктураРесурсов = РегистрыСведений.ПерсонифицированныйПрайс.Получить(ДатаУстановки, СтруктураОтбора); // Сообщить цену Сообщение = Новый СообщениеПользователю; Сообщение.Текст = Строка(СтруктураРесурсов.Цена); Сообщение.Сообщить(); Часто встречаются задачи, в которых каждая запись периодического регистра сведений используется не как средство для хранения данных, а как средство для хранения информации истории изменения данных. Ведь в рассмотренном выше примере, если цена на товар для этого покупателя была установлена не на эту дату, а на какую-то другую, метод Получить() вернет структуру с пустыми значениями (рис. 1.67). С прикладной точки зрения в ситуации, отображенной на схеме, при обращении к данным регистра пользователь, скорее всего, хотел получить актуальное для 12.10.2009 значение цены, а не установленное 12.10.2009. То есть в логике пользователя как само собой разумеющееся может лежать правило: «пока цена не сменилась, действует прежняя». И при обращении к данным регистра пользователь желает получить цену, установленную на некую дату, а если не установлена, то прежнюю, в общем случае – последнюю установленную. 98 Реализация прикладных задач в системе «1С:Предприятие 8.2» Рис. 1.67. Пример использования метода «Получить()» для периодического регистра сведений Для реализации подобной логики в функциональности периодического регистра сведений существует метод ПолучитьПоследнее(). Для тех же переменных получение последних актуальных данных может быть таким (листинг 1.33). Листинг 1.33. Пример использования метода «ПолучитьПоследнее()» // Подготовить структуру отбора по измерениям СтруктураОтбора = Новый Структура; СтруктураОтбора.Вставить("Покупатель", Покупатель); СтруктураОтбора.Вставить("Номенклатура", Товар); // Получить структуру с данными актуальных значений ресурсов СтруктураРесурсов = РегистрыСведений.ПерсонифицированныйПрайс .ПолучитьПоследнее(ДатаУстановки, СтруктураОтбора); // Сообщить "последнюю" цену Сообщение = Новый СообщениеПользователю; Сообщение.Текст = Строка(СтруктураРесурсов.Цена); Сообщение.Сообщить(); В результате получим желаемый результат (рис. 1.68). Может встретиться задача, когда пользователь заранее не знает, для каких комбинаций значений измерений ему требуется получить данные последних актуальных (на дату КонецПериода) значений ресурсов регистра. То есть хочет получить все значения для всех комбинаций измерений (или для некоторых, соответствующих условиям отбора), рис. 1.69. Глава 1. Хранение информации 99 Рис. 1.68. Пример использования метода «ПолучитьПоследнее()» Рис. 1.69. Задача получения последних значений по комбинации значений измерений Для решения подобных задач можно использовать метод СрезПоследних(), возвращающий таблицу значений, заполненную данными записей, наиболее поздних, ближайших к дате среза (КонецПериода), табл. 1.17. Таблица 1.17. Результат получения среза последних Покупатель Номенклатура Цена ООО «Сигма» Пульт VX 120,00 ООО «Сигма» Пульт PW 218,00 Ялта-ЛТД Пульт VX 135,00 100 Реализация прикладных задач в системе «1С:Предприятие 8.2» В ходе выполнения метода СрезПоследних() платформа «1С:Предприятие» фактически выполняет запрос к базе данных. Данный запрос реализует следующий алгоритм: ■ Выбрать записи таблицы регистра, соответствующие условиям отбора по значениям измерений, у которых значение поля Период меньше или равно значению параметра КонецПериода. ■ По выбранным записям получить максимальные значения поля Период для каждой комбинации значений полей измерений. Это будут данные вложенного запроса. Получается, что в нем известны ключи последних актуальных записей, то есть наиболее близких к дате среза. ■ Соединить таблицу вложенного запроса с основной таблицей регистра по равенству значений полей измерений и поля Период. ■ Из полученной таблицы получить интересующие данные последних актуальных записей. Подобную функциональность можно реализовать запросом по основной таблице периодического регистра сведений (листинг 1.34). Листинг 1.34. Пример получения среза последних запросом ВЫБРАТЬ ПерсонифицированныйПрайс.Покупатель, ПерсонифицированныйПрайс.Номенклатура, ПерсонифицированныйПрайс.Цена ИЗ (ВЫБРАТЬ ПерсонифицированныйПрайс.Покупатель КАК Покупатель, ПерсонифицированныйПрайс.Номенклатура КАК Номенклатура, МАКСИМУМ(ПерсонифицированныйПрайс.Период) КАК Период ИЗ РегистрСведений.ПерсонифицированныйПрайс КАК ПерсонифицированныйПрайс ГДЕ ПерсонифицированныйПрайс.Период <= &КонецПериода // Указать другие условия отбора при необходимости СГРУППИРОВАТЬ ПО ПерсонифицированныйПрайс.Покупатель, ПерсонифицированныйПрайс.Номенклатура) КАК ВложенныйЗапрос ВНУТРЕННЕЕ СОЕДИНЕНИЕ РегистрСведений.ПерсонифицированныйПрайс КАК ПерсонифицированныйПрайс ПО ВложенныйЗапрос.Покупатель = ПерсонифицированныйПрайс.Покупатель И ВложенныйЗапрос.Номенклатура = ПерсонифицированныйПрайс.Номенклатура И ВложенныйЗапрос.Период = ПерсонифицированныйПрайс.Период Поскольку задачи получения среза последних встречаются достаточно часто, система «1С:Предприятие» позволяет использовать виртуальную таблицу получения среза последних, которая реализует описанный выше алгоритм. Глава 1. Хранение информации 101 То есть вместо использования запроса по основной таблице регистра разработчик для получения среза может воспользоваться запросом, например, следующего вида (листинг 1.35). Как видите, текст запроса значительно проще. Листинг 1.35. Пример использования виртуальной таблицы «СрезПоследних» ВЫБРАТЬ СрезЦен.Покупатель, СрезЦен.Номенклатура, СрезЦен.Цена ИЗ РегистрСведений.ПерсонифицированныйПрайс.СрезПоследних(&КонецПериода, ) КАК СрезЦен Таким образом, за счет использования виртуальных таблиц разработчик работает сразу с производными данными, необходимыми для решения прикладных задач. А тонкости организации оптимального получения этих данных обеспечиваются системой. Что же за данные можно получить посредством виртуальной таблицы среза последних? Практически все, которые касаются записей. Виртуальная таблица СрезПоследних содержит следующие поля: ■ ■ ■ ■ ■ ■ Период – это поле имеет тип Дата. Содержит период, к которому отно- сится запись регистра. Регистратор – это поле имеет тип ДокументСсылка.<имя>. Существует только в случаях, если периодичность регистра – По позиции регистратора. Данное поле содержит ссылку на документ-регистратор, к которому относится запись регистра. НомерСтроки – это поле имеет тип Число. Существует только в случаях, если периодичность регистра – По позиции регистратора. Содержит значение поля НомерСтроки записи движения регистра. Активность – это поле имеет тип Булево. Существует только в случаях, если периодичность регистра – По позиции регистратора. Содержит признак активности записи, то есть влияния на получение среза последних (или среза первых). <Измерение> – тип значения этого поля определяется типом измерения. Каждое из таких полей содержит значение измерения регистра. Имена полей совпадают с именами измерений, заданными для объекта конфигурации. <Ресурс> – тип значения этого поля определяется типом ресурса. Каждое из таких полей содержит значение ресурса регистра. Имена полей совпадают с именами ресурсов, заданными для объекта конфигурации. 102 ■ Реализация прикладных задач в системе «1С:Предприятие 8.2» <Реквизит> – тип значения этого поля определяется типом реквизита. Каждое из таких полей содержит значение реквизита регистра. Имена полей совпадают с именами реквизитов, заданными для объекта конфигурации. Виртуальная таблица среза последних не хранится в базе данных, а строится в момент обращения к ней. Поэтому при использовании ее в запросах поддерживается весьма гибкая функциональность за счет использования параметров: ■ Дата – имеет тип Дата, МоментВремени или Граница. Если параметр не задан, будут выбираться наиболее поздние записи, то есть без ограничения по времени. ■ Условие – содержит конструкцию языка запросов – условие. Строится по любым полям регистра сведений (или подчиненным им полям). Используется для ограничения состава исходных записей, по которым при построении виртуальной таблицы будет выполняться срез. Если параметр не указан, будут использоваться все активные записи регистра. Например, соответствующее применение условий в запросах с использованием виртуальных таблиц позволяет легко решать задачи отбора информации так, как это потребуется. Рассмотрим несколько примеров для периодического регистра сведений ЦеныНоменклатуры (рис. 1.70). Рис. 1.70. Структура регистра «ЦеныНоменклатуры» Рассмотрим следующую задачу: требуется получить информацию о том, по каким товарам на текущий момент есть цены ниже 100, кто за это ответственен, и когда он установил такую цену. Задача может быть решена следующим образом (листинг 1.36). Глава 1. Хранение информации 103 Листинг 1.36. Пример получения данных из периодического регистра сведений ВЫБРАТЬ ЦеныНоменклатурыСрезПоследних.Период, ЦеныНоменклатурыСрезПоследних.Номенклатура, ЦеныНоменклатурыСрезПоследних.ТипЦены, ЦеныНоменклатурыСрезПоследних.Цена, ЦеныНоменклатурыСрезПоследних.Ответственный ИЗ РегистрСведений.ЦеныНоменклатуры.СрезПоследних КАК ЦеныНоменклатурыСрезПоследних ГДЕ ЦеныНоменклатурыСрезПоследних.Цена < 100 Обратите внимание: в постановке задачи акцент ставился на текущие цены. Поэтому в запросе сначала выполняется срез последних, а потом в таблице среза определяются записи, в которых цена ниже 100. То есть если когда-то на какой-то товар была низкая цена, но на текущий момент положение исправлено (установлена цена выше 100), то «никого за это наказывать не будем». Рассмотрим другую задачу: требуется получить информацию, по каким товарам вообще когда-нибудь устанавливались цены ниже 100, кто ответственен за последние назначения таких цен, и когда они выполнялись. Возможно следующее решение (листинг 1.37). Листинг 1.37. Пример получения данных из регистра сведений ВЫБРАТЬ ЦеныНоменклатурыСрезПоследних.Период, ЦеныНоменклатурыСрезПоследних.Номенклатура, ЦеныНоменклатурыСрезПоследних.ТипЦены, ЦеныНоменклатурыСрезПоследних.Цена, ЦеныНоменклатурыСрезПоследних.Ответственный ИЗ РегистрСведений.ЦеныНоменклатуры.СрезПоследних(, Цена < 100) КАК ЦеныНоменклатурыСрезПоследних В данном случае акцент сделан на записях регистра, в которых цена ниже 100. А вот уже для записей, соответствующих этому условию, будет произведен срез последних. То есть в данном случае отвечать будет последний, кто устанавливал низкие цены, даже если на текущий момент цена на этот товар уже совсем другая. Рассмотренная выше функциональность получения среза последних для периодического регистра, но только уже «с другим знаком», легко получается за счет применения методов ПолучитьПервое(), СрезПервых() и виртуальной таблицы СрезПервых. Для таких задач важны данные записей, соответствующих точке среза, или первых следующих после нее в истории изменения информации регистра. 104 Реализация прикладных задач в системе «1С:Предприятие 8.2» Например, для ситуации, когда нужны данные по конкретной комбинации значений измерений (рис. 1.71). Рис. 1.71. Получение первых данных по комбинации значений измерений Также возможна ситуация, когда нужны данные среза всех первых следующих записей регистра (рис. 1.72). Рис. 1.72. Получение среза первых По аналогии с работой в отношении получения последних актуальных приемы получения первых следующих абсолютно те же, только меняются название методов и виртуальной таблицы. Задача получения первых следующих записей заключается в том, чтобы найти записи с минимальным периодом среди тех записей, период которых равен или больше, чем указываемый параметр среза. Соответственно, если параметр среза (НачалоПериода или Дата) не указан, срез будет производиться по значению даты по умолчанию, то есть «01.01.01 00:00:00». А значит, в срез попадут самые первые по хронологии записи таблицы регистра. Глава 1. Хранение информации 105 Особенности получения данных из регистров сведений с режимом записи «Подчинение регистратору» Установка режима записи Подчинение регистратору означает добавление к физической таблице регистра сведений в базе данных ряда предопределенных полей: ■ Регистратор, ■ НомерСтроки, ■ Активность. Кроме того, как было рассмотрено выше, для таких регистров невозможно наличие записей без ссылки на документ-регистратор. Данные особенности играют свою роль при получении информации из регистра. Для быстрого получения информации наборов записей, подчиненных некоему регистратору, имеются возможности использования объектной модели представления данных – метод ВыбратьПоРегистратору(). Например, если ссылка на нужный документ хранится в переменной ДокументРегистратор, то получить записи регистра можно с помощью следующего кода (листинг 1.38). Листинг 1.38. Пример получения данных из регистра сведений, подчиненного регистратору ВыборкаДвиженийДокумента = РегистрыСведений.ЦеныНоменклатуры .ВыбратьПоРегистратору(ДокументРегистратор); Пока ВыборкаДвиженийДокумента.Следующий() Цикл // Выполнить действие с очередной записью движения //... КонецЦикла; Аналогичного результата можно добиться, используя соответствующий отбор в запросе (листинг 1.39). Листинг 1.39. Пример получения данных регистра сведений запросом Запрос = Новый Запрос; Запрос.Текст = " |ВЫБРАТЬ | * |ИЗ | РегистрСведений.ЦеныНоменклатуры КАК ЦеныНоменклатуры |ГДЕ | ЦеныНоменклатуры.Регистратор = &РегистраторОтбора"; Запрос.УстановитьПараметр("РегистраторОтбора", ДокументРегистратор); Результат = Запрос.Выполнить(); 106 Реализация прикладных задач в системе «1С:Предприятие 8.2» Выборка = Результат.Выбрать(); Пока Выборка.Следующий() Цикл // Выполнить действие с очередной записью движения //... КонецЦикла; В ряде задач может оказаться полезным использование полей Активность и НомерСтроки. Например, рассмотрим задачу получения перечня «длинных» документов (которым, например, подчинено более 100 записей в движениях по регистру). Данная задача может быть решена посредством применения следующего запроса (листинг 1.40). Листинг 1.40. Пример получения данных из регистра сведений ВЫБРАТЬ РАЗЛИЧНЫЕ ЦеныНоменклатуры.Регистратор ИЗ РегистрСведений.ЦеныНоменклатуры КАК ЦеныНоменклатуры ГДЕ ЦеныНоменклатуры.НомерСтроки > 100 Рассмотрим другую задачу: требуется получить перечень документов с неактивными записями. Эта задача может быть решена посредством следующего запроса (листинг 1.41). Листинг 1.41. Пример получения данных регистра сведений ВЫБРАТЬ РАЗЛИЧНЫЕ ЦеныНоменклатуры.Регистратор ИЗ РегистрСведений.ЦеныНоменклатуры КАК ЦеныНоменклатуры ГДЕ (НЕ ЦеныНоменклатуры.Активность) Важно помнить, что для получения срезов первых и срезов последних система использует только те записи, поле Активность которых имеет значение Истина. Снять или установить активность можно только для всех записей набора записей, подчиненных некоему регистратору. Таким образом, реализуется прикладная задача: при необходимости можно сделать документ «неиграющим» без удаления его движений. Но поскольку документ с прикладной точки зрения – это регистрация события, то отключение влияния события может выполняться только полностью для всех записей, принадлежащих данному документу. Глава 1. Хранение информации 107 В остальном примеры и возможности получения данных из регистра сведений, описанные в разделах «Получение данных из непериодических регистров сведений» (см. стр. 87) и «Получение данных из периодических регистров сведений» (см. стр. 93), вполне применимы и для регистров сведений, подчиненных регистратору. Проектирование структуры регистров сведений Как было рассмотрено ранее, регистр сведений может содержать несколько измерений, ресурсов и реквизитов. Зачастую у разработчиков при проектировании прикладных решений возникает вопрос: «Что лучше? Создать несколько регистров с большим количеством ресурсов или, наоборот, создать много регистров, но с меньшим количеством ресурсов?». В общем случае единого ответа на этот вопрос нет. Для того чтобы облегчить принятие решения в каждой конкретной ситуации, приведем несколько моментов, на которые следует обращать внимание при проектировании регистров сведений. Структурный подход. Каждая запись в регистре сведений содержит информацию о том, что для данной комбинации ключевых полей установлены некоторые значения ресурсов. В том числе и в периодическом регистре сведений. То есть если запись добавляется или модифицируется, это выполняется для всех значений ресурсов. Нельзя отметить, что, начиная с такого-то момента, значение такого-то ресурса не меняется, а меняются только значения других ресурсов. Восприятие пользователем. При проектировании регистра важно проанализировать, как реально меняются значения данных, которые будут храниться в регистре, и выработать определенную модель отражения этих изменений в базе данных. Важно, чтобы отражение предметной области в регистре правильно воспринималось пользователем. Например, при хранении информации о курсах валют приходится иметь дело с информацией о курсе и кратности каждой валюты (24 рубля за 100 японских йен – курс 24, кратность 100). Курс Центробанка меняется ежедневно, кратность… ну, наверное, один раз в несколько десятков лет. То есть если исходить из «накладных затрат» на выполнение операций с этой информацией в регистре, то напрашивается решение о разделении ее на два регистра: КурсыВалют и КратностиВалют. Однако с точки зрения восприятия информации пользователем, данные о курсе отдельно от данных о кратности – это нонсенс. Ну а поскольку работать с курсом и кратностью всегда придется одновременно, то проще реализовать задачу одним регистром с двумя ресурсами. 108 Реализация прикладных задач в системе «1С:Предприятие 8.2» Учет потенциальных модификаций состава регистра. Как обсуждалось выше, состав существующего регистра сведений всегда можно расширить. Одним из направлений расширения является ввод новых разрезов информации, то есть измерений. Например, принимая решение по добавлению ресурса ПредпочитаемыйЦвет, в котором будет содержаться информация о том, какого цвета товары предпочитает покупатель, для регистра ПерсонифицированныйПрайс (рис. 1.73) желательно заранее уточнить, а не потребуется ли впоследствии добавить к такому регистру измерение Договор для более детального учета обещанных покупателю отпускных цен. Рис. 1.73. Структура регистра «ПерсонифицированныйПрайс» Если потребуется, то лучше будет все же разделить информацию между несколькими регистрами. В одном будет храниться информация о какихто качественных пожеланиях покупателей, в другом – информация о ценах с другим уровнем детализации. Время получения данных, необходимых для работы механизмов решения. Например, при работе некоторого механизма важно получать данные объекта и данные, связанные с данным объектом. Очевидно, что получение этих связанных данных из нескольких ресурсов одного регистра (одной таблицы) будет происходить в общем случае быстрее, нежели получение этих данных из нескольких регистров (нескольких таблиц). Время записи информации в базу данных. Запись в несколько регистров сведений в общем случае будет выполняться медленнее, нежели запись одной записи с несколькими ресурсами. «Слабое звено». Если данные одного из ресурсов нужно модифицировать очень часто, то объем базы будет расти существеннее, если в составе регистра много ресурсов. Особенно, если какой-нибудь из ресурсов будет являться хранилищем значений, в котором будет храниться картинка или бинарные данные. Такие данные вообще целесообразнее выделять в отдельный регистр. Глава 1. Хранение информации 109 Хранение дополнительных характеристик Один из часто встречающихся вопросов хранения информации – это вопрос организации хранения значений характеристик, набор которых заранее неизвестен. Таким образом, при разработке прикладного решения нет возможности создать заранее набор реквизитов объекта. Кроме этого, велика вероятность, что конкретные характеристики будут использоваться не для всех объектов, а только для некоторого ограниченного их количества. Например, для некоторых элементов справочника Номенклатура может потребоваться хранить информацию об их цвете, мощности, габаритах (для бытовой техники); для других же – о размере, росте, материале и опять же о цвете (одежда); для третьих подобная информация вообще не имеет смысла (услуги). При этом не исключена вероятность, что автоматизируемая компания станет попутно торговать еще мобильными телефонами, что потребует наличия ряда специфичных характеристик номенклатуры, таких как поддерживаемые стандарты обмена информацией, наличие цифровой камеры, тип батареи и т. д. Классическая реляционная модель предполагает, что для хранения какой-либо информации в базе данных в таблице заводится колонка (поле) с определенным типом и именем. То есть введение реквизитов является естественным способом решения подобной задачи. Однако в рассматриваемом случае подобное решение является неэффективным и зачастую неприемлемым с точки зрения требований, предъявляемых заказчиком. Неэффективность решения «в лоб» заключается в том, что подавляющее большинство характеристик используются лишь для небольшого, ограниченного количества элементов справочника Номенклатура. Это означает, что, вводя для каждой характеристики отдельный реквизит, мы тем самым необоснованно увеличиваем объем хранимой информации. В самом деле, создав реквизит Размер (тип Число), мы добавили в физическую таблицу справочника Номенклатура новую колонку. Но эта колонка будет хранить «содержательные» данные только для элементов справочника из группы Одежда (которых, например, 100–150 штук). Если при этом общее количество элементов в справочнике Номенклатура будет равняться 10–15 тысячам, значит, практически для всех элементов справочника в этой колонке будет содержаться значение 0, т. к. данная характеристика для них не имеет смысла. С практической точки зрения создание реквизитов для хранения значений характеристик в большинстве случаев может быть неприемлемо потому, что добавление нового реквизита возможно только в режиме работы Конфигуратор. В реальной ситуации, как правило, необходимо создавать новые характеристики непосредственно в процессе работы, в режиме 1С:Предприятие. 110 Реализация прикладных задач в системе «1С:Предприятие 8.2» Таким образом, путь ввода новых реквизитов может оказаться слишком «затратным» во всех смыслах. В данном разделе мы рассмотрим возможные варианты решения задач динамического дополнения состава информации, характеризующей объекты. Хранение дополнительных характеристик . определенного типа Рассмотрение задачи хранения дополнительных характеристик начнем с простого примера, когда все дополнительные характеристики, вводимые пользователем, имеют один и тот же тип значения. Допустим, необходимо организовать хранение дополнительной информации о контрагентах: ■ кто из них относится к нерезидентам (зарубежные контрагенты); ■ с кем из них можно торговать в кредит; ■ кто относится к категории постоянных покупателей; ■ и так далее. Другими словами, необходимо обеспечить возможность ввода и хранения следующих характеристик контрагентов: ■ ■ ■ Резидент (тип Булево – Истина, Ложь); ПостоянныйПокупатель (тип Булево – Истина, Ложь); <новая характеристика> (тип Булево – Истина, Ложь). Как было рассмотрено выше, вариант с булевыми реквизитами Резидент, ПостоянныйПокупатель и т. п. слишком «затратен» и неудобен. Один из вариантов решения этой задачи приведен в демонстрационной конфигурации «Хранение информации и учет движения средств», которая находится на прилагаемом компакт-диске. Это использование справочника Категории для хранения видов характеристик и регистра сведений КатегорииКонтрагентов для хранения соответствия конкретной характеристики конкретному контрагенту (рис. 1.74). Рис. 1.74. Структура регистра «КатегорииКонтрагентов» Глава 1. Хранение информации 111 Тип значения измерения Контрагент – СправочникСсылка.Контрагенты. Тип значения измерения Категория – СправочникСсылка.Категории. Использование справочника Категории как объекта для хранения классификатора категорий позволяет предоставить пользователям возможности динамической модификации этой информации. То есть ввод новой характеристики (категории) не требует помощи разработчика. Далее обратите внимание: в составе регистра нет ресурсов. Хотя, как описано в разделе «Хранение информации в регистрах сведений» на стр. 54, именно посредством ресурсов организуется хранение информации в регистрах сведений. Дело в том, что комбинации значений измерений обеспечивают уникальность каждой записи регистра, а наличие самой записи, по сути, и является информацией. Ведь по каждой комбинации Контрагент – Категория необходимо обеспечить хранение информации булевого типа. Если Истина, значит, контрагент относится к этой категории. Это в нашем случае реализовано просто наличием записи. Ну а значение Ложь в нашем случае будет реализовано отсутствием записи. Итак, общую схему хранения дополнительных характеристик контрагентов можно представить следующим образом (рис. 1.75). Рис. 1.75. Общая схема хранения дополнительных характеристик Дальнейшее использование этой информации в учетных или аналитических механизмах прикладного решения можно будет реализовывать посредством, например, соединений с информацией регистра. Так, в составе демонстрационной конфигурации «Хранение информации и учет движения средств», которая находится на прилагаемом компакт-диске, есть отчет ПродажиКонтрагентовИмеющихКатегорию, в котором пользователь может применять отборы по категориям контрагентов (рис. 1.76). 112 Реализация прикладных задач в системе «1С:Предприятие 8.2» Рис. 1.76. Отчет продажи контрагентов, имеющих категорию Сам отчет формируется при помощи системы компоновки данных. В схеме компоновки данных отчета создан набор данных – запрос, которому передается следующий текст запроса (листинг 1.42). Листинг 1.42. Пример запроса, используемого при формировании отчета ВЫБРАТЬ ПродажиОбороты.Номенклатура КАК Номенклатура, ПродажиОбороты.Контрагент КАК Контрагент, ПродажиОбороты.КоличествоОборот КАК КоличествоОборот, ПродажиОбороты.СуммаОборот КАК СуммаОборот ИЗ (ВЫБРАТЬ РАЗЛИЧНЫЕ КатегорииКонтрагентов.Контрагент КАК Контрагент ИЗ РегистрСведений.КатегорииКонтрагентов КАК КатегорииКонтрагентов {ГДЕ КатегорииКонтрагентов.Категория.*}) КАК ВложенныйЗапрос ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.Продажи.Обороты(&НачалоПериода, &КонецПериода, , ) КАК ПродажиОбороты ПО ВложенныйЗапрос.Контрагент = ПродажиОбороты.Контрагент Глава 1. Хранение информации 113 Краткий комментарий: условие отбора контрагентов по категориям реализуется во вложенном запросе по регистру сведений за счет использования языка запросов системой компоновки данных (инструкции, заключенные в {…}). Благодаря этому, вопрос организации отбора по категории берет на себя система компоновки данных. То есть пользователь сможет при необходимости обойтись вообще без отбора (тогда в отчет попадут все контрагенты из регистра сведений КатегорииКонтрагентов), организовать отбор по одной категории, по списку категорий, по всем категориям, кроме выбранных, и так далее. Реализация этой функциональности не требует усилий разработчика. Далее таблица неповторяющихся контрагентов, полученных во вложенном запросе, соединяется с таблицей оборотов регистра Продажи. Затем средствами системы компоновки данных, в соответствии с настройками и структурой отчета, заданными разработчиком в схеме компоновки данных, отчет компонуется и выводится пользователю. В форме отчета пользователь может изменить отчетный период, настроить отбор, сортировку и условное оформление отчета по своему желанию и переформировать отчет. Здесь мы рассмотрели вариант отображения и отбора контрагентов с установленными категориями в отчете. От разработчика требовалось по крайней мере сформировать текст запроса. Но ряд функциональных вопросов в таком решении платформа может взять на себя полностью. Так, если установить для измерений регистра КатегорииКонтрагентов свойство Ведущее, то пользователь при необходимости сможет быстро получать форму списка регистра с отбором по соответствующим значениям из форм справочников (рис. 1.77). Рис. 1.77. Использование команды перехода к списку регистра «Категории контрагентов» в панели навигации формы элемента справочника «Контрагенты» 114 Реализация прикладных задач в системе «1С:Предприятие 8.2» Кроме того, при удалении объектов, с которыми связаны записи регистра, система будет автоматически удалять такие записи. Это описано в разделе «Дополнительная функциональность при создании и удалении записей регистра сведений» на стр. 84. Хранение дополнительных характеристик . произвольного типа Рассмотрим теперь более сложную и более распространенную задачу, когда все дополнительные характеристики, вводимые пользователем, имеют произвольный тип значения. Допустим, необходимо организовать хранение дополнительных характеристик номенклатурных позиций. При этом для ряда товаров необходимо организовать хранение информации о весе, для некоторых товаров – о цвете, для некоторых – об области применения и так далее. Пример решения данной задачи с использованием регистра сведений имеет право на жизнь. Однако, в отличие от рассмотренной в предыдущем разделе («Хранение дополнительных характеристик определенного типа») ситуации, здесь будем иметь дело с информацией уже не булевого, а произвольного, заранее неизвестного типа. То есть в регистре потребуется использование поля ресурса ЗначениеХарактеристики. При попытке реализации данного регистра в конфигурации встанет один существенный вопрос: какой тип значения должен быть у ресурса ЗначениеХарактеристики? Действительно, характеристики будут иметь не только разный смысл, но и различные типы значений. Получается, что для ввода произвольных данных в поле ресурса тип значения последнего должен быть составным и включать в себя все возможные типы значений. Но для каждой характеристики тип значения должен быть персональным, чтобы не получилось, что пользователь может ввести цвет «01.01.2010 г.», а потом пытаться понять, как с этим работать. Использование плана видов характеристик для хранения видов характеристик Для решения задачи хранения информации о соответствии видов характеристик и типов их значений в составе конфигурации следует использовать объект План видов характеристик. План видов характеристик по своему устройству очень похож на справочник. Он поддерживает работу пользователей с видами характеристик («элемен- Глава 1. Хранение информации 115 тами») и списками видов характеристик, может поддерживать иерархию, может включать в состав своих объектов реквизиты и табличные части, возможно использование предопределенных видов характеристик, заданных разработчиком. Однако самой важной особенностью объектов планов видов характеристик, отличающей их от других объектов, является использование свойства Тип значения. Это свойство позволяет определить список возможных типов данных, используемых для отдельных видов характеристик (то есть для каждого элемента плана видов характеристик), рис. 1.78. Рис. 1.78. Тип значения вида характеристики То есть для вида характеристики Цвет можно определить тип значения СправочникСсылка.Цвета, для вида характеристики Год выпуска – тип значения Дата, для Уровня шума – Число и так далее. Кроме этого, возможно использование составных типов значений, в состав которых могут входить как примитивные типы (Дата, Число, Строка, Булево), так и ссылочные типы данных (ДокументСсылка.<имя>, СправочникСсылка.<имя> и так далее, включая ПланВидовХарактеристикСсылка.<имя>). Пример создания и использования плана видов характеристик ВидыХарактеристик приведен в составе демонстрационной конфигурации «Хранение информации и учет движения средств», которая находится на прилагаемом компакт-диске. 116 Реализация прикладных задач в системе «1С:Предприятие 8.2» Для того чтобы при описании типов значений для новых видов характеристик (элементов этого плана видов характеристик) пользователь мог выбирать значения только из определенного разработчиком списка, при конфигурировании используется свойство Тип значения характеристик (рис. 1.79). Рис. 1.79. Свойство «Тип значения характеристик» Обратите внимание: на рисунке видно, что в состав типов значений характеристик плана ВидыХарактеристик включено использование справочника ЗначенияХарактеристик. Введение подобного справочника в состав решения помогает обеспечить самостоятельный ввод новых возможных значений новых характеристик самим пользователем в тех ситуациях, когда в составе конфигурации нет объектов для отображения новой сущности. Например, в процессе эксплуатации программы возникла необходимость создания новых видов характеристик Область применения, Вариант оплетки, Формат бумаги и так далее. Вместо того чтобы под каждую сущность создавать свой справочник или перечисление, все значения таких дополнительных характеристик можно хранить в справочнике ЗначенияХарактеристик (рис. 1.80). Глава 1. Хранение информации Рис. 1.80. Справочник «Значения характеристик» Рис. 1.81. Свойство «Дополнительные значения характеристик» 117 118 Реализация прикладных задач в системе «1С:Предприятие 8.2» Однако для того чтобы при выборе значений характеристик из этого справочника информация разных видов характеристик не перемешивалась, нужно подчинить элементы справочника элементам плана вида характеристик. Это реализуется следующим образом: ■ устанавливается владелец справочника ЗначенияХарактеристик – план видов характеристик ВидыХарактеристик; ■ свойство Дополнительные значения характеристик объекта конфигурации плана вида характеристик заполняется указанием справочника ЗначенияХарактеристик (рис. 1.81). Этого достаточно, например, для того, чтобы платформа взяла на себя вопросы реализации основной функциональности, касающейся заполнения, хранения и отображения связей между видом характеристики и возможными ее значениями (рис. 1.82). Рис. 1.82. Использование команды перехода к списку значений характеристик в панели навигации формы плана видов характеристик Таким образом, создав план видов характеристик, разработчик определяет возможности хранения в базе данных перечня видов характеристик и определяет область допустимых значений этих характеристик. Глава 1. Хранение информации 119 Описание дополнительных характеристик объектов конфигурации Естественно, характеристики объектов создаются не просто так, а для получения данных в разрезе этих характеристик. Но сначала нужно описать, где и как хранятся характеристики объектов конфигурации. Платформа предоставляет возможность сделать это прямо в дереве объектов конфигурации. Удобство такого решения очевидно: описав один раз связь между объектом конфигурации и его характеристиками, разработчику больше не придется в каждом отчете, использующем характеристики объекта, указывать, где и каким образом хранятся его характеристики. В результате все отчеты и динамические списки, в которых участвует объект конфигурации, будут «подхватывать» его характеристики. Описание характеристик объектов конфигурации содержится в свойстве Характеристики. Диалог для описания характеристик можно вызвать, нажав кнопку Характеристики на закладке Данные в окне редактирования объекта конфигурации, например, Справочник Номенклатура (рис. 1.83). Свойство Характеристики можно задать для таких объектов конфигурации, как Справочник, Документ, Перечисление, План видов характеристик, План счетов, План видов расчета, План обмена, Задача, Бизнес-процесс. Команда Характеристики также доступна в контекстном меню дерева объектов конфигурации и в палитре свойств этих объектов. Рис. 1.83. Вызов диалога описания характеристик справочника «Номенклатура» 120 Реализация прикладных задач в системе «1С:Предприятие 8.2» В диалоге описания дополнительных характеристик объекта конфигурации нужно указать, где хранятся виды характеристик и значения этих характеристик. В реальной практике часто требуется хранить дополнительные характеристики не одного, а сразу нескольких объектов конфигурации – например, справочников номенклатуры, контрагентов, различных документов и т. д. И хранить их можно по-разному. Это зависит от специфики конкретной задачи, предпочтений разработчика, пожеланий заказчика и т. п. Ниже мы рассмотрим по мере усложнения следующие варианты хранения дополнительных характеристик объектов конфигурации и их значений: 1. В качестве источника характеристик указывается план видов характеристик, а значения характеристик находятся в регистре сведений. При этом один план видов характеристик хранит виды характеристик только для одного объекта конфигурации. 2. План видов характеристик хранит виды характеристик для разных объектов конфигурации, а значения характеристик находятся так же, как и в предыдущем варианте, в регистре сведений. 3. Значения характеристик хранятся не в регистре сведений, а в справочнике, например, или в табличной части справочника. 4. В качестве источника характеристик указывается не план видов характеристик, а табличная часть справочника, которая хранит ссылки на виды характеристик. Варианты описания дополнительных характеристик Первый вариант Рассмотрим самый простой случай, когда в качестве источника характеристик указывается план видов характеристик, а значения характеристик находятся в регистре сведений. При этом один план видов характеристик хранит виды характеристик только для одного объекта конфигурации. Допустим, необходимо организовать хранение значений дополнительных характеристик номенклатурных позиций в регистре сведений. В составе демонстрационной конфигурации «Хранение информации и учет движения средств», которая находится на прилагаемом компакт-диске, для этого используется регистр сведений ДополнительныеХарактеристики (рис. 1.84). Глава 1. Хранение информации 121 Рис. 1.84. Структура регистра сведений «ДополнительныеХарактеристики» Измерение Объект имеет тип значения СправочникСсылка.Номенклатура, свойство – Ведущее. Тип значения измерения ВидХарактеристики – ПланВидовХарактеристикСсылка.ВидыХарактеристик, свойство – Ведущее. Тип значения ресурса ЗначениеХарактеристики – Характеристика.ВидыХарактеристик. В результате регистром сведений будет поддерживаться уникальность записей по набору значений измерений Объект – ВидХарактеристики, а для значений ресурса ЗначениеХарактеристики тип значения будет определяться теми значениями, которые указаны в составе соответствующего плана видов характеристик. Однако необходимо понимать, что мы описали все необходимое для хранения характеристик, но не для организации заполнения. С точки зрения системы измерения Объект и ВидХарактеристики никак не связаны между собой. А при вводе значений в поле ресурса по умолчанию никак не учитывается выбранный в поле измерения вид характеристики – система будет предлагать заполнять поле любым из типов, описанных в плане видов характеристик. В описании структуры регистра никак не задается информация о логической связи полей, в которых хранятся виды характеристик и значения характеристик. Более того, зачастую это сделать было бы просто невозможно. Дело в том, что в реальном решении такая связь может быть очень сложной. И хранение соответствия номенклатурных позиций и видов их характеристик может выполняться в других объектах конфигурации (например, в отдельном регистре сведений, хранящем связи «многие ко многим» между номенклатурными группами и видами характеристик, между отдельными номенклатурными позициями и группами видов характеристик и т. д.). А данные связи могут влиять на связи между видами характеристик и возможными их значениями. Поэтому реализация всех этих связей выполняется разработчиком конфигурации в рамках специфики поставленной задачи. 122 Реализация прикладных задач в системе «1С:Предприятие 8.2» Допустим, необходимо реализовать достаточно простой вариант, когда для любой номенклатурной позиции можно использовать любой вид характеристики, и нужно лишь обеспечить удобство редактирования записей регистра в отношениях между видом характеристики и возможными значениями. В демонстрационной конфигурации «Хранение информации и учет движения средств», которая находится на прилагаемом компакт-диске, пример реализации этой задачи сделан с использованием свойств Связь по типу и Связи параметров выбора ресурса ЗначениеХарактеристики регистра сведений ДополнительныеХарактеристики. Для ограничения типов значений характеристики типами конкретного выбранного вида характеристики у ресурса ЗначениеХарактеристики в качестве значения свойства Связь по типу выбрано измерение регистра ВидХарактеристики, а также свойство Связи параметров выбора ресурса ЗначениеХарактеристики установлено как Отбор.Владелец(ВидХарактеристики). Для этого при нажатии кнопки выбора из списка возможных реквизитов регистра измерение ВидХарактеристики перенесено в список параметров выбора (рис. 1.85). Рис. 1.85. Свойства «Связь по типу» и «Связи параметров выбора» ресурса «ЗначениеХарактеристики» Глава 1. Хранение информации 123 В результате значения, вводимые в поле Значение характеристики, будут соответствовать типу вида характеристики, выбранной в поле Вид характеристики. Кроме того, при выборе значений характеристики, содержащихся в справочнике Значения характеристик, для выбора будут предлагаться только те значения, которые относятся к выбранному виду характеристики (рис. 1.86). Рис. 1.86. Соответствие вида характеристики и ее значений Остальная функциональность вопросов ввода, модификации, удаления данных посредством менеджера записи регистра реализуется системой и описана в разделе «Создание, изменение, удаление записей регистра сведений» на стр. 69. Таким образом, схему организации хранения дополнительных характеристик номенклатуры в рассмотренном решении в общем виде можно представить так (рис. 1.87). Рис. 1.87. Общая схема хранения дополнительных характеристик одного объекта конфигурации 124 Реализация прикладных задач в системе «1С:Предприятие 8.2» В этом случае описание характеристик номенклатуры примет следующий вид (рис. 1.88). Рис. 1.88. Описание дополнительных характеристик справочника «Номенклатура» После описания характеристик в свойствах объектов конфигурации в настройках отчетов и динамических списков объектов конфигурации можно использовать их характеристики. Например, в отчете, отражающем остатки номенклатуры на складах, можно настроить отбор по характеристикам номенклатуры (рис. 1.89). Рис. 1.89. Настройка отбора в отчете с использованием характеристик номенклатуры Глава 1. Хранение информации 125 В результате отчет примет следующий вид (рис. 1.90). Рис. 1.90. Отчет «Остатки на складах» с отбором по характеристике номенклатуры «Цвет» Второй вариант Усложним задачу. Пусть план видов характеристик хранит виды характеристик для разных объектов конфигурации, например для справочников номенклатуры, контрагентов и организаций. При этом значения характеристик находятся так же, как и в предыдущем варианте, в регистре сведений. В этом варианте в план видов характеристик необходимо ввести реквизит, позволяющий отделять характеристики одного объекта конфигурации от другого, а при описании характеристик каждого объекта указывать данный реквизит и его значение в полях Поле отбора видов и Значение отбора видов, чтобы отбирались характеристики именно этого объекта. Для реализации данного решения в демонстрационной конфигурации «Хранение информации и учет движения средств», которая находится на прилагаемом компакт-диске, создано перечисление ВидыОбъектов (рис. 1.91). Рис. 1.91. Перечисление «ВидыОбъектов» 126 Реализация прикладных задач в системе «1С:Предприятие 8.2» В план видов характеристик ВидыХарактеристик добавлен реквизит ВидОбъектов типа ПеречислениеСсылка.ВидыОбъектов (рис. 1.92). Рис. 1.92. Реквизит «ВидОбъектов» плана видов характеристик В регистре сведений ДополнительныеХарактеристики, хранящем значения характеристик, указывается, что тип измерения Объект будет составным и будет включать ссылки на справочники номенклатуры, контрагентов и организаций – СправочникСсылка.Номенклатура, СправочникСсылка.Контрагенты, СправочникСсылка.Организации (рис. 1.93). Схему организации хранения дополнительных характеристик различных объектов конфигурации в рассмотренном решении в общем виде можно представить, как на рис. 1.94. В этом случае описание характеристик одного из справочников, например, справочника контрагентов, примет вид, как на рис. 1.95. То есть при описании характеристик для справочника Контрагенты в Поле отбора видов указывается реквизит ВидОбъектов плана видов характеристик ВидыХарактеристик, а в поле Значение отбора видов указывается значение перечисления ВидыОбъектов – СправочникКонтрагенты. Для справочников Номенклатура и Организации значение поля Поле отбора видов будет таким же, а в поле Значение отбора видов нужно указать соответствующее значение перечисления ВидыОбъектов – СправочникНоменклатура или СправочникОрганизации. Глава 1. Хранение информации 127 Рис. 1.93. Тип измерения «Объект» регистра сведений «ДополнительныеХарактеристики» Рис. 1.94. Общая схема хранения дополнительных характеристик различных объектов конфигурации 128 Реализация прикладных задач в системе «1С:Предприятие 8.2» Рис. 1.95. Описание дополнительных характеристик справочника «Контрагенты» Теперь в режиме 1С:Предприятие останется только заполнить реквизит ВидОбъектов плана видов характеристик соответствующими значениями (рис. 1.96). Рис. 1.96. Заполнение реквизита «ВидОбъектов» плана видов характеристик После этого при настройке списка контрагентов по команде Все действия Настроить список в списке доступных полей будут доступны дополнительные характеристики, относящиеся к справочнику контрагентов (ВидОбъектов – Справочник "Контрагенты"), в данном случае – Категория (рис. 1.97). Глава 1. Хранение информации 129 Рис. 1.97. Настройка динамического списка с использованием характеристик контрагентов Например, при условии, что в регистре ДополнительныеХарактеристики присутствуют записи о контрагентах с выбранной категорией, список контрагентов примет следующий вид (рис. 1.98). Рис. 1.98. Список контрагентов с отбором по характеристике «Категория» В рассмотренном примере Категория – это дополнительная характеристика справочника контрагентов, имеющая тип СправочникСсылка.Категории. Для того чтобы при вводе значений в регистр ДополнительныеХарактеристики пользователь мог выбирать из справочника Категории, нужно указать этот справочник в составе свойства Тип значения характеристик плана видов характеристик ВидыХарактеристик (рис. 1.99). 130 Реализация прикладных задач в системе «1С:Предприятие 8.2» Рис. 1.99. Тип значения характеристик В заключение отметим, что если для справочника Организации реализовать первый вариант описания характеристик (без указания полей Поле отбора видов и Значение отбора видов), то даже при условии заполнения реквизита ВидОбъектов в плане видов характеристик при настройке списков и отчетов, в которых участвует данный справочник, все дополнительные характеристики будут представлены «общей кучей», без разбивки на виды объектов конфигурации. Третий вариант Теперь рассмотрим случай, когда значения характеристик хранятся не в регистре сведений, а в табличной части справочника. Виды характеристик будут храниться по-прежнему в плане видов характеристик. В процессе работы прикладного решения для одного объекта (например, элемента справочника) может потребоваться указывать сразу несколько значений одной и той же характеристики. Так, для некоторых номенклатурных позиций может понадобиться указать сразу несколько значений характеристики Область применения: Связь, Медицина, Обучение и т. д. Это значит, что элемент справочника относится сразу к нескольким областям применения. В этом случае уже не получится хранить значения характеристик, как раньше, в регистре сведений, потому что регистр сведений не позволит сделать запись Глава 1. Хранение информации 131 с неуникальными значениями измерений (один и тот же объект и одна и та же характеристика). И значит, их можно хранить, например, прямо в табличной части этого самого элемента справочника. Как в этом случае для справочника будут описываться характеристики, мы сейчас и рассмотрим. В демонстрационной конфигурации «Хранение информации и учет движения средств», которая находится на прилагаемом компакт-диске, к справочнику Номенклатура добавлена табличная часть ДополнительнаяИнформация, включающая в себя реквизиты ДополнительноеСвойство (тип значения ПланВидовХарактеристикСсылка.ВидыХарактеристик) и ЗначениеСвойства (тип значения Характеристика.ВидыХарактеристик), рис. 1.100. Рис. 1.100. Структура справочника «Номенклатура» В результате в самом объекте справочника можно указывать сразу несколько значений для одной и той же характеристики (рис. 1.101). Рис. 1.101. Форма элемента справочника «Номенклатура» Для обеспечения того, чтобы данные в табличной части вводились корректно, выполнены доработки, аналогичные рассмотренным в разделе «Первый 132 Реализация прикладных задач в системе «1С:Предприятие 8.2» вариант» на стр. 120. То есть задействованы свойства Связь по типу и Связи параметров выбора для реквизита ЗначениеСвойства табличной части ДополнительнаяИнформация. В целом схему организации хранения произвольных дополнительных характеристик номенклатуры в самом объекте можно представить так (рис. 1.102). Рис. 1.102. Схема хранения значений дополнительных характеристик В этом случае описание характеристик номенклатуры примет следующий вид (рис. 1.103). Рис. 1.103. Описание дополнительных характеристик справочника «Номенклатура» В отличие от предыдущих вариантов, где все поля мы создавали самостоятельно, тут в табличной части справочника используется поле Ссылка, которое мы не создавали. Это поле создает сама платформа, когда мы указываем, что у справочника будет табличная часть. Несмотря на то, что это «служебное» поле, мы можем его использовать (и используем) при описании того, где хранятся значения характеристик. Т. к. для каждой табличной части справочника существует отдельная таблица в базе данных, то записи этой табличной части всех элементов справочника хранятся в этой таблице. И именно по значению поля Ссылка можно определить, к какому же именно элементу Глава 1. Хранение информации 133 справочника относятся эти записи. Поэтому при описании места хранения значений характеристик в качестве поля объекта мы указываем поле Ссылка, чтобы система отбирала из таблицы только те записи, которые относятся именно к этому элементу. Таким образом, табличная часть ДополнительнаяИнформация будет хранить значения характеристик номенклатуры так же, как и регистр сведений. Виды характеристик будут храниться по-прежнему в плане видов характеристик ВидыХарактеристик (рис. 1.104). Рис. 1.104. Хранение дополнительных характеристик в табличной части справочника «Номенклатура» В результате в отчете по остаткам номенклатуры на складах можно вывести значения дополнительных полей – характеристик, введенные в табличной части элементов номенклатуры (рис. 1.105). Рис. 1.105. Отчет «Остатки на складах» с дополнительными полями-характеристиками номенклатуры «Цвет», «Вес» 134 Реализация прикладных задач в системе «1С:Предприятие 8.2» Четвертый вариант В заключение рассмотрим случай, когда в качестве источника характеристик указывается не план видов характеристик, а табличная часть справочника, которая хранит ссылки на виды характеристик. А значения характеристик содержатся в регистре сведений. На практике одна и та же характеристика может использоваться одновременно для нескольких объектов конфигурации (например, как для справочника Номенклатура, так и для справочника Контрагенты). А такого рассмотренные выше способы описания характеристик не позволяют сделать. При использовании одного плана видов характеристик для всех объектов конфигурации (вариант 2) в его специальном реквизите мы указывали единственный объект конфигурации, к которому применяется эта характеристика. Значит, если есть необходимость применять эту характеристику и к другому объекту конфигурации, придется дублировать вид характеристики и в ней указывать другой объект конфигурации. Если для каждого объекта конфигурации использовать собственный план видов характеристик, то тоже придется дублировать вид характеристики, но уже в другом плане видов характеристик. Чтобы избежать такого дублирования, характеристики объединены в наборы характеристик, свойственные каждому объекту конфигурации. Эти наборы хранятся в отдельном справочнике, табличная часть которого и содержит описание характеристик каждого набора. Для реализации данного решения в демонстрационной конфигурации «Хранение информации и учет движения средств», которая находится на прилагаемом компакт-диске, создан справочник НаборыДополнительныхХарактеристик с табличной частью ДополнительныеСведения, включающей в себя реквизит Свойство (тип значения ПланВидовХарактеристикСсылка.ВидыХарактеристик), рис. 1.106. Рис. 1.106. Структура справочника «НаборыДополнительныхХарактеристик» Глава 1. Хранение информации 135 Справочник НаборыДополнительныхХарактеристик содержит предопределенные элементы, ссылки на которые позволяют создавать наборы характеристик, в которых одна и та же характеристика может применяться к различным объектам конфигурации (рис. 1.107). Рис. 1.107. Предопределенные элементы справочника «НаборыДополнительныхХарактеристик» Схему организации хранения дополнительных характеристик различных объектов конфигурации в рассмотренном решении в общем виде можно представить так (рис. 1.108). Рис. 1.108. Схема хранения значений дополнительных характеристик В этом случае описание характеристик одного из справочников, например, справочника номенклатуры, примет вид, как на рис. 1.109. При описании табличной части справочника НаборыДополнительныхХарактеристик в качестве источника характеристик в Поле ключа указывается поле 136 Реализация прикладных задач в системе «1С:Предприятие 8.2» Свойство табличной части, в Поле отбора видов – поле Ссылка справочника, в поле Значение отбора видов – значение ссылки на предопределенный элемент справочника НаборыДополнительныхХарактеристик. Рис. 1.109. Описание дополнительных характеристик справочника «Номенклатура» Рис. 1.110. Набор дополнительных характеристик справочника «Номенклатура» Глава 1. Хранение информации 137 На приведенном выше рисунке важна только вторая запись. Именно о ней мы и говорим. А первая запись осталась от предыдущего примера. Но в принципе этот рисунок показывает и то, что характеристики объекта конфигурации могут находиться в разных местах, по-разному храниться, и все это можно описать в диалоге описания характеристик объекта конфигурации, в одном месте, с помощью нескольких записей. Таким образом, для каждого предопределенного элемента справочника НаборыДополнительныхХарактеристик в режиме 1С:Предприятие можно ввести свойственные ему наборы характеристик (рис. 1.110). Как видно из рисунка, сами характеристики содержатся в плане видов характеристик, а табличная часть элементов справочника хранит только ссылки на него. После этого при настройке динамических списков и отчетов, в которых участвует данный объект конфигурации, будут доступны его характеристики, указанные в табличной части справочника НаборыДополнительныхХарактеристик. 138 Реализация прикладных задач в системе «1С:Предприятие 8.2» Глава 2. Документы и последовательности Место документов в концепции системы «1С:Предприятие» При создании бизнес-приложений для решения задач учета, планирования, принятия решений, управления и т. д., как правило, используются определенные информационные модели. И, как правило, одно из центральных мест любой подобной модели занимает понятие события. Например, один из наиболее активно используемых вариантов исторически сложившейся информационной модели учетных решений можно представить в виде следующей схемы (рис. 2.1). Рис. 2.1. Информационная модель учетного решения 140 Реализация прикладных задач в системе «1С:Предприятие 8.2» Основа учета – регистрация событий, происходящих с учитываемыми показателями. Она может выполняться посредством внесения записей в журналы, записью проводок и т. д. В общем, посредством документирования. Причем документирование должно производиться не в «вольной» форме, а согласуясь с заранее разработанными и стандартизованными обозначениями, зачастую сведенными в виде неких классификаторов. Конечно же, документирование нужно не как самоцель, а для обоснования информации, предоставляемой о состоянии учитываемых показателей. Так называемой отчетной информации. При выдаче же отчетной информации большое значение придается наглядности, удобству и быстроте ее получения. Для того чтобы обеспечить максимальную быстроту получения отчетной информации, идеально было бы получать ее сразу, минуя этап длительного перебора записей событий и подсчета их влияния на показатели. Поэтому отражение результата влияния зарегистрированных событий на показатели обычно производится заранее. То есть не в момент, когда потребуется отчет, а в момент, когда событие только регистрируется. Для запоминания же состояния учитываемых таким образом показателей используются специальные регистры учета. Например, для классического бухгалтерского учета посредством двойной записи итоги хозяйственной деятельности в виде сальдо «оседают» на бухгалтерских счетах. Рассмотрим, что предлагает платформа «1C:Предприятие 8» для реализации информационных моделей бизнес-приложений. Платформа «1С:Предприятие» позволяет строить прикладные решения, оперируя совокупностями объектов: ■ соответствующими прикладным сущностям; ■ выбираемыми из набора жестко определенных в платформе классов объектов. Общую схему возможных вариантов взаимодействия прикладных объектов системы для решения той или иной задачи можно представить следующим образом (рис. 2.2). Можно отметить, что данная схема позволяет полностью реализовать функциональность предыдущей и при этом может обеспечить существенное расширение и дополнение ее. Фактически она позволяет строить модели на более высоком уровне абстрагирования. Например, справочники, планы видов характеристик, перечисления, константы, планы счетов и планы видов расчетов могут использоваться не только для обеспечения заполнения документов, но и для заполнения некоторых видов регистров напрямую. А вообще – для хранения информации, не привязанной ко времени. Глава 2. Документы и последовательности 141 Рис. 2.2. Варианты взаимодействия прикладных объектов Документы предназначены для ввода первичной информации, связанной с регистрацией событий, воздействующих на учитываемые в системе показатели. Если посмотреть на прикладные решения, то подавляющее большинство документов используют привязку ко времени – поле Дата, которое есть у всех документов. То есть можно говорить, что документы – это объекты для регистрации информации, для которой важна привязка ко времени. Для облегчения обеспечения действий, связанных с вводом, отображением, логикой учета документов, при необходимости используются такие объекты, как нумераторы, журналы документов, последовательности. Отчеты и обработки могут обеспечивать не только вывод информации в удобном для пользователя виде, но и ввод. То есть могут использоваться для обеспечения интерфейса выполнения воздействий на объекты, отвечающие за хранение информации. Однако сами для хранения информации не используются. Регистры же можно воспринимать как объекты, предназначенные для хранения «вторичной» информации о состоянии показателей со сложными привязками к моментам времени и периодам. Обычно эта информация получается в процессе переработки исходной информации, вводимой документами. Например, факт болезни нужно регистрировать посредством документа Больничный. Информация документа при его проведении будет отражена в регистре расчета зарплаты с тем, чтобы впоследствии, после проведения расчетных 142 Реализация прикладных задач в системе «1С:Предприятие 8.2» операций (включающих, например, вытеснение оклада за период болезни), из регистра можно было взять информацию о начисленном по болезни пособии и о начисленной заработной плате вообще. Однако опять же можно смотреть на использование регистров шире. Есть возможность использования регистров сведений (периодических или непериодических) с независимым режимом записи. То есть если это оправдано с точки зрения решения прикладной задачи, для таких регистров данные могут вводиться непосредственно, минуя этап работы с документом. Итак, подведем краткий итог: документирование событий – основа практически любой модели бизнес-приложений. Без документирования информация, получаемая из системы, была бы необоснованной, а значит, возможно, недостоверной. Таким образом, основное назначение документов – регистрация информации о происходящих событиях с привязкой ко времени. Документы Функциональность документов Для выполнения задач своего предназначения документы имеют соответствующий состав и обеспечивают возможность следующих основных действий: ■ заполнение, ■ запись, ■ проведение, ■ формирование движений по регистрам, ■ расположение на оси времени, ■ пометка на удаление, ■ удаление. Такой набор функциональности заложен в систему и обеспечивает быструю разработку и удобство использования документов. Разберем эти возможные действия подробнее. Заполнение документов Заполнение документа может производиться разными способами в зависимости от прикладной задачи и необходимого уровня сервиса для пользователя. Глава 2. Документы и последовательности 143 Самый простой вариант заполнения – ручной ввод документа (рис. 2.3). Данный вариант обеспечивается чаще всего посредством формы, имеющей в качестве основного реквизита объект документа. Тогда ряд элементов формы обеспечивают отображение и ввод значений в реквизиты формы, а ряд – инициацию процесса записи документа, когда данные реквизитов формы записываются в сами объекты. Формы, основным реквизитом которых назначен объект документа, и элементы этих форм обладают расширениями, позволяющими реализовывать специфичное поведение системы для облегчения работы разработчика с документами. Рис. 2.3. Ручной ввод документа Копирование. Вариант, когда новый документ создается копированием существующего, причем его данные заполняются данными существующего документа (рис. 2.4). Может инициироваться интерактивными действиями пользователя или программно – методом Скопировать(). Оба действия приводят к одному событию ПриКопировании и могут быть перехвачены обработчиком события, располагаемым в модуле документа. В самом обработчике может быть реализовано заполнение нового документа в зависимости от требуемого алгоритма (не обязательно только данными исходного документа). 144 Реализация прикладных задач в системе «1С:Предприятие 8.2» Рис. 2.4. Создание документа копированием Заполнение. Вариант создания нового документа, который инициируется в следующих случаях: ■ командой Создать в панели действий приложения или в форме списка документов (см. рис. 2.3); ■ командой ввода на основании СоздатьНаОсновании (рис. 2.5); ■ при программном вызове методов глобального контекста ОткрытьФорму() и ПолучитьФорму(); ■ при программном вызове метода Заполнить(). Рис. 2.5. Создание документа вводом на основании Глава 2. Документы и последовательности 145 Поскольку можно заполнять документ на основании данных любого объекта, то говорить об однозначном соответствии данных источника и документаполучателя не приходится. Поэтому само заполнение данных документа осуществляется в рамках обработчика события ОбработкаЗаполнения. Процедура обработчика располагается в модуле документа и содержит в качестве параметра объект-источник. Также в механизме заполнения участвуют свойства реквизитов объектов конфигурации Значение заполнения и Заполнять из данных заполнения. Если свойство реквизита Заполнять из данных заполнения установлено в значение Истина, то процедура стандартной обработки заполнения будет заполнять реквизит из данных заполнения (например, платформа автоматически будет заполнять реквизиты документов, по которым установлен отбор в форме списка). Если в данных заполнения нет данных для заполнения этого реквизита или свойство имеет значение Ложь, то реквизит будет заполнен из свойства Значение заполнения, если оно установлено. Программное заполнение документов. Может выполняться за счет операций присвоения значений реквизитам документа (рис. 2.6). В данном случае выбор элементов формы и событий, при обработке которых будут производиться эти действия, предоставлен разработчику конфигурации. Создание нового документа при этом может производиться посредством метода СоздатьДокумент() на сервере или ОткрытьФорму() на клиенте. К данному способу прибегают обычно в случаях, когда создание нового документа должно производиться не вручную, не копированием-заполнением, а в результате выполнения каких-либо программных алгоритмов. Рис. 2.6. Программное заполнение документа 146 Реализация прикладных задач в системе «1С:Предприятие 8.2» Расположение на оси времени Поскольку документ является регистратором события, одной из важных задач документа является фиксация времени, когда событие имело место. Поэтому все документы имеют поле Дата. И, более того, система не позволяет записать документы с неустановленной датой (равной значению даты по умолчанию). Согласно значениям этого поля все записанные документы могут быть расположены на единой временной оси в хронологическом порядке (рис. 2.7). Рис. 2.7. Расположение документов на оси времени Причем даже если ряд документов имеет одинаковое значение поля Дата, система «1С:Предприятие» имеет средства для обеспечения однозначного хронологического порядка – объект МоментВремени, содержащий дату и ссылку на документ (рис. 2.8). Рис. 2.8. Использование момента времени Объект МоментВремени используется системой автоматически при решении задачи отображения списков документов в хронологическом порядке. Также его используют, когда требуется получить данные из регистров именно на момент времени документа. Однако необходимо заметить, что за счет использования момента времени можно только получить хронологию расположения документов, изменить же ее в пределах одной секунды невозможно. Хронологический порядок документов определяется системой при обращении к данным – по датам, а для одинаковых дат – по ссылкам документов. И для документов с одинаковым Глава 2. Документы и последовательности 147 временем не зависит ни от порядка создания документов, ни от номера документа, ни от чего-то подобного. Если необходимо изменить хронологию документов, нужно менять значения поля Дата документов, «разводя» их в разные секунды. Кроме того, в случаях, когда требуется обеспечить ввод и проведение документов реальным временем, можно воспользоваться возможностями механизма оперативного проведения документов и оперативной отметки времени. Это позволяет распределять документы на временной оси автоматически с соблюдением как минимум секундного интервала. О работе данного механизма подробно рассказывается в разделе «Проведение документов» на стр. 177. Запись документов Запись объекта документа – физический процесс, заключающийся в сохранении значений реквизитов документов в базе данных. Может инициироваться интерактивными действиями пользователя или программно – методом Записать(). Запись документа имеет несколько возможных режимов (просто – запись, проведение, отмена проведения). О происходящих при этих режимах записи процессах будет рассказано ниже. Общий же смысл использования этих режимов – обеспечение логических процессов бизнес-решения с использованием определенных «сценариев», заложенных в систему (удаление существующих движений, формирование новых, установка значения поля Проведен и прочее). Разработчик вправе принимать решения о необходимости применения того или иного сценария или механизма (рис. 2.9). Рис. 2.9. Запись документа 148 Реализация прикладных задач в системе «1С:Предприятие 8.2» Проведение документов Обсуждая это действие, необходимо разделять два понятия: ■ «Проведен» – состояние документа; ■ «Проведение» – как процесс. Проведенность как состояние может быть установлена различными способами. Может классически – в результате выполнения процесса проведения, а может просто присвоением значения Истина свойству документа Проведен. С прикладной точки зрения проведенным считается документ, если обработка данного документа полностью завершена и принято решение, что данный документ должен участвовать в учете. То есть событие, регистрируемое документом, полностью описано и учтено в информационной модели. Для отражения этого состояния документа используется системное поле Проведен. Процесс проведения документа в системе является частным случаем записи документа. Если состояние проведения было достигнуто в процессе проведения документа, то, значит, были обработаны все события, связанные с записью документа в режиме проведения. А именно в обработчиках этих событий обычно и содержатся указания, что, где и как должно измениться в объектах информационной базы для реализации бизнес-логики, заложенной в решение (рис. 2.10). Рис. 2.10. Проведение документа Кроме того, зачастую используется процесс, обратный проведению, – отмена проведения. Выполнение этого процесса приводит к записи документа Глава 2. Документы и последовательности 149 с отменой проведения. При этом выполняются обработчики, связанные с ним (рис. 2.11). Рис. 2.11. Отмена проведения документа Если же свойство Проведен просто установлено или снято для документа и документ был записан, то в результате для такого документа был выполнен процесс обычной записи документа. То есть часть событий не произошла для такого документа, а значит, не были обработаны соответствующим образом обработчики этих событий (рис. 2.12). Рис. 2.12. Использование свойства «Проведен» Однако для каких-нибудь регламентных или вспомогательных обработок может оказаться важной такая возможность: получить проведенные документы без процесса проведения или непроведенные документы без процесса отмены проведения. 150 Реализация прикладных задач в системе «1С:Предприятие 8.2» Формирование движений по регистрам По своему назначению регистры служат для запоминания и переработки информации, внесенной в систему, как правило, документами. Поэтому для записей любых регистров (за исключением регистров сведений с установленным режимом записи Независимый) обязательно наличие заполненного поля Регистратор. В этом поле должна находиться ссылка на документ, которому подчинен этот набор записей. Такие наборы записей называют движениями (рис. 2.13). Рис. 2.13. Движения документа Глава 2. Документы и последовательности 151 Поведение системы во многом определяется наличием связи документов и подчиненных им движений. Например, движения отдельно от своих регистраторов существовать не могут. Поэтому при удалении документов или отмене проведения (если свойство Удаление движений установлено в значение, отличное от Не удалять) система производит поиск движений этого документа в таблицах всех регистров, для которых данный документ может быть регистратором, и удаляет их. Именно поэтому, например, не рекомендуется «про запас» указывать регистры, для которых документ может быть регистратором. Нужно указывать только те, которые действительно требуются для обеспечения бизнес-логики, заложенной в решение. Сами же движения могут: ■ создаваться при проведении документов; ■ создаваться при записи документов; ■ формироваться в виде набора записей регистра (обязательно с отбором по регистратору); ■ формироваться интерактивно (например, документом РучнаяОперация). То есть и непроведенные документы могут иметь движения по регистрам. Это обеспечивает возможность достаточно гибкого отражения ситуаций, возникающих в автоматизируемых задачах, и может быть использовано, когда обработка документа пользователем еще не завершена, но документ уже должен изменить некие учетные данные. Например, так может выглядеть задача последовательной обработки документа ЗаказПокупателя различными подразделениями компании. Для отслеживания различных стадий обработки этого документа используется регистр сведений ОперативноеУправлениеЗаказами (рис. 2.14). Рис. 2.14. Регистр сведений «ОперативноеУправлениеЗаказами» 152 Реализация прикладных задач в системе «1С:Предприятие 8.2» Заполнение регистра производится при реализации промежуточных операций обработки документа (рис. 2.15). Рис. 2.15. Промежуточные операции обработки документа Сначала документ выписывается менеджером и записывается. При этом в регистре сведений ОперативноеУправлениеЗаказами формируется запись, указывающая, что данный заказ находится в стадии КФинансовомуКонтролю. Далее ответственный сотрудник финансового отдела проверяет возможность удовлетворения данного заказа с точки зрения допустимости долга покупателя и соблюдения ценовых порогов. В случае положительного решения выставляется флажок Отпуск разрешен. При записи документа с этим установленным флажком модифицируется запись в регистре сведений ОперативноеУправлениеЗаказами. Теперь для данного документа актуально состояние КРазмещению. Далее обработку документа выполняет менеджер отдела запасов. Он работает со всеми заказами, имеющими статус КРазмещению. Если принимается решение об отгрузке из наличных свободных остатков, устанавливается флажок Отгрузка из свободных остатков, и заказ записывается. При записи такого заказа его статус меняется на значение КРезервированию. Если же будет принято решение о выборе варианта Размещение в заказе поставщику, выполняется проведение документа с формированием движений по регистру ЗаказыПоставщикам. Глава 2. Документы и последовательности 153 Заказы покупателей, перечисленные в регистре сведений ОперативноеУправлениеЗаказами и имеющие статус КРезервированию, проверяются и окончательно проводятся уже товароведом на складе. В таких случаях формируются движения по регистру Резервы (табл. 2.1). Таблица 2.1. Промежуточные операции обработки документа № Пользователь Стадия обработки Движения по регистрам Комментарий 1 Менеджер Регистр сведений Формирование записи по заказу: статус 2 3 Заполнение Финансовый отдел Контроль кредитной линии Отдел запасов Решение об отгрузке из свободных остатков или заказе поставщику Оперативное управление заказами Регистр сведений Оперативное управление заказами Регистр сведений Оперативное управление заказами Регистр остатков Заказы поставщикам К финансовому контролю Модификация записи по заказу: статус К размещению Модификация записи по заказу: статус К резервированию, если принято решение об отгрузке из свободных остатков Проведение документа с формированием движений по регистру Заказы поставщикам (движения по регистру Оперативное управление заказами 4 Склад Отметка о постановке в очередь на отгрузку Регистр остатков Резервы автоматически удаляются) Проведение документа с формированием движений по регистру Резервы (движения по регистру Оперативное управление заказами автоматически удаляются) Обратите внимание: хотя движения по регистрам для обрабатываемого заказа формируются на каждой стадии обработки, «финальное проведение» выполняется только на последней стадии. Причем разработчик может выполнять его в рамках обработчика события ОбработкаПроведения, а может и самостоятельно, очищая старые движения, формируя новые и устанавливая свойство Проведен данного документа. 154 Реализация прикладных задач в системе «1С:Предприятие 8.2» Пометка на удаление документа Так же как и при работе с проведением, необходимо различать: ■ состояние документа «ПометкаУдаления»; ■ процесс «ПометкаУдаления». Документ считается помеченным на удаление в том случае, если в системное поле документа ПометкаУдаления записано значение Истина. Поведение документа, помеченного на удаление, имеет свои особенности. Например, такой документ не может быть проведен (рис. 2.16). Рис. 2.16. Проведение документа, помеченного на удаление Сам же процесс «ПометкаУдаления» обычно инициируется интерактивно или методом объекта документа УстановитьПометкуУдаления(ИСТИНА) и приводит к тому, что документ записывается с соответствующим значением поля ПометкаУдаления. При этом если документ был проведен, инициируется еще отмена проведения документа и удаление движений данного документа (рис. 2.17). Обратите внимание: отмена проведения и удаление движений производятся при установке пометки удаления, только если документ был проведен. Если документ не был проведен, но имел движения, то при установке пометки удаления удаление движений не будет произведено. Если же для помеченного на удаление документа интерактивно снимается пометка удаления или применяется метод УстановитьПометкуУдаления(ЛОЖЬ), то инициируется запись документа с изменением значения на Ложь в поле ПометкаУдаления (рис. 2.18). Кроме того, значение свойства ПометкаУдаления объекта документа можно устанавливать программно и просто записывать документ. В таких случаях инициация события ОбработкаУдаленияПроведения не происходит. И если при этом документ был изначально не проведен, он записывается помеченным на удаление. Если же подобные действия выполняются для проведенного документа, то система выдает предупреждение о невозможности записи документа и проведенного, и помеченного на удаление (рис. 2.19). Глава 2. Документы и последовательности Рис. 2.17. Установка пометки на удаление Рис. 2.18. Снятие пометки удаления Рис. 2.19. Использование свойства «ПометкаУдаления» 155 156 Реализация прикладных задач в системе «1С:Предприятие 8.2» А вот возможность помеченного на удаление документа иметь движения может быть полезной, если по какой-то причине необходимо отражать в учете данные документа, готовящегося к удалению. Например, пока не будет проведен документ, его заменяющий. Сами события «Установка пометки на удаление» и «Снятие пометки удаления» с точки зрения документа выделенными процессами не являются. Поскольку в любом случае идет речь о записи помеченного на удаление документа (или со снятой пометкой), то все необходимые действия можно выполнить в обработчиках событий, связанных с записью документа. Например, если для документа ПоступлениеТоваров требуется «перехватить» изменение значения свойства ПометкаУдаления для уже записанного документа, можно поступить следующим образом (листинг 2.1). Листинг 2.1. Обработчик события «ПередЗаписью» Процедура ПередЗаписью(Отказ, РежимЗаписи, РежимПроведения) // Ограничить действия: только для записанных документов Если Не ЭтоНовый() Тогда // Получить пометку удаления текущего документа из базы данных Запрос = Новый Запрос; Запрос.Текст = "ВЫБРАТЬ | ПоступлениеТоваров.ПометкаУдаления |ИЗ | Документ.ПоступлениеТоваров КАК ПоступлениеТоваров |ГДЕ | ПоступлениеТоваров.Ссылка = &ТекущийДокумент"; Запрос.УстановитьПараметр("ТекущийДокумент", Ссылка); Результат = Запрос.Выполнить(); Выборка = Результат.Выбрать(); Выборка.Следующий(); // Сравнить текущее значение пометки удаления // и взятое из базы данных Если ПометкаУдаления <> Выборка.ПометкаУдаления Тогда Если ПометкаУдаления Тогда // Выполнить действия при установке пометки удаления // ... Иначе // Выполнить действия при снятии пометки удаления // ... КонецЕсли; КонецЕсли; КонецЕсли; КонецПроцедуры Глава 2. Документы и последовательности 157 Удаление документов Удаление документов может производиться в составе механизма контроля ссылочной целостности. А может иметь место и непосредственное удаление объектов. Использование механизма контроля ссылочной целостности при удалении объектов или неиспользование определяется разработчиком и администратором конфигурации. Если документ имеет движения по регистрам, то при непосредственном удалении документа система автоматически удалит их. Событие ПередУдалением может обрабатываться в модуле объекта документа. Например, если требуется позволить непосредственное удаление только тех документов, которые не имеют движений, достаточно сделать следующее (листинг 2.2). Листинг 2.2. Обработчик события «ПередУдалением» Процедура ПередУдалением(Отказ) Для Каждого НаборЗаписейРегистра из Движения Цикл // Прочитать движения по каждому регистру НаборЗаписейРегистра.Прочитать(); // Проверить наличие записей в движениях по конкретному регистру. Если НаборЗаписейРегистра.Количество()>0 Тогда Сообщение = Новый СообщениеПользователю; Сообщение.Текст = "Документ " + Метаданные().Представление() + " № " + Номер + " от " + Дата + " имеет движения!"; Сообщение.Сообщить(); Отказ = Истина; КонецЕсли; КонецЦикла; КонецПроцедуры Состав документов Что в себя включают документы? Рассмотрим этот вопрос, учитывая области абстрагирования, использующиеся для работы с объектами в системе. Потому что в каждой области абстрагирования документ описывается по-разному. Можно говорить о составе документа как прикладного объекта, используемого для организации прикладного решения. Можно как об объекте 158 Реализация прикладных задач в системе «1С:Предприятие 8.2» конфигурации, позволяющем организовать работу в отношении реализации прикладной задачи в рамках конфигурации. Можно о составе таблиц, полей, индексов, посредством которых организовано непосредственное хранение данных документов (рис. 2.20). Рис. 2.20. Понятие «Документ» Поскольку основной задачей документов как объектов прикладной области является регистрация событий, структура документов определяется именно этой задачей. Тогда что за информацию можно отражать в системе при регистрации события? Прежде всего, сам факт того, что событие произошло и когда оно произошло. Поэтому, как правило, для каждого события необходимо регистрировать порядковый номер этого события и дату происхождения. Соответственно, в состав любого документа включаются поля Номер и Дата. Это минимально возможный состав регистратора события. Действительно, могут иметь место ситуации, когда больше никакой информации относительно данных документа и не требуется. Например, для документов, отражающих регламентные операции («завершение периода», «снятие итогов» и т. п.). Для ситуаций, когда при регистрации события необходимо запоминать информацию, имеющую единичные значения для одного события, должны использоваться реквизиты документов. Например, Поставщик при регистрации факта поставки товаров. Для ситуации, когда при регистрации события необходимо запоминать информацию, имеющую множественные значения, необходимо использовать табличные части документов. Например, табличная часть Товары при регистрации факта поставки множества товаров. Глава 2. Документы и последовательности 159 Как объект конфигурации для обеспечения решения задач прикладной области документ обладает свойствами (автонумерация, проведение и т. д.) и имеет в своем составе подчиненные объекты: ■ Реквизиты документов – объекты, используемые для запоминания информации об объекте (документе), имеющей единичные значения для каждого экземпляра документа. ■ Табличные части документов – объекты, используемые для запоминания дополнительной информации об объекте, представляемой в виде таблиц. ■ Формы – объекты, используемые для обеспечения интерактивного ввода, просмотра и редактирования информации. ■ Команды – объекты, используемые для разработки командного интерфейса документа. В модулях команд находятся обработчики для их выполнения. ■ Макеты – объекты (например, табличные документы), обычно используемые при формировании печатных форм объекта. Для обеспечения возможности манипулирования данными при написании алгоритмов обработки информации документов используются соответствующие объекты встроенного языка. На самом нижнем уровне абстрагирования используются объекты информационной базы, обеспечивающие выполнение задач вышестоящих уровней. Структура таблиц базы данных На уровне объектов базы данных информация о документах хранится в следующих таблицах: ■ основная таблица документа, для каждого объекта конфигурации Документ; ■ таблица табличной части документа, для каждой табличной части каждого объекта конфигурации Документ. Структура полей этих таблиц следующая. Основная таблица документа: ■ ■ ■ ■ ■ Ссылка – уникальный идентификатор, позволяющий однозначно опреде- лить данную запись. ВерсияДанных – версия записи (изменяется после каждого обновления данной записи). ПометкаУдаления – Булево. Проведен – Булево. Дата – дата/время регистрируемого документа. 160 Реализация прикладных задач в системе «1С:Предприятие 8.2» ■ Номер – номер регистрируемого документа (поле существует, если доку- ■ … ■ РеквизитN – … мент как объект конфигурации имеет длину номера, отличную от нуля). ■ ПрефиксНомера – начало периода уникальности номера. Поле определено, если в конфигурации для документа задана поддержка уникальности номера в пределах периода. ■ Реквизит1 – тип значения поля определяется типом значения реквизита. Таблица табличной части документа: ■ Ссылка – ссылка на документ, которому подчинена данная запись. Содержит то же значение, что и поле Ссылка основной таблицы доку- ментов. Ключ – ключ записи табличной части в рамках одного объекта базы данных; ■ НомерСтроки – предопределенный реквизит табличной части, тип значения Число. ■ Реквизит1 – тип значения поля определяется типом значения реквизита. ■ ■ … ■ РеквизитN – … Допустим, в конфигурации для регистрации контактов – деловых встреч, звонков, писем – используется документ Событие (рис. 2.21). Рис. 2.21. Документ «Событие» В базе было записано 4 документа. 01.03.2010 был оформлен документ с номером Т-001, в котором зафиксировано проведение переговоров с контрагентом КомбиТранс и сторонней организацией Баязет. Далее 02.03.2010 был зафиксирован телефонный звонок Баязет документом Т-002. Глава 2. Документы и последовательности 161 Затем задним числом был введен документ Т-003, в котором зафиксирован выезд к заказчику Коринф. Последним документом с номером Т-004 был зафиксирован случайный звонок в офис. Данные этого документа в информационной базе будут храниться в таблице документа и таблице табличной части документа. Таблица документа будет иметь следующий вид (табл. 2.2). Таблица 2.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 Таблица 2.2. Таблица документа «Событие» (правая часть) Вид События Контрагент Описание События Ответственный Переговоры КомбиТранс Переговоры Иванов Телефонный звонок Баязет Выяснение реквизитов Петров Выезд к заказчику Коринф Переговоры Иванов Ошиблись номером Иванов Телефонный звонок Обратите внимание: записи в самой таблице упорядочены согласно хронологии ввода информации. Таблица табличной части документа будет содержать записи только для тех документов, у которых она была заполнена (табл. 2.3). Таблица 2.3. Таблица табличной части документа «Событие» Ссылка Номер строки Контрагент Лицо Док1 1 Баязет Семенов Док1 2 Баязет Горбунков Если к реквизитам документа добавить еще реквизит, система при изменении конфигурации базы данных добавит к таблице документа еще одну колонку. Причем для «старых» записей значения этого поля будут заполнены соответствующими типу значения реквизита значениями по умолчанию. Аналогичные действия в отношении таблицы табличной части документа будут произведены, если к реквизитам табличной части документа добавить еще один реквизит. 162 Реализация прикладных задач в системе «1С:Предприятие 8.2» Чтобы обеспечить должное быстродействие при обращении к данным информационной базы, для таблиц хранения информации документов создаются следующие индексы: ■ Ссылка; ■ Дата + Ссылка; ■ Номер + Ссылка – если для данного документа длина номера не равна ■ Реквизит + Ссылка – если для данного реквизита свойство Индексиро- нулю; вать установлено в значение Индексировать; Реквизит + Дата + Ссылка – если для данного реквизита свойство Индексировать установлено в значение Индексировать с доп. упорядочиванием; ■ Реквизит – если документ включен в критерий отбора через данный реквизит; ■ ПрефиксНомера + Номер + Ссылка – если для данного документа длина номера не равна нулю. Табличная модель обращения к данным (посредством запросов) дает возможность получения информации из этих таблиц в виде таблицы документа (табл. 2.4). ■ Отдельные вопросы . типового использования документов Нумерация документов Для решения бизнес-задач зачастую серьезным вопросом является нумерация документов. Например, существует даже такое понятие, как «документы строгой учетности», предъявляющие определенные требования к порядку ведения нумерации документов. Для обеспечения этого и других вопросов в системе созданы следующие возможности: На уровне объекта конфигурации Документ можно управлять свойствами: ■ Длина номера – определяет разрядность поля, отводимого под номер документа. ■ Контроль уникальности – определяет необходимость контроля неповторяемости номеров средствами системы перед записью объекта. ■ Автонумерация – определяет необходимость формирования новых номеров средствами системы при попытке создания новых объектов. РезультатЗапроса Произвольный, определяется типом реквизита <Реквизиты> <Табличные части> МоментВремени жащее имя документа, его номер и дату. Не может использоваться для операций сравнения в тексте запроса Виртуальное поле, не хранится в базе данных. Содержит объект МоментВремени (который включает в себя дату и ссылку на документ) Каждое из полей содержит значения реквизитов документа. Имена полей совпадают с названиями реквизитов, заданными для объекта конфигурации Каждое из полей содержит табличные части документа. Имена полей совпадают с названиями табличных частей, заданными для объекта конфигурации. Сами значения полей содержат результаты запросов по табличным частям документа. Результат запроса к табличной части состоит из колонок с именами, соответствующими именам реквизитов табличной части документа и колонки НомерСтроки МоментВремени Назначение ДокументСсылка.<Имя> Содержит ссылку на документ Строка Содержит версию данных документа Булево Содержит признак пометки на удаление Число, Строка Содержит номер документа Дата Содержит дату документа Булево Содержит признак проведенности документа Строка Виртуальное поле, не хранится в базе данных. Строковое представление, содер- Тип Ссылка ВерсияДанных ПометкаУдаления Номер Дата Проведен Представление Поле Таблица 2.4. Состав таблицы документа Глава 2. Документы и последовательности 163 164 Реализация прикладных задач в системе «1С:Предприятие 8.2» ■ Периодичность (Непериодический, В пределах года, В пределах квартала, В пределах месяца, В пределах дня) – определяет границы периодов контроля уникальности и повторяемости номеров автонумерации. ■ Тип номера (Строка, Число) – определяет тип поля Номер. ■ Нумератор – используется для возможности организации сквозной нумерации документов разных видов. Автоматическая нумерация Автоматическая нумерация позволяет создавать новые документы с заведомо уникальными номерами в пределах указанной периодичности. Для включения этой возможности достаточно установить флажок Автонумерация. Тогда система будет присваивать каждому новому документу номер, на единицу больший самого большого номера среди документов данного вида в пространстве префикса документа, в том периоде, к которому относится дата документа. Причем независимо от того, создается этот новый документ интерактивно или программным способом. Механизм автонумерации позволяет работать в двух режимах: в режиме с возвратом неиспользованных номеров и в режиме без возврата неиспользованных номеров. Режим устанавливается свойством объекта метаданных Конфигурация РежимАвтонумерацииОбъектов. Режим автонумерации прикладных объектов конфигурации определяет, использовать или нет автоматически полученные номера объектов, если они не записаны в базу данных. Для документов, требующих непрерывной нумерации, которая будет реализована при записи, свойство РежимАвтонумерацииОбъектов необходимо установить в значение НеОсвобождатьАвтоматически (этот режим устанавливается стандартно), а значение ОсвобождатьАвтоматически можно использовать для обеспечения механизма нумерации, аналогичного версии платформы «1С:Предприятие 8.0». За выдачу номеров отвечает специальный менеджер автонумерации. Его использование позволяет существенно повысить параллельность работы за счет отсутствия блокировок базы данных. Механизм автонумерации выдает номера в разрезе пространств номеров и префиксов. Пространство номера в зависимости от типа объекта может содержать метаданные, владельца, период и др. В пределах пространства номеров номер выдается в разрезе префиксов. Глава 2. Документы и последовательности 165 Префикс документа определяется системой путем приведения строковых номеров к числу. Причем к числовому формату цифры номеров приводятся от последней к первой, пока процесс не дойдет до символа, который невозможно распознать как число. После этого символы левой части номера считаются префиксами. По каждому префиксу хранится максимальный выданный номер, на основании которого выдается следующий номер. Один и тот же максимальный номер может соответствовать нескольким префиксам. Для получения максимального номера по пустому префиксу система определяет наибольший префикс по порядку алфавитного возрастания. Далее определяется самый большой номер с данным префиксом. Именно он впоследствии будет инкрементироваться для определения следующего номера. Приведем пример работы данного алгоритма. Допустим, в таблице документов содержатся записи со следующими номерами (табл. 2.5). Таблица 2.5. Номера документов Номер АТ0001 МП_0009 АТР-3 Ф002 Наибольший по алфавиту префикс – Ф. Поскольку самый старший номер с таким префиксом Ф002, то автонумерацией будет создан следующий номер: Ф003. При первом получении номера по определенному пространству номеров и префиксу выполняется неблокирующее чтение максимального номера из базы данных, т. е. механизм автонумерации использует базу данных для получения максимального номера по определенному пространству номеров и префиксу только один раз. При последующих попытках получить очередной номер механизм автонумерации использует максимальный номер по данному пространству номеров и префиксу, как было описано ранее. Ниже на схемах показаны возможные варианты использования автонумерации. Если у свойства Периодичность документа установлено значение Непериодический, то в результате автонумерации будем видеть такую картину (рис. 2.22). 166 Реализация прикладных задач в системе «1С:Предприятие 8.2» Рис. 2.22. Непериодическая автонумерация Если у свойства Периодичность документа установлено значение В пределах года, то в результате автонумерации будем видеть такую картину (рис. 2.23). Рис. 2.23. Автонумерация в пределах года Однако нельзя забывать о том, что при автонумерации следующий номер, выдаваемый системой, всегда на единицу больше самого старшего. Например, если в последнем примере (с периодичностью год) изменить дату «прошлогоднего документа», то можно получить такую картину: дата документа с номером 00118 была изменена на 01.01.2010. В результате последующие номера, формируемые автонумерацией, начинаются от 00119 (рис. 2.24). Рис. 2.24. Работа автонумерации при изменении даты документа Использование лидирующих нулей Если автонумерация применяется для номеров строкового типа, то в этом случае используются лидирующие нули в составе номера. Все пробелы перед самим номером замещаются нулями. Например, 00031. Это необходимо для обеспечения корректности поиска и сортировки по номеру. Иначе документ с номером 31 располагался бы раньше документа с номером 7 (рис. 2.25). Рис. 2.25. Использование лидирующих нулей Глава 2. Документы и последовательности 167 Параллельное ведение нумераций документов одного вида Например, выписываемые от разных юридических лиц накладные должны иметь нумерации, сквозные в пределах каждого отдельного юридического лица. Для решения этой проблемы устанавливается строковый тип номеров документа и автонумерация. Далее необходимо программно назначать префиксы автонумерации в обработчиках соответствующих событий. В результате система формирует новый номер по вышеописанным правилам, но только еще в пределах назначенного префикса автонумерации. Для назначения префикса автонумерации можно использовать обработчик события ПриУстановкеНовогоНомера или метод объекта документа УстановитьНовыйНомер(). Например, если необходимо установить новый номер в пределах префикса автонумерации, значение которого хранится в реквизите Префикс организации, указанной в реквизите документа Организация, тогда можно поступить следующим образом (листинг 2.3). Листинг 2.3. Установка нового номера в пределах префикса автонумерации Процедура ПриУстановкеНовогоНомера(СтандартнаяОбработка, Префикс) Префикс = Организация.Префикс; КонецПроцедуры Событие ПриУстановкеНовогоНомера вызывается при записи документа, только если для данного документа назначена автонумерация и только в транзакции записи, между событиями ПередЗаписью и ПриЗаписи объекта Документ (рис. 2.26). Если в процедуре-обработчике этого события параметру Префикс назначить значение, то именно это значение и будет использовано в качестве префикса автонумерации для установки нового номера. Если же, кроме того, номер документа необходимо менять в ответ на изменение значения реквизита Организация, то в соответствующем обработчике события можно применить метод объекта документа УстановитьНовыйНомер(). Он устанавливает новый номер документа в пределах периода, в соответствии с установленной датой документа для заданного префикса автонумерации (листинг 2.4). Рис. 2.26. Установка нового номера документа в транзакции записи документа 168 Реализация прикладных задач в системе «1С:Предприятие 8.2» Листинг 2.4. Обработчик события «ПриИзменении» элемента формы документа «Организация» &НаКлиенте Процедура ОрганизацияПриИзменении(Элемент) // Установить новый номер согласно префиксу организации УстановитьНовыйНомерНаСервере(); КонецПроцедуры Из обработчика события, возникающего при изменении элемента формы Организация, вызывается метод объекта документа УстановитьНовыйНомерНаСервере() (листинг 2.5). Листинг 2.5. Использование метода документа «УстановитьНовыйНомерНаСервере()» &НаСервере Процедура УстановитьНовыйНомерНаСервере() Документ = РеквизитФормыВЗначение("Объект"); Документ.УстановитьНовыйНомер(Объект.Организация.Префикс); ЗначениеВРеквизитФормы(Документ, "Объект"); КонецПроцедуры ПРИМЕЧАНИЕ Эти примеры приведены в демонстрационной конфигурации «Хранение информации и учет движения средств», которая находится на прилагаемом компакт-диске, для документа ПриходныйКассовыйОрдер. В результате подобных действий можно добиться того, что вне зависимости от порядка оформления документов по разным организациям нумерация будет сквозной именно по каждой из организаций. Вернее по префиксу каждой организации (рис. 2.27). Рис. 2.27. Автонумерация с использованием префиксов Хотелось бы упредить от попыток использования префиксов, которые целиком входят в состав других префиксов, например, АИ и А. В этом случае, как разбирали выше, при попытке формирования нового номера с префиксом А получим следующий номер от префиксации АИ. Дело в том, Глава 2. Документы и последовательности 169 что механизм автонумерации считает префикс А зависимым от префикса АИ и изменяет максимальный номер зависимых префиксов в соответствии с номером того префикса, в состав которого они входят. Организация сквозной нумерации при помощи нумераторов Кроме разделения нумерации может возникнуть обратная задача – обеспечение общей сквозной нумерации. Обычно это требуется, когда имеется несколько видов документов для отражения похожих хозяйственных операций, но необходимо организовать для них сквозную нумерацию, невзирая на вид документа (рис. 2.28). Рис. 2.28. Использование нумераторов Для решения такой задачи используется объект конфигурации Нумератор. В нем описываются: ■ Длина номера, ■ Контроль уникальности, ■ Периодичность, ■ Тип номера. Далее у всех документов – объектов конфигурации, для которых нужна сквозная нумерация, указывается этот нумератор и устанавливается свойство Автонумерация. В результате формирование нового номера производится при обращении уже не к одной таблице документов информационной базы, а к таблицам документов, которым назначен данный нумератор. Запись документов Запись документа может производиться как из формы документа, так и не из формы документа. В первом случае запись документа инициируется расширением формы документа (для функционирования этого расширения необходимо, чтобы основным реквизитом формы был объект документа). Работа расширения формы обеспечивает специфичное, удобное для пользователя поведение формы при редактировании и записи документа. 170 Реализация прикладных задач в системе «1С:Предприятие 8.2» Во втором случае форма документа не используется, а обращение идет непосредственно к объекту документа. При реализации записи документа из формы, кроме самой записи, выполняются еще стандартные действия, определяемые расширением формы: установка даты документа, установка режима проведения, запрет определенных действий пользователя и т. д. Подробно эти действия рассматриваются в разделе «Особенности работы формы документа» на стр. 195. При записи документа не из формы выполняется только запись документа (рис. 2.29). Рис. 2.29. Запись документа При выполнении самой записи документа производятся следующие действия: ■ Контроль уникальности номера документа. Выполняется, если у документа как объекта конфигурации установлено свойство Контроль уникальности. При этом если у документа установлено свойство Автонумерация, при попытке редактирования номера документа будет получено предупреждение: «Номер заполняется при записи автоматически. Продолжить редактирование?». Затем, если номер документа был изменен, в транзакции записи между событиями ПередЗаписью и ПриЗаписи объекта Документ выполняется контроль уникальности номера документа, и если номер не уникальный, то транзакция записи отменяется. ■ Проверка версии документа. Проверяется идентичность версий объекта документа и версии записей базы данных, хранящих данные этого документа. Если версии не совпадают, транзакция прерывается и выдается предупреждение: «Операция не может быть выполнена из-за несоответствия версии или отсутствия записи базы данных (возможно запись была изменена или удалена)!». Это необходимо, например, при следующей Глава 2. Документы и последовательности 171 ситуации: некой обработкой программно было обеспечено, что для двух пользователей были открыты формы одного и того же документа. Первый пользователь изменил значение Контрагента в документе, второй значение – Номенклатуры. На момент первой попытки записи измененного документа версии объекта документа и записей базы данных совпадут – документ будет записан. Но при попытке записи документа другим пользователем версии не совпадут, и система не позволит записать параллельно измененный документ, поскольку данное действие может породить коллизии. ■ Запись данных в таблицы документов. ■ Запись данных в таблицы табличных частей документов. Данное действие оптимизировано по скорости исполнения. Это происходит за счет автоматического различения ситуаций, когда необходимо записать (модифицировать) данные всех записей, подчиненных записываемому документу, или только одной записи. Причем если модифицированы были значения реквизитов документа, а не табличной части документа, то данное действие вообще не выполняется. ■ Запись данных в таблицы журналов, если данные документа используются в этих журналах. ■ Запись данных в таблицы регистрации изменений планов обменов, если данный документ входит в состав обмениваемых данных. Причем сама запись документа может вызываться интерактивно или программно. Интерактивно запись инициируется действиями пользователей, приводящими к выполнению системных действий: ■ «Записать»; ■ «Провести и закрыть»/«Записать и закрыть»; ■ «Провести»; ■ «Отмена проведения». Программно в контексте формы документа запись может быть инициирована посредством метода Записать() расширения формы документа. Причем методу может быть передана структура ПараметрыЗаписи, содержащая предопределенные параметры записи РежимЗаписи и РежимПроведения. Параметр РежимЗаписи содержит значения из системного перечисления РежимЗаписиДокумента: Запись, ОтменаПроведения, Проведение. В зависимости от значения параметра поведение системы будет различным. Например, для значения Запись будет вызвана запись данного документа без проведения, для значения Проведение – запись с проведением, для значения ОтменаПроведения – запись с отменой проведения. 172 Реализация прикладных задач в системе «1С:Предприятие 8.2» Параметр РежимПроведения используется в случае записи документа с проведением и содержит значения из системного перечисления РежимПроведенияДокумента: Неоперативный, Оперативный. Для значения Неоперативный будет выполнено неоперативное проведение документа, т. е. проведение выполняется не в реальном времени (например, проведение задним числом), для значения Оперативный будет выполнено оперативное проведение документа, т. е. проведение выполняется в реальном времени (например, при этом может быть выполнен контроль текущих остатков). Действие «Записать» При записи документа, вызванной интерактивным действием «Записать» или применением метода Записать(Новый Структура("РежимЗаписи", РежимЗаписиДокумента.Запись), кроме самой записи инициируется последовательность событий. Для непроведенного документа последовательность событий при записи из формы документа будет следующей (рис. 2.30а). Рис. 2.30а. Вызов событий при выполнении действия «Записать» для непроведенного документа Глава 2. Документы и последовательности 173 Следует иметь в виду, что для расширения формы документа платформа по умолчанию устанавливает свойство ПриЗаписиПерепроводить. То есть при записи проведенного документа будет автоматически выполняться его перепроведение. В этом случае для проведенного документа последовательность событий при записи из формы документа будет следующей (рис. 2.30б). Рис. 2.30б. Вызов событий при выполнении действия «Записать» для проведенного документа Если свойство ПриЗаписиПерепроводить у расширения формы документа не установлено, то последовательность событий при записи в форме для проведенного документа будет такой же, как и у непроведенного документа (см. рис. 2.30а). Для документа, у которого запрещено проведение (свойство Проведение установлено в значение Запретить), последовательность событий при записи из формы документа будет следующей (рис. 2.30в). 174 Реализация прикладных задач в системе «1С:Предприятие 8.2» Рис. 2.30в. Вызов событий при выполнении действия «Записать» для документа, у которого запрещено проведение Часть событий относится к контексту формы документа, и они могут быть перехвачены соответствующими обработчиками событий, располагаемыми в модуле формы документа. Часть событий относится к контексту объекта документа, и они могут быть перехвачены там. Заметьте, что при записи проведенного документа с перепроведением (см. рис. 2.30б) и при записи документа, у которого запрещено проведение (см. рис. 2.30в), кроме самой записи в контексте формы и в контексте объекта вызывается также событие ОбработкаПроверкиЗаполнения, которое вызывается расширением формы при необходимости проверки заполнения реквизитов при записи или при проведении документа в форме. В обработчиках этого события в модуле формы или в модуле объекта разработчик может самостоятельно реализовать проверку заполнения данных формы. В обработчиках события ПередЗаписью посредством установки параметру Отказ значения Истина можно предотвратить последующий набор действий. То есть, например, если установлен отказ в записи документа на уровне Глава 2. Документы и последовательности 175 контекста формы документа, то последующие в показанной выше схеме события уже не произойдут, поскольку платформа прекращает выполнение данной последовательности действий. Действия «Провести и закрыть», «Провести» В случае записи документа, вызванной интерактивными действиями «Провести и закрыть» (если у документа не запрещено проведение), «Провести» или применением метода Записать(Новый Структура("РежимЗаписи", РежимЗаписиДокумента.Проведение), кроме самой записи инициируются следующие события (рис. 2.31). Рис. 2.31. Вызов событий при выполнении действий «Провести и закрыть», «Провести» То есть добавляется еще одно событие – ОбработкаПроведения. Процедураобработчик этого события может находиться только в модуле объекта документа, предназначена для указания действий, которые нужно выполнить при проведении документа, и также имеет параметр Отказ. Действия с ним аналогичны предыдущему случаю. То есть последующие события уже не выполняются, если параметру Отказ установлено значение Истина. 176 Реализация прикладных задач в системе «1С:Предприятие 8.2» Действие «Отмена проведения» В случае записи документа, вызванной системным действиями «Отмена проведения» или применением метода Записать(Новый Структура("РежимЗаписи", РежимЗаписиДокумента.ОтменаПроведения), кроме самой записи инициируются следующие события (рис. 2.32). Рис. 2.32. Вызов событий при выполнении действия «Отмена проведения» То есть в этом случае появляется еще событие ОбработкаУдаленияПроведения. Процедура-обработчик этого события также может располагаться только в модуле объекта документа, содержит указание действий, которые должны быть выполнены при отмене проведения, и имеет параметр Отказ. Применение этого параметра аналогично разобранным выше случаям. В случаях, если запись документа производится не в форме, отличия состоят в том, что при выполнении этого действия не задействуются события, связанные с формой. Например, программная запись с проведением будет производиться следующим образом (рис. 2.33). Глава 2. Документы и последовательности 177 Рис. 2.33. Последовательность событий при программной записи объекта документа с проведением Проведение документов Ввод информации в документ в общем случае может осуществляться не за один раз. Кроме того, часть информации, необходимой для полной регистрации события в учетных механизмах, может становиться известной не сразу, а часть информации может быть получена в результате анализа и обработки исходной. Поэтому в системе есть возможность различать состояния документа – «введен» и «проведен». Для этого чаще всего разделяются операции ввода первичной информации (заполнение документа) и отражения данных документа в учете (обработка первичной информации и формирование движений), рис. 2.34. Обработку информации для отражения в учете и формирование движений по регистрам обычно выполняют при проведении документа. Данный механизм удобен для выполнения подобных действий. 178 Реализация прикладных задач в системе «1С:Предприятие 8.2» Рис. 2.34. Последовательность работы с документом Рассмотрим более подробно варианты проведения документов. Их использование определяется значениями свойств документа как объекта конфигурации, а именно: ■ ■ ■ ■ Проведение, Оперативное проведение, Удаление движений, Запись движений при проведении. Свойство «Проведение» объекта конфигурации Свойство Проведение объекта конфигурации Документ может иметь значения Разрешить или Запретить. В первом случае поведение документа соответствует вышеописанному (разделение операций заполнения документа и отражения его данных в учетных механизмах). То есть именно для таких документов имеют смысл работа с полем Проведен и процесс «Проведение». Если же свойство объекта конфигурации Проведение имеет значение Запретить, это означает, что такой документ вообще не должен проводиться. Такая ситуация может использоваться: ■ Для документов, для которых нет необходимости в индикации того, что выполнены изменения в учетных механизмах, либо когда такие изменения документами не производятся. ■ Для документов, которые используются для интерактивного ввода движений (например, документ Ручная операция). Поскольку в случае ручной операции нет разделения информации на исходную (инфор- Глава 2. Документы и последовательности 179 мацию документа) и обработанную (информация, записываемая в регистр со ссылкой на документ), информация сразу же вводится в регистр (рис. 2.35). Рис. 2.35. Ручная операция Для документов, у которых запрещено проведение, системное поле Проведен при записи получает значение Ложь. Но во всех таблицах, отображающих данные динамических списков документов или журналов документов, пиктограмма документов, у которых запрещено проведение, похожа на пиктограмму проведенных документов. Таким образом, система подсказывает пользователю, что больше никакой обработки для данных документов не требуется (рис. 2.36). Рис. 2.36. Пиктограмма документа, для которого запрещено проведение Поведение форм, основным реквизитом которых является объект или список документа, учитывает значение свойства Проведение. Например, в командной панели формы документа с запрещенным проведением система не создает кнопок с действиями «Провести» или «Отмена проведения». Однако система не запрещает попыток программной записи таких документов с проведением или с отменой проведения. Не запрещает, но все подобные попытки реализует по схеме обычной записи документа без проведения. 180 Реализация прикладных задач в системе «1С:Предприятие 8.2» Свойство «Оперативное проведение» объекта конфигурации Свойство Оперативное проведение объекта конфигурации Документ может иметь значения Разрешить или Запретить. Для документов, у которых данное свойство имеет значение Разрешить, разрешено использование механизма оперативного проведения. Поскольку посредством документов производится регистрация событий, причем на временной оси, то в общем случае положение проводимого документа может быть отнесено к прошлому, настоящему или будущему. Как правило, документы, относимые к прошлому, регистрируют уже произошедшие события. Обычно такой способ регистрации называют «задним числом». В настоящем регистрируются события, которые только-только происходят. Такой способ регистрации называют «реальным временем». Кроме того, бывают ситуации, когда событие должно быть зарегистрировано в будущем. Например, при решении задач планирования (рис. 2.37). Рис. 2.37. Общие случаи регистрации событий Оперативное проведение используется в ситуациях, когда есть необходимость отличать проведение в реальном режиме времени (оперативное) от другого и выполнять различные действия для одного и другого режимов. Вариант использования данного механизма может, например, включать разделение случаев (рис. 2.38): ■ когда документ проводится в реальном времени и есть необходимость, например, проконтролировать остаток товаров на складе при проведении документа; ■ когда проведение документа просто отражает уже свершившийся факт и нужно просто зафиксировать в учетных механизмах совершенное событие. Глава 2. Документы и последовательности 181 Рис. 2.38. Оперативное и неоперативное проведение С точки зрения технологических средств механизм оперативного проведения включает в себя: ■ Запрет проведения будущей датой. ■ Использование механизма оперативной отметки времени для принудительного изменения значения даты документа в случаях, когда это требуется. В ситуации, когда пользователи системы находятся в разных часовых поясах, в пределах одной информационной базы может существовать несколько последовательностей оперативных отметок времени, каждая – для своего часового пояса. ■ Передачу в обработчик события ОбработкаПроведения параметру РежимПроведения значения Оперативный системного перечисления РежимПроведенияДокумента. В каких случаях можно намеренно не использовать механизм оперативного проведения? В любых, когда его использование не требуется логикой решаемой задачи. Например: ■ когда нет нужды использовать разные алгоритмы проведения документов для оперативного или неоперативного режимов; ■ когда не требуется при проведении документов обеспечивать их расположение в определенном порядке на временной оси посредством выдачи оперативных отметок времени. При отказе от использования механизма оперативного проведения главное – не нарушить логику его использования для других документов. Например, если для проведения документа Поступление товаров используется один и тот же алгоритм для любого вида проведения, это еще не означает, что можно установить запрет использования режима оперативного проведения. Его проведение будущей датой изменит данные оперативных итогов регистров именно будущей датой. То есть будет различие между актуальными 182 Реализация прикладных задач в системе «1С:Предприятие 8.2» итогами регистров и итогами на момент оперативной отметки времени. Это может привести к нарушению логики использования механизма оперативного проведения для документов Реализация товаров. Свойство «Удаление движений» объекта конфигурации Свойство Удаление движений объекта конфигурации Документ может иметь значения Удалять автоматически при отмене проведения (стандартное значение), Удалять автоматически или Не удалять автоматически. В случае значения Удалять автоматически при отмене проведения для свойства Удаление движений движения, связанные с документом, удаляются автоматически только при удалении и отмене проведения документа. При проведении документа движения не удаляются, а перезаписываются. Такое поведение является стандартным для платформы «1С:Предприятие». Используя два других значения свойства Удаление движений, разработчик может реализовывать нестандартные сценарии проведения документа. В случае значения Удалять автоматически для свойства Удаление движений платформа сама автоматически удаляет старые записи движений, связанных с данным документом, в следующих ситуациях: ■ при записи документа с проведением (старые записи удаляются, а новые формируются); ■ при пометке документа на удаление (процесс, а не состояние); ■ при отмене проведения документа (процесс, а не состояние); В случае же значения Не удалять автоматически для свойства Удаление движений автоматическое удаление движений для этих ситуаций производиться не будет. Например, ответственность за правильность оформления заказов покупателей лежит на отделе продаж. Однако заказы выборочно контролируются финансовым отделом. При обнаружении нарушений в назначении цен документ снимается с проведения, что означает необходимость его дальнейшей доработки. Но движения по регистрам учета при этом удаляться не должны, чтобы не исключать данный заказ из учета вообще. Свойство «Запись движений при проведении» объекта конфигурации Свойство Запись движений при проведении объекта конфигурации Документ может иметь значения Записывать выбранные (стандартное значение) или Записывать модифицированные. Глава 2. Документы и последовательности 183 В случае значения Записывать выбранные разработчик должен в обработчике проведения документа в явном виде указать, какие наборы движений документа следует записывать. Для этого нужно установить свойство набора записей Записывать в значение Истина. После выхода из обработки проведения те наборы записей, у которых свойство Записывать все еще имеет значение Истина, будут автоматически записаны платформой. При выполнении записи движений, например, при оперативном проведении документа методом Записать(), свойство Записывать у записанных наборов движений сбрасывается в значение Ложь. Такое поведение является стандартным для платформы «1С:Предприятие» и оптимизирует запись измененных наборов записей без удаления движений в начале проведения. В случае значения Записывать модифицированные для свойства Запись движений при проведении после выхода из обработки проведения все модифицированные наборы записей будут автоматически записаны платформой. Свойства «Привилегированный режим при проведении», «Привилегированный режим при отмене проведения» объекта конфигурации Для ускорения работы с документом платформа стандартно устанавливает свойства документа Привилегированный режим при проведении и Привилегированный режим при отмене проведения. В результате проведение и отмена проведения документа выполняются на сервере, без контроля прав, максимально быстро. Использование механизма оперативного проведения Рассмотрим, как работает механизм при интерактивном проведении из формы документа. Пусть документу как объекту конфигурации разрешено оперативное проведение (свойство Оперативное проведение имеет значение Разрешить), и свойство ИспользоватьРежимПроведения расширения формы документа имеет значение Автоматически. При этом значении режим проведения документов из формы будет подбираться системой автоматически, исходя из даты документа, позиции документа по отношению к оперативной отметке времени и других параметров. Запрет проведения будущей датой При проведении документа система прежде всего проверит положение даты документа относительно текущей даты сеанса. Текущая дата сеанса равна системной дате компьютера, приведенной к часовому поясу сеанса. 184 Реализация прикладных задач в системе «1С:Предприятие 8.2» В свою очередь, часовой пояс сеанса изначально равен часовому поясу информационной базы (если он установлен – УстановитьЧасовойПоясИнформационнойБазы()) или часовому поясу сервера. Часовой пояс сеанса можно установить программно – УстановитьЧасовойПоясСеанса(). Если дата документа на день позже текущей даты сеанса, пользователь получит предупреждение: «Дата оперативно проводимого документа больше текущей. Документ не может быть проведен оперативно!». Проведение при этом не состоится. Если дата документа на день меньше текущей даты сеанса, документ будет проведен неоперативно. Если обе даты определяют один и тот же день, система принимает решение, что документ может быть проведен оперативно, то есть реальным временем. Механизм оперативной отметки времени Для того чтобы документы располагались последовательно и не попадали внутрь одной секунды (внутри одной секунды порядок следования не будет зависеть от разработчика), система выполняет автоматическое изменение времени документа. Дата документа получает значение оперативной отметки времени, которая рассчитывается системой по определенному алгоритму. Далее управление передается обработчику события ОбработкаПроведения, при этом параметр РежимПроведения получает значение РежимПроведенияДокумента.Оперативный (рис. 2.39). Рис. 2.39. Использование оперативной отметки времени Глава 2. Документы и последовательности 185 Механизм оперативной отметки времени позволяет при параллельной работе пользователей записывать оперативно проводимые документы с возрастающей последовательностью значений свойства Дата. Дата оперативно проводимого документа получается равной текущей дате сеанса или на секунду больше предыдущей выданной оперативной отметки времени (рис. 2.40). Рис. 2.40. Формирование оперативной отметки времени Если одновременно проводить оперативно несколько документов, то результат работы данного механизма можно представить следующим образом (рис. 2.41). Рис. 2.41. Использование оперативной отметки времени 186 Реализация прикладных задач в системе «1С:Предприятие 8.2» Как уже говорилось выше, в пределах одной информационной базы может существовать несколько последовательностей оперативных отметок времени. Если все пользователи работают в одном и том же часовом поясе, то тогда последовательность оперативных отметок времени будет одна-единственная. Если же есть пользователи, работающие в других часовых поясах, тогда таких последовательностей будет несколько, каждая для своего часового пояса. Последняя выданная оперативная отметка времени для каждого часового пояса сеанса хранится до момента выхода из программы последнего пользователя (включая и режим работы Конфигуратор). В клиент-серверном варианте работы системы эти отметки хранятся на сервере, в оперативной памяти. Хранение и выдачу оперативных отметок времени на сервере поддерживает сервис времени. В файловом варианте работы системы такие отметки хранятся в специальной служебной таблице информационной базы. Получение оперативной отметки времени может выполняться не только автоматически, но и разработчиком посредством метода ПолучитьОперативнуюОтметкуВремени() (листинг 2.6). Листинг 2.6. Получение оперативной отметки времени НоваяОперативнаяОтметкаВремени = ПолучитьОперативнуюОтметкуВремени(); Хотелось бы обратить внимание на ограничение формирования даты документа при интерактивном проведении документа в пределах дня. Если в рамках одного дня уже выдана оперативная отметка времени со временем 23:59:59, то следующий оперативно проводимый документ того же дня выдаст пользователю сообщение о невозможности провести данный документ оперативно (в рамках того же дня) – «Дата документа не соответствует текущей дате или дате последнего оперативно проведенного документа. Документ не может быть проведен оперативно!», и проведение документа не состоится (рис. 2.42). Рис. 2.42. Получение оперативной отметки времени следующим днем Глава 2. Документы и последовательности 187 Сделано это потому, что дата документа может иметь юридическое значение. Поэтому в такой ситуации у пользователя есть два варианта: изменить дату документа следующим днем и провести документ оперативно или же иметь возможность провести документ неоперативно. Однако для того, чтобы пользователь мог выбирать режим проведения, свойство ИспользоватьРежимПроведения расширения формы документа должно быть установлено в значение Запрашивать, и у пользователя должно быть право на неоперативное проведение. Если же свойство ИспользоватьРежимПроведения имеет значение Автоматически или Оперативный, то платформа будет пытаться выполнить оперативное проведение документа, что приведет к сообщению об ошибке. Подробно о режимах проведения документа из формы рассказывается в разделе «Установка режима проведения» на стр. 198. Налицо определенное ограничение, накладываемое системой. Однако в практике ввода документов реальным временем столкнуться с ним почти невозможно. Для воспроизведения такой ситуации требуется, чтобы, например, 61 одновременно работающий пользователь в течение последней минуты уходящего дня начал проведение оперативно проводимых документов. Если же все же подобная ситуации при автоматизации некоего предприятия с ночным режимом работы имеет место, 61-й и последующие документы, скорее всего, можно уже датировать следующим днем либо обеспечить их возможность проведения в неоперативном режиме. Ведь невозможность оперативного проведения еще не означает невозможность проведения вообще. Кроме того, запись документов с проведением может еще вызываться и программно. В таком случае можно указать режим проведения в параметре РежимПроведения (листинг 2.7). Листинг 2.7. Указание режима программного проведения документа Записать(РежимЗаписиДокумента.Проведение, РежимПроведенияДокумента.Оперативный); Тогда поведение системы в отношении установки даты документа и передачи параметра обработчику события ОбработкаПроведения будет соответствовать оперативному проведению. Однако необходимо помнить, что дата документа при этом должна соответствовать дню текущей даты сеанса. Иначе обработка проведения пойдет по схеме неоперативного проведения. 188 Реализация прикладных задач в системе «1С:Предприятие 8.2» Проблемы выдачи оперативной отметки времени после 23:59:59 при программной записи документов с оперативным проведением нет. Поскольку программное проведение означает вмешательство неких алгоритмов в ход формирования, заполнения и записи документов, то в данном случае может оказаться, что некому реагировать на предупреждение о невозможности оперативного проведения в рамках того же дня. Поэтому система для подобного документа просто сформирует дату на секунду больше последней оперативной отметки времени. Если потребуется не допустить формирования и проведения документов с датой будущего дня, это можно обеспечить программно, в составе соответствующих обработчиков. Передача значения «Оперативный» в параметр «РежимПроведения» обработчика события «ОбработкаПроведения» Итак, при оперативном проведении документов система позволяет добиться расстановки документов в идеальной хронологической последовательности (каждое событие зарегистрировано на момент его отражения в учете) и, кроме того, известить об этом обработчик проведения. То есть с точки зрения отражения документа в учете сам механизм оперативного проведения не выполняет никаких действий, он только передает параметр в обработчик проведения. Что это дает разработчику? Дает возможность отличать ситуации проведения документов реальным временем от иных ситуаций. А это уже впоследствии может быть использовано для решения прикладных задач. Может использоваться следующая градация действий при проведении документов: ■ при оперативном проведении – помощь пользователю посредством контроля возможности операции и правильности ее оформления, после этого – отражение ее в учетных механизмах; ■ при неоперативном проведении – отражение в учетных механизмах факта свершившегося события без всякой обработки. То есть, например, при проведении документа РеализацияТоваров алгоритм обработки оперативного проведения будет контролировать остатки товаров, перечисленных в табличной части документа, на складе, указанном в документе. Для этого в процедуре обработки проведения после записи движений документа будут получены актуальные остатки расходуемых товаров из регистра накопления ТоварыНаСкладах. В случае отрицательных остатков какого-либо товара на складе (а значит, невозможности отгрузки) пользователь будет получать соответствующее сообщение, и документ проводиться не будет. Глава 2. Документы и последовательности 189 Если пользователь проводит документ, соответствующий уже произошедшему событию (неоперативно), нужда в контроле остатка отпадает. Например, вчера отключилось электричество, и не успели отразить в программе операцию отгрузки двух холодильников со склада. Вводя сегодня данные о событии вчерашней отгрузки, контролировать возможность данной операции уже бессмысленно, поскольку холодильники уже отгружены (листинг 2.8). ПРИМЕЧАНИЕ Пример алгоритма проведения документа РеализацияТоваров содержится в демонстрационной конфигурации «Хранение информации и учет движения средств», которая находится на прилагаемом компакт-диске. Листинг 2.8. Пример процедуры «ОбработкаПроведения» Процедура ОбработкаПроведения(Отказ, РежимПроведения) // Укажем, по каким регистрам нужно записывать движения Движения.ТоварыНаСкладах.Записывать = Истина; Движения.Продажи.Записывать = Истина; // Создать менеджер временных таблиц МенеджерВТ = Новый МенеджерВременныхТаблиц; Запрос = Новый Запрос; // Укажем, какой менеджер временных таблиц использует этот запрос Запрос.МенеджерВременныхТаблиц = МенеджерВТ; Запрос.Текст = "ВЫБРАТЬ | РеализацияТоваровСостав.Номенклатура, | РеализацияТоваровСостав.Номенклатура.Услуга КАК Услуга, | СУММА(РеализацияТоваровСостав.Количество) КАК КоличествоВДокументе, | СУММА(РеализацияТоваровСостав.Сумма) КАК СуммаВДокументе |ПОМЕСТИТЬ НоменклатураДокумента |ИЗ | Документ.РеализацияТоваров.Состав КАК РеализацияТоваровСостав |ГДЕ | РеализацияТоваровСостав.Ссылка = &Ссылка | |СГРУППИРОВАТЬ ПО | РеализацияТоваровСостав.Номенклатура, | РеализацияТоваровСостав.Номенклатура.Услуга"; Запрос.УстановитьПараметр("Ссылка", Ссылка); Результат = Запрос.Выполнить(); Запрос2 = Новый Запрос; Запрос2.МенеджерВременныхТаблиц = МенеджерВТ; Запрос2.Текст = "ВЫБРАТЬ | НоменклатураДокумента.Номенклатура, | НоменклатураДокумента.Услуга, | НоменклатураДокумента.КоличествоВДокументе, 190 Реализация прикладных задач в системе «1С:Предприятие 8.2» | ЕСТЬNULL(НоменклатураДокумента.СуммаВДокументе, 0) КАК СуммаВДокументе |ИЗ | НоменклатураДокумента КАК НоменклатураДокумента"; Если РежимПроведения = РежимПроведенияДокумента.Оперативный Тогда // Установим необходимость блокировки данных в регистре ТоварыНаСкладах Движения.ТоварыНаСкладах.БлокироватьДляИзменения = Истина; // Запишем пустые наборы записей, чтобы читать остатки без учета данных в документе Движения.ТоварыНаСкладах.Записать(); КонецЕсли; Результат = Запрос2.Выполнить(); ВыборкаДетальныеЗаписи = Результат.Выбрать(); Пока ВыборкаДетальныеЗаписи.Следующий() Цикл Если НЕ ВыборкаДетальныеЗаписи.Услуга Тогда // Сформировать движения по регистру ТоварыНаСкладах (расход) Движение = Движения.ТоварыНаСкладах.Добавить(); Движение.ВидДвижения = ВидДвиженияНакопления.Расход; Движение.Период = Дата; Движение.Номенклатура = ВыборкаДетальныеЗаписи.Номенклатура; Движение.Склад = Склад; Движение.Количество = ВыборкаДетальныеЗаписи.КоличествоВДокументе; КонецЕсли; // Сформировать движения по регистру Продажи Движение = Движения.Продажи.Добавить(); Движение.Период = Дата; Движение.Номенклатура = ВыборкаДетальныеЗаписи.Номенклатура; Движение.Контрагент = Контрагент; Движение.Количество = ВыборкаДетальныеЗаписи.КоличествоВДокументе; Движение.Сумма = ВыборкаДетальныеЗаписи.СуммаВДокументе; Движение.ВидОперации = ВидОперации; КонецЦикла; Движения.Записать(); Если РежимПроведения = РежимПроведенияДокумента.Оперативный Тогда // Проверить отрицательные остатки Запрос3 = Новый Запрос; Запрос3.МенеджерВременныхТаблиц = МенеджерВТ; Запрос3.Текст = "ВЫБРАТЬ | ТоварыНаСкладахОстатки.Номенклатура, | ТоварыНаСкладахОстатки.КоличествоОстаток |ИЗ | РегистрНакопления.ТоварыНаСкладах.Остатки( | , | Номенклатура В | (ВЫБРАТЬ | НоменклатураДокумента.Номенклатура | ИЗ | НоменклатураДокумента) | И Склад = &Склад) КАК ТоварыНаСкладахОстатки |ГДЕ | ТоварыНаСкладахОстатки.КоличествоОстаток < 0"; Запрос3.УстановитьПараметр("Склад", Склад); Глава 2. Документы и последовательности 191 РезультатСНехваткой = Запрос3.Выполнить(); ВыборкаРезультатаСНехваткой = РезультатСНехваткой.Выбрать(); Пока ВыборкаРезультатаСНехваткой.Следующий() Цикл Сообщение = Новый СообщениеПользователю(); Сообщение.Текст = "Не хватает " + Строка(- ВыборкаРезультатаСНехваткой .КоличествоОстаток) + " единиц товара """ + ВыборкаРезультатаСНехваткой .Номенклатура + """ на складе """ + Склад + "."; Сообщение.Сообщить(); Отказ = Истина; КонецЦикла; КонецЕсли; КонецПроцедуры Рассмотрим подробно последовательность действий в процедуре ОбработкаПроведения. Сначала в обработчике указываются наборы записей, содержащие движения документа по регистрам, которые должны быть записаны при проведении документа. Для этого нужным наборам записей устанавливается свойство Записывать в значение Истина (например, Движения.ТоварыНаСкладах.Записывать = Истина). Затем данные табличной части документа РеализацияТоваров помещаются во временную таблицу. Эти данные посредством менеджера временных таблиц будут затем использованы в запросе для формирования движений документа и в запросе к регистру накопления для контроля остатков товаров на складах. Заметьте, что данные табличной части документа группируются по полям Номенклатура и Услуга, чтобы суммировать поля Количество и Сумма при наличии в документе нескольких строк с одинаковой номенклатурой. Затем в случае оперативного проведения документа (РежимПроведения = РежимПроведенияДокумента.Оперативный) данные регистра ТоварыНаСкладах блокируются путем установки свойства БлокироватьДляИзменения в значение Истина. Это делается для того, чтобы заблокировать остатки от чтения другими транзакциями до тех пор, пока не будет завершена текущая транзакция. А также движения данного документа в регистре очищаются путем записи пустого набора данных (Движения.ТоварыНаСкладах.Записать()). Это обеспечивает чтение остатков без учета существующих движений документа (в случае его перепроведения). Далее выполняется запрос к временной таблице, содержащей перечень расходуемых товаров, и в цикле выборки результата запроса формируются движения по нужным регистрам. Затем движения документа в регистрах 192 Реализация прикладных задач в системе «1С:Предприятие 8.2» записываются в явном виде (Движения.Записать()). Метод Записать() выполняет запись всех наборов движений, у которых свойство Записывать установлено в значение Истина. И, наконец, при оперативном проведении выполняется контроль достаточности остатка товаров на складе. Для этого после записи движений выполняется запрос для получения отрицательных остатков номенклатуры, содержащейся во временной таблице, и на складе, указанном в документе. После этого выборка записей запроса обходится в цикле, и, если есть такие записи, сообщение о них выводится пользователю. В результате документ не проводится, т. к. параметру Отказ присваивается значение Истина. Если каждый документ, формирующий движения в количественном учете, будет проводиться с поддержкой механизма оперативного проведения и движения его будут датироваться именно датой документа, то можно быть уверенным в двух фактах: ■ Не будет ситуации, когда два документа претендуют на одно и то же время (механизм выдачи оперативной отметки времени распределит их с интервалом в секунду). ■ Текущий проводимый документ находится на временной оси всегда позже последнего оперативно проведенного документа. А это важно при получении остатков из регистров. Так как кроме движений и помесячных остатков таблицы регистров хранят еще подсчитанные итоги, актуальные на момент времени последней записи в них. И если мы уверены, что «за» оперативной отметкой времени не было движений, то тогда для получения актуальных данных контроля остатка можно использовать виртуальную таблицу остатков регистра без указания параметра Период (или с указанием значения Неопределено в качестве его значения). Данная операция будет выполняться быстрее, если в качестве параметра передать значение момента времени документа. Потому что при отсутствии параметра система не будет пытаться обращаться к таблице записей регистра для «досчета» остатков до нужной временной точки, а сразу возьмет данные последних актуальных итогов из таблицы итогов данного регистра (рис. 2.43). Но нужно понимать, что для корректности использования механизма оперативного проведения при данном алгоритме работы необходимо сделать так, чтобы никакими способами не были сформированы движения в будущем. Иначе использование актуальных итогов регистров в обработке проведения будет невозможно (вернее придется рассчитывать регистры на момент времени документа, но тогда какой смысл в оперативной работе, если при этом итоги регистров не будут актуальны на момент оперативно проводимого документа). Глава 2. Документы и последовательности 193 Рис. 2.43. Получение итогов регистра В основном это обеспечивается системой: стандартные команды форм не позволяют пользователю оперативно проводить документы будущей датой и не предлагают в таких случаях проводить документы неоперативно. Кроме того, система при выполнении попытки программной записи с проведением в оперативном режиме (листинг 2.9) сначала выполняет проверку положения даты документа относительно дня оперативной отметки времени. Листинг 2.9. Оперативное программное проведение документа Записать(РежимЗаписиДокумента.Проведение, РежимПроведенияДокумента.Оперативный); И если документ пытаются записать в будущем, выдается соответствующее предупреждение о невозможности выполнения данной операции. Но вот программное неоперативное проведение документов система не запрещает. Кроме того, при формировании движений можно добиться ситуации, чтобы Период движения не совпадал со значением Дата документа. То есть в принципе движения могут быть сформированы будущей датой. Ответственность за недопущение подобных фактов – на разработчике. В завершение хотелось бы отметить, что использование механизма оперативного проведения может быть составной частью более сложных алгоритмов. Например, для того, чтобы во время активного ввода информации сократить количество действий по отражению документов в учете (а значит, обеспечить большую скорость проведения документов), часть этих действий не выполняется при неоперативном проведении, а часть относится на действия, выполняемые регламентными обработками. 194 Реализация прикладных задач в системе «1С:Предприятие 8.2» Стратегия отражения документов в учетных механизмах выглядит тогда следующим образом: ■ при оперативном проведении – помощь пользователю посредством контроля возможности операции и правильности ее оформления, отражение совершаемого события только в механизмах, обеспечивающих контрольные функции при оперативном проведении других документов; ■ при неоперативном проведении – отражение факта свершившегося события без всякой обработки и только в учетных механизмах; ■ при проведении специальной регламентной обработкой – отдельно для каждого зарегистрированного события контроль возможности и правильности его оформления, отражение данного события во всех оставшихся учетных механизмах. Примером подобного использования механизма оперативного проведения можно считать задачу проведения документа, отражающего реализацию товаров со склада не только в количественном, но и в количественно-стоимостном учете. Постановка задачи может быть следующей: при реализации товаров со склада реальным временем (оперативное проведение) необходимо предварительно выполнить ряд проверок правомерности этой операции (наличие достаточного остатка на складе, контроль предоплаты со стороны покупателя). Эти проверки и сама регистрация факта отгрузки в количественном учете товаров на складе выполняются в обработке проведения документа. Если же требуется проведение документа реализации задним числом (неоперативное проведение), это означает необходимость отражения уже свершившегося факта. Тогда не требуется проверять предоплату и наличие товаров на складе, поскольку товар уже отгружен клиенту. Нужно просто отразить факт отгрузки в количественном учете товаров на складе при проведении документа. Окончательное же отражение произошедших событий в механизме количественно-стоимостного учета товаров на складе производится посредством отдельной регламентной обработки, которая будет выполняться не в период активного ввода первичной информации, а впоследствии. При ее выполнении будут собраны все необходимые данные для всех еще не полностью отраженных событий, проведены все необходимые проверки и расчеты, и приписаны необходимые движения к документам реализации. Периодичность выполнения этой обработки определяется пользователем. Например, чтобы быть достаточной для получения регламентной отчетности (рис. 2.44). Глава 2. Документы и последовательности 195 Рис. 2.44. Проведение документа «Реализация товаров» В случаях отказа от использования оперативного проведения разработчику достаточно лишь установить свойству Оперативное проведение документа как объекта конфигурации значение Запретить. И тогда все необходимые элементы работы механизма проведения придется реализовывать самостоятельно. То есть, например, при проведении документа предварительно проводить контроль даты документа, контроль возможности проведения документа и т. д. Особенности работы формы документа Если основной реквизит формы имеет тип значения ДокументОбъект.<имя>, то для данной формы действует расширение формы документа. Посредством него решаются вопросы специфичной функциональности формы документа. Расширение помогает обрабатывать различные команды пользователя, выполнять предварительные проверки и другие сервисные действия. Кроме того, действие расширения формы документа распространяется и на механизмы записи и проведения документа. При этом не важно, была вызвана запись документа интерактивными действиями пользователя в форме документа или средствами языка методом Записать(). Рассмотрим ряд примеров работы этих механизмов. 196 Реализация прикладных задач в системе «1С:Предприятие 8.2» Установка даты документа при открытии формы Если дата документа изначально не установлена, то при открытии формы нового документа происходит установка дате документа значения текущей даты сеанса. Причем время документа будет установлено в зависимости от следующих настроек. Если свойство АвтоВремя расширения формы документа имеет значение НеИспользовать, то время документа будет установлено по значению текущей даты сеанса. В остальных случаях дате документа присваивается время начала дня (00:00:00), рис. 2.45. Рис. 2.45. Установка даты нового документа при открытии формы документа Установка даты нового документа при записи нового документа в форме При записи документа в режиме оперативного проведения значение даты документа устанавливается согласно выданной оперативной отметке времени. Тут настройки свойств расширения формы не играют роли. Но если время документа «нулевое» (0:00:00), то при неоперативном проведении документа оно будет изменено согласно настройкам свойства АвтоВремя (рис. 2.46). Исключение – когда АвтоВремя имеет значение НеИспользовать. Тогда время документа не меняется. Глава 2. Документы и последовательности 197 Рис. 2.46. Установка даты нового документа при записи документа в форме Запрет интерактивной записи проведенного документа без проведения (перепроведения) Запрет интерактивной записи документа без проведения (перепроведения) используется, чтобы не создавалась, например, такая ситуация: сначала документ реализации был заполнен и проведен, при проведении сформированы движения по регистру с указанием количества, соответствующего количеству в документе. После этого пользователь исправил данные документа и сохранил без проведения (рис. 2.47). Рис. 2.47. Данные документа «РеализацияТоваров» и движения документа в регистре «ТоварыНаСкладах» 198 Реализация прикладных задач в системе «1С:Предприятие 8.2» В результате таких манипуляций в документе будут записаны новые данные, а в движениях по регистру останутся данные от прошлого проведения документа, то есть они никак не будут соответствовать текущим данным документа. Предотвращение подобных ситуаций достигается за счет установки свойства расширения формы документа ПриЗаписиПерепроводить в значение Истина. Тогда отказ в обработке проведения приведет к откату транзакции – документ не будет и перезаписан. Установка режима проведения При проведении документа из формы система проверяет наличие у пользователя соответствующих прав (Проведение, Интерактивное проведение, Интерактивное проведение неоперативное). Если их нет, то выдается сообщение о невозможности проведения документа, и запись с проведением документа из формы отменяется. Мы будем рассматривать только возможность отсутствия/наличия прав на неоперативное проведение, в зависимости от которого система может менять свое поведение, так как если нет первых двух прав, то документ не может быть проведен из формы в принципе. Если интерактивное проведение разрешено, сам выбор варианта проведения должен быть обусловлен логикой применения механизма установки режима проведения из формы. То есть в некоторых ситуациях система должна выбирать режим жестко, в некоторых право выбора режима можно предоставить пользователю. Для этого разработчик обладает рядом возможностей, предоставляемых системой посредством разграничения прав и расширениями формы документа. При записи документа из формы расширение формы документа выполняет установку режима проведения документа. Для реализации данного функционала система использует вариант (Автоматически, Оперативный, Неоперативный, Запрашивать), указанный в качестве значения свойства ИспользоватьРежимПроведения расширения формы документа. Вариант «Автоматически» Вариант Автоматически устанавливается посредством выбора значения Автоматически у свойства ИспользоватьРежимПроведения расширения формы документа. Платформа стандартно устанавливает это значение для новой формы. При использовании данного варианта, в зависимости от ситуации и настроек, происходит первичный подбор режима проведения из вариантов Оперативный или Неоперативный. Глава 2. Документы и последовательности 199 Для проводимого документа происходит проверка положения даты документа относительно текущей даты сеанса. Если дата документа (без учета времени) равна текущей дате сеанса, то система автоматически выбирает вариант проведения Оперативный. Если дата документа (без учета времени) больше текущей даты сеанса, пользователю выдается предупреждение: «Дата оперативно проводимого документа больше текущей. Документ не может быть проведен оперативно!», и проведение документа отменяется. Если дата документа (без учета времени) меньше текущей даты сеанса, выбирается вариант проведения Неоперативный. При этом если у пользователя нет права на неоперативное проведение, выдается предупреждение: «Недостаточно прав для неоперативного проведения», и проведение документа отменяется (рис. 2.48). Рис. 2.48. Использование режима проведения «Автоматически» Вариант «Оперативный» Вариант Оперативный устанавливается посредством выбора значения Оперативный у свойства ИспользоватьРежимПроведения расширения формы документа. 200 Реализация прикладных задач в системе «1С:Предприятие 8.2» В данном варианте, если дата документа (без учета времени) меньше текущей даты сеанса, выдается предупреждение: «Дата оперативно проводимого документа меньше текущей. Документ не может быть проведен оперативно!», и проведение документа отменяется. Если дата документа (без учета времени) равна текущей дате сеанса, производится запись документа с оперативным проведением. Если дата документа (без учета времени) больше текущей даты сеанса, выдается предупреждение: «Дата оперативно проводимого документа больше текущей. Документ не может быть проведен оперативно!», и проведение документа отменяется (рис. 2.49). Рис. 2.49. Использование режима проведения «Оперативный» Вариант «Неоперативный» Вариант Неоперативный устанавливается посредством выбора значения Неоперативный у свойства ИспользоватьРежимПроведения расширения формы документа. При использовании данного варианта проведение документа из формы всегда производится в неоперативном режиме, независимо от положения даты документа по отношению к текущей дате сеанса. Глава 2. Документы и последовательности 201 При этом если у пользователя нет права на неоперативное проведение, выдается предупреждение: «Недостаточно прав для неоперативного проведения», и проведение документа отменяется (рис. 2.50). Рис. 2.50. Использование режима проведения «Неоперативный» Вариант «Запрашивать» Вариант Запрашивать устанавливается посредством выбора значения Запрашивать у свойства ИспользоватьРежимПроведения расширения формы документа. Данный вариант реализован в системе для того, чтобы помочь пользователю принять решение о выборе режима проведения для каждой конкретной ситуации. В данном варианте пользователь перед началом проведения должен будет выбрать режим проведения документа в специальном системном окне (рис. 2.51). Рис. 2.51. Выбор режима проведения Поведение системы при этом варианте определяется прежде всего положением даты документа (без времени) по отношению к текущей дате сеанса. 202 Реализация прикладных задач в системе «1С:Предприятие 8.2» При равенстве этих дат далее проверяется, имеет ли пользователь право проводить документ неоперативно. Если пользователь такого права не имеет, система проводит данный документ в оперативном режиме. Если право на неоперативное проведение есть, пользователю выдается диалог с режимом выбора проведения. После выбора режима проведения система проводит документ соответственно в оперативном или неоперативном режиме (рис. 2.52). Рис. 2.52. Использование режима проведения «Запрашивать» при условии равенства даты документа и текущей даты сеанса Если дата документа (без учета времени) меньше текущей даты сеанса, поведение системы определяется опять же наличием права на неоперативное проведение у пользователя. Если пользователь таким правом не обладает, выдается предупреждение: «Дата оперативно проводимого документа меньше текущей. Документ не может быть проведен оперативно!», и проведение документа отменяется. Если право на неоперативное проведение есть, пользователю выдается диалог с режимом выбора проведения. После выбора неоперативного режима проведения система проводит документ в неоперативном режиме. Если же пользователь выберет оперативный режим проведения, выдается предупреж- Глава 2. Документы и последовательности 203 дение: «Дата оперативно проводимого документа меньше текущей. Документ не может быть проведен оперативно!», и проведение документа отменяется (рис. 2.53). Рис. 2.53. Использование режима проведения «Запрашивать» при условии, что дата документа меньше текущей даты сеанса Если дата документа (без учета времени) больше текущей даты сеанса, система не позволяет проводить документ оперативно. Поэтому если права неоперативного проведения нет, сразу выдается предупреждение: «Дата оперативно проводимого документа больше текущей. Документ не может быть проведен оперативно!», и проведение документа отменяется. Если право на неоперативное проведение есть, пользователю выдается диалог с режимом выбора проведения. После выбора неоперативного режима проведения система проводит документ в неоперативном режиме. Если же пользователь выберет оперативный режим проведения, будет выдано предупреждение: «Дата оперативно проводимого документа больше текущей. Документ не может быть проведен оперативно!», и проведение документа отменится (рис. 2.54). 204 Реализация прикладных задач в системе «1С:Предприятие 8.2» Рис. 2.54. Использование режима проведения «Запрашивать» при условии, что дата документа больше текущей даты сеанса Прочие функции Кроме выбора режима проведения и установки даты документа, расширение формы документа реализует также следующий функционал: ■ при открытии формы проведенного документа, если у пользователя нет права Интерактивное изменение данных, форма переводится в режим ТолькоПросмотр; ■ при открытии формы документа, в которой находятся таблицы, отражающие движения основного реквизита (объекта документа), эти движения автоматически считываются из базы данных и отображаются; ■ при записи из формы (даже если и программной – посредством Записать()) система выполняет проверку прав на интерактивное проведение или интерактивную отмену проведения. Ввод на основании Ввод на основании является одним из вариантов реализации заполнения нового объекта данными другого объекта. Чаще всего это действие применяется для документов, но может использоваться для ряда других объектов Глава 2. Документы и последовательности 205 (Справочники, Планы видов характеристик, Планы счетов, Планы расчетов, Планы обменов, Бизнес-процессы, Задачи). Причем в общем случае вводится любой объект на основании любого. Механизм работы ввода на основании включает в себя формирование нового объекта и вызов обработчика события ОбработкаЗаполнения создаваемого объекта. Например, необходимо реализовать заполнение документа, реализующего отгрузку товаров, на основании объекта, содержащего информацию о том, что именно нужно отгрузить. Исходным объектом, применяемым в конкретном случае, может быть, например, документ ЗаказПокупателя или элемент справочника ДоговорыКонтрагентов (рис. 2.55). Рис. 2.55. Пример использования ввода на основании Ввод на основании может быть организован за счет интерфейсных средств или программно. 206 Реализация прикладных задач в системе «1С:Предприятие 8.2» Интерактивный ввод на основании Интерфейсные возможности реализуются за счет соответствующих расширений форм и элементов форм. Кроме того, необходимо, чтобы в свойствах объекта конфигурации было указано, на основании каких объектов он может вводиться (рис. 2.56). Рис. 2.56. Указание объектов, являющихся основанием для ввода В результате: ■ Разработчику будет доступен вызов конструктора ввода на основании для документа РеализацияТоваров. ■ В автозаполняемых командных панелях форм, у которых основным реквизитом является объект документа ЗаказПокупателя и объект элемента справочника Договоры, а также в командных панелях форм списков данных объектов появляется новое подменю СоздатьНаОсновании (рис. 2.57) с действием РеализацияТоваров. Если же данное подменю уже было, то к нему просто добавится указанное действие. Рис. 2.57. Кнопка «Ввести на основании» Глава 2. Документы и последовательности 207 Посредством конструктора ввода на основании (или без его использования) в составе модуля объекта документа РеализацияТоваров может быть реализована процедура – обработчик события ОбработкаЗаполнения. Поскольку параметром ДанныеЗаполнения данной процедуры система передает ссылку на объект источник, то у разработчика появляется возможность заполнить данные документа информацией объекта-источника. Для нашего примера ее текст может быть таким (листинг 2.10). Листинг 2.10. Пример процедуры «ОбработкаЗаполнения» Процедура ОбработкаЗаполнения(ДанныеЗаполнения, СтандартнаяОбработка) Если ТипЗнч(ДанныеЗаполнения) = Тип("ДокументСсылка.ЗаказПокупателя") Тогда // Заполнение шапки Договор = ДанныеЗаполнения.Договор; Контрагент = ДанныеЗаполнения.Контрагент; ОснованиеРеализации = ДанныеЗаполнения.Ссылка; // Заполнить табличную часть данными табличной части основания Для Каждого ТекСтрокаСостав Из ДанныеЗаполнения.Состав Цикл НоваяСтрока = Состав.Добавить(); НоваяСтрока.Количество = ТекСтрокаСостав.Количество; НоваяСтрока.Номенклатура = ТекСтрокаСостав.Номенклатура; НоваяСтрока.Сумма = ТекСтрокаСостав.Сумма; НоваяСтрока.Цена = ТекСтрокаСостав.Цена; КонецЦикла; ИначеЕсли ТипЗнч(ДанныеЗаполнения) = Тип("СправочникСсылка.ДоговорыКонтрагентов") Тогда // Заполнение шапки Контрагент = ДанныеЗаполнения.Владелец; ДатаПоставки = ДанныеЗаполнения.ДатаПоставки; Договор = ДанныеЗаполнения.Ссылка; ОснованиеРеализации = ДанныеЗаполнения.Ссылка; // Заполнить табличную часть данными табличной части основания Для Каждого ТекСтрокаСпецификация Из ДанныеЗаполнения.Спецификация Цикл НоваяСтрока = Состав.Добавить(); НоваяСтрока.Количество = ТекСтрокаСпецификация.Количество; НоваяСтрока.Цена = ТекСтрокаСпецификация.Цена; НоваяСтрока.Номенклатура = ТекСтрокаСпецификация.Номенклатура; НоваяСтрока.Сумма = ТекСтрокаСпецификация.Сумма; КонецЦикла; КонецЕсли; КонецПроцедуры ПРИМЕЧАНИЕ Данный пример приведен в демонстрационной конфигурации «Хранение информации и учет движения средств», которая находится на прилагаемом компакт-диске. 208 Реализация прикладных задач в системе «1С:Предприятие 8.2» В результате, если пользователь в соответствующей форме выберет из подменю СоздатьНаОсновании действие РеализацияТоваров, произойдет создание нового документа и вызов обработчика события ОбрботкаЗаполнения. То есть произойдут следующие события (рис. 2.58). Рис. 2.58. Последовательность событий при интерактивном вводе на основании Кроме того, произойдет заполнение значения параметра Основание расширения формы документа. Ему также будет присвоено значение ссылки на объект-источник. Это свойство можно активно использовать в обработчиках событий формы. Например, требуется запретить интерактивный ввод документа РеализацияТоваров на основании документа ЗаказПокупателя, если у последнего не заполнен контрагент. Для реализации этой задачи достаточно написать процедуру обработчика создания формы документа РеализацияТоваров, например, следующим образом (листинг 2.11). Листинг 2.11. Пример процедуры «ПриСозданииНаСервере» &НаСервере Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка) Если ТипЗнч(Параметры.Основание) = Тип("ДокументСсылка.ЗаказПокупателя") Тогда Если Параметры.Основание.Контрагент.Пустая() Тогда Сообщение = Новый СообщениеПользователю(); Сообщение.Текст = "Не заполнено поле 'Контрагент'!"; Сообщение.Сообщить(); Отказ = Истина; КонецЕсли; КонецЕсли; КонецПроцедуры Глава 2. Документы и последовательности 209 В случае выполнения условий, то есть если объектом-источником будет документ ЗаказПокупателя с невыбранным контрагентом, произойдет выдача сообщения пользователю и отказ от создания формы нового документа, вводимого на основании. Программный ввод на основании Программный способ заполнения документа данными из других объектов реализуется посредством метода Заполнить(). Например, если в переменной СсылкаНаИсходныйОбъект содержится ссылка на некий заказ покупателя или на некий договор контрагента, то программное создание документа РеализацияТоваров с заполнением данных из исходного объекта и последующая его запись могут быть выполнены следующим образом (листинг 2.12). Листинг 2.12. Пример создания нового документа на основании НовыйДокумент = Документы.РеализацияТоваров.СоздатьДокумент(); НовыйДокумент.Дата = ТекущаяДата(); НовыйДокумент.Заполнить(СсылкаНаИсходныйОбъект); НовыйДокумент.Записать(); Сначала новый документ будет создан в оперативной памяти, заполнено свойство Дата текущим временем, далее посредством метода Заполнить() управление будет передано обработчику события ОбработкаЗаполнения. Обратите внимание: в результате применения программного заполнения документов контекст формы не задействуется (рис. 2.59). После заполнения документ записывается. Событие ПриУстановкеНовогоНомера произойдет в транзакции записи, только если для документа используется автонумерация. Причем в соответствии с установкой параметров метода Записать() по умолчанию в данном примере документ будет записан без проведения. Следует заметить, что событие ОбработкаЗаполнения есть не только у объектных данных (документов, справочников и т. п.), но и у регистра сведений, и оно располагается в модуле объекта РегистрСведенийНаборЗаписей.<имя>. Рис. 2.59. Последовательность событий при программном вводе на основании 210 Реализация прикладных задач в системе «1С:Предприятие 8.2» Получение документов, введенных на основании Кроме того, при решении прикладных задач иногда возникает необходимость получения всех документов, связанных с неким исходным объектом. Например, в рамках некоего договора был оформлен ЗаказПокупателя, на основании документа ЗаказПокупателя был введен документ РеализацияТоваров, на основании РеализацииТоваров были введены СчетФактура и ПриходныйКассовыйОрдер. Впоследствии часть товара была возвращена, то есть на основании РеализацииТоваров был введен ВозвратТоваровОтПокупателя. Кроме того, аналогичная цепочка документов может быть оформлена в отношении другого ЗаказаПокупателя (рис. 2.60). Рис. 2.60. Цепочка документов, введенных на основании Поскольку все события происходили в рамках договорных отношений одного договора, пользователю может оказаться необходимо увидеть все документы, касающиеся этого договора, в одном списке. Для реализации этого в состав всех объектов, которые нужно отобрать по данному договору, можно включить реквизит, ссылающийся на данный договор. Пусть он называется Договор. Далее для реализации отбора подчиненных договору документов можно использовать запросы или, например, критерии отбора. КритерийОтбора – объект конфигурации, представляющий собой одну из составляющих механизма отборов информации. Критерии отбора позволяют разработчику реализовать предопределенные правила отборов информации за счет создания дополнительных индексов в таблицах объектов в базе данных. Глава 2. Документы и последовательности 211 Для вышеприведенного примера можно создать новый критерий отбора ДокументыПоДоговору. Тип критерия отбора указывается в соответствии с типом данных, по которым будут отбираться объекты. То есть в данном примере – СправочникСсылка.ДоговорыКонтрагентов, но в общем случае может быть и составным. В составе критерия отбора указываются реквизиты объектов, по которым нужно будет производить отбор. В данном случае это реквизит Договор документов ЗаказПокупателя, ПриходныйКассовыйОрдер, РеализацияТоваров (рис. 2.61). Рис. 2.61. Состав объектов, входящих в критерий отбора «ДокументыПоДоговору» В результате для таблиц объектов (в данном случае для таблиц документов) в базе данных будут созданы индексы по полям, хранящим значения этих реквизитов. Обратите внимание: в состав критерия отбора можно включить несколько реквизитов одного и того же документа или несколько реквизитов табличной части документа. Согласно информации о типе критерия отбора в группе Перейти панели навигации форм объектов, имеющих соответствующий тип, платформа создает команды для открытия списка критерия отбора. В приведенном выше примере такие команды будут созданы в группе Перейти панели навигации формы элемента справочника ДоговорыКонтрагентов. По умолчанию эта команда невидима, но можно включить ее видимость на закладке Командный интерфейс в форме элемента (рис. 2.62). 212 Реализация прикладных задач в системе «1С:Предприятие 8.2» Рис. 2.62. Команда открытия критерия отбора из формы элемента справочника «ДоговорыКонтрагентов» В результате, открыв какой-либо элемент справочника ДоговорыКонтрагентов, можно перейти к списку документов, в которых указан данный договор (рис. 2.63). Рис. 2.63. Открытие списка критерия отбора «Документы по договору» по текущему элементу справочника Также разработчик может сам вставить команду для открытия списка критерия отбора в форму списка объекта соответствующего типа (в данном случае справочника ДоговорыКонтрагентов). Для этого нужно найти соответствующую глобальную параметризируемую команду на закладке редактора формы списка – Команды Глобальные команды Параметризуемые Элементы Список Имя критерия отбора(Элементы.Список.ТекущиеДанные.Ссылка), рис. 2.64. Если же требуется обеспечить переходы другими средствами, то это можно реализовать программно. Достаточно лишь иметь в наличии ссылку на значение отбора. Глава 2. Документы и последовательности 213 Рис. 2.64. Открытие списка критерия отбора «Документы по договору» по текущему элементу справочника То есть для вышеприведенного примера критерия отбора и переменной СсылкаНаЗначениеОтбора это может быть реализовано так (листинг 2.13). Листинг 2.13. Пример использования критерия отбора &НаКлиенте Процедура ОткрытьСписокКритерияОтбора(Команда) // Открыть форму списка критерия отбора с отбором по договору ЗначениеОтбора = Новый Структура("Значение", СсылкаНаЗначениеОтбора); ПараметрыФормы = Новый Структура("Отбор", ЗначениеОтбора); ОткрытьФорму("КритерийОтбора.ДокументыПоДоговору.ФормаСписка", ПараметрыФормы); КонецПроцедуры Краткий комментарий: сначала создается структура отбора ЗначениеОтбора со значением реквизита формы СсылкаНаЗначениеОтбора, содержащим ссылку на договор, и добавляется в структуру параметров формы ПараметрыФормы. Эти параметры передаются в форму списка критерия отбора ДокументыПоДоговору, и форма открывается с отбором по полю Значение списка критерия отбора, указанному в форме обработки ОткрытьФормуКритерияОтбора. 214 Реализация прикладных задач в системе «1С:Предприятие 8.2» Кроме того, может возникнуть потребность программного получения коллекции подчиненных документов (или других объектов), то есть соответствующих отбору по определенному значению. Это можно реализовать посредством объектной техники (листинг 2.14) или посредством запроса (листинг 2.15). Листинг 2.14. Пример использования объектной техники МассивСсылокНаОбъекты = КритерииОтбора.ДокументыПоДоговору.Найти(СсылкаНаЗначениеОтбора); Листинг 2.15. Пример использования запроса ВЫБРАТЬ ДокументыПоДоговору.Ссылка ИЗ КритерийОтбора.ДокументыПоДоговору(&Значение) КАК ДокументыПоДоговору В качестве значения параметру Значение необходимо будет передать ссылку на значение отбора. Для функционирования конкретного критерия отбора в базе данных для исходных таблиц были созданы соответствующие индексы. Поэтому обеспечивается достаточно быстрая работа этого механизма. Специальные случаи использования документов. . Ручная операция Кроме типовой стратегии использования документов в конфигурации, когда движения формируются при проведении документов, система допускает и другие варианты участия документов в учетных механизмах. Так, в частности, допускается программное и интерактивное изменение записей регистров, в том числе и подчиненных регистратору. Причем от регистратора может использоваться только ссылка для определения отбора по регистратору. Остальное может быть выполнено вообще без использования данных документа. Такая возможность не нарушает общую модель использования документов и регистров, а лишь дополняет ее для решения нестандартных задач. Например, когда пользователям нужно предоставить возможность отражения в учетных механизмах операций, для которых в конфигурации не предусмотрено специальных документов (в бухгалтерском учете их обычно называют ручными операциями). Либо когда при регистрации события пользователь заполняет ровно те поля, которые требуется заполнять в регистре. И ввод этой учетной информации не требует никакой дополнительной обработки. Глава 2. Документы и последовательности Рассмотрим движений. подробнее возможность интерактивного 215 формирования Например, в рамках демонстрационной конфигурации «Хранение информации и учет движения средств», которая находится на прилагаемом компакт-диске, создан документ РучнаяОперация, данными которого будут только Дата и Номер. Поскольку проведение данного документа не предусматривается, свойству Проведение данного документа указано значение Запретить. Однако в разделе свойства Движения отмечен регистр, для которого данный документ может быть регистратором (ТоварыНаСкладах), рис. 2.65. Рис. 2.65. Документ «РучнаяОперация» Далее при создании формы документа в окне элементов формы необходимо разместить таблицу, отображающую данные Объект.Движения.ТоварыНаСкладах (рис. 2.66). Пользователь при работе с данным документом сможет интерактивно формировать или модифицировать движения данного документа по регистру ТоварыНаСкладах и записывать документ. При записи документа данные, отображаемые в этой таблице, будут записаны в регистр (рис. 2.67). Однако необходимо иметь в виду, что поведение подобного документа может быть неожиданным для пользователей, привыкших работать с документами по стандартной схеме. 216 Реализация прикладных задач в системе «1С:Предприятие 8.2» Рис. 2.66. Источник данных таблицы формы, отображающей движения документа в регистре «ТоварыНаСкладах» Рис. 2.67. Схема документа «Ручная операция» Например, при установке пометки удаления на такой документ не будет срабатывать отмена проведения и удаление движений документа. Ведь документ и не проводился (ему было запрещено проведение). А как же обеспечить удаление движений? Вариантов несколько: ■ Удалить сам документ. Тогда система удалит связанные с ним движения, поскольку записи регистра подчинены регистратору и в данном случае без регистратора существовать не могут. Глава 2. Документы и последовательности 217 ■ Интерактивно удалить записи в таблице, отображающей движения документа, и записать документ. ■ Программно очистить движения, то есть создать пустой набор записей с отбором по данному регистратору, и записать его. Кроме того, возможна ситуация, когда необходимо, чтобы движения существовали, но не участвовали в получении итогов регистра. Для этого можно снять активность записей движений. Необходимо помнить, что хотя Активность является свойством записей, однако она может быть установлена или снята только для всего набора записей данного регистратора по данному регистру. Программно это может быть выполнено следующим образом (листинг 2.16). Листинг 2.16. Изменение активности записей Движения.ТоварыНаСкладах.УстановитьАктивность(Ложь); Кроме того, «неожиданным» для пользователя может оказаться тот факт, что при копировании подобного документа содержимое таблицы движений автоматически копироваться не будет. Ведь там отображаются движения документа по регистру, а они не относятся к данным документа. Данный вопрос должен прорабатываться разработчиком. Для реализации подобной функциональности необходимо воспользоваться обработчиком события ПриКопировании объекта документа (листинг 2.17). Листинг 2.17. Использование обработчика события «ПриКопировании» Процедура ПриКопировании(ОбъектКопирования) // Перебрать движения документа-источника ДвиженияОбъектаКопирования = РегистрыНакопления.ТоварыНаСкладах. ВыбратьПоРегистратору(ОбъектКопирования.Ссылка); Пока ДвиженияОбъектаКопирования.Следующий() Цикл // Создать новую запись в движениях текущего документа НовоеДвижение = Движения.ТоварыНаСкладах.Добавить(); // Заполнить поля новой записи регистра НовоеДвижение.ВидДвижения = ДвиженияОбъектаКопирования.ВидДвижения; НовоеДвижение.Период = ДвиженияОбъектаКопирования.Период; НовоеДвижение.Номенклатура = ДвиженияОбъектаКопирования.Номенклатура; НовоеДвижение.Склад = ДвиженияОбъектаКопирования.Склад; НовоеДвижение.Количество = ДвиженияОбъектаКопирования.Количество; КонецЦикла; КонецПроцедуры 218 Реализация прикладных задач в системе «1С:Предприятие 8.2» Поскольку обработчик события ПриКопировании в качестве параметра получает объект копируемого документа, то в самой процедуре считываются его движения. Далее в цикле перебора набора записей документа источника формируются новые записи уже в коллекции движений нового документа. Значения полей новых записей заполняются значением полей записей из движений документа-источника. При интерактивном формировании движений документа в общем случае поле Период записей регистра доступно для редактирования. Это позволяет устанавливать произвольный период начала действия любой записи на итоги регистра. В ряде прикладных задач, однако, подобную «вольность» требуется пресечь. Для принудительной синхронизации поля Период, например, по значению даты документа можно использовать следующее (листинг 2.18). Листинг 2.18. Синхронизация даты движений с датой документа в обработчике события «ПередЗаписью» формы документа &НаКлиенте Процедура ПередЗаписью(Отказ, ПараметрыЗаписи) Для Каждого ЗаписьРегистра Из Объект.Движения.ТоварыНаСкладах Цикл ЗаписьРегистра.Период = Объект.Дата; КонецЦикла; КонецПроцедуры Саму синхронизацию в зависимости от реализуемого алгоритма работы с документом можно располагать или в обработчике события ПередЗаписью в модуле формы документа, или в модуле объекта документа. В первом случае синхронизация будет производиться только при интерактивной записи документа, во втором – и при программной записи тоже. Кроме того, как определяли в начале этого раздела, формирование движений не обязательно может идти от документа. Движения могут быть сформированы программно, посредством объекта НаборЗаписей регистра (просто с установленным отбором по нужному регистратору). Для синхронизации значения поля Дата записей регистра со значением поля Дата документа и для таких случаев необходимо использовать обработчик события ПередЗаписью самого набора записей (листинг 2.19). Листинг 2.19. Пример процедуры «ПередЗаписью» модуля набора записей регистра Процедура ПередЗаписью(Отказ, Замещение) // Получить дату регистратора ДатаРегистратора = ЭтотОбъект.Отбор.Регистратор.Значение.Дата; // Принудительно установить значение поля "Период" каждой записи Для Каждого ЗаписьНабораЗаписей Из ЭтотОбъект Цикл ЗаписьНабораЗаписей.Период = ДатаРегистратора; КонецЦикла; КонецПроцедуры Глава 2. Документы и последовательности 219 Выше мы рассмотрели ситуации и задачи, которые могут возникнуть при интерактивном формировании движений документов, которым проведение запрещено. Подобным образом могут решаться еще задачи для проводимых документов. Например, если пользователь должен иметь возможность в дополнение к сформированным при проведении документа движениям добавлять новые или вручную корректировать существующие движения. То есть в форме документа можно также создать таблицу для интерактивной работы с набором записей данного документа по нужному (нужным) регистру. Но при этом разработчику обязательно нужно учитывать и корректно отрабатывать возможные попытки перепроведения документа с «интерактивно откорректированными» движениями. Если ничего не предпринимать, а свойство документа Удаление движений будет иметь значение Удалять автоматически, то система при перепроведении удалит старые движения и сформирует новые такими, какими их формирует обработка проведения. То есть результаты ручной коррекции будут потеряны. Что именно должна выполнять конфигурация в подобной ситуации, зависит от постановки задачи. Все возможные предпосылки для ее решения у системы есть. Это и отключение автоматического удаления движений, и возможность отключения активности записей, и возможность реализации отказа в проведении документа, и т. д. Журналы документов Журнал документов – объект конфигурации, предназначенный для обеспечения работы с документами нескольких видов в одном списке. Посредством журналов легко обеспечивается интерактивный вызов следующих действий (например, посредством командной панели формы журнала): ■ ■ ■ ■ ■ ■ ■ ■ добавление нового документа; копирование документа; пометка на удаление документа/снятие пометки на удаление документа; удаление документа; открытие формы документа (для редактирования документа); проведение документа; отмена проведения документа; ввод на основании; 220 Реализация прикладных задач в системе «1С:Предприятие 8.2» ■ переход к связанной информации (в том числе отображение списков движений документа); ■ установка отбора, сортировки, группировки и условного оформления списка документов; ■ вывод данных из списка журнала документов в табличный документ или текстовый документ; ■ изменение настройки списка отображаемых в журнале колонок; ■ установка интервала дат в списке документов; ■ поиск документа по значению в колонке списка/отмена поиска. С прикладной точки зрения журналы документов – средство группирования связанных по смыслу документов. Например, журнал КассовыеДокументы может включать в себя документы ПриходныйКассовыйОрдер, РасходныйКассовыйОрдер, Чек, ОтчетКассовойСмены и так далее. Для отображения данных только одного вида документов создавать журнал документов не стоит. Потому что формируемая по умолчанию или созданная в конфигурации форма списка документа целиком реализует ту же функциональность без лишних структурных затрат. По сути дела журналы документов – вторичные данные системы, представляющие собой еще одно представление списка документов. Каждый документ может входить в один или несколько журналов или не входить ни в один. Все определяется наличием необходимости работы с рядом документов в составе одного списка (рис. 2.68). Рис. 2.68. Включение документов в различные журналы Глава 2. Документы и последовательности 221 Состав журналов В состав журнала как объекта конфигурации включаются регистрируемые документы и графы (рис. 2.69). Рис. 2.69. Окно редактирования журнала документов При регистрации документа сразу же обеспечиваются возможности отображения в списке журнала таких полей, как: ■ Тип документа, ■ Дата, ■ Номер, ■ ПометкаУдаления, ■ Проведен. Наличие дополнительных граф в составе журнала дает возможность пользователю получать в списке журнала сведения о документах, дополнительные к вышеперечисленным. Графа журнала представляет собой перечень реквизитов документов, регистрируемых в журнале, значения которых нужно отображать в списке в одной колонке (рис. 2.70). В списке журнала по каждому конкретному экземпляру документа информация будет отображаться для пользователя в составе только одной строки списка. Поэтому в каждую графу журнала можно включить только один реквизит для каждого вида документа и невозможно включать реквизиты табличной части документа. 222 Реализация прикладных задач в системе «1С:Предприятие 8.2» Рис. 2.70. Регистрация реквизитов документов в графе журнала Кроме того, рекомендуется включать в состав одной графы данные одного типа значений или близких по смыслу типов значений. Например, графа ДокументОснование будет включать в себя данные значений соответствующих реквизитов разных видов документов. При этом типы значений реквизитов могут быть различными, но они близки по смыслу. На уровне объектов базы данных информация журналов документов хранится в отдельных таблицах для каждого журнала документов. Эти таблицы имеют следующий состав полей и содержат следующую информацию: ■ Ссылка – ссылка на регистрируемый в журнале документ. ■ Дата – дата/время регистрируемого документа. – пометка удаления регистрируемого документа (Булево). ■ Проведен – пометка проведенности регистрируемого документа (Булево). ■ Номер – номер регистрируемого документа (поле существует, если хоть один из регистрируемых документов имеет номер с длиной, отличной от нуля). ■ Графа1 – содержимое соответствующих реквизитов регистрируемых документов. Тип значения поля определяется типом значений реквизитов регистрируемых документов. ■ …–… ■ ГрафаN – … Согласно вышеописанному можно сделать вывод о том, что состав и тип значения полей таблиц разных журналов отличаются. Кроме того, при добавлении новых документов к перечню зарегистрированных может меняться не только тип значения полей, но и состав полей. ■ ПометкаУдаления Глава 2. Документы и последовательности 223 Например, если ранее все зарегистрированные документы имели номера нулевой длины, то добавление нового с номером ненулевой длины приведет к добавлению поля Номер в составе таблицы журнала. Заполнение журналов Заполнение/редактирование таблицы журнала происходит при записи/ удалении документов, в рамках той же транзакции. Причем только в следующих ситуациях: ■ запись нового документа; ■ запись документа, у которого есть изменения в реквизитах самого документа (изменения в табличных частях не приводят к необходимости «перезаполнения» записей в таблицах журналов); ■ запись документа с измененной датой или номером, с изменением признака проведения или пометки удаления; ■ удаление документа. Таким образом, функциональность журналов обеспечивается с минимальными временными затратами на ее поддержание. Сколько документов можно зарегистрировать в составе одного журнала? В принципе число документов, регистрируемых в составе одного журнала, неограниченное – могут быть зарегистрированы хоть все документы конфигурации. При решении данного вопроса необходимо только помнить о необходимости обеспечения параллельности работы пользователей и достаточного уровня быстродействия системы при выполнении операций записи/удаления документов. В отношении обеспечения параллельности работы: ■ При файл-серверном варианте использования программы транзакционные блокировки устанавливаются на уровне таблиц базы данных. Поэтому документы, входящие в один журнал, одновременно не смогут быть записаны. ■ При клиент-серверном варианте использования программы блокировки устанавливаются на уровне записей. Поэтому блокировки СУБД допускают более высокую параллельность выполнения транзакций. В отношении скорости записи/удаления документов: чем меньше количество журналов, в которых регистрируется документ, тем быстрее проходит его запись или удаление. Поэтому к вопросу организации журналов в составе функционально наполненных конфигураций нужно подходить внимательно. Также внимательно следует подходить к вопросу определения граф журнала. Большое количество граф может сказаться на производительности системы 224 Реализация прикладных задач в системе «1С:Предприятие 8.2» при просмотре журнала. Поэтому при отображении динамических списков документов, входящих в журнал, из базы данных считываются только те поля, которые связаны с соответствующими колонками таблицы формы списка журнала. Это сделано для уменьшения объема выбираемой из базы данных информации. Последовательности документов Последовательность документов – средство группирования документов в едином хронологическом порядке для обеспечения ведения единой логики событий в рамках некоего механизма учета. В отличие от журналов документов, которые используются в основном для группирования документов в «интерфейсных интересах» (для визуализации), последовательности группируют документы для обеспечения правильного отражения данных документов в учете. Поскольку учетных механизмов в составе одной конфигурации может быть несколько, то и последовательностей может быть адекватное количество. Кроме того, сами модели применения объекта Последовательность могут отличаться. В качестве первого примера рассмотрим использование последовательности для учета правильности списания партий товаров со склада. Проведение ряда документов (документов реализации) обусловлено состоянием данных, хранящихся в базе данных, на момент времени регистрации документов (остатки партий в регистре ПартииТоваров). Изменение же этих исходных данных впоследствии, после проведения документа, ставит под сомнение правильность прошлого отражения данного документа в учете. Например, документ реализации Рнк-1 оформлен и проведен после двух приходных накладных, оприходовавших товар (рис. 2.71). Рис. 2.71. Набор документов Глава 2. Документы и последовательности 225 При проведении было реализовано списание партий по методу FIFO (первый пришел – первый ушел). То есть расходная накладная использовала данные об остатках партий на момент ее проведения. В результате все операции были отражены в учете партий в виде следующих записей регистра ПартионныйУчет (табл. 2.6). Таблица 2.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 Пульт VH Пнк-2 5 60 Пульт VH Пнк-1 9 90 Видно, что при реализации была частично списана партия Пнк-1. Далее было произведено изменение одной из исходных приходных накладных с последующим ее перепроведением (рис. 2.72). Рис. 2.72. Нарушение последовательности проведения документов Для новой ситуации движения документа Реализация, полученные в результате старого проведения, некорректны (табл. 2.7). Таблица 2.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 226 Реализация прикладных задач в системе «1С:Предприятие 8.2» Ведь для списания девяти пультов одной партии Пнк-1 теперь недостаточно! К аналогичному печальному результату можно прийти и в случае любого изменения записей регистра задним числом (рис. 2.73). Рис. 2.73. Пример изменения записей регистра задним числом В результате записи в регистре (учете) будут следующими (табл. 2.8). Таблица 2.8. Записи регистра «ПартионныйУчет» Период Регистратор 01.03.2010 Ручная корректировка 00:00:00 остатков РК-1 29.03.2010 17:00:00 13.03.2010 ПоступлениеТоваров № 1 15:00:01 13.03.2010 15:00:01 23.03.2010 ПоступлениеТоваров № 2 15:30:45 23.03.2010 15:30:45 27.03.2010 Реализация № 1 12:30:45 27.03.2010 12:30:45 Вид Товар движения Партия Кол-во Сумма Приход Пульт VH РК-1 2 16 Приход Пульт �� VH Пнк-1 10 100 Приход Пульт VH Пнк-2 5 60 Расход Пульт VH Пнк-1 9 90 То есть движения документа Реализация не отвечают требованиям метода списания FIFO. Для исправления ситуации объект Последовательность позволяет в таких случаях оперировать понятием граница последовательности. Это и есть момент времени максимально глубокого в прошлом изменения записей регистра (регистров), от которого зависит проведение документов, зарегистрированных в последовательности. Именно с этого момента времени возможны коллизии правильности ведения учета. То есть до границы последовательности документы проведены заведомо правильно, после – возможно, неправильно. Глава 2. Документы и последовательности 227 Сам процесс восстановления логики учета может быть реализован путем последовательного перепроведения документов, зарегистрированных в последовательности, начиная от границы последовательности, и называется восстановление последовательности. Другой вариант использования объекта Последовательность: пользователи в течение дня вводят поток заявок от покупателей и внутренних заявок. Причем в силу специфики автоматизируемого предприятия часто имеет место ситуация ввода нескольких заявок от одних и тех же покупателей или для одних и тех внутренних подразделений. Кроме того, возможен ввод «запоздавших» заявок прошлых дней. Документы записываются, но не проводятся. По окончании рабочего времени офиса автоматически включается обработка Консолидация заявок, которая собирает все непроведенные заявки (разных видов), начиная от границы последовательности, консолидирует их, оформляет соответствующим образом и проводит уже обобщенные заявки. Впоследствии исходные заявки удаляются. После этого граница последовательности смещается на момент времени последней проведенной консолидированной заявки (рис. 2.74). Рис. 2.74. Использование последовательности для консолидации заявок Первый приведенный пример можно назвать классическим. Он касается давно существующей задачи «борьбы с коллизиями из-за работы пользователей задним числом». Данная задача полностью или в большей своей части может быть решена за счет встроенных в платформу автоматических средств объекта Последовательность. Второй приведенный пример показывает, что разработчик при использовании объекта Последовательность не обязательно должен замыкаться только на «коллизиях работы задним числом». Благодаря наличию различных программных средств и возможностей логика применения последовательностей документов определяется самим разработчиком. 228 Реализация прикладных задач в системе «1С:Предприятие 8.2» Устройство последовательностей Для создания объекта конфигурации Последовательность разработчик должен указать, какие документы необходимо регистрировать в последовательности, и список регистров, данные которых используются этими документами при своем проведении (рис. 2.75). Рис. 2.75. Свойства, относящиеся к использованию последовательности Хотелось бы обратить внимание на то, что автоматическое отслеживание изменения таких данных осуществляется только для регистров: ■ регистров накопления, ■ регистров сведений, ■ регистров бухгалтерии, ■ регистров расчета. Но это не мешает при необходимости реализовать программными средствами изменение положения границы последовательности при изменении данных других объектов. Например, для последовательности документов, критичных к изменению условий в элементе справочника Договоры, при записи модифицированного элемента данного справочника можно программно установить границу последовательности на момент времени самого первого документа по этому договору. Кроме того, последовательность может иметь разрезы. Это реализуется включением измерений в данные последовательности. Например, если доба- Глава 2. Документы и последовательности 229 вить в последовательность измерение Организация, то с прикладной точки зрения общая последовательность будет разбита на ряд последовательностей. Каждая из них может функционировать в рамках отдельной организации. То есть, например, будет возможно произвести восстановление последовательности документов только одной организации, не затрагивая остальных. С другой стороны, наличие измерений не препятствует работе с последовательностью в целом. Для хранения данных объекта Последовательность в базе данных существуют две таблицы: таблица регистрации документов в последовательности и таблица границ последовательности. Состав колонок обеих таблиц сходен: Период, Регистратор, Измерение1, …, ИзмерениеN. Различно функциональное использование этих таблиц. Данные, хранящиеся в таблице регистрации документов, используются для решения вопросов, связанных с коллекцией зарегистрированных в последовательности документов. Причем в разрезе измерений. Для определенной комбинации значений измерений по одному регистратору в таблице регистрации документов может храниться только одна запись. Впоследствии данные этой таблицы могут использоваться, например, для получения упорядоченного по хронологии набора документов, которые требуется перепровести для восстановления последовательности. Или просто для получения массива ссылок на документы, записи по которым соответствуют некоему отбору по измерениям последовательности. Данные в таблице границ последовательностей хранят значения моментов времени границ последовательностей (Период + Регистратор) по каждому набору значений измерений последовательности. То есть уникальность записей таблицы границ последовательностей определяется набором значений измерений. Если измерений у последовательности нет, значит, в этой таблице будет только одна запись. Пример содержимого таблиц при наличии измерений у последовательности приведен в табл. 2.9 и табл. 2.10. Таблица 2.9. Пример таблицы регистрации документов в последовательности Период Регистратор Организация Склад 01.03.2010 00:00:00 Ручная корректировка остатков РК-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 Сигма Главный Сигма Торговый Сигма Торговый Марон Главный 13.03.2010 15:00:01 23.03.2010 15:30:45 27.03.2010 12:30:45 230 Реализация прикладных задач в системе «1С:Предприятие 8.2» Таблица 2.10. Пример таблицы границ последовательности Организация Склад Период Регистратор Сигма Главный 01.03.2010 00:00:00 Сигма Торговый 13.03.2010 15:00:01 Марон Главный Ручная корректировка остатков РК-1 от 29.03.2010 17:00:00 ПоступлениеТоваров № 17 13.03.2010 15:00:01 Реализация № 1 27.03.2010 12:30:45 27.03.2010 12:30:45 Работа с последовательностями Работа с последовательностью включает в себя три процесса: ■ регистрация документа в последовательности; ■ перемещение границы последовательности назад; ■ перемещение границы последовательности вперед (восстановление границы последовательности). В принципе эти процессы, во-первых, независимы, во-вторых, могут выполняться системой автоматически или посредством программных действий, заложенных разработчиком. Управление регистрацией документов в последовательности Для автоматической регистрации документа в последовательностях необходимо, чтобы свойство Заполнение последовательностей документа как объекта конфигурации было установлено в значение Заполнять автоматически. Если последовательность имеет измерения, то для обеспечения автоматического заполнения полей этих измерений в формируемой записи таблицы регистрации документов последовательности настраивается соответствие между реквизитами документа и измерениями последовательности документа (рис. 2.76). Рис. 2.76. Соответствие между реквизитами документа и измерениями последовательности Глава 2. Документы и последовательности 231 В случае указания соответствия между реквизитами документа (не табличной части) и измерениями последовательности при записи документа в таблице регистрации документов в последовательности формируется запись, в которой поля автоматически заполняются значениями из документа. Если при настройке такого соответствия указывается реквизит табличной части документа, то в таблице регистрации документов будет сформировано столько записей, сколько уникальных значений будет иметь данный реквизит табличной части документа в записываемом документе (рис. 2.77). Рис. 2.77. Пример формирования записей в таблице регистрации документов в последовательности Если указывается несколько реквизитов одной табличной части, будет сформировано столько записей, сколько уникальных комбинаций из них указано в табличной части документа (рис. 2.78). Рис. 2.78. Пример формирования записей в таблице регистрации документов в последовательности Если же в соответствиях с измерениями последовательностей будут указаны реквизиты различных табличных частей, то документ будет зарегистрирован столько раз, сколько уникальных комбинаций значений можно составить (рис. 2.79). 232 Реализация прикладных задач в системе «1С:Предприятие 8.2» Рис. 2.79. Пример формирования записей в таблице регистрации документов в последовательности Исходя из вышесказанного, к вопросу добавления измерений в последовательность нужно подходить осмотрительно. Если для заполнения значений измерений использовать реквизиты табличных частей, да еще и разных, то количество записей в таблице регистрации документов в последовательности может быть очень велико. Это может сказаться на производительности системы. Следует иметь в виду еще один важный момент: при проведении документов, зарегистрированных в последовательности, платформа автоматически перемещает границу последовательности на момент регистрации этих документов, так как свойство Перемещение границы при проведении последовательности как объекта конфигурации стандартно установлено в значение Перемещать. Данная операция перемещения границы последовательности не может выполняться параллельно, соответственно, документы тоже не могут проводиться параллельно. Это может вызвать проблемы, если документы, участвующие в последовательности, должны вводиться в больших количествах. Во избежание данной ситуации можно установить это свойство в значение Не перемещать, тогда граница последовательности при проведении документов автоматически перемещаться не будет. Это позволит одновременно и регистрировать документ в последовательности, и параллельно проводить сразу несколько таких документов. Затем граница последовательности может быть перемещена программно при помощи специальной регламентной обработки. Регистрация документа в последовательности выполняется при записи документа. Процесс записи документа происходит поэтапно (рис. 2.80). В случае же записи документа с проведением очередность этапов процесса будет следующей (рис. 2.81). Глава 2. Документы и последовательности Рис. 2.80. Действия, выполняемые при записи документа Рис. 2.81. Действия, выполняемые при записи документа с проведением 233 234 Реализация прикладных задач в системе «1С:Предприятие 8.2» Добавляется обработка проведения документа и процесс переноса границы последовательности вперед при выполнении необходимых для этого условий. В случае же записи документа с отменой проведения последовательность действий будет следующей (рис. 2.82). Рис. 2.82. Действия, выполняемые при записи документа с отменой проведения Разработчику нужно помнить, что при создании новой последовательности документов автоматическая регистрация старых документов в ней не производится. Для осуществления регистрации нужно будет или перезаписать существующие документы, или написать обработку, которая зарегистрирует все нужные документы в последовательности. Если средств автоматической регистрации недостаточно или их использование неудобно, для управления регистрацией документа в последовательности документов служит набор записей регистрации в последовательности документов. Глава 2. Документы и последовательности 235 У объекта документа есть свойство ПринадлежностьПоследовательностям. Его значением является коллекция наборов записей регистрации в последовательности документов. Для каждой последовательности, в которую входит документ, существует свой набор записей регистрации в последовательности документов (рис. 2.83). Рис. 2.83. Последовательности, в которые входит документ При автоматическом способе регистрации (напомним, для этого у документа как объекта конфигурации должен стоять признак автоматического заполнения последовательности) наборы записей таблиц регистрации документов в последовательностях автоматически заполняются до записи документа и записываются после записи документа в одной транзакции. Поэтому если требуется программно очистить эти наборы записей и создать новые, можно это сделать в обработчике события ПередЗаписью или ПриЗаписи объекта документа (не путать с аналогичными обработчиками событий ПередЗаписью формы документа). Например, в составе последовательности документов ПартионныйУчет есть измерение Номенклатура. В табличной части Товары документа могут содержаться номенклатурные позиции, соответствующие услугам. По таким значениям измерения регистрировать документ в последовательности не нужно. Для того чтобы документ регистрировался в последовательности только по товарам (исключая услуги), можно сделать следующее (листинг 2.20). 236 Реализация прикладных задач в системе «1С:Предприятие 8.2» Листинг 2.20. Пример процедуры «ПередЗаписью» в модуле объекта документа «РеализацияТоваров» Процедура ПередЗаписью(Отказ, РежимЗаписи, РежимПроведения) НаборЗаписейРегистрации = ПринадлежностьПоследовательностям.ПартионныйУчет; // Очистить автоматически сформированный набор записей регистрации НаборЗаписейРегистрации.Очистить(); // Получить выборку товаров из табличной части документа Запрос = Новый Запрос; Запрос.Текст = "ВЫБРАТЬ РАЗЛИЧНЫЕ | РеализацияТоваровСостав.Номенклатура |ИЗ | Документ.РеализацияТоваров.Состав КАК РеализацияТоваровСостав |ГДЕ | РеализацияТоваровСостав.Ссылка = &Ссылка | И (НЕ РеализацияТоваровСостав.Номенклатура.Услуга)"; Запрос.УстановитьПараметр("Ссылка", Ссылка ); Результат = Запрос.Выполнить(); Выборка = Результат.Выбрать(); // Добавить новые записи регистрации и заполнить их Пока Выборка.Следующий() Цикл НоваяЗапись = НаборЗаписейРегистрации.Добавить(); НоваяЗапись.Номенклатура = Выборка.Номенклатура; НоваяЗапись.Период = Дата; КонецЦикла; КонецПроцедуры Краткий комментарий: у элемента коллекции наборов записей регистрации документов в последовательности, соответствующей последовательности ПартионныйУчет, сначала очищаются все записи. Далее запросом получаются все номенклатурные позиции, входящие в табличную часть Товары текущего документа и не являющиеся услугами. В цикле перебора выборки из результата запроса добавляются в набор новые записи регистрации данного документа в последовательности ПартионныйУчет. Обратите внимание: в данном примере из-за того, что объект НаборЗаписейРегистрации был получен посредством свойства ПринадлежностьПоследовательностям объекта документа, при формировании новых записей достаточно было заполнить только значения измерений последовательности и поле Период, а поле Регистратор автоматически заполняется ссылкой на документ. Глава 2. Документы и последовательности 237 Если же потребуется очистить всю таблицу записей регистрации документов в последовательности, то данную операцию легко выполнить программно. Запросом считать все регистраторы, на которые имеются ссылки в таблице записей регистрации документов. А затем по всем регистраторам записать пустой набор записей (листинг 2.21). Листинг 2.21. Пример очистки таблицы регистрации документов в последовательности Процедура ОчисткаТаблицыРегистрацииПоследовательностиПартионныйУчет() // Получить все документы, зарегистрированные в последовательности Запрос = Новый Запрос; Запрос.Текст = "ВЫБРАТЬ РАЗЛИЧНЫЕ | ПартионныйУчет.Регистратор |ИЗ | Последовательность.ПартионныйУчет КАК ПартионныйУчет"; Результат = Запрос.Выполнить(); Выборка = Результат.Выбрать(); // Создать набор записей таблицы регистрации последовательности // (при этом он пуст) НаборЗаписейРегистрации = Последовательности.ПартионныйУчет.СоздатьНаборЗаписей(); // Перебрать выборку из результата запроса Пока Выборка.Следующий() Цикл // Установить отбор по очередному зарегистрированному документу // в наборе записей НаборЗаписейРегистрации.Отбор.Регистратор.Установить(Выборка.Регистратор); // Записать пустой набор записей с замещением исходного НаборЗаписейРегистрации.Записать(); КонецЦикла; КонецПроцедуры Как видно из примера, для чтения данных таблиц регистрации документов в последовательностях можно применять запросы. Кроме того, у разработчика есть возможность проверить, принадлежит ли данный документ последовательности, и посредством метода Принадлежит() объекта ПоследовательностьМенеджер.<имя>. Например, нужно проверить принадлежность документа последовательности ПартионныйУчет (листинг 2.22). Листинг 2.22. Проверка принадлежности документа последовательности ФлагПринадлежности = Последовательности.ПартионныйУчет .Принадлежит(СсылкаНаПроверяемыйДокумент); 238 Реализация прикладных задач в системе «1С:Предприятие 8.2» Или, например, проверить, принадлежит ли данный документ последовательности по конкретному значению измерения Номенклатура (листинг 2.23). Листинг 2.23. Проверка принадлежности последовательности // Подготовить структуры отбора по значениям измерений последовательности, ОтборПоИзмерениям = Новый Структура; ОтборПоИзмерениям.Вставить("Номенклатура", СсылкаНаТовар); // Проверить принадлежность к последовательности в отношении нужного значения измерения ФлагПринадлежности = Последовательности.ПартионныйУчет .Принадлежит(СсылкаНаДокумент, ОтборПоИзмерениям); В приведенном примере, если документ зарегистрирован в данной последовательности по нужному значению измерения, переменная ФлагПринадлежности получит булево значение Истина; если нет – Ложь. В общем случае при формировании записей набора записей регистрации документов в последовательности поле Период может заполняться произвольным значением. То есть момент времени самого документа и момент времени регистрации документа в последовательности могут отличаться. Также в общем случае может отличаться от даты документа и значение поля Период записей движений по регистрам. Это может понадобиться для реализации какой-нибудь особой логики. Например, для решения задач сложного многоитерационного планирования, когда в течение месяца могут вводиться, дополняться, частично отменяться планы, касающиеся как текущего месяца, так и следующего. Поэтому движения по регистру могут регистрироваться и на момент времени документа, и на начало текущего месяца, и на начало следующего. Вероятные коллизии устраняются посредством использования объекта Последовательность. И поскольку документы планирования имеют разные приоритеты для разрешения коллизий планирования, регистрироваться в последовательности они могут не только на момент времени документа (рис. 2.84). Кроме того, для некоторых задач может оказаться полезным, что документ в разных последовательностях может регистрироваться на разные моменты времени, или в одних последовательностях регистрироваться, а в других – нет. Например, при раздельной работе с последовательностями ПартионныйУчет и Торговля. Глава 2. Документы и последовательности 239 Рис. 2.84. Пример использования нестандартной регистрации документов в последовательности Перемещение границы последовательности назад Перенос границы последовательности выполняется при записи набора записей регистров. Сам процесс автоматического перемещения границы последовательности назад (сбивание границы) состоит из следующих операций (рис. 2.85): ■ проверка того, что граница последовательности больше момента времени записи регистра; ■ перемещение границы последовательности на момент времени записи регистра. Рис. 2.85. Автоматическое сбивание границы последовательности 240 Реализация прикладных задач в системе «1С:Предприятие 8.2» На уровне таблиц базы данных результатом перемещения границы последовательности назад является модификация записей в таблице границ последовательностей. То есть запись с ключом, соответствующим нужной комбинации значений измерений, заменяется на запись с тем же ключом, но со значениями полей Период и Регистратор, соответствующими моменту регистрации в последовательности документа, которому подчинены измененные записи регистра. Важно понимать, что границу последовательности перемещают назад не документы, а движения регистров. Сделано это потому, что модификация (а также добавление или удаление) записей регистра не обязательно может быть связана с проведением или удалением документа. В платформе есть средства, позволяющие просто «приписывать» движения к документам, не используя объекты документов. Например, возможна следующая ситуация: граница последовательности Планирование установлена на дату: 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. Измерений у последовательности нет. В результате этого действия граница последовательности будет перемещена назад при записи записей регистра именно на момент времени добавленных записей (рис. 2.86). Рис. 2.86. Пример автоматического сбивания границы последовательности Глава 2. Документы и последовательности 241 То есть для перемещения назад границы последовательности ни дата документа, ни дата регистрации документа в последовательности значения не имеют. Но перенос (установка) границы последовательности программными средствами доступен разработчику на произвольный момент времени. Например, если требуется установить границу последовательности ПартионныйУчет на момент времени, состоящий из значений переменных ДатаУстановки, ДокументУстановки по значению измерения Номенклатура, содержащемуся в переменной НоменклатураУстановки (листинг 2.24). Листинг 2.24. Перенос границы последовательности на произвольный момент времени // Подготовить параметры установки границы последовательности: // Момент времени установки МоментУстановки = Новый МоментВремени(ДатаУстановки, ДокументУстановки); // Подготовить структуру отбора по значениям измерений последовательности, ОтборПоИзмерениям = Новый Структура; ОтборПоИзмерениям.Вставить("Номенклатура", НоменклатураУстановки); // Установить границы последовательности "Партионный учет" Последовательности.ПартионныйУчет.УстановитьГраницу(МоментУстановки, ОтборПоИзмерениям); Также есть средства для получения данных таблицы границ последовательности. Данные о значениях границ последовательности можно получить запросом или с помощью методов ПолучитьГраницы() и ПолучитьГраницу() объекта ПоследовательностьМенеджер.<имя>. Например, получение таблицы текущих границ последовательностей может выглядеть следующим образом (листинг 2.25). Листинг 2.25. Пример получения границ последовательности ТаблицаГраницПоследовательности = Последовательности.ПартионныйУчет.ПолучитьГраницы("Номенклатура"); Для использования метода ПолучитьГраницы() обязательно указание названий измерений (через запятую), которые будут разрезами в таблице границ. Кроме того, можно использовать второй параметр метода, указав там структуру отбора по значениям измерений. Результатом вышеприведенного примера будет таблица значений, включающая в себя колонки со значениями измерений (в данном случае Номенклатура) и колонку МоментВремени, в которой будут содержаться моменты времени границ последовательностей по хранящимся в последовательности комбинациям значений измерений. 242 Реализация прикладных задач в системе «1С:Предприятие 8.2» Кроме того, можно получать первую на временной оси границу последовательности для ситуации последовательности с измерениями (рис. 2.87). Реализуется это следующим образом (листинг 2.26). Рис. 2.87. Пример границ последовательности «ПартионныйУчет» Листинг 2.26. Получение минимальной границы последовательности ТекущаяГраницаПоследовательности = Последовательности.ПартионныйУчет.ПолучитьГраницу(); В заключение хотелось бы еще раз обратить внимание на то, что в случае наличия измерений в последовательности перемещение границы последовательности назад происходит только для тех комбинаций значений измерений, которые уже присутствуют в таблице границ последовательности. То есть если в рассмотренном выше примере, где существуют границы последовательности по номенклатурным позициям Самовар, Утюг, Холодильник, сформировать в регистре задним числом записи с другими номенклатурными позициями (не записывая документ), то граница последовательности ПартионныйУчет перемещаться назад не будет. Восстановление последовательности Процесс переноса границы последовательности вперед называется восстановление последовательности. Необходимым условием автоматического восстановления последовательности является установка значения Перемещать свойству Перемещение границы при проведении последовательности как объекта конфигурации. Глава 2. Документы и последовательности 243 Сам процесс автоматического восстановления последовательности выполняется только при проведении документа и состоит из следующих операций (рис. 2.88): ■ проверка того, что момент регистрации документа больше, чем граница последовательности; ■ проверка того, что в последовательности нет других проведенных документов в интервале между границей последовательности и моментом регистрации документа; ■ установка границы последовательности на момент регистрации документа. Рис. 2.88. Автоматическое восстановление границы последовательности На уровне таблиц базы данных результатом восстановления границы последовательности является модификация записей в таблице границ последовательностей. То есть запись с ключом, соответствующим нужной комбинации значений измерений, заменяется на запись с тем же ключом, но со значениями полей Период и Регистратор, соответствующими моменту регистрации в последовательности документа, проведение которого привело к восстановлению последовательности. Автоматическое перемещение границы последовательности вперед происходит только при проведении документа. Не важно – нового или уже ранее проведенного, лишь бы соблюдались все условия алгоритма. Главное, что восстановление происходит именно при записи с проведением. 244 Реализация прикладных задач в системе «1С:Предприятие 8.2» Сделано это по следующей причине: проведение документа – это сложный процесс, включающий в себя удаление предыдущих движений, установку признака проведенности, запись документа, запись движений документа и т. д., вплоть до «подтягивания» границы последовательности. Если разработчик отказался от этого процесса и просто формирует новые записи в регистре для некоего документа-регистратора (даже если тот является следующим после момента времени границы последовательности), то говорить о том, что с прикладной точки зрения последовательность восстановлена, слишком оптимистично и в принципе неверно. Например, нет никакой уверенности, что при перепроведении такого документа не возникнет коллизий. Но если такая уверенность есть или она обеспечена соответствующим комплексом мероприятий, предусмотренным разработчиком, то при необходимости для реализации неавтоматического переноса границы последовательности (назад или вперед) можно использовать программные средства – метод УстановитьГраницу() объекта ПоследовательностьМенеджер.<имя>. Использование механизма восстановления последовательности в прикладном смысле может быть разносторонним. При последовательном проведении всех документов, входящих в последовательность, начиная с момента границы последовательности, последовательность восстанавливается. И наоборот, при восстановлении последовательности перепроводятся проведенные документы, входящие в последовательность, но находящиеся за границей последовательности. Здесь хотелось бы отметить ряд особенностей. Во-первых, хотя автоматическая регистрация документов в последовательности происходит при записи документа (при любой записи документа, не обязательно при проведении), при восстановлении последовательности производится перепроведение только проведенных документов. То есть только тех документов, у которых стоит признак проведения (рис. 2.89). Рис. 2.89. Проведение документов при восстановлении последовательности Глава 2. Документы и последовательности 245 Во-вторых, перепроводиться будут документы в хронологии, определяемой моментами регистрации документов в последовательности, а не моментами времени самих документов. Это может оказаться существенным, если документы регистрируются в последовательности на отличные от своих моменты времени (рис. 2.90). Рис. 2.90. Порядок проведения документов при восстановлении последовательности В-третьих, если в составе последовательности есть измерения, а восстановление последовательности проводится общее (без разрезов по измерениям), то порядок перепроведения документов, которые нужно перепровести, опять же однозначно определяется хронологией регистрации документов в последовательности. Сам процесс восстановления последовательности документов по определенную дату может быть инициирован: ■ посредством системной команды Проведение документов (рис. 2.91); ■ программно, с помощью метода Восстановить() объекта ПоследовательностьМенеджер.<имя>. Рис. 2.91. Команда восстановления последовательностей 246 Реализация прикладных задач в системе «1С:Предприятие 8.2» В первом случае есть возможность прервать интерактивный процесс восстановления последовательности путем нажатия комбинации клавиш Ctrl + Break. В последнем случае последовательность можно восстановить в целом, можно даже без указания, по какой момент времени (листинг 2.27), а можно и в пределах указанных комбинаций измерений последовательности. Листинг 2.27. Пример использования метода «Восстановить()» Последовательности.ПартионныйУчет.Восстановить(); Например, необходимо восстановить последовательность документов ПартионныйУчет по момент времени документа из переменной СсылкаНаДокумент по значению измерения Номенклатура, хранящемуся в переменной Товар. Вариант выполнения такого действия представлен в листинге 2.28. Листинг 2.28. Пример восстановления границы последовательности // Сформировать момент времени, по который будет восстанавливаться последовательность МоментВосстановленияПо = Новый МоментВремени(СсылкаНаДокумент.Дата, СсылкаНаДокумент); // Сформировать таблицу отбора ТаблицаКомбинацийИзмерений = Новый ТаблицаЗначений; // Добавить колонки с именами, соответствующими // именам измерений последовательности ТаблицаКомбинацийИзмерений.Колонки.Добавить("Номенклатура"); // Добавить строку(и) со значением(ями) отбора СтрокаТаблицы = ТаблицаКомбинацийИзмерений.Добавить(); СтрокаТаблицы.Номенклатура = СсылкаНаТовар; // Восстановить последовательность Последовательности.ПартионныйУчет. Восстановить(МоментВосстановленияПо, ТаблицаКомбинацийИзмерений); Параллельный ввод документов, . участвующих в последовательности Как было описано выше, в базе данных информация последовательностей документов хранится в двух таблицах: ■ таблице записей регистрации документов в последовательности; ■ таблице границ последовательностей. Глава 2. Документы и последовательности 247 Выполнение различных действий с последовательностью в клиент-серверном варианте использования программы порождает блокирование этих таблиц в различных диапазонах: ■ При регистрации документа в последовательности происходит добавление или модификация набора записей таблицы регистрации документов в последовательности, подчиненного регистратору. Поэтому заблокированным оказывается как минимум диапазон записей, соответствующих одному регистратору (плюс две граничные записи «вокруг» этого диапазона). ■ При перемещении границы последовательности назад происходит модификация записей границ по соответствующим комбинациям значений измерений. Поэтому блокируются записи таблицы границ последовательности, соответствующие данным комбинациям значений измерений. А если измерений в последовательности нет, то вся таблица целиком. ■ При перемещении границы последовательности вперед. Этот процесс происходит только при проведении документа, поэтому блокируются обе таблицы. Таблица регистрации документов в последовательности оказывается заблокированной в диапазоне от границы последовательности по момент времени регистрации проводимого документа в последовательности. То есть заблокированными могут оказаться записи, подчиненные документам не проведенным, но зарегистрированным в последовательности в указанном интервале. Таблица границ последовательностей будет заблокирована целиком. Если у последовательности есть измерения, то вышеописанные блокировки при данном действии будут касаться только записей с комбинациями значений измерений, совпадающими со значениями измерений записей регистрации. ■ В файловом варианте работы системы в любом случае происходит блокировка таблиц целиком. Согласно данному описанию механизма блокировок видно, что узким местом обеспечения параллельности ввода и проведения документов для клиент-серверного варианта работы системы являются действия, связанные с автоматическим перемещением границы последовательности. То есть если документ зарегистрирован в последовательности, то при его проведении система может предпринять попытку автоматического перемещения границы последовательности на момент регистрации данного документа. Это приведет к блокировке таблицы границ последовательности целиком или в диапазоне соответствующей комбинации значений измерений последовательности. Параллельно проводимый документ, входящий в ту же последовательность, при попытке заблокировать те же записи или таблицу не сможет этого сделать. В результате вместо параллельного проведения для таких документов получим последовательное. 248 Реализация прикладных задач в системе «1С:Предприятие 8.2» Одним из вариантов выхода из ситуации является отключение автоматического перемещения границы последовательности при проведении документов. Для этого свойству Перемещение границы при проведении последовательности как объекта конфигурации устанавливается значение Не перемещать. В этом случае при проведении документа, даже если он регистрируется в последовательности, система не предпринимает попытки перемещения границы (границ) последовательности. А блокировки, возникающие при регистрации разных документов в последовательности, не мешают друг другу. То есть тогда работа с объектом Последовательность не препятствует параллельному проведению документов. Необходимо лишь не забыть позже реализовывать перемещение границы последовательности, например, служебной обработкой. Глава 3. Реализация задач учета движения средств Оперативный учет. Описание задач, решаемых регистрами накопления Практически все теории, тем или иным образом связанные с технологиями учета, управления, принятия решений и т. д., базируются на понятии «показатель». Показатель – данные, по которым можно судить о развитии, ходе, состоянии чего-нибудь. Оперативный учет – учет, позволяющий максимально быстро получать информацию о значениях показателей, учитываемых в автоматизируемой системе. Платформа системы «1С:Предприятие» предлагает удобное для учета показателей средство – регистры. Посредством их использования обеспечиваются необходимое быстродействие, функциональная гибкость и простота решения этих информационных задач. Как правило, информационные модели при этом включают не только одни регистры. Обычно используется следующая схема (рис. 3.1): ■ документами регистрируются события, приводящие к изменению значений показателей; ■ сами значения показателей хранятся в регистрах; ■ посредством отчетов пользователи получают информацию о состоянии показателей и проводят ее анализ. 250 Реализация прикладных задач в системе «1С:Предприятие 8.2» Рис. 3.1. Общая схема оперативного учета Какие же именно показатели используются при решении задач учета движения средств? И какие регистры нужно для них использовать? При автоматизации учета движения средств чаще приходится сталкиваться с ситуацией, когда в момент регистрации изменений показателя фиксируется не конечное итоговое значение показателя, а его приращение. Например, при регистрации поступления товаров на склад – количество поступивших товаров, а не находящихся в остатке; при регистрации выдачи денег подотчетнику фиксируется выданная сумма, а не оставшаяся в кассе, и тому подобное. А вот при получении данных из системы учета уже требуются накопленные (итоговые) значения показателей. Такие показатели называют показателями накопления. Для решения задачи учета показателей накопления в системе «1С:Предприятие» используются регистры накопления. Регистр накопления – объект конфигурации, предназначенный для хранения итоговых (накопленных) значений показателей и хранения движений (приращений) показателей. Помимо итоговых значений показателей, регистр может хранить и промежуточные итоги, рассчитанные для указанных периодов. Информация о приращениях показателей (заметьте, они могут быть как положительными, так и отрицательными) вносится в регистр накопления только посредством движений, то есть посредством наборов записей регистра, подчиненных документу-регистратору. Этим обеспечивается обоснованность регистрации изменений показателей – регистрацией событий, приводящих к этим изменениям. Глава 3. Реализация задач учета движения средств 251 Упрощенно можно сравнить регистр накопления с неким «черным ящиком», «на вход» которого подаются значения приращений, а «на выходе» можно получить накопленные значения приращений (рис. 3.2). Рис. 3.2. Упрощенная схема регистра накопления Как можно заметить из приведенного рисунка, показатели накопления имеют различный прикладной смысл. Различают следующие виды накапливаемых показателей: ■ показатели остатков, ■ оборотные показатели. Итоги показателей остатков отражают значения учитываемых показателей на некоторый момент времени. Итоги оборотных показателей отражают значения совокупного изменения показателя за временной интервал между двумя моментами времени (период). Если эти изменения положительные или отрицательные, можно оперировать такими понятиями, как Приход и Расход (рис. 3.3). 252 Реализация прикладных задач в системе «1С:Предприятие 8.2» Рис. 3.3. Различные виды накапливаемых показателей Таким образом, можно сказать, что показатели остатка и оборотные показатели характеризуют один и тот же процесс, но с разных сторон. Важно отметить, что показатели остатка имеют абсолютные итоги относительно момента начала ведения учета. При этом изменения в приращениях (движениях) любых прошлых периодов влияют на текущее значение итога. Рассмотрим пример, приведенный на рис. 3.4. Рис. 3.4. Пример влияния изменений в прошлых периодах на показатели остатков Глава 3. Реализация задач учета движения средств 253 Изменения показателя Деньги в кассе фиксируются посредством документов Приходный кассовый ордер (ПКО) и Расходный кассовый ордер (РКО). Оформление поступления денег в январе повлияет на остатки, как на начало февраля, так и начало марта и т. д. В противоположность рассмотренному примеру итоги оборотных показателей за разные периоды независимы. Рассмотрим пример на рис. 3.5. Рис. 3.5. Отсутствие влияния изменений в прошлых периодах на оборотные показатели Изменения показателя Сумма проданного регистрируются посредством документа Расходная накладная (Рнк). Введенные изменения в объемах продаж января будут касаться только января, но никак не коснутся февральских объемов продаж. Для гибкого и эффективного решения задач прикладной области система «1С:Предприятие» позволяет использовать два вида регистров накопления. Регистры накопления остатков позволяют получать итоговые значения показателей остатков и, кроме того (суммируя приращения этих показателей за периоды), позволяют получать обороты. Например, при решении задачи учета товаров на складах может понадобиться как значение остатка товаров на момент времени, так и оборот поступлений или расходов товара за периоды времени. Если же для некоторых сущностей накопление остатков смысла не имеет и требуется накапливать только обороты, тогда следует использовать оборотные регистры накопления. Например, учет оборотов продаж компании. О продажах всегда можно говорить только в отношении временного периода. 254 Реализация прикладных задач в системе «1С:Предприятие 8.2» ВНИМАНИЕ! Перечисленные виды регистров накопления не являются в общем случае взаимозаменяющими. Каждый из них предназначен для решения своего собственного круга прикладных задач. Например, для решения задач, связанных с учетом только оборотных показателей, не следует использовать регистры остатков и, наоборот, не следует пытаться вести учет показателей остатков на оборотных регистрах. Подобные попытки могут привести как минимум к неоправданному снижению быстродействия прикладного решения или вообще к некорректности данных учета. Структура регистра накопления В состав регистра накопления как объекта конфигурации входят измерения, ресурсы и реквизиты (рис. 3.6). Рис. 3.6. Состав регистра накопления Ресурсы используются для хранения информации как о приращениях, так и о самих значениях показателей. По сути, каждый ресурс хранит данные одного показателя. Однако регистры могут быть не только одномерными. Например, для решения задачи учета количества товаров нерационально оперировать большим количеством ресурсов (показателей) типа КоличествоХолодильников, КоличествоПылесосов, КоличествоПультовVH и т. д. Лучше Глава 3. Реализация задач учета движения средств 255 использовать один ресурс (показатель) Количество, но ввести разрез учета – ПоНоменклатурнымПозициям. В регистрах накопления разрезы учета реализуются с помощью измерений. В состав регистра можно включить более одного измерения, поэтому в общем случае регистр накопления можно представить как n-мерную систему разрезов учета (измерений), в узлах которой хранятся совокупные данные ресурсов (итоги), рис. 3.7. Рис. 3.7. Многомерная модель регистра накопления На представленной схеме – двумерная модель хранимой в регистре информации по итогам. Разрезы учета (измерения) Номенклатура и Склад. Узлами пересечений этих разрезов учета будут все возможные комбинации значений номенклатурных позиций на складах. Итог показателя Количество в каждом узле пересечения отражает данные: сколько (в количественном выражении) конкретной номенклатуры находится на конкретном складе. Данные этой графической двумерной модели можно представить в виде табличной модели (табл. 3.1). Таблица 3.1. Табличное представление данных регистра Номенклатура Склад Количество Барометр G5 Главный 30 Барометр G5 Фили-2 15 Пульт VH Фили-2 11 Станция G121 Главный 5 Каждая строка содержит значение итога ресурса Количество для конкретной комбинации значений разрезов учета Номенклатура и Склад. 256 Реализация прикладных задач в системе «1С:Предприятие 8.2» Из достоинств табличной модели сейчас хотелось бы отметить универсальность. Если графическое отображение более чем трехмерного пространства тяжело или вообще невозможно для человеческого восприятия, то табличная модель в принципе не ограничивает количество разрезов учета. Впоследствии будет рассмотрено, что хранение итогов регистров в базе данных основано именно на использовании табличной модели. Реквизиты – дополнительные характеристики движений, то есть первичных записей регистра. Реквизиты не влияют на итоги, хранимые в регистре. На вышеприведенной схеме, отражающей итоги, нет места реквизитам. Однако реквизиты могут быть использованы при решении задач анализа выполненных движений. То есть таких задач, в которых работа идет только с приращениями показателей, безотносительно их итоговых значений. Например, если при формировании движений регистра ТоварыНаСкладах заполнять соответствующие значения: поступление, реализация в розницу, реализация оптом, списание, перемещение и т. д. для реквизита ВидОперации, то впоследствии можно будет анализировать, какая из операций производится чаще других, какая реже; какие операции не выполняли в течение последнего квартала и т. п. Итак, в отношении задач, решаемых регистрами накопления, структура регистра как объекта конфигурации позволяет вести многомерный учет, как приращений, так и итогов показателей накопления, с возможностью при необходимости использования дополнительных характеристик движений. Для обеспечения данных возможностей предусмотрена соответствующая структура таблиц базы данных и порядок работ с ними. Данные каждого регистра накопления хранятся в базе данных в двух таблицах: ■ таблица движений регистра накопления; ■ таблица итогов регистра накопления. Существует два вида регистров накопления, и каждый предназначен для ведения учета показателей своего вида (остатков или оборотов). И, как разбирали выше, задачи учета показателей этих видов различны. Поэтому структура таблиц базы данных для регистров накопления разных видов тоже отличается. Она оптимизирована под решение соответствующих задач. Для регистра накопления остатков состав колонок таблицы движений следующий: ■ ■ Период – дата записи. Совместно с полями Регистратор и НомерСтроки определяет положение данной записи на временной оси. Регистратор – ссылка на документ, которому подчинена данная запись. Глава 3. Реализация задач учета движения средств 257 ■ НомерСтроки – уникальный номер данной записи в наборе записей регистра, подчиненных документу, указанному в поле Регистратор. ■ ВидДвижения – значение системного перечисления ВидДвиженияНакопления, обозначающее направление приращения указанных в записи ресурсов на итоги по этим ресурсам (Приход или Расход). ■ Активность – тип Булево. Содержит признак влияния записи на итоги ■ <Измерение> – значение измерения. Количество таких полей равно регистра. количеству измерений, определенных в данных регистра как объекта конфигурации. ■ <Ресурс> – значение ресурса. Количество таких полей равно количеству ресурсов, определенных в данных регистра как объекта конфигурации. ■ <Реквизит> – значение реквизита. Количество таких полей равно количеству реквизитов, определенных в данных регистра как объекта конфигурации. Таблица движений регистра хранит данные о выполненных по регистру движениях. Таблица итогов регистра накопления остатков хранит текущие итоги на момент времени последнего движения (актуальные итоги). Дополнительно к этому могут храниться промежуточные итоги, если установлен период рассчитанных итогов. Период рассчитанных итогов влияет только на производительность при получении итогов на некоторую промежуточную дату; если он установлен, итоги будут получены быстрее. Структура таблицы итогов регистра накопления остатков следующая: ■ Период – дата, на которую актуально состояние хранимого в таблице ■ <Измерение> – значение измерения – разреза учета хранимых итогов. итога. Количество таких полей равно количеству измерений, определенных в данных регистра как объекта конфигурации. ■ <Ресурс> – значение итога ресурса. Количество таких полей равно количеству ресурсов, определенных в данных регистра как объекта конфигурации. ■ Разделитель – поле, позволяющее распараллелить обновление записей итогов. Добавляется в структуру таблицы итогов для регистров накопления, у которых установлено свойство Разрешить разделение итогов. Пример заполнения таблицы движений регистра накопления остатков приведен в табл. 3.2. 258 Реализация прикладных задач в системе «1С:Предприятие 8.2» 1 2 1 1 1 1 Сумма Склад Количество Приход Истина Пульт VH Приход Истина Пульт VH Приход Истина Пульт PW Приход Ложь Пульт VH Расход Истина Пульт VH Приход Истина Пульт PW Приход Истина Пульт 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 Номер строки Период Таблица 3.2. Пример заполнения таблицы движений регистра накопления остатков Главный 1 10 Главный 9 90 Главный 7 490 Фили-2 5 60 Главный 8 80 Фили-2 1 17 Фили-2 1 18 Для вышеприведенного примера заполнения таблицы движений регистра таблица итогов регистра после расчета итогов по 31.05.2010 будет выглядеть так, как показано в табл. 3.3. Таблица 3.3. Пример заполнения таблицы итогов регистра накопления остатков Период 01.05.2010 Итоги апреля 2010 года 00:00:00 01.06.2010 00:00:00 Итоги мая 2010 года 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 Глава 3. Реализация задач учета движения средств 259 Обратите внимание: данные таблицы итогов содержат значения итогов ресурсов для всех возможных комбинаций значений измерений. Исключения составляют итоги, если для данной комбинации значений измерений значения всех ресурсов равны нулю. Такие записи в таблице итогов не хранятся за ненадобностью, потому что с прикладной точки зрения ситуация «нет итогов по данной комбинации значений измерений» равносильна ситуации «по данной комбинации значений измерений все итоги равны нулю». В разделе «Получение данных из регистров накопления» на стр. 299 рассмотрим, как при решении задач получения данных о значениях показателей (ресурсов) система может оптимальным с точки зрения быстродействия способом обращаться к данным как таблицы движений, так и таблицы итогов регистра. Структура таблиц оборотного регистра накопления, хранимых в базе данных, схожа. Отличие заключается только в том, что для оборотных регистров не существует понятия вид движения и понятия текущие итоги. Состав колонок таблицы движений оборотного регистра накопления следующий: ■ Период – дата записи. Совместно с полями Регистратор и НомерСтроки ■ Период – период (месяц), за который накоплен оборот итогов ресурсов. ■ <Измерение> – значение измерения – разреза учета хранимых итогов. Коли- определяет положение данной записи на временной оси. ■ Регистратор – ссылка на документ, которому подчинена данная запись. ■ НомерСтроки – уникальный номер данной записи в наборе записей регистра, подчиненных документу, указанному в поле Регистратор. ■ Активность – тип Булево. Содержит признак влияния записи на итоги регистра. ■ <Измерение> – значение измерения. Количество таких полей равно количеству измерений, определенных в данных регистра как объекта конфигурации. ■ <Ресурс> – значение ресурса. Количество таких полей равно количеству ресурсов, определенных в данных регистра как объекта конфигурации. ■ <Реквизит> – значение реквизита. Количество таких полей равно количеству реквизитов, определенных в данных регистра как объекта конфигурации. Структура таблицы итогов оборотного регистра накопления тоже схожа: чество таких полей равно количеству измерений, определенных в данных регистра как объекта конфигурации, у которых установлено свойство Использование в итогах. 260 ■ Реализация прикладных задач в системе «1С:Предприятие 8.2» <Ресурс> – значение итога оборота ресурса. Количество таких полей равно количеству ресурсов, определенных в данных регистра как объекта конфигурации. ■ Разделитель – поле, позволяющее распараллелить обновление записей итогов. Добавляется в структуру таблицы итогов для регистров накопления, у которых установлено свойство Разрешить разделение итогов. Но вот сами данные, хранимые в таблице итогов, и механизмы их использования коренным образом отличаются от регистра остатков. Для оборотного регистра в таблице итогов хранятся посчитанные суммарные обороты (итоги) ресурсов за каждый месяц, в рамках которого были зарегистрированы движения в данном регистре. Пример заполнения таблицы движений оборотного регистра накопления Продажи представлен в табл. 3.4. Истина 1 Истина 1 Истина 1 Ложь 1 Истина Сумма 1 Пульт VH Пульт VH Пульт VH Пульт VH Пульт PW Пульт PW Количество Истина Контрагент 1 Номенклатура Реализация № 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 Номер строки Период Таблица 3.4. Пример заполнения таблицы движений оборотного регистра накопления Ялта-Лтд 9 135 Компания "Риона" Компания "Риона" Компания "Риона" Крона 10 150 1 15 1 15 1 90 Ялта-Лтд 1 95 Для вышеприведенного примера заполнения таблицы движений таблица итогов регистра будет заполнена следующим образом (табл. 3.5). Глава 3. Реализация задач учета движения средств 261 Таблица 3.5. Пример заполнения таблицы итогов оборотного регистра накопления Период 01.05.2010 00:00:00 Итоги мая 2010 года 01.05.2010 00:00:00 Итоги июня 2010 года 01.06.2010 00:00:00 Итоги ноября 2010 года 01.11.2010 00:00:00 Номенклатура Контрагент Количество Сумма Пульт VH Ялта-Лтд Пульт VH Пульт VH Пульт PW Компания "Риона" Компания "Риона" Ялта-Лтд 9 135 10 150 2 30 1 95 В разделе «Получение данных из регистров накопления» на стр. 299 будет рассмотрено, в каких случаях и какими средствами достигается оптимальное быстродействие при получении данных оборотных регистров. Здесь же следует сказать, что как для регистров остатков, так и для оборотных регистров система «1С:Предприятие» индексирует таблицы движений и таблицы итогов. При этом для таблиц движений регистров создаются следующие индексы: ■ Период + Регистратор + НомерСтроки; ■ Регистратор + НомерСтроки; ■ Измерение + Период + Регистратор + НомерСтроки, если для измерения Измерение свойство Индексировать установлено в значение Индекси- ■ ровать; Реквизит + Период + Регистратор + НомерСтроки, если для реквизита Реквизит свойство Индексировать установлено в значение Индекси- ровать. Для таблиц итогов создается следующий индекс: ■ Период + Измерение1 + Измерение2 + … + ИзмерениеN + Разделитель – по всем измерениям регистра. Измерение + Период, если для измерения Измерение свойство Индексировать установлено в значение Индексировать. Использование индексов позволяет еще больше сократить время выполнения операций с данными регистра. Однако необходимо иметь в виду, что Microsoft SQL Server накладывает определенное ограничение на количество полей, входящих в составной индекс, – не более 16 полей в индексе. Поэтому работа с регистрами, имеющими очень большое количество измерений, может быть неэффективна по скорости из-за невозможности использования индексных таблиц. ■ Подробнее об индексировании таблиц базы данных можно прочитать в разделе «Индексы таблиц базы данных» на стр. 697. 262 Реализация прикладных задач в системе «1С:Предприятие 8.2» Механизмы заполнения таблиц регистров накопления в базе данных Как было определено выше, данные каждого регистра накопления хранятся в двух таблицах базы данных: ■ таблице движений регистра накопления; ■ таблице итогов регистра накопления. В таблицу движений регистра записи могут вводиться пользователем вручную, генерироваться в процессе выполнения обработок либо при проведении документов. Подробно это описано ниже, в разделе «Запись данных в таблицу движений регистра накопления» на стр. 264. При формировании данных таблицы итогов важно обеспечить их непротиворечивость данным таблицы движений. Чтобы, например, не получилось, что по данным таблицы движений за все время в кассу предприятия пришло 100 рублей, ушло 50 рублей, но таблица итогов содержит данные об остатке 1 000 рублей. Поэтому заполнение таблицы итогов осуществляется системой согласно данным активных записей таблицы движений, при расчете итогов (автоматическом или инициированным специальными методами). Подробно это описано в разделе «Механизмы заполнения таблицы итогов регистра накопления» на стр. 289. То есть пользователь или разработчик не могут непосредственно записывать данные в таблицу итогов регистра накопления, зато могут инициализировать действия системы, производящие расчет и заполнение итогов (рис. 3.8). Рис. 3.8. Заполнение таблицы итогов регистра накопления Глава 3. Реализация задач учета движения средств 263 Если признак расчета итогов регистра включен, то расчет и заполнение данными таблицы итогов регистра производятся автоматически при записи набора записей. Проверить значение признака расчета итогов можно с помощью метода ПолучитьИспользованиеИтогов() менеджера регистра накопления (листинг 3.1). Листинг 3.1. Пример использования метода «ПолучитьИспользованиеИтогов()» ПризнакИспользованияИтогов = РегистрыНакопления.ПартииТоваров.ПолучитьИспользованиеИтогов(); Если ПризнакИспользованияИтогов Тогда Сообщение = Новый СообщениеПользователю(); Сообщение.Текст = "Итоги по регистру 'ПартииТоваров' рассчитываются"; Сообщение.Сообщить(); КонецЕсли; При необходимости разработчик может отключать или включать расчет итогов при записи движений. Это может понадобиться для того, чтобы повысить скорость записи набора записей регистра при массовых загрузках данных. Например, требуется загрузить массив информации по документам и их движениям (листинг 3.2). Листинг 3.2. Пример отключения использования итогов регистра накопления // Отключить использование итогов регистра РегистрыНакопления.ПартииТоваров.УстановитьИспользованиеИтогов(Ложь); Для Каждого Элемент из МассивИнформации Цикл // Выполнить действия по загрузке документов (регистраторов) // и наборов записей регистра // ... // Записать загруженные наборы записей // ... КонецЦикла; // Включить использование итогов регистра // (одновременно выполнится пересчет итогов) РегистрыНакопления.ПартииТоваров.УстановитьИспользованиеИтогов(Истина); В приведенном примере обеспечивается ситуация, когда заполнение таблицы итогов выполняется единоразово, а не при каждой записи набора записей загружаемых документов. Дело в том, что при включении использования итогов система производит пересчет всех итогов с момента самого раннего движения, сделанного после отключения активности итогов. 264 Реализация прикладных задач в системе «1С:Предприятие 8.2» В отношении использования подобных приемов необходимо понимать, что при отключенном расчете итогов регистра система не может обеспечить непротиворечивость данных таблиц движений и итогов регистра. Поэтому попытки обращений к итогам такого регистра будут отклоняться системой с выдачей соответствующих предупреждений об этом. Запись данных в таблицу движений регистра накопления Для понимания работы механизмов формирования или модификации записей в таблице движений регистра накопления необходимо, прежде всего, исходить из положения о том, что все записи в регистрах уникальны с точки зрения комбинации значений в ключевых полях. Регистры накопления не поддерживают независимого формирования записей без использования документа-регистратора. Этим достигается обоснованность информации регистров – данными документов. То есть обоснованность информации объектов, осуществляющих учет показателей, данными объектов, осуществляющих первичную регистрацию событий, приводящих к изменению значений показателей. С другой стороны, к одному регистратору может быть отнесено более одной записи движения. Поэтому для регистров накопления в таблице движений ключевыми являются поля Регистратор и НомерСтроки (рис. 3.9). Рис. 3.9. Набор записей регистра накопления Глава 3. Реализация задач учета движения средств 265 Для обеспечения манипулирования записями регистра при формировании или модифицировании движений используется объект встроенного языка системы РегистрНакопленияНаборЗаписей.<имя>. В отношении регистров накопления эти действия выполняются при использовании обязательного отбора по регистратору. То есть запись модифицированных данных в таблицу движений регистра накопления не может выполняться отдельно для каждого движения, а только «блоками», то есть наборами записей, подчиненных одному регистратору. Поле НомерСтроки система заполняет автоматически, при добавлении или вставке новой записи в набор записей, отобранных по первому ключевому полю Регистратор. Поле НомерСтроки содержит порядковый номер записи в наборе записей, подчиненных одному регистратору. Кроме того, в регистре накопления не могут существовать записи с пустым значением поля Регистратор, то есть не подчиненные ни одному регистратору или «подчиненные пустому регистратору». Это противоречило бы принципу «обоснованности данных регистра накопления». Таким образом, в отношении движений регистров накопления можно констатировать строгую связь с двумя классами объектов конфигурации: ■ с регистрами как «хранителями» движений; ■ с документами как с «обоснованием» формирования и наличия движений. Соответственно, для заполнения или модификации данных таблицы движений есть две возможности: ■ посредством создания набора записей регистра с обязательным отбором по регистратору; ■ посредством использования свойства объекта документа Движения, представляющего собой коллекцию наборов записей, подчиненных данному регистратору. ПРИМЕЧАНИЕ Можно сказать, что свойство Движения объекта документа представляет собой определенный «сервис», призванный облегчить труд разработчика по созданию движений документа. В этом свойстве содержатся пустые наборы записей по всем регистрам, по которым документ может выполнять движения. Для этих наборов записей уже установлен отбор по регистратору, соответствующему текущему документу. Сами же действия по записи могут инициироваться как программно (при выполнении обработок), так и интерактивно. Примеры подобных действий приводятся ниже. 266 Реализация прикладных задач в системе «1С:Предприятие 8.2» Свойство «Движения» объекта документа Свойство Движения – это свойство объекта документа (ДокументОбъект.<Имя>). Состав наборов записей, входящих в эту коллекцию, определяется системой исходя из информации, хранящейся в конфигурации. Модификация этого состава может осуществляться при работе с документом как с объектом конфигурации (рис. 3.10). Рис. 3.10. Регистры, для которых документ является регистратором Кроме этого, состав наборов записей, создаваемых системой в свойстве Движения, может быть изменен при редактировании регистра как объекта конфигурации (рис. 3.11). Благодаря использованию данного свойства облегчается работа разработчика, которому необходимо сформировать или модифицировать набор (наборы) записей регистра (регистров), подчиненных данному документу (рис. 3.12). Важно понимать, что платформа во многих механизмах использует обращение к элементам коллекции Движения. Например, при удалении документа система будет для каждого регистра, в котором он может быть регистратором, проверять наличие движений документа с целью их удаления. Поэтому не рекомендуется включать в коллекцию Движения элементы «с запасом». И наоборот, если не указано, что документ может быть регистратором для некоего регистра, то система никоим образом не позволит записать в данный регистр движения данного документа. Глава 3. Реализация задач учета движения средств Рис. 3.11. Документы, которые могут создавать движения в регистре Рис. 3.12. Свойство «Движения» объекта документа 267 268 Реализация прикладных задач в системе «1С:Предприятие 8.2» Формирование наборов записей посредством свойства объекта документа «Движения» Формирование новых наборов записей включает в себя операции, состоящие: ■ из добавления новых записей к набору записей; ■ заполнения полей записей; ■ записи набора записей. Например, требуется сформировать движения по регистру ТоварыНаСкладах на основании данных документа ПоступлениеТоваров. Причем информация для заполнения полей записей движений в основном находится в табличной части Состав документа. Данная операция может быть выполнена так, как показано в листинге 3.3. Листинг 3.3. Пример формирования движений документа // Укажем, что движения по данному регистру нужно записывать Движения.ТоварыНаСкладах.Записывать = Истина; // Перебрать коллекцию строк табличной части документа Для Каждого ТекСтрокаСостав Из Состав Цикл // Добавить новую запись к набору записей регистра ТоварыНаСкладах Движение = Движения.ТоварыНаСкладах.Добавить(); // Заполнить поля добавленной записи Движение.ВидДвижения = ВидДвиженияНакопления.Приход; Движение.Период = Дата; Движение.Номенклатура = ТекСтрокаСостав.Номенклатура; Движение.Склад = Склад; Движение.Количество = ТекСтрокаСостав.Количество; Движение.ВидОперации = ВидОперации; КонецЦикла; Краткий комментарий: сначала указываются наборы записей, содержащие движения документа по регистрам, которые должны быть записаны при проведении документа. Формирование новых записей движений и их заполнение выполняются в цикле перебора строк табличной части документа. Для каждой строки добавляется новая запись к набору записей регистра ТоварыНаСкладах, полученному как элемент коллекции свойства Движения данного объекта документа. Поскольку метод Добавить() возвращает сам добавленный объект, новая запись получается в переменную Движение. Дальнейшее заполнение полей записи осуществляется посредством этой переменной. Глава 3. Реализация задач учета движения средств 269 После выхода из обработки проведения те наборы записей, у которых свойство Записывать имеет значение Истина, будут автоматически записаны платформой. После этого свойство Записывать у этих наборов движений будет установлено в значение Ложь. Следует учитывать, что при автоматической записи движений они будут записаны с замещением, то есть старые движения документа будут замещены новыми. Если же при записи движений документа нужно добавлять новые движения к старым, то для этого нужно использовать параметр Замещать метода Записать() набора записей регистра накопления и явно записывать набор записей с параметром Замещать, установленным в значение Ложь. Параметр Замещать может принимать значения типа Булево, по умолчанию – значение Истина. Действие данного параметра проявляется в случае, если на момент записи нового (или модифицированного) набора записей в регистре присутствуют еще записи, подчиненные данному же регистратору. Например, в регистре ТоварыНаСкладах присутствует набор записей, подчиненный регистратору ПоступлениеТоваров № 1 (табл. 3.6). Приход Истина Приход Истина Пульт VH Пульт PW Количество Склад Номенклатура ПоступлениеТоваров № 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 Вид движения Период Номер строки Таблица 3.6. Состав записей регистра накопления Главный 10 Главный 7 Записывается новый набор записей (табл. 3.7). Приход Истина Приход Истина Пульт VH Пульт PW Шнур R-100 Количество Истина Склад Приход Номенклатура Активность ПоступлениеТоваров № 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 Номер строки Период Таблица 3.7. Записываемый набор записей Главный 10 Главный 7 Главный 100 270 Реализация прикладных задач в системе «1С:Предприятие 8.2» Тогда если при записи набора записей для параметра Замещать будет указано значение Ложь (листинг 3.4), то записи, существовавшие в регистре накопления, будут сохранены, и к ним будут добавлены новые записи из записываемого набора (табл. 3.8). Листинг 3.4. Запись набора записей с добавлением Движения.ТоварыНаСкладах.Записать(Ложь); Истина 2 Приход Истина 3 Приход Истина 4 Приход Истина 5 Приход Истина Пульт VH Пульт PW Пульт VH Пульт PW Шнур R-100 Количество Приход Склад 1 Номенклатура Активность ПоступлениеТоваров № 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 Вид движения Регистратор 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 Номер строки Период Таблица 3.8. Состав записей регистра накопления Главный 10 Главный 7 Главный 10 Главный 7 Главный 100 Если же запись набора записей будет выполняться с замещением (листинг 3.5), то старый набор записей будет замещен, и после выполнения операции регистр будет содержать записи, показанные в табл. 3.9. Листинг 3.5. Запись набора записей с замещением Движения.ТоварыНаСкладах.Записать(Истина); // Альтернативный вариант вызова Движения.ТоварыНаСкладах.Записать(); Данная возможность позволяет решать различные прикладные задачи, связанные: ■ с добавлением новых движений к старым; ■ замещением старых движений новыми. Хотелось бы отметить, что все вышеописанные действия по формированию движений типизированы, и большая часть кода посвящена заполнению полей регистра значениями полей документа. Поэтому для облегчения напи- Глава 3. Реализация задач учета движения средств 271 сания соответствующего кода разработчик может использовать конструктор движений документа (рис. 3.13). Приход Истина 3 Приход Истина Количество 2 Пульт VH Пульт PW Шнур R-100 Склад Приход Истина Номенклатура 1 Активность ПоступлениеТоваров № 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 Номер строки Период Таблица 3.9. Состав записей регистра накопления Главный 10 Главный 7 Главный 100 Рис. 3.13. Конструктор движений документа Программное изменение данных регистра можно использовать при проведении документа, а можно и без проведения. Поскольку заполнение учетных данных чаще всего выполняется во время операции проведения документа, то конструктор движений документа создает соответствующий код именно в рамках процедуры обработчика события ОбработкаПроведения. 272 Реализация прикладных задач в системе «1С:Предприятие 8.2» Формирование движений при проведении документа Проведение документов чаще всего используется для формирования движений документов. Этому способствует удобство функциональных решений, заложенных в платформу. Например: ■ С точки зрения платформы отдельного процесса «проведение» не существует. Есть запись документа с проведением, причем в рамках одной транзакции. Подробно это описано в разделе «Запись документов» на стр. 169. Таким образом, в момент выполнения обработчика события ОбработкаПроведения документ уже записан. То есть разработчику не нужно беспокоиться о предотвращении попыток проведения незаписанных документов (рис. 3.14). Рис. 3.14. Последовательность событий при записи документа с проведением ■ Свойство Удаление движений документа как объекта конфигурации стандартно устанавливается платформой в значение Удалять автоматически при отмене проведения. Это значит, что при перепроведении документа движения, подчиненные данному документу, перезаписываются, а при отмене проведения движения документа автоматически удаляются. Если разработчик захочет реализовать нестандартный вариант проведения документа и установит свойство Удаление движений в значение Удалять автоматически, то при записи документа с проведением сначала будут удалены все старые движения документа. То есть на момент выполнения обработчика события ОбработкаПроведения в регистрах не будет наборов записей с движениями данного документа. ■ При записи с проведением система автоматически запишет выбранные и незаписанные наборы записей, находящиеся в свойстве Движения. Это еще один «сервис», обеспечиваемый свойством Движения. Отсюда следуют два важных вывода. Во-первых, если наборы записей необходимо записывать с добавлением, то это нужно выполнять в явном виде, т. к. при автоматической записи движений они будут записаны с замещением. Глава 3. Реализация задач учета движения средств 273 Во-вторых, последовательность обращения к регистрам при автоматической записи движений будет одна и та же для разных документов. Это позволяет снизить вероятность взаимных блокировок при проведении документа в конкурентных режимах работы. В случаях, если необходимо программно вызвать саму обработку проведения, инициируется запись документа с проведением. Пример программного вызова проведения документа в оперативном режиме приведен в листинге 3.6. Листинг 3.6. Пример программного вызова проведения документа Записать(РежимЗаписиДокумента.Проведение, РежимПроведенияДокумента.Оперативный); В демонстрационной конфигурации «Хранение информации и учет движения средств», которая находится на прилагаемом компакт-диске, в обработке ДействияСДвижениямиРегистраНакопления приводится пример перепроведения документов РеализацияТоваров в интервале с ДатаНачала по ДатаОкончания (листинг 3.7). Листинг 3.7. Пример перепроведения документов «РеализацияТоваров» // Получить ссылки на проведенные документы в требуемом интервале Запрос = Новый Запрос; Запрос.Текст = "ВЫБРАТЬ | РеализацияТоваров.Ссылка |ИЗ | Документ.РеализацияТоваров КАК РеализацияТоваров |ГДЕ | РеализацияТоваров.Дата МЕЖДУ &ДатаНачала И &ДатаОкончания | И РеализацияТоваров.Проведен"; Запрос.УстановитьПараметр("ДатаНачала", ДатаНачала); Запрос.УстановитьПараметр("ДатаОкончания", ДатаОкончания); Результат = Запрос.Выполнить(); // Перебрать ссылки полученных документов Выборка = Результат.Выбрать(); Пока Выборка.Следующий() Цикл // Перепровести каждый документ неоперативно Документ = Выборка.Ссылка.ПолучитьОбъект(); Документ.Записать(РежимЗаписиДокумента.Проведение); КонецЦикла; Здесь инициировалось проведение в неоперативном режиме. Значение по умолчанию параметра РежимПроведения метода объекта документа Записать() – именно РежимПроведенияДокумента.Неоперативный. Говоря о записи документа, необходимо отдельно упомянуть случай, когда документ записывается с проведением в форме самого документа. 274 Реализация прикладных задач в системе «1С:Предприятие 8.2» Запись в форме позволяет использовать функциональность, определяемую расширением формы документа: установка даты документа, установка режима проведения, запрет определенных действий пользователя и т. д. Подробно эти действия рассматриваются в разделе «Особенности работы формы документа» на стр. 195. В качестве примера записи в форме в демонстрационной конфигурации «Хранение информации и учет движения средств», которая находится на прилагаемом компакт-диске, в форме документа РеализацияТоваров в командную панель формы добавлена кнопка Провести неоперативно. Действие, выполняемые по нажатию этой кнопки, представлены в листингах 3.8, 3.9. Листинг 3.8. Обработчик события нажатия кнопки «Провести неоперативно» &НаКлиенте Процедура ПровестиНеоперативно(Команда) ПровестиНеоперативноНаСервере(); КонецПроцедуры Листинг 3.9. Пример записи документа с неоперативным проведением в форме &НаСервере Процедура ПровестиНеоперативноНаСервере(); // Установить использование режима неоперативного проведения ИспользоватьРежимПроведения = ИспользованиеРежимаПроведения.Неоперативный; // Выполнить проведение в форме Записать(Новый Структура("РежимЗаписи", РежимЗаписиДокумента.Проведение)); КонецПроцедуры В данном примере используется свойство ИспользоватьРежимПроведения и метод Записать() расширения формы документа. Формирование движений в объекте документа, но без проведения документа С прикладной точки зрения часто возникает потребность сформировать движения для документов, чья обработка еще полностью не завершена, и завершена будет, возможно, не в этом сеансе работы с программой, а через некоторое время. Поэтому платформа «1С:Предприятие» позволяет в способе формирования движений не ограничиваться только проведением документа. Глава 3. Реализация задач учета движения средств 275 Однако нужно помнить, что кроме выполнения самих движений при формировании движений вне процедуры, обрабатывающей проведение документа, необходимо: ■ контролировать, чтобы документ был сохранен на момент записи движений в регистр (записи должны содержать ссылку на регистратор); ■ решать, что делать со старыми движениями документа; ■ явно записывать сформированные наборы записей движений. Пример формирования движений без проведения документа приведен в демонстрационной конфигурации «Хранение информации и учет движения средств», которая находится на прилагаемом компакт-диске. В командной панели формы документа ПоступлениеТоваров создано подменю Действия с движениями. В нем находится команда Формирование движений. Обработчик действия данной команды (листинг 3.11, 3.12) передает управление процедуре ФормированиеДвиженийБезПроведения() модуля объекта документа (листинг 3.10). Листинг 3.10. Пример формирования движений документа без проведения Процедура ФормированиеДвиженийБезПроведения() Экспорт // Проверить и записать документ, если ранее не записан Если ЭтоНовый() Тогда Записать(); КонецЕсли; Для Каждого ТекСтрокаСостав Из Состав Цикл // Сформировать и заполнить запись движения Движение = Движения.ТоварыНаСкладах.Добавить(); Движение.ВидДвижения = ВидДвиженияНакопления.Приход; Движение.Период = Дата; Движение.Номенклатура = ТекСтрокаСостав.Номенклатура; Движение.Склад = Склад; Движение.Количество = ТекСтрокаСостав.Количество; Движение.ВидОперации = ВидОперации; КонецЦикла; // Записать движения регистров с замещением старых наборов записей Движения.ТоварыНаСкладах.Записать(); КонецПроцедуры Краткий комментарий: сначала необходимо убедиться, что ссылка на данный документ уже есть в базе данных, то есть документ не новый. Если нет, документ записывается, поскольку без ссылки на регистратор движения в регистре накопления сформированы быть не могут. Затем формируется новый набор записей в цикле перебора строк табличной части Состав документа. Далее сформированный набор записей записывается в регистр. 276 Реализация прикладных задач в системе «1С:Предприятие 8.2» Также следует обратить внимание на то, что в заголовке процедуры, выполняющей эти действия, указано ключевое слово Экспорт. В результате данная процедура доступна в контексте объекта документа. Вызов данной процедуры в демонстрационной конфигурации «Хранение информации и учет движения средств», которая находится на прилагаемом компакт-диске, выполняется из модуля формы данного документа. Основным реквизитом формы документа как раз и является объект документа, поэтому процедура будет доступна в контексте формы документа. Но для того, чтобы вызвать процедуру объекта документа, нужно сначала конвертировать основной реквизит формы Объект в этот объект (листинг 3.12, 3.13). Листинг 3.11. Обработчик действия команды «ФормированиеДвижений» &НаКлиенте Процедура ФормированиеДвижений(Команда) ФормированиеДвиженийДокумента(); КонецПроцедуры Листинг 3.12. Пример вызова процедуры из формы документа &НаСервере Процедура ФормированиеДвиженийДокумента() Документ = РеквизитФормыВЗначение("Объект"); Документ.ФормированиеДвиженийБезПроведения(); КонецПроцедуры В принципе вызов этой процедуры может быть реализован почти из любого модуля программы. Для этого нужно лишь получить объект документа (например, из ссылки на документ), листинг 3.13. Листинг 3.13. Пример вызова процедуры из модуля обработки // Получить объект документа Документ = СсылкаНаДокумент.ПолучитьОбъект(); // Вызвать процедуру модуля объекта документа, формирующую движения Документ.ФормированиеДвиженийБезПроведения(); Модификация существующих движений документа Кроме задачи формирования новых движений без проведения документа разработчикам иногда приходится решать задачи изменения информации в движениях (модификации движений), снятия активности движений документа или вообще удаления движений. Технология их решения абсолютно та же. Это запись наборов записей регистра. Только соответствующим образом модифицированных. Глава 3. Реализация задач учета движения средств 277 Для модификации движений можно сначала прочитать набор записей движений, далее модифицировать записи и записать уже модифицированный набор записей движений. Обратите внимание: элемент коллекции свойства документа Движения представляет собой набор записей регистра. Но он, пока не прочитан, пуст (рис. 3.15). Рис. 3.15. Коллекция «Движения» содержит пустые наборы записей Поэтому, для того чтобы модифицировать записи регистра, необходимо сначала прочитать данные наборы записей (рис. 3.16). Рис. 3.16. Чтение набора записей 278 Реализация прикладных задач в системе «1С:Предприятие 8.2» В демонстрационной конфигурации «Хранение информации и учет движения средств», которая находится на прилагаемом компакт-диске, в форме документа ПоступлениеТоваров приведен пример заполнения поля реквизита Поставщик регистра ТоварыНаСкладах значением из константы ОсновнойПоставщик (листинг 3.14). Листинг 3.14. Пример модификации движений документа // Получить значение основного поставщика ОсновнойПоставщик = Константы.ОсновнойПоставщик.Получить(); // Прочитать набор записей движений по регистру "ТоварыНаСкладах" Документ = РеквизитФормыВЗначение("Объект"); НаборЗаписей = Документ.Движения.ТоварыНаСкладах; НаборЗаписей.Прочитать(); // Модифицировать каждую запись в прочитанных движениях Если НаборЗаписей.Количество()<> 0 Тогда Для Каждого Движение Из НаборЗаписей Цикл Движение.Поставщик = ОсновнойПоставщик; КонецЦикла; // Записать измененный набор записей НаборЗаписей.Записать(); КонецЕсли; Снятие активности движений – по сути дела та же задача модификации движений документа. Только в отношении поля Активность и может выполняться аналогично. Однако с прикладной точки зрения свойство записи движения Активность особое. Во-первых, наличие активных движений документа в регистре означает, что данный документ отражен в неком аспекте учета. Вернее, в учете отражено событие, зафиксированное данным документом. Во-вторых, наличие движений документа со снятой активностью означает, что движения данного документа не используются в учетном механизме. В-третьих, наличие движений документа в регистре, из которых часть активна, а часть неактивна, с точки зрения практического применения нонсенс. Например, попробуйте представить себе ситуацию: «Отгружено пять пылесосов и холодильник, но не совсем. Холодильник не отгружен». Поэтому платформа не допускает записи набора записей движений регистра, если часть записей в этом наборе активна, а часть – нет (рис. 3.17). Глава 3. Реализация задач учета движения средств 279 Рис. 3.17. Варианты использования свойства «Активность» В системе предусмотрена возможность установки и снятия активности целиком для всего набора записей посредством метода УстановитьАктивность() набора записей регистра накопления. В демонстрационной конфигурации «Хранение информации и учет движения средств», которая находится на прилагаемом компакт-диске, в форме документа ПоступлениеТоваров приводится пример снятия активности всех движений документа по регистрам (листинг 3.15). Листинг 3.15. Пример снятия активности записей Документ = РеквизитФормыВЗначение("Объект"); // Перебрать наборы записей по регистрам Для Каждого НаборЗаписей Из Документ.Движения Цикл // Прочитать движения по регистру НаборЗаписей.Прочитать(); // Снять активность НаборЗаписей.УстановитьАктивность(Ложь); // Записать набор записей НаборЗаписей.Записать(); КонецЦикла; 280 Реализация прикладных задач в системе «1С:Предприятие 8.2» И, наконец, операция удаления движений документа. Она сводится к записи пустого набора записей регистра. В ситуации, когда набор записей регистра прочитан и не пуст, можно использовать его предварительную очистку. В демонстрационной конфигурации «Хранение информации и учет движения средств», которая находится на прилагаемом компакт-диске, в форме документа ПоступлениеТоваров при выполнении действия ОчиститьДвиженияДокумента выполняется процедура с текстом, который представлен в листинге 3.16. Листинг 3.16. Пример удаления движений документа Документ = РеквизитФормыВЗначение("Объект"); // Перебрать наборы записей по регистрам Для Каждого НаборЗаписей Из Документ.Движения Цикл // Очистить набор записей движений по регистру НаборЗаписей.Очистить(); // Записать набор записей НаборЗаписей.Записать(); КонецЦикла; Однако если бы была полная уверенность, что ни один из наборов записей регистров для данного объекта документа на момент выполнения процедуры не прочитан, то предварительную очистку можно было бы не делать (листинг 3.17). Листинг 3.17. Пример удаления движений документа Документ = РеквизитФормыВЗначение("Объект"); // Перебрать наборы записей по регистрам Для Каждого НаборЗаписей Из Документ.Движения Цикл // Записать набор записей НаборЗаписей.Записать(); КонецЦикла Интерактивное формирование наборов записей с помощью свойства «Движения» объекта документа Описанный выше функционал системы касался наиболее часто встречающихся решений задач формирования движений документов. То есть пользователь отвечает за правильность ввода информации в документ, а разработчик – за правильность работы обработок, интерпретирующих Глава 3. Реализация задач учета движения средств 281 и записывающих в регистры учетную информацию, полученную согласно данным документов. Однако иногда могут встречаться ситуации, когда не требуется никакой дополнительной обработки для вводимой пользователем информации. То есть тогда можно обеспечить ввод информации напрямую в данные регистра, без промежуточной регистрации ее в данных документа. Для регистров накопления в любой ситуации возможно содержание информации только с использованием документа-регистратора. Поэтому в таких случаях для обеспечения требования обоснованности данных регистра наличием регистратора и желания уменьшить избыточность хранения информации в базе данных возможно применение технологии, условно называемой «ручная операция». В форме документа отображаются данные и документа, и движений регистра, которые починены данному документу (рис. 3.18). Рис. 3.18. Редактирование движений вручную В состав демонстрационной конфигурации «Хранение информации и учет движения средств», которая находится на прилагаемом компакт-диске, входит документ РучнаяОперация. Его создание и технологические вопросы, возникающие при его использовании, подробно описаны в разделе «Специальные случаи использования документов. Ручная операция» на стр. 214. Хотелось бы только еще раз подчеркнуть, что для облегчения работы разработчика здесь использовалось свойство Движения объекта документа. И таблица в форме документа отображает данные одного из элементов этой коллекции – набора записей движений по регистру ТоварыНаСкладах. 282 Реализация прикладных задач в системе «1С:Предприятие 8.2» Пользователь, работая с формой документа, на самом деле интерактивно модифицирует считанные данные набора записей движений регистра, подчиненных данному документу (рис. 3.19). Рис. 3.19. Форма документа «РучнаяОперация» А вопросы отображения данных регистра в таблице формы, записи модифицированных данных из реквизита формы в таблицу движений регистра и т. д. берет на себя платформа посредством возможностей, предоставляемых расширением формы документа. Причем системой отрабатывается большинство ситуаций, которые могут привести к коллизиям. Например, если пользователь после внесения изменений в содержимое таблицы формы, но до записи модифицированных данных в регистр нажмет кнопку Перечитать (или выполнит команду формы Все действия Перечитать), то он получит предупреждение (рис. 3.20). Рис. 3.20. Предупреждение при перечитывании данных Если перечитать данные до записи модифицированных данных в регистр (ответ – Да), то последние изменения будут потеряны. Глава 3. Реализация задач учета движения средств 283 Запись набора записей регистра без использования свойства «Движения» В разделе «Свойство «Движения» объекта документа» на стр. 266 были описаны действия с объектом документа, приводящие к чтению, модификации, добавлению и записи наборов записей в регистр. Те же самые результаты можно получить и без использования объекта документа, работая непосредственно с набором записей (рис. 3.21). Рис. 3.21. Использование набора записей регистра накопления В данном случае для модификации движений документа не используется объект документа (используется только ссылка на документ). Поэтому при выполнении обработок массового формирования или модификации движений, связанных не с единичными документами, а с большими массивами документов, уместнее применение приемов работы, основанных на использовании набора записей регистра, т. к. этот способ является менее ресурсоемким. Например, в состав конфигурации уже заполненной базы данных ввели новый оборотный регистр Продажи со следующей структурой (рис. 3.22). Рис. 3.22. Структура регистра «Продажи» 284 Реализация прикладных задач в системе «1С:Предприятие 8.2» Он должен заполняться при проведении документа РеализацияТоваров данными документа (включая данные его табличной части Состав), поэтому в обработку проведения данного объекта конфигурации были внесены соответствующие изменения. Однако существует уже достаточно много документов РеализацияТоваров, оформленных и проведенных еще в то время, когда нового регистра не было. Как для них сформировать движения по новому регистру? Можно, конечно, перепровести все ранее проведенные документы РеализацияТоваров. Однако при проведении документа не только выполняются движения по новому регистру. Формируются движения по другим регистрам, записываются данные в таблицу документа, в таблицы журналов документов и т. д. Поэтому данное решение может оказаться неудобным в отношении скорости исполнения или по другим причинам. В данной ситуации более эффективным выглядит применение следующей обработки. Из базы данных запросом выбрать ссылки на проведенные документы РеализацияТоваров и другие данные этих документов, необходимые для формирования движений. Эти данные можно получить из таблицы документа. Перебирая выборку результата запроса, применять отбор по регистраторам (ссылкам на документы) для формирования наборов записей движений, подчиненных этим документам (листинг 3.18). Листинг 3.18. Пример формирования движений документов Процедура ФормированиеДвиженийПоПродажамДляВсехРеализацияТоваров() // Обратиться к набору записей регистра НаборЗаписейРегистра = РегистрыНакопления.Продажи.СоздатьНаборЗаписей(); // Прочитать из базы данных данные, необходимые для формирования движений Запрос = Новый Запрос; Запрос.Текст = "ВЫБРАТЬ | РеализацияТоваровСостав.Ссылка КАК Ссылка, | РеализацияТоваровСостав.Ссылка.Дата, | РеализацияТоваровСостав.Ссылка.Контрагент, | РеализацияТоваровСостав.Ссылка.ВидОперации, | РеализацияТоваровСостав.Номенклатура, | РеализацияТоваровСостав.Количество, | РеализацияТоваровСостав.Сумма |ИЗ | Документ.РеализацияТоваров.Состав КАК РеализацияТоваровСостав |ГДЕ | РеализацияТоваровСостав.Ссылка.Проведен |ИТОГИ ПО | Ссылка"; Результат = Запрос.Выполнить(); Глава 3. Реализация задач учета движения средств 285 // Перебрать все документы из результата запроса ВыборкаДокументов = Результат.Выбрать(ОбходРезультатаЗапроса.ПоГруппировкам); Пока ВыборкаДокументов.Следующий() Цикл // Установить отбор набора записей по регистратору, к которому будут приписаны движения НаборЗаписейРегистра.Отбор.Регистратор.Установить(ВыборкаДокументов.Ссылка); // Перебрать данные о составе документа, необходимые для заполнения формируемых движений ВыборкаДетальныхЗаписей = ВыборкаДокументов.Выбрать(); Пока ВыборкаДетальныхЗаписей.Следующий() Цикл // Сформировать движения по регистру Продажи НоваяЗапись = НаборЗаписейРегистра.Добавить(); НоваяЗапись.Период = ВыборкаДетальныхЗаписей.Дата; НоваяЗапись.Номенклатура = ВыборкаДетальныхЗаписей.Номенклатура; НоваяЗапись.Количество = ВыборкаДетальныхЗаписей.Количество; НоваяЗапись.Сумма = ВыборкаДетальныхЗаписей.Сумма; НоваяЗапись.Контрагент = ВыборкаДокументов.Контрагент; НоваяЗапись.ВидОперации = ВыборкаДокументов.ВидОперации; КонецЦикла; // Записать сформированные для очередного документа движения НаборЗаписейРегистра.Записать(); // Очистить набор записей регистра // перед использованием для следующего документа НаборЗаписейРегистра.Очистить(); КонецЦикла; КонецПроцедуры Данный пример приведен в составе обработки ДействияСДвижениямиРегистраНакопления демонстрационной конфигурации «Хранение информации и учет движения средств», которая находится на прилагаемом компакт-диске. Еще раз хотелось бы подчеркнуть, что данная обработка вообще не обращается к объектам документов. По сути, движения «приписываются» к документам «без ведома объектов документов». Подобным же образом можно решать не только задачи формирования новых движений документов, но и модификации существующих движений. Примеры чтения движений регистров накопления будут приведены ниже, в разделе «Получение движений регистров накопления» на стр. 300. Частным случаем операций модификации наборов записей регистров накопления является удаление движений. Удалить движения регистра Продажи в пределах заданного временного интервала можно следующим образом (листинг 3.19). 286 Реализация прикладных задач в системе «1С:Предприятие 8.2» Листинг 3.19. Пример удаления движений документа &НаСервереБезКонтекста Процедура УдалитьДвиженияПоПродажамЗаПериод(ДатаНачала, ДатаОкончания) // Обратиться к набору записей регистра НаборЗаписейРегистра = РегистрыНакопления.Продажи.СоздатьНаборЗаписей(); // Получить из базы данных ссылки на документы, у которых нужно удалить движения Запрос = Новый Запрос; Запрос.Текст = "ВЫБРАТЬ РАЗЛИЧНЫЕ | Продажи.Регистратор |ИЗ | РегистрНакопления.Продажи КАК Продажи |ГДЕ | Продажи.Период МЕЖДУ &ДатаНачала И &ДатаОкончания"; Запрос.УстановитьПараметр("ДатаНачала", ДатаНачала); Запрос.УстановитьПараметр("ДатаОкончания", ДатаОкончания); Результат = Запрос.Выполнить(); // Перебрать все документы из результата запроса Выборка = Результат.Выбрать(); Пока Выборка.Следующий() Цикл // Установить отбор набора записей по регистратору, к которому будут приписаны движения НаборЗаписейРегистра.Отбор.Регистратор.Установить(Выборка.Регистратор); // Записать пустой набор записей движений для очередного документа НаборЗаписейРегистра.Записать(); КонецЦикла; КонецПроцедуры В данном примере использовался следующий прием: набор записей регистра, не прочитанный из базы, пуст. Если записать пустой набор записей регистра с замещением, это приведет к удалению движений замещаемого в рамках отбора набора записей. В заключение хотелось бы только еще раз подчеркнуть – для регистров накопления все действия с модификацией наборов записей регистра можно выполнять только в рамках отбора по регистратору, то есть документу, которому подчинен этот набор записей. Глава 3. Реализация задач учета движения средств 287 Интерактивное формирование движений с помощью формы набора записей Выше, в разделе «Интерактивное формирование наборов записей с помощью свойства «Движения» объекта документа» на стр. 266, рассматривался пример, когда в рамках формы документа пользователю предоставлялись возможности интерактивного формирования/модификации движений документа. Если пользователю необходимо предоставить те же интерактивные возможности, но без использования формы документа, задача может быть решена посредством использования формы набора записей. В демонстрационной конфигурации «Хранение информации и учет движения средств», которая находится на прилагаемом компакт-диске, в форме списка документа РучнаяОперация приведен подобный пример. В состав регистра ТоварыНаСкладах включена форма ФормаНабораЗаписей, основной реквизит которой имеет тип РегистрНакопленияНаборЗаписей.ТоварыНаСкладах. Вызов данной формы может осуществляться любой обработкой или командой. Единственное, для возможности выполнения действий по модификации наборов записей регистра накопления необходимо помнить об обязательности установки отбора по регистратору. В демонстрационной конфигурации «Хранение информации и учет движения средств», которая находится на прилагаемом компакт-диске, вызов формы набора записей регистра ТоварыНаСкладах реализуется из формы списка документа РучнаяОперация (рис. 3.23). Рис. 3.23. Форма списка документа «РучнаяОперация» Обработчик команды ОткрытьФормуНабораЗаписей реализован следующим образом (листинг 3.20). 288 Реализация прикладных задач в системе «1С:Предприятие 8.2» Листинг 3.20. Пример использования формы набора записей &НаКлиенте Процедура ОткрытьФормуНабораЗаписей(Команда) // Получить ссылку на текущий документ ТекущийДокумент = Элементы.Список.ТекущаяСтрока; // Открыть форму набора записей с отбором по регистратору ЗначениеОтбора = Новый Структура("Регистратор", ТекущийДокумент); ПараметрыФормы = Новый Структура("Отбор", ЗначениеОтбора); ОткрытьФорму("РегистрНакопления.ТоварыНаСкладах.Форма.ФормаНабораЗаписей", ПараметрыФормы) КонецПроцедуры Краткий комментарий: сначала создается структура отбора ЗначениеОтбора с ключом Регистратор, содержащим ссылку на текущий документ (Элементы.Список.ТекущаяСтрока), и добавляется в структуру параметров формы ПараметрыФормы. Эти параметры передаются в форму набора записей ФормаНабораЗаписей, и эта форма открывается с отбором по полю Регистратор регистра накопления ТоварыНаСкладах. В форме набора записей пользователь может интерактивно модифицировать как сам набор записей (удалять, добавлять, копировать и т. д.), так и содержимое полей записей, входящих в набор записей. Впоследствии модифицированный набор может быть сохранен, то есть записан в регистр (рис. 3.24). Рис. 3.24. Форма набора записей регистра Обеспечение выполнения этих действий и устранение возможных коллизий реализуются средствами расширения формы набора записей регистра. Глава 3. Реализация задач учета движения средств 289 Механизмы заполнения таблицы итогов . регистра накопления Таблицы итогов регистров накопления заполняются автоматически вследствие добавления, удаления или модификации наборов записей в таблице движений регистра, если для этого регистра не отключен режим расчета итогов. Расчет итогов производится согласно записям таблицы движений регистра, если свойство Активность этих записей имеет значение Истина. Но для разных видов регистров накопления заполнение данных таблицы итогов выполняется по разным правилам. Это объясняется спецификой показателей, учитываемых посредством регистров. Подробно данная специфика была описана ранее, в разделе «Оперативный учет. Описание задач, решаемых регистрами накопления» на стр. 249. Механизм заполнения таблицы итогов регистра накопления остатков В таблице итогов регистра остатков хранятся текущие итоги и могут храниться итоги рассчитанных периодов. Текущие (актуальные) итоги – это итоговые значения учитываемых в регистре ресурсов (показателей) на момент времени заведомо больший, нежели любое значение поля Период записей таблицы движений. Для определенности текущие итоги регистров остатков датированы на 01.11.3999 00:00:00. Итоги рассчитанных периодов содержат данные конечных значений ресурсов для каждого месяца, предшествующего границе рассчитанных итогов. При записи набора активных записей в таблице движений всегда рассчитываются и перезаписываются текущие итоги в таблице итогов, если у регистра установлен признак использования итогов. Данные итогов периодов в таблице итогов появляются вследствие расчета итогов. Такой расчет может быть инициирован посредством системной команды Управление итогами. Для этого нужно вызвать стандартную функцию Управление итогами (Все функции Стандартные) и переключить ее в режим Полные возможности (рис. 3.25). Период для подсчета итогов – всегда месяц. Чтобы установить границу рассчитанных итогов сразу для всех регистров накопления остатков, можно переключить обработку в режим Часто используемые возможности и выполнить команду Установить период рассчитанных итогов. Также расчет итогов может быть выполнен программно (листинг 3.21). 290 Реализация прикладных задач в системе «1С:Предприятие 8.2» Рис. 3.25. Стандартная обработка «Управление итогами» Листинг 3.21. Программный расчет итогов регистра РегистрыНакопления.ТоварыНаСкладах.УстановитьПериодРассчитанныхИтогов(Дата(2010, 05, 31)); Например, пусть таблица движений регистра накопления будет заполнена данными, как показано в табл. 3.10. 1 Приход Истина 1 Приход Истина 2 Приход Истина 1 Приход Ложь 1 Расход Истина 1 Приход Истина 1 Приход Истина Пульт VH Пульт VH Пульт PW Пульт VH Пульт VH Пульт PW Пульт VH Сумма Количество Склад Номенклатура Активность ПоступлениеТоваров № 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 Номер строки Период Таблица 3.10. Таблица движений регистра накопления остатков Главный 1 10 Главный 9 90 Главный 7 490 Фили-2 5 60 Главный 8 80 Фили-2 1 17 Фили-2 1 18 291 Глава 3. Реализация задач учета движения средств Для вышеприведенного примера заполнения таблицы движений регистра таблица итогов регистра после расчета итогов по 31.05.2010 будет выглядеть так, как показано в табл. 3.11. Таблица 3.11. Таблица итогов регистра накопления остатков Итоги апреля 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 1 17 Обратите внимание: майские итоги хранятся с указанием периода 01.06.2010 00:00:00, потому что итоги рассчитаны на начало июня. То есть при их расчете учтены все записи, которые зафиксированы в мае, включая 31.05.2010 23:59:59 (рис. 3.26). Рис. 3.26. Хранение рассчитанных итогов регистра накопления остатков Наличие посчитанных по конец каждого месяца итогов положительно сказывается на быстродействии обращений к остаткам регистра. Как будет еще более подробно описано ниже, в разделе «Получение остатков» на стр. 310, расчет остатков начинается с определения ближайшего равного или большего итога (хранимого в таблице итогов регистра) с последующим «досчетом» остатка на нужный момент времени по таблице движений. 292 Реализация прикладных задач в системе «1С:Предприятие 8.2» Но зачастую может сложиться ситуация, что граница рассчитанных итогов очень сильно «отстает» от периода самой последней записи в регистре. Данное положение не сказывается на функциональности регистра, сказывается только на быстродействии обращений к его остаткам. Поскольку досчет тогда будет производиться, скорее всего, по большому количеству записей. При добавлении, удалении, модификации записей таблицы движений регистра система автоматически производит пересчет всех рассчитанных итогов, начиная с того периода (месяца), к которому относится значение поля Период записей. Так же пересчитываются текущие итоги. Этот процесс захватывает все записи итогов, в которых указаны значения измерений модифицируемых записей. Главное, чтобы значение поля Активность модифицируемых записей таблицы движений было Истина. Например, пусть к записям регистра добавляются записи, выделенные в табл. 3.12. 2 Приход Истина 1 Приход Истина 1 Приход Ложь 1 Приход Ложь 1 Расход 1 Приход Истина 1 Приход Истина Истина Сумма Приход Истина Количество 1 Пульт VH Пульт VH Пульт PW Пульт PW Пульт PW Пульт VH Пульт VH Пульт PW Пульт 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 Номер строки Период Таблица 3.12. Добавление записей в таблицу движений регистра накопления остатков Главный 1 10 Главный 9 90 Главный 7 490 Фили-2 10 120 Главный 1 1 Фили-2 5 60 Главный 8 80 Фили-2 1 17 Фили-2 1 18 В этом случае будет производиться перерасчет итогов только по комбинации значений измерений Пульт PW и Фили-2 (табл. 3.13). Ведь свойство Активность движений документа Поступление товаров № 7 имеет значение Ложь. 293 Глава 3. Реализация задач учета движения средств Таблица 3.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 Пульт 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 Если в результате расчета текущих итогов или итогов периода окажется, что по некой комбинации значений измерений итоги всех ресурсов «выводятся в ноль», то данная запись удаляется системой из таблицы итогов при общем пересчете итогов. Например, если к вышеприведенным примерам в таблицу движений добавить еще записи, представленные в табл. 3.14, то таблица итогов регистра после общего пересчета итогов в результате будет заполнена так, как показано в табл. 3.15. 2 Расход Истина Пульт Главный VH Пульт Главный PW Таблица 3.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 Главный Главный Главный Фили-2 Фили-2 Главный Фили-2 1 2 7 11 1 6 11 10 20 490 137 18 420 137 Сумма Истина Количество Расход Склад 1 Номенклатура Активность РеализацияТоваров № 2 02.06.2010 10:00:00 РеализацияТоваров № 2 02.06.2010 10:00:00 Вид движения Регистратор 02.06.2010 10:00:00 02.06.2010 10:00:00 Номер cтроки Период Таблица 3.14. Записи, добавляемые в регистр накопления остатков 2 20 1 70 294 Реализация прикладных задач в системе «1С:Предприятие 8.2» Если впоследствии будет произведен расчет итогов по 30.06.2010, то таблица итогов примет вид, представленный в табл. 3.16. Таблица 3.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 Механизм заполнения таблицы итогов оборотного регистра накопления При добавлении, удалении или модификации наборов записей в таблице движений всегда рассчитываются итоги в том периоде (месяце), к которому принадлежит значение поля Период записи. В отличие от регистра остатков этот процесс не зависит от периода рассчитанных итогов базы данных (рис. 3.27). Рис. 3.27. Хранение рассчитанных итогов оборотного регистра накопления Для расчета итогов учитываются только записи, у которых поле Активность имеет значение Истина. Пример заполнения таблицы движений оборотного регистра Продажи представлен в табл. 3.17. 295 Глава 3. Реализация задач учета движения средств Пульт VH 1 Истина Пульт VH 1 Истина Пульт VH 1 Истина Пульт VH 1 Ложь Пульт PW 1 Истина Пульт PW Сумма Истина Количество 1 Контрагент Номенклатура Реализация № 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 Номер строки Период Таблица 3.17. Таблица движений оборотного регистра накопления Ялта-Лтд 9 135 10 150 1 15 1 15 Крона 1 90 Ялта-Лтд 1 95 Компания "Риона" Компания "Риона" Компания "Риона" Для вышеприведенного примера заполнения таблицы движений система заполнит таблицу итогов регистра следующим образом (табл. 3.18). Таблица 3.18. Таблица итогов оборотного регистра накопления Период Итоги марта 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 10 150 2 30 1 95 Пульт VH Пульт VH Пульт �� PW Компания "Риона" Компания "Риона" Ялта-Лтд Обратите внимание: поле Период заполняется значением даты начала периода (месяца), по которому хранятся итоги. Хотя для оборотного регистра не существует понятий «расход» и «приход», при необходимости можно использовать формирование движений с отрицательными значениями ресурсов. Например, для отражения ситуации «возврат от покупателя» в регистр Продажи можно добавить такую запись (табл. 3.19). 296 Реализация прикладных задач в системе «1С:Предприятие 8.2» Сумма Пульт PW Количество Истина Контрагент 1 Номенклатура ВозвратОтПокупателя № 1 17.06.2010 17:30:00 Активность Регистратор 17.06.2010 17:30:00 Номер строки Период Таблица 3.19. Запись, добавляемая в оборотный регистр накопления Ялта-Лтд -1 -95 В результате система пересчитает июньские итоги по комбинации значений измерений ПультPW, Ялта-Лтд. Поскольку при общем пересчете итогов для оборотного регистра также удаляются записи, содержащие нулевые значения всех ресурсов, то содержание таблицы итогов после этого будет следующим (табл. 3.20). Таблица 3.20. Таблица итогов оборотного регистра накопления Период Номенклатура Контрагент Количество Сумма 01.03.2010 00:00:00 01.03.2010 00:00:00 01.04.2010 00:00:00 Пульт VH Пульт VH Пульт VH Ялта-Лтд Компания "Риона" Компания "Риона" 9 10 2 135 150 30 Режим разделения итогов Использование режима разделения итогов обеспечивает более высокую параллельность работы при записи в регистр, что позволяет ускорить запись в регистр и избежать блокировок в тех случаях, когда разные пользователи записывают данные с одинаковыми значениями измерений за один и тот же период. При использовании режима разделения итогов система при одновременной записи движений несколькими сеансами не будет обновлять одни и те же записи итогов, а будет записывать изменения итогов в отдельные записи. При получении итогов эти данные складываются. Таким образом, обеспечивается и поддержание в актуальном состоянии итогов (например, для быстрого получения отчетов), и параллельность записи движений. Как было рассказано выше, таблица итогов содержит алгебраическую сумму движений (с учетом вида движений) по каждой комбинации измерений. И при записи движений записи в таблице итогов автоматически пересчитываются. Считываемые записи таблицы итогов в момент пересчета блокируются. Таким образом, документы, содержащие движения по одинаковым комбинациям значений измерений, не могут быть проведены параллельно. 297 Глава 3. Реализация задач учета движения средств Например, таблица движений регистра накопления содержит следующие записи (табл. 3.21). Приход 1 Приход 1 Расход Сумма 2 Пульт VH Пульт PW Пульт VH Пульт VH Количество Приход Склад 1 Номенклатура ПоступлениеТоваров № 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 Номер строки Период Таблица 3.21. Таблица движений регистра накопления остатков Главный 9 90 Главный 7 490 Главный 5 50 Главный 8 80 Таким образом, в приведенном примере документы ПоступлениеТоваров № 1 и ПоступлениеТоваров № 2 не могут быть параллельно проведены, так как не могут быть записаны параллельно записи таблицы итогов регистра накопления по комбинации значений измерений ПультVH – Главный. Механизм разделения итогов вводит в состав хранимой таблицы итогов специальное поле (Разделитель), позволяющее распараллелить обновление записей итогов. Например, если одновременно записываются документы ПоступлениеТоваров № 1 и ПоступлениеТоваров № 2, то записи таблицы итогов будут выглядеть следующим образом (табл. 3.22). Таблица 3.22. Таблица итогов регистра накопления остатков Разделитель Номенклатура Склад Количество Сумма 0 1 0 Пульт VH Пульт VH Пульт PW Главный Главный Главный 9 5 7 90 50 490 После записи документа Реализация № 1 записи таблицы итогов будут выглядеть следующим образом (табл. 3.23). Таблица 3.23. Таблица итогов регистра накопления остатков Разделитель Номенклатура Склад Количество Сумма 0 1 0 Пульт VH Пульт VH Пульт PW Главный Главный Главный 1 5 7 10 50 490 298 Реализация прикладных задач в системе «1С:Предприятие 8.2» При получении итогов регистра накопления запросом или методом встроенного языка или при пересчете итогов записи сворачиваются по комбинациям значений измерений. При этом избыточные записи из регистра удаляются (табл. 3.24). Таблица 3.24. Таблица итогов регистра накопления остатков Номенклатура Склад Пульт VH Пульт PW Главный 6 Главный 7 Количество Сумма 60 490 Новые записи с уже существующими комбинациями измерений создаются системой только в случае, если параллельно выполняются две и более транзакции. Таким образом, увеличение количества записей итогов зависит от количества одновременно выполняемых транзакций. Заметим, что данный механизм не работает в файловом варианте, так как там поддерживается только блокировка на уровне таблиц. Разумеется, работа данного механизма влечет за собой дополнительные накладные расходы (наличие поля в таблицах итогов, увеличение количества записей в таблицах итогов). Чтобы управлять работой данного механизма, предусмотрены две возможности. В конфигурации для регистров введено свойство Разрешить разделение итогов. Стандартно для новых регистров накопления, создаваемых в конфигурации, это свойство включено. Установка этого свойства позволяет включить или отключить возможность разделения итогов для конкретного регистра. Отключение свойства полностью исключает влияние данного механизма на работу регистра, так как само поле, используемое для разделения итогов, не включается в структуру регистра. Например, отключение данной возможности полезно для регистров, которые не используются при параллельной работе пользователей. Например, для регистров, всегда заполняемых специальными регламентными обработками. Признак использования разделения итогов для регистров (для которых разделение итогов разрешено в конфигурации) может быть получен и установлен программно методами менеджера регистра накопления ПолучитьРежимРазделенияИтогов() и УстановитьРежимРазделенияИтогов(), а также в стандартной функции управления итогами (Все функции Стандартные Управление итогами Полные возможности Разделение итогов Включить разделение итогов/Выключить разделение итогов). Такая возможность позволяет включать или выключать режим разделения итогов в зависимости от условий работы пользователей в конкретной организации. Например, Глава 3. Реализация задач учета движения средств 299 при интенсивном параллельном вводе информации этот режим может быть полезен. Но если с системой работает небольшое количество пользователей, то выигрыш от его применения будет небольшой, а некоторое замедление при получении отчетов и лишние записи в таблицах итогов фактически будут лишними (неоправданными). Получение данных из регистров накопления Вопросы получения данных из регистров накопления могут касаться как получения движений, так и получения итоговых значений, учитываемых в регистре показателей. Получение движений может требоваться как для решения технологических задач работы с информацией регистров, так и для решения аналитических задач, но касающихся только приращений, учитываемых в регистрах показателей. Приемы и средства решения этих задач, как правило, не зависят от вида регистра, то есть одинаковы для регистров остатков и оборотных регистров. Это объясняется тем, что в любом случае обращение к данным движений в регистрах (хоть запросом, хоть посредством объектной модели) интерпретируется в запрос СУБД к таблице движений регистра. А приемы работы с одной таблицей базы данных практически одинаковы, тем более что состав полей и их содержимое, хоть бы и для разных видов регистров накопления, весьма схожи. Получение движений можно производить посредством следующих приемов (табл. 3.25). Таблица 3.25. Способы получения движений Табличная модель Регистр остатков Оборотный регистр Объектная модель Регистр остатков Оборотный регистр Запрос к основной таблице регистра Методы Выбрать() и ВыбратьПоРегистратору() менеджера регистра А вот приемы получения разных видов итогов и эффективности этих действий по скорости выполнения для разных видов регистров, как будет рассматриваться ниже, сильно отличаются. Тут проявляются различия в природе показателей, учитываемых в регистрах остатков и оборотных регистрах (описаны в разделе «Оперативный учет. Описание задач, решаемых регистрами накопления» на стр. 249). Природа этих показателей такова, что требуются различные способы хранения промежуточных итогов (описаны в разделе «Структура регистра накопления» на стр. 254). 300 Реализация прикладных задач в системе «1С:Предприятие 8.2» В целом действия, которые выполняются при получении итогов регистров, можно классифицировать следующим образом (табл. 3.26). Таблица 3.26. Способы получения итогов Табличная модель Регистр . остатков Получение остатков Получение оборотов Получение остатков и оборотов Оборотный регистр Запрос к таблице остатков Запрос к таблице оборотов Объектная модель Регистр . остатков Оборотный регистр Метод Остатки() менеджера регистра Метод Обороты() менеджера регистра Запрос к таблице остатков и оборотов Следует заметить, что для любого действия, связанного с получением итогов регистра накопления, справедливы следующие утверждения: ■ Итоги ресурсов собираются только по активным записям. ■ Итоги можно получать только по тем регистрам, у которых использование итогов включено. При попытке получения итогов для регистра накопления с отключенными итогами выдается сообщение об ошибке. Получение движений регистров накопления С точки зрения методических приемов чтение данных движений регистров накопления одинаково как для задач последующей модификации движений, так и для задач анализа движений регистров накопления. Например, для последующей обработки необходимо выбрать содержимое движений документов РеализацияТоваров по регистру ТоварыНаСкладах с отбором по складу СкладОтбора. При этом необходимо посчитать количество движений, выполненных каждым регистратором. Решение этой задачи может быть таким. В запросе обращаемся к данным основной таблицы регистра ТоварыНаСкладах, в качестве выходных указываем поля, соответствующие полям таблицы движений. Отбор выполняем по значению поля Склад и вхождению значений поля Регистратор в таблицу документов РеализацияТоваров. Выводим промежуточные итоги количества значений поля НомерСтроки в разрезе по регистраторам (в принципе подсчет количества можно было реализовать по любому из полей), листинг 3.22. Глава 3. Реализация задач учета движения средств 301 Листинг 3.22. Пример получения движений регистра накопления Запрос = Новый Запрос; Запрос.Текст = "ВЫБРАТЬ | ТоварыНаСкладах.Период, | ТоварыНаСкладах.Регистратор КАК Регистратор, | ТоварыНаСкладах.НомерСтроки КАК НомерСтроки, | ТоварыНаСкладах.Активность, | ТоварыНаСкладах.ВидДвижения, | ТоварыНаСкладах.Номенклатура, | ТоварыНаСкладах.Склад, | ТоварыНаСкладах.Количество, | ТоварыНаСкладах.Поставщик |ИЗ | РегистрНакопления.ТоварыНаСкладах КАК ТоварыНаСкладах |ГДЕ | ТоварыНаСкладах.Склад = &Склад | И ТоварыНаСкладах.Регистратор ССЫЛКА Документ.РеализацияТоваров |ИТОГИ | КОЛИЧЕСТВО(НомерСтроки) |ПО | Регистратор"; Запрос.УстановитьПараметр("Склад", СкладОтбора); Результат = Запрос.Выполнить(); ВыборкаРегистратор = Результат.Выбрать(ОбходРезультатаЗапроса.ПоГруппировкам); Пока ВыборкаРегистратор.Следующий() Цикл // Выполнить действия в цикле перебора регистраторов // ... ВыборкаДвижения = ВыборкаРегистратор.Выбрать(); Пока ВыборкаДвижения.Следующий() Цикл // Выполнить действия в цикле перебора движений // ... КонецЦикла; КонецЦикла; Дальнейшее развитие приведенного алгоритма может идти в различных направлениях. Можно вывести в табличный документ содержимое движений регистра, а можно результат запроса использовать для модификации данных наборов записей с последующей записью измененных движений в регистр. Рассмотрим более подробно вопросы быстродействия системы при получении движений регистра накопления тем или иным способом. 302 Реализация прикладных задач в системе «1С:Предприятие 8.2» Вопросы быстродействия системы при получении движений Как правило, при решении задач, связанных с чтением движений из регистров накопления, для повышения эффективности решений большое значение имеют вопросы использования состава регистра накопления и использования табличной или объектной модели обращения к данным. Рассмотрим пример. Пусть необходимо подсчитать по данным регистра ТоварыНаСкладах, в каком количестве поставлялись товары в разрезе поставщиков. Данная задача может быть решена несколькими способами. Например, можно использовать внутреннее соединение основной таблицы регистра ТоварыНаСкладах и таблицы документа ПоступлениеТоваров (листинг 3.23). Листинг 3.23. Пример получения движений с использованием соединения с таблицей документа ВЫБРАТЬ ПоступлениеТоваров.Контрагент КАК Поставщик, ТоварыНаСкладах.Номенклатура, СУММА(ТоварыНаСкладах.Количество) КАК Количество ИЗ РегистрНакопления.ТоварыНаСкладах КАК ТоварыНаСкладах ВНУТРЕННЕЕ СОЕДИНЕНИЕ Документ.ПоступлениеТоваров КАК ПоступлениеТоваров ПО ТоварыНаСкладах.Регистратор = ПоступлениеТоваров.Ссылка ГДЕ ТоварыНаСкладах.Период МЕЖДУ &ДатаНачала И &ДатаОконачания СГРУППИРОВАТЬ ПО ТоварыНаСкладах.Номенклатура, ПоступлениеТоваров.Контрагент Условием соединения является равенство значений поля Регистратор таблицы регистра и поля Ссылка таблицы документа. Подобный способ получения движений в общем случае может оказаться неудобным, например, если поставки фиксируются несколькими видами документов. В этом случае усложнится текст запроса и замедлится его выполнение за счет большого количества соединений. Более удобным является подход с использованием реквизита регистра. Если для решения данной задачи в состав регистра включить реквизит Поставщик (тип значения – СправочникСсылка.Контрагенты), то значение поля реквизита можно будет заполнять при проведении только нужных документов. Глава 3. Реализация задач учета движения средств 303 И тогда, независимо от количества видов документов поставки, задача будет решаться запросом только к основной таблице регистра (листинг 3.24). Листинг 3.24. Пример получения движений регистра накопления ВЫБРАТЬ ТоварыНаСкладах.Поставщик, ТоварыНаСкладах.Номенклатура, СУММА(ТоварыНаСкладах.Количество) КАК Количество ИЗ РегистрНакопления.ТоварыНаСкладах КАК ТоварыНаСкладах ГДЕ ТоварыНаСкладах.Период МЕЖДУ &ДатаНачала И &ДатаОконачания И ТоварыНаСкладах.Поставщик <> &ПустойПоставщик СГРУППИРОВАТЬ ПО ТоварыНаСкладах.Поставщик, ТоварыНаСкладах.Номенклатура Дополнительное условие «по непустым поставщикам» отсечет из подсчета результатов (и из самих результатов) записи, которые сформированы ненужными документами. Например, перемещениями, реализацией и прочими (при проведении этих документов поле Поставщик не заполнялось). Значение же параметра ПустойПоставщик может быть установлено следующим образом (листинг 3.25). Листинг 3.25. Установка значения параметра «ПустойПоставщик» Запрос.УстановитьПараметр("ПустойПоставщик", Справочники.Контрагенты.ПустаяСсылка()); Необходимо иметь в виду, что при использовании реквизитов составного типа незаполненное при проведении документа поставки значение реквизита будет иметь тип Неопределено. Поэтому для варианта, когда реквизит Поставщик имеет составной тип, значение параметра ПустойПоставщик может быть установлено следующим образом (листинг 3.26). Листинг 3.26. Пример установки параметра «ПустойПоставщик» Запрос.УстановитьПараметр("ПустойПоставщик", Неопределено); Если же при проведении документов реквизит может не заполняться или заполняться пустыми значениями, возможно, придется в запросе учесть ряд вариантов значения реквизита (листинг 3.27). 304 Реализация прикладных задач в системе «1С:Предприятие 8.2» Листинг 3.27. Пример установки параметров запроса Запрос.УстановитьПараметр("ПустойПоставщик", Неопределено); Запрос.УстановитьПараметр("ПустойПоставщикКонтрагент", Справочники.Контрагенты.ПустаяСсылка()); Запрос.УстановитьПараметр("ПустойПоставщикФизЛицо", Справочники.ФизическиеЛица.ПустаяСсылка()); В приведенном примере предполагается, что реквизит Поставщик имеет составной тип, включающий типы СправочникСсылка.Контрагенты и СправочникСсылка.ФизическиеЛица. Итак, за счет изменения состава регистра, использования реквизитов можно применять более эффективные по скорости алгоритмы для получения движений регистров накопления. Обращение к данным одной таблицы базы данных всегда будет проходить быстрее, нежели обращение к данным той же таблицы, но в соединении с другими таблицами базы данных. Таким образом, за счет «структурных изменений» ряд задач можно сводить только к работе с таблицей движений регистра накопления. При обращении к данным таблицы движений регистра разработчик может применять обращение посредством выборки (объектная модель работы с данными) или посредством запроса (табличная модель чтения данных). С точки зрения обращения к информации базы данных выборка – это тот же самый запрос. При одинаковых условиях и выборка, и прямое обращение запросом работают одинаково эффективно. Разница в том, что выборка не так «гибка», зато получает данные порциями (это особенно важно, если ожидается большой объем данных в результате запроса). Для получения данных выборка использует механизм динамического чтения данных. Посредством этого механизма чтение данных осуществляется по блокам, а не целиком сразу всех. Кроме того, при использовании выборки объекты считываются целиком. Работа же посредством запроса позволяет считывать содержимое только тех полей, которые используются в запросе. Операция перебора всех движений регистров с помощью выборки может осуществляться, например, следующим образом (листинг 3.28). Листинг 3.28. Пример получения движений регистра накопления с помощью выборки ВыборкаДвижений = РегистрыНакопления.ТоварыНаСкладах.Выбрать(); Пока ВыборкаДвижений.Следующий() Цикл // Выполнить действие с очередным движением //... КонецЦикла; Глава 3. Реализация задач учета движения средств 305 Кроме таких простых операций, возможно выполнять и более «тонкие» действия. Например, в ходе работы пользователя требуется оперативно определять факт того, что были поставки определенного поставщика в заданном временном интервале. При решении данной задачи у реквизита Поставщик регистра ТоварыНаСкладах свойству Индексировать следует установить значение Индексировать (рис. 3.28). Рис. 3.28. Индексирование реквизита регистра накопления В результате в базе данных будет создан составной индекс по полям Поставщик + Период + Регистратор + НомерСтроки. Данные этого индекса система использует при обращении к движениям и посредством запроса, и посредством выборки. Использование выборки позволит получить данные не медленнее, нежели посредством запроса (листинг 3.29). 306 Реализация прикладных задач в системе «1С:Предприятие 8.2» Листинг 3.29. Получение движений регистра накопления с помощью выборки ОтборПоПоставщику = Новый Структура(“Поставщик”, ПоставщикОтбора); ВыборкаДвижений = РегистрыНакопления.ТоварыНаСкладах.Выбрать(НачалоИнтервала, КонецИнтервала, ОтборПоПоставщику); Сообщение = Новый СообщениеПользователю(); Если ВыборкаДвижений.Следующий() Тогда Сообщение.Текст = "В указанном интервале были поставки от " + ПоставщикОтбора.Наименование; Иначе Сообщение.Текст = "В указанном интервале поставок от " + ПоставщикОтбора.Наименование + " не было"; КонецЕсли; Сообщение.Сообщить(); Очевидно, что в переменные ПоставщикОтбора, НачалоИнтервала, КонецИнтервала нужно передать соответствующие значения. ВНИМАНИЕ! Необходимо помнить о том, что при использовании метода Выбрать() в качестве параметра Отбор может использоваться структура, имеющая только один элемент. Для более гибких или сложных отборов следует использовать получение данных посредством запроса. Теперь чуть подробнее остановимся на НачалоИнтервала и КонецИнтервала. использовании параметров При работе с запросом можно произвольным образом использовать условия больше/меньше, равно/не равно, больше или равно, между и так далее, как в отношении значений поля Период записей движений, так и в отношении Регистратор или НомерЗаписи. Чтобы добиться подобной гибкости в отношении границ временного интервала выборки, можно использовать различные варианты значений параметров НачалоИнтервала и КонецИнтервала. В параметр НачалоИнтервала передается начало интервала, в котором будут выбираться записи регистра накопления. Он может задаваться значениями типа Дата, МоментВремени и Граница. Если значение данного параметра не указано, то будут выбираться записи с самой ранней включительно. В параметр КонецИнтервала передается конец интервала, в котором будут выбираться записи регистра накопления. Он может задаваться значениями типа Дата, МоментВремени и Граница. Если значение данного параметра не указано, то будут выбираться записи по самую последнюю включительно. Глава 3. Реализация задач учета движения средств 307 В результате при передаче значений типа Дата или МоментВремени в выборку получим записи, включая значения НачалоИнтервала и КонецИнтервала (рис. 3.29). Рис. 3.29. Получение записей, включая границы интервала Если требуется получить записи, исключая граничные, необходимо использовать объект Граница. Пример получения выборки в интервале дат, исключая границы интервала, приведен в листинге 3.30 и на рис. 3.30. Листинг 3.30. Пример получения записей, исключая границы интервала ГраницаНачалаИнтервала = Новый Граница(НачалоИнтервала,ВидГраницы.Исключая); ГраницаКонцаИнтервала = Новый Граница(КонецИнтервала, ВидГраницы.Исключая); ВыборкаДвижений = РегистрыНакопления.ТоварыНаСкладах.Выбрать(ГраницаНачалаИнтервала, ГраницаКонцаИнтервала); Пока ВыборкаДвижений.Следующий() Цикл // Выполнить действие с очередным движением // ... КонецЦикла; Рис. 3.30. Получение записей, исключая границы интервала Кроме выборок всех записей можно при необходимости осуществлять выборку записей, подчиненных некоему документу. Это может быть реализовано посредством метода ВыбратьПоРегистратору(). Например, если в переменной РегистраторОтбора содержится ссылка на регистратор, по которому нужно отобрать все его движения, то код, получающий такую выборку, будет выглядеть следующим образом (листинг 3.31). 308 Реализация прикладных задач в системе «1С:Предприятие 8.2» Листинг 3.31. Пример получения движений по регистратору ВыборкаДвижений = РегистрыНакопления.ТоварыНаСкладах. ВыбратьПоРегистратору(РегистраторОтбора); Пока ВыборкаДвижений.Следующий() Цикл // Выполнить действие с очередным движением //... КонецЦикла; Поскольку, как обсуждалось выше, в разделе «Структура регистра накопления» на стр. 254, для таблицы движений регистра поле Регистратор является индексируемым, быстродействие подобной выборки будет достаточно высоким, не медленнее, чем применение запроса (листинг 3.32). Листинг 3.32. Пример получения движений регистратора с помощью запроса Запрос = Новый Запрос; Запрос.Текст = "ВЫБРАТЬ | ТоварыНаСкладах.Период, | ТоварыНаСкладах.Регистратор, | ТоварыНаСкладах.НомерСтроки, | ТоварыНаСкладах.Активность, | ТоварыНаСкладах.ВидДвижения, | ТоварыНаСкладах.Номенклатура, | ТоварыНаСкладах.Склад, | ТоварыНаСкладах.Количество, | ТоварыНаСкладах.Поставщик |ИЗ | РегистрНакопления.ТоварыНаСкладах КАК ТоварыНаСкладах |ГДЕ | ТоварыНаСкладах.Регистратор = &РегистраторОтбора"; Запрос.УстановитьПараметр("РегистраторОтбора", РегистраторОтбора); Результат = Запрос.Выполнить(); Выборка = Результат.Выбрать(); Пока Выборка.Следующий() Цикл // Выполнить действие с очередным движением // ... КонецЦикла; А теперь рассмотрим один из примеров, когда в условиях усложнения задачи применение объектной модели обращения к информации базы данных уже менее эффективно, чем обращение посредством запроса. Глава 3. Реализация задач учета движения средств 309 Например, в составе оборотного регистра Продажи есть реквизит ВидОперации (рис. 3.31). Рис. 3.31. Структура регистра «Продажи» При проведении документов продажи формируются движения по этому регистру. Необходимо предпринять некие действия по фактам произведенных розничных продаж (вид операции – РеализацияВРозницу) с ценой меньше закупочной. Закупочная цена хранится в одноименных реквизитах элементов справочника Номенклатура. Поиск таких фактов посредством запроса может быть выполнен так, как показано в листинге 3.33. Листинг 3.33. Пример получения движений регистра накопления с помощью запроса Запрос = Новый Запрос; Запрос.Текст = "ВЫБРАТЬ | Продажи.Регистратор, | Продажи.Номенклатура |ИЗ | РегистрНакопления.Продажи КАК Продажи |ГДЕ | Продажи.Период МЕЖДУ &ДатаНачала И &ДатаОкончания | И Продажи.ВидОперации = &РозничнаяПродажа | И Продажи.Сумма / Продажи.Количество < Продажи.Номенклатура.ЗакупочнаяЦена"; Запрос.УстановитьПараметр("ДатаНачала", ДатаНачала); Запрос.УстановитьПараметр("ДатаОкончания", ДатаОкончания); Запрос.УстановитьПараметр("РозничнаяПродажа", Перечисления.ВидыОпераций.РеализацияВРозницу); Результат = Запрос.Выполнить(); Выборка = Результат.Выбрать(); Пока Выборка.Следующий() Цикл // Выполнить действия по факту продажи ниже закупочной цены // ... КонецЦикла; 310 Реализация прикладных задач в системе «1С:Предприятие 8.2» Посредством выборки движений регистра аналогичный результат может быть получен так, как показано в листинге 3.34. Листинг 3.34. Пример получения движений регистра накопления с помощью выборки Выборка = РегистрыНакопления.Продажи.Выбрать(ДатаНачала, ДатаОкончания); Пока Выборка.Следующий() Цикл Если Выборка.ВидОперации = Перечисления.ВидыОпераций.РеализацияВРозницу И Выборка.Сумма/Выборка.Количество < Выборка.Номенклатура.ЗакупочнаяЦена Тогда // Выполнить действия по факту продажи ниже закупочной цены // ... КонецЕсли; КонецЦикла; Использование выборки в данной ситуации является очень неэффективным решением. В первом случае условие превышения закупочной цены будет обеспечено выполнением неявного левого внешнего соединения всей таблицы регистра с таблицей справочника за один раз. Во втором случае проверка условия Выборка.Сумма/Выборка.Количество < Выборка.Номенклатура.ЗакупочнаяЦена потребует обращений к данным справочника в базе данных для каждого элемента коллекции движений. Это был только один из примеров, когда в условиях более сложных задач чтения движений применение запросов более эффективно, нежели применение выборки. А вообще посредством запроса возможен доступ практически ко всему содержимому таблицы движений регистра накопления. Для этого используется так называемая основная таблица регистра накопления. Это реальная таблица, содержащая данные таблицы движений регистра в базе данных. Состав полей этой таблицы представлен в табл. 3.27. Основная таблица для оборотного регистра имеет почти аналогичный состав. Отличие заключается в том, что она не содержит поле ВидДвижения. Получение остатков Получение итогов остатков регистра накопления, конечно же, возможно только в отношения регистра накопления остатков. Применение табличного или объектного подхода для решения этой задачи определяется сложностью и необходимой гибкостью совершаемых при этом действий. Дата ДокументСсылка.<имя> Число Тип Назначение Число Произвольный, определяется типом измерения Тип Каждое из полей содержит значения измерений регистра. Имена полей совпадают с именами измерений, заданными для объекта конфигурации Имена полей совпадают с именами ресурсов, заданными для объекта конфигурации. Имена полей составляются из названий ресурсов с добавлением слова «Остаток» Назначение Тип Дата, МоментВремени, Граница <Условие> Конструкция языка запросов – условие <Период> Параметр Строится по полям измерений, регистра накопления (или по подчиненным им полям). Используется для ограничения состава исходных записей, по которым при построении виртуальной таблицы будут собираться итоги. Если параметр не указан, для сбора итогов будут анализироваться все активные записи регистра Используется для указания периода, НА значение которого будут рассчитаны остатки. Если параметр не задан, итоги рассчитываются ПО самую последнюю запись Назначение Таблица 3.29. Параметры виртуальной таблицы «Остатки» регистра накопления остатков <Ресурс>Остаток <Измерение> Поле Таблица 3.28. Состав полей виртуальной таблицы «Остатки» регистра накопления остатков Период Регистратор НомерСтроки Содержит период, к которому относится запись регистра Содержит ссылку на документ регистратор движения Содержит номер строки, определяемый как порядковый номер записи в наборе записей, подчиненных документу-регистратору Булево Активность Содержит признак активности записи, то есть влияния на получение итогов регистра МоментВремени МоментВремени Виртуальное поле, не хранится в базе данных. Содержит объект МоментВремени (который включает в себя дату и ссылку на документ). ВидДвиженияНакопления Содержит вид движения данной записи (Приход или Расход) ВидДвижения <Измерение> Произвольный, определяется Каждое из полей содержит значения измерений регистра. Имена полей совпадают типом измерения с именами измерений, заданными для объекта конфигурации Число <Ресурс> Каждое из полей содержит значения ресурса регистра. Имена полей совпадают с именами ресурсов, заданными для объекта конфигурации <Реквизит> Произвольный, определяется Каждое из полей содержит значения реквизитов регистра. Имена полей совпадают типом реквизита с именами реквизитов, заданными для объекта конфигурации Поле Таблица 3.27. Состав полей основной таблицы регистра накопления остатков Глава 3. Реализация задач учета движения средств 311 312 Реализация прикладных задач в системе «1С:Предприятие 8.2» Виртуальная таблица остатков Для получения данных по остаткам из регистра накопления остатков запросом используется виртуальная таблица остатков. Ее данные представляют собой итоги ресурсов в разрезе измерений (табл. 3.28). Параметры виртуальной таблицы остатков представлены в табл. 3.29. Виртуальная таблица остатков не хранится в базе данных, а строится в момент обращения к ней. Для построения виртуальной таблицы всегда используются данные таблицы итогов регистра базы данных и, при необходимости, таблицы движений регистра. При этом учитываются значения параметров виртуальной таблицы. Сам алгоритм построения этой виртуальной таблицы включает в себя следующие этапы: ■ Подбирается больший или равный значению параметра Период момент времени, на который рассчитаны остатки. ■ На этот момент времени получаются остатки из таблицы итогов. ■ Если момент времени, на который считаются остатки, не совпадает с моментом времени итогов, то остатки досчитываются по движениям за период с момента требуемого запроса остатков по момент итогов. Реализуется это за счет объединения отобранных записей таблицы итогов и таблицы движений регистра. ■ Группирование результата виртуальной таблицы выполняется согласно составу выходных полей запроса, использующего поля виртуальной таблицы. Для получения результата запроса система преобразует текст запроса, написанного на встроенном языке системы «1С:Предприятие», в запрос СУБД. В данный запрос включается соответствующий текст подзапроса, получающийся согласно описанному выше алгоритму. В отношении сортировки записей, полученных виртуальной таблицей остатков, необходимо заметить, что если разработчик в запросе не применит ключевые слова УПОРЯДОЧИТЬ ПО или АВТОУПОРЯДОЧИВАНИЕ, то в общем случае система не будет производить упорядочивание записей. То есть таблица результата виртуальной таблицы «самогруппируется», но не «самосортируется». Можно сделать ряд выводов о скорости получения виртуальной таблицы остатков. Она зависит от следующих факторов: ■ требуются ли только текущие итоги; ■ требуются ли остатки на момент времени, находящийся до границы рассчитанных итогов; Глава 3. Реализация задач учета движения средств 313 ■ как много записей находится между требуемым моментом расчета итогов и ближайшим (более поздним) моментом уже рассчитанных итогов в таблице итогов. Например, в базе данных таблицы движений и итогов регистра остатков заполнены так, как показано в табл. 3.30 и табл. 3.31. Истина 2 Приход Истина 1 Приход Ложь 1 Расход Истина 1 Приход Истина 1 Приход Истина 1 Приход Истина 1 Приход Истина Пульт VH Пульт PW Пульт VH Пульт VH Пульт PW Пульт PW Пульт PW Пульт PW Количество Приход Склад 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 Номер строки Период Таблица 3.30. Таблица движений регистра накопления Главный 10 Главный 7 Фили-2 5 Главный 9 Фили-2 1 Фили-2 2 Фили-2 1 Фили-2 1 Таблица 3.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 Рассмотрим случай, когда требуется получить итоги регистра с помощью кода, приведенного в листинге 3.35. 314 Реализация прикладных задач в системе «1С:Предприятие 8.2» Листинг 3.35. Пример получения итогов регистра накопления ВЫБРАТЬ ТоварыНаСкладахОстатки.Номенклатура КАК Номенклатура, ТоварыНаСкладахОстатки.Склад КАК Склад, ТоварыНаСкладахОстатки.КоличествоОстаток КАК Количество ИЗ РегистрНакопления.ТоварыНаСкладах.Остатки(&Период) КАК ТоварыНаСкладахОстатки В зависимости от значения, переданного параметру виртуальной таблицы остатков Период, система будет выполнять следующие действия: 1. Если передать значение Неопределено (листинг 3.36) или значение даты по умолчанию (листинг 3.37), то будут получены актуальные данные непосредственно из таблицы итогов, без обращений к таблице движений (табл. 3.32). Листинг 3.36. Установка параметра запроса значением «Неопределено» Запрос.УстановитьПараметр("Период", Неопределено); Листинг 3.37. Установка параметра запроса значением даты по умолчанию Запрос.УстановитьПараметр("Период", Дата(1, 1, 1)); Таблица 3.32. Результат выполнения запроса Номенклатура Склад Количество Пульт VH Пульт PW Пульт PW 1 7 5 Главный Главный Фили-2 2. Если передать значение типа Дата, совпадающее с датой рассчитанных итогов (листинг 3.38), то будут получены данные на начало даты «1 июня 2010 года» непосредственно из таблицы итогов, без обращений к таблице движений (табл. 3.33). Листинг 3.38. Установка параметра запроса значением даты Запрос.УстановитьПараметр("Период", Дата(2010, 6, 1)); Таблица 3.33. Результат выполнения запроса Номенклатура Склад Количество Пульт VH Пульт PW Пульт PW 1 7 1 Главный Главный Фили-2 Глава 3. Реализация задач учета движения средств 315 ПРИМЕЧАНИЕ Заметьте, движения документа ПоступлениеТоваров № 4, сформированные на эту же дату, учтены не будут. Потому что момент времени этих движений позже начала даты. 3. Если передать значение типа Дата, не совпадающее с датой рассчитанных итогов, то возможны несколько вариантов. Рассмотрим каждый из них. а) Значение даты (листинг 3.39). находится в середине рассчитанного периода Листинг 3.39. Установка параметра запроса значением даты Запрос.УстановитьПараметр("Период", Дата(2010, 5, 20)); В этом случае сначала будут получены данные на начало даты «1 июня 2010 года» из таблицы итогов (табл. 3.34). Таблица 3.34. Данные, полученные из таблицы итогов Номенклатура Склад Количество Пульт VH Пульт PW Пульт PW 1 7 1 Главный Главный Фили-2 Затем будут получены записи из таблицы движений в интервале между началом 20 мая 2010 и началом 1 июня 2010 года. Причем только те, у которых поле Активность имеет значение Истина. Поскольку «досчитываться» значения остатков будут в обратную сторону, то данные ресурсов таблицы движений получаются со знаком, обратным виду движения (табл. 3.35). Таблица 3.35. Данные, полученные из таблицы движений Номенклатура Склад Количество Пульт VH Пульт PW 9 -1 Главный Фили-2 Далее эти записи объединятся, группируются, убираются записи, содержащие нулевые значения всех ресурсов (табл. 3.36). Таблица 3.36. Результат выполнения запроса Номенклатура Склад Пульт VH Пульт PW Количество Главный 10 Главный 7 316 Реализация прикладных задач в системе «1С:Предприятие 8.2» б) Значение даты (листинг 3.40). находится в конце рассчитанного периода Листинг 3.40. Установка параметра запроса значением даты Запрос.УстановитьПараметр("Период", Дата(2010, 5, 31)); В этом случае сначала будут получены данные на начало даты «1 июня 2010 года» из таблицы итогов (табл. 3.37). Таблица 3.37. Данные, полученные из таблицы итогов Номенклатура Склад Пульт VH Пульт PW Пульт PW Главный 1 Главный 7 Фили-2 1 Количество Затем будут получены записи из таблицы движений в интервале между началом 31 мая 2010 и началом 1 июня 2010 года, с учетом вида движении и «обратного подсчета» (табл. 3.38). Таблица 3.38. Данные, полученные из таблицы движений Номенклатура Склад Количество Пульт PW Фили-2 -1 Далее записи объединятся, и по этим данным будут посчитаны остатки на нужный период (табл. 3.39). Таблица 3.39. Результат выполнения запроса Номенклатура Склад Пульт VH Пульт PW Главный 1 Главный 7 Количество в) Значение даты представляет собой конец дня последней даты рассчитанного периода (листинг 3.41). Листинг 3.41. Установка параметра запроса значением даты Запрос.УстановитьПараметр("Период", КонецДня(Дата(2010, 5, 31))); В этом случае сначала будут получены данные на начало даты «1 июня 2010 года» из таблицы итогов (табл. 3.40). Глава 3. Реализация задач учета движения средств 317 Таблица 3.40. Данные, полученные из таблицы итогов Номенклатура Склад Количество Пульт VH Пульт PW Пульт PW 1 7 1 Главный Главный Фили-2 Затем будут получены записи из таблицы движений в интервале между концом 31 мая 2010 и началом 1 июня 2010 года, с учетом вида движении и «обратного подсчета». К таким записям как раз и относится датированное последней секундой дня движение документа ПоступлениеТоваров № 3 (табл. 3.41). Таблица 3.41. Данные, полученные из таблицы движений Номенклатура Склад Количество Пульт PW -1 Фили-2 Далее записи объединятся, и по этим данным будут посчитаны остатки на нужный период (табл. 3.42). Таблица 3.42. Результат выполнения запроса Номенклатура Склад Количество Пульт VH Пульт PW 1 7 Главный Главный г) Значение даты является началом даты нерассчитанного периода (листинг 3.42). Листинг 3.42. Установка параметра запроса значением даты ПериодВключая = Новый Граница(Дата(2010, 6, 1), ВидГраницы.Включая) Запрос.УстановитьПараметр("Период", ПериодВключая); Значение параметра больше, чем начало дня «01.06.2010», поэтому будут взяты данные из таблицы итогов на больший период, то есть текущие итоги (табл. 3.43). Таблица 3.43. Данные, полученные из таблицы итогов Номенклатура Склад Количество Пульт VH Пульт PW Пульт PW 1 7 5 Главный Главный Фили-2 318 Реализация прикладных задач в системе «1С:Предприятие 8.2» Будут взяты записи из таблицы движений, в интервале между значением параметра и периодом текущих итогов (с учетом операции «обратного подсчета»). Заметьте, движения, датированные «01.06.2010 00:00:00», сюда не попадают (табл. 3.44). Таблица 3.44. Данные, полученные из таблицы движений Номенклатура Склад Пульт PW Пульт PW Количество Фили-2 -1 Фили-2 -1 Далее записи объединятся, и по этим данным будут посчитаны остатки на нужный период (табл. 3.45). Таблица 3.45. Результат выполнения запроса Номенклатура Склад Пульт VH Пульт PW Пульт PW Количество Главный 1 Главный 7 Фили-2 3 Аналогично поступила бы система, если бы в качестве параметра было передано значение типа МоментВремени с датой 01.06.2010 00:00:00 и ссылкой на какой-нибудь документ. Кроме того, хотелось бы заметить, что если бы в последнем примере граница рассчитанных итогов стояла бы не в конце мая, а хотя бы в конце июня, то не пришлось бы досчитывать от текущих итогов. Достаточно было бы досчитать от ближайшего, но большего периода рассчитанных итогов. Использование в любых «неровных» ситуациях именно обратного досчета объясняется тем, что при решении оперативных задач вправе ожидать более напряженной работы с текущими итогами или близкими к текущему моменту, нежели получение остатков прошлых месяцев или даже лет. Усложнение же механизма расчета итогов остатков «анализатором» ситуации (от какого периода итогов ближе до нужного значения параметра) нецелесообразно. Поскольку для обеспечения работы «анализатора» пришлось бы получать записи таблицы движений в обе стороны (и назад, и вперед). То есть «анализатор» сам работал бы дольше, чем «обратный досчет». Однако пересчет текущих итогов (если у регистра установлен признак использования итогов) каждый раз при записи набора активных записей в таблице движений может быть неэффективным. Например, когда период рассчитанных итогов регулярно устанавливается обработкой и есть уверенность в хранении посчитанных итогов на начало каждого месяца, может быть Глава 3. Реализация задач учета движения средств 319 выгоднее «досчитывать» остатки от хранимых итогов. В таком случае можно не устанавливать использование текущих итогов для регистра остатков – УстановитьИспользованиеТекущихИтогов(Ложь). Если использование текущих итогов выключено, то расчет актуальных остатков будет производиться следующим образом: сначала будут получены остатки на самые поздние хранимые итоги, а потом по движениям за оставшийся период будут получены актуальные остатки. Данный подход позволяет увеличить параллельность при записи наборов записей данного регистра, так как не требуется обновления текущих итогов. Получить признак использования текущих итогов из встроенного языка можно методом менеджера регистра накопления остатков ПолучитьИспользованиеТекущихИтогов(). Включить или выключить использование текущих итогов можно методом УстановитьИспользованиеТекущихИтогов(Истина/Ложь), а также в стандартной функции управления итогами (Все функции Стандартные Управление итогами Полные возможности Текущие итоги Включить использование текущих итогов/Выключить использование текущих итогов). Таким образом, можно сделать вывод, что быстродействие получения остатков реальным временем (актуальных) вообще не зависит от общего объема накопленной в базе данных информации. Для получения же данных на прошедшие моменты времени при использовании расчета промежуточных ежемесячных итогов среднее быстродействие построения виртуальной таблицы получения остатков определяется не общим объемом базы данных, а количеством движений по регистру, формируемым в течение месяца. Это очень важно для недопущения деградации системы при многолетней эксплуатации базы данных. Кроме того, хотелось бы обратить внимание, что на каждом этапе выполнения алгоритма, когда система получает данные из той или иной таблицы базы данных, применяются отборы только тех записей, которые удовлетворяют условиям, описанным в параметрах виртуальной таблицы остатков. Использование метода «Остатки()» менеджера регистра накопления Если при получении данных об остатках не применяется сложных отборов либо эти данные впоследствии не нужно соединять с другими данными, можно использовать также и объектную модель доступа к данным – метод Остатки() менеджера регистра накопления. Например, если требуется сообщить остатки на складах по некой товарной позиции, как это показано в листинге 3.43. 320 Реализация прикладных задач в системе «1С:Предприятие 8.2» Листинг 3.43. Пример получения остатков регистра накопления с использованием объектной модели Отбор = Новый Структура("Номенклатура", ТоварОтбора); ТаблицаОстатков = РегистрыНакопления.ТоварыНаСкладах.Остатки(МоментВремени, Отбор, "Склад", "Количество"); Для Каждого СтрокаТаблицы Из ТаблицаОстатков Цикл Сообщение = Новый СообщениеПользователю(); Сообщение.Текст = "Склад " + СтрокаТаблицы.Склад + ": Остаток " + СтрокаТаблицы.Количество; Сообщение.Сообщить(); КонецЦикла; Метод Остатки() возвращает таблицу значений, содержащую данные об остатках регистра, вычисленных на момент значения параметра МоментВремени. При этом будет использован отбор, согласно значению параметра Отбор, а сама таблица значений свернута по полю Склад, с суммированием значений поля Количество. Механизм построения результата метода Остатки() практически тот же, что и в случае применения виртуальной таблицы получения остатков. В качестве типов значения переменных, передаваемых параметру МоментВремени, возможны те же, что использовались для виртуальной таблицы получения остатков. То есть Дата, МоментВремени, Граница. Особенности применения различных значений и их использование системой при подсчете данных будут рассмотренны ниже, в разделе «Особенности использования периодов и моментов времени при получении остатков» на стр. 321. Различия проявляются в условиях отбора информации. Посредством параметра Отбор типа Структура можно строить только простейшие отборы на равенство значений измерений. Например, как показано в листинге 3.44. Листинг 3.44. Пример получения остатков регистра накопления Отбор = Новый Структура("Номенклатура, Склад", ТоварОтбора, СкладОтбора); Но варианты более сложных отборов, например, отбор по двум значениям измерения Номенклатура, для метода Остатки() неприемлемы. Глава 3. Реализация задач учета движения средств 321 Последние два параметра метода Остатки() касаются операции свертки полученных в запросе СУБД данных перед выгрузкой в таблицу значений. Однако если значения данных параметров не указывать, то результирующая таблица значений будет содержать колонки, соответствующие всем измерениям и/или всем ресурсам. Недостаточная гибкость объектной модели чтения итогов регистров объясняется тем, что в платформе на объектные методы возлагаются в основном задачи обеспечения записи, модификации и динамического чтения данных реальных таблиц базы данных. А задачи гибкого, тонкого, эффективного чтения для обеспечения последующего анализа состояния учитываемых в системе показателей возлагаются на более подходящие для этого инструменты – объекты Запрос, ПостроительОтчета, АнализДанных и т. п. Особенности использования периодов и моментов времени при получении остатков Рассмотрим различные ситуации получения остатков запросом (листинг 3.45) или с помощью метода Остатки() (листинг 3.46). Листинг 3.45. Пример получения остатков на «Период» запросом ВЫБРАТЬ ТоварыНаСкладахОстатки.Номенклатура КАК Номенклатура, ТоварыНаСкладахОстатки.Склад КАК Склад, ТоварыНаСкладахОстатки.КоличествоОстаток КАК Количество ИЗ РегистрНакопления.ТоварыНаСкладах.Остатки(&Период) КАК ТоварыНаСкладахОстатки Листинг 3.46. Пример получения остатков на «Период» методом «Остатки()» ТаблицаОстатков = РегистрыНакопления.ТоварыНаСкладах.Остатки(Период); Параметр Период виртуальной таблицы остатков и метода Остатки() может получать значения типа Дата, МоментВремени и Граница, кроме того, может быть вообще не указан, или иметь значение Неопределено, или содержать значение даты по умолчанию '00010101000000'. Последние три случая (не указан, или Неопределено, или значение даты по умолчанию) приводят к построению таблицы остатков с данными актуальных остатков (учитывающих все активные записи регистра). Если в качестве параметра передается значение типа Дата, важно помнить следующие моменты. 322 Реализация прикладных задач в системе «1С:Предприятие 8.2» Дата в системе «1С:Предприятие» включает в свой состав время. Даже если время не указано явно, оно принимает значение 00:00:00. То есть если в качестве параметра передать «31 декабря 2009 года» (данное значение может быть получено так: '20091231'), то в результате таблица остатков будет построена на дату 31.12.2009 00:00:00 (рис. 3.32). Рис. 3.32. Получение остатков на дату Таблица получения остатков строится на начало даты, то есть не включая. Выше приведены примеры использования запроса к виртуальной таблице остатков и использования метода Остатки(). И в том и другом случае, если в таблице движений регистра будут присутствовать записи со значением поля Период, равным дате 31.12.2009 23:59:59, они не будут учтены (рис. 3.33), если получать данные на конец дня. Рис. 3.33. Получение остатков, не включая дату границы интервала Глава 3. Реализация задач учета движения средств 323 Если необходимо учесть и их тоже, следует применять параметр Период с типом значения Граница. Параметр «Период» типа «МоментВремени» для получения остатков используют, если требуются итоги, полученные с точностью большей, чем до секунды. Например, если несколько документов имеют одинаковое время, но при проведении каждого из них требуется получать данные, актуальные на момент времени документа (рис. 3.34). Рис. 3.34. Момент времени документа Объект МоментВремени состоит из даты и ссылки на документ и может быть получен посредством применения метода МоментВремени() ссылки или объекта документа (листинг 3.47). Листинг 3.47. Получение момента времени документа МоментВремениДокумента = СсылкаНаДокумент.МоментВремени(); Также значение типа МоментВремени может быть получено с помощью конструктора (листинг 3.48). Листинг 3.48. Получение момента времени с помощью конструктора МоментВремениДокумента = Новый МоментВремени(СсылкаНаДокумент.Дата, Документ); В случае использования конструктора возможно указание даты, не совпадающей с датой документа. Рассмотрим следующий пример получения остатков на момент времени документа. Например, есть следующие записи таблицы движений регистра остатков (табл. 3.46). 324 Реализация прикладных задач в системе «1С:Предприятие 8.2» Расход Истина Расход Истина Пульт Фили-2 VH Пульт Фили-2 VH Пульт Фили-2 VH Количество Истина Склад Приход Номенклатура ПоступлениеТоваров № 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 Вид движения Период Номер строки Таблица 3.46. Таблица движений регистра накопления 5 4 1 Если получить остатки на дату 27.05.2010 12:30:45, то получим следующий результат (табл. 3.47). Таблица 3.47. Полученные итоги Номенклатура Склад Пульт VH Количество Фили-2 5 Если получить остатки на момент времени, включающий дату 27.05.2010 12:30:45 и ссылку на документ Реализация № 1, получим такие же итоги (табл. 3.47). А вот если получить остатки на момент времени, включающий дату 27.05.2010 12:30:45 и ссылку на документ Реализация № 2, получим следующий результат (табл. 3.48). Таблица 3.48. Полученные итоги Номенклатура Склад Пульт VH Количество Фили-2 1 При получении таблицы остатков с указанием параметра Период типа МоментВремени, полученного из даты документа и ссылки на документ, необходимо иметь в виду, что данные получаются, исключая записи движений самого документа (рис. 3.35). Для случаев, когда необходимо получить данные об остатках, включая движения, относящиеся к дате или моменту времени, применяют значения параметра «Период» с типом значения «Граница». Объект Граница получается посредством применения соответствующего конструктора. Именно в конструкторе указывается вид границы. Глава 3. Реализация задач учета движения средств 325 Рис. 3.35. Получение остатков на момент времени документа В случае получения остатков на конец дня граница может быть создана так, как показано в листинге 3.49. Листинг 3.49. Создание границы с помощью конструктора ГраницаПоДату = Новый Граница(КонецДня(ДатаОтчета), ВидГраницы.Включая); В этом случае остатки будут получены, включая движения на дату формирования отчета (рис. 3.36). Рис. 3.36. Получение остатков, включая движения на дату формирования отчета В случае получения остатков на момент времени документа граница может быть создана так, как показано в листинге 3.50. 326 Реализация прикладных задач в системе «1С:Предприятие 8.2» Листинг 3.50. Создание границы с помощью конструктора ГраницаПоДокумент = Новый Граница(СсылкаНаДокумент.МоментВремени(), ВидГраницы.Включая); В этом случае остатки будут получены, включая движения указанного документа (рис. 3.37). Рис. 3.37. Получение остатков, включая движения указанного документа Получение оборотов Задачи получения итогов оборотов могут решаться и для регистров остатков, и для оборотных регистров. И в том и в другом случае возможно чтение информации как посредством запроса, так и посредством метода Обороты(). Разберем подробнее, в чем разница применения этих подходов. Виртуальная таблица оборотов Виртуальная таблица оборотов регистра накопления остатков позволяет получать итоговые значения оборотов ресурсов (далее будем называть «оборотов») за временной интервал (далее будем называть «период»). Итоговые значения могут быть получены в разрезе комбинаций значений измерений и/или в развороте дополнительной периодичности. Виртуальная таблица оборотов регистра накопления остатков имеет следующий состав полей: ■ Период – это поле имеет тип Дата. Оно существует только в случаях, если указано значение параметра виртуальной таблицы оборотов Периодичность: Год, Полугодие, Квартал, Месяц, Декада, Неделя, День, Секунда, Минута, Час, Регистратор или Запись. Данное поле содержит начальную дату периода, к которому относится оборот регистра. Глава 3. Реализация задач учета движения средств ■ 327 Регистратор – это поле имеет тип ДокументСсылка.<имя>. Оно сущес- твует только в случаях, если указано значение параметра виртуальной таблицы оборотов Периодичность: Регистратор или Запись. Данное поле содержит ссылку на документ-регистратор, к которому относится оборот регистра. ■ НомерСтроки – это поле имеет тип Число. Оно существует только в тех случаях, когда указано значение параметра виртуальной таблицы оборотов Периодичность: Запись. Содержит значение поля НомерСтроки записи движения регистра. ■ <Измерение> – это поле может иметь произвольный тип, который определяется типом измерения. Количество таких полей равно количеству измерений регистра накопления. Каждое из этих полей содержит значения измерений регистра. Имена полей совпадают с названиями измерений, заданными для объекта конфигурации. ■ <Ресурс>Оборот – это поле имеет тип Число. Количество таких полей равно количеству ресурсов регистра накопления. Каждое из полей содержит значения, посчитанные как сумма приходов за минусом суммы расходов ресурса регистра накопления по всем движениям внутри соответствующего периода. Имена полей составляются из названий ресурсов с добавлением слова «Оборот». ■ <Ресурс>Приход – это поле имеет тип Число. Количество таких полей равно количеству ресурсов регистра накопления. Каждое из полей содержит значения, посчитанные как сумма приходов ресурса регистра накопления по всем движениям внутри соответствующего периода. Имена полей составляются из названий ресурсов с добавлением слова «Приход». ■ <Ресурс>Расход – это поле имеет тип Число. Количество таких полей равно количеству ресурсов регистра накопления. Каждое из полей содержит значения, посчитанные как сумма расходов ресурса регистра накопления по всем движениям внутри соответствующего периода. Имена полей составляются из названий ресурсов с добавлением слова «Расход». В отличие от регистра накопления остатков, оборотный регистр накапливает только обороты. То есть для ресурсов оборотного регистра не существует понятий «Приход» и «Расход». Поэтому состав полей виртуальной таблицы оборотов оборотного регистра накопления несколько короче состава полей аналогичной таблицы регистра накопления остатков: ■ Период – это поле имеет тип Дата. Оно существует только в случаях, если указано значение параметра виртуальной таблицы оборотов Периодичность: Год, Полугодие, Квартал, Месяц, Декада, Неделя, День, Секунда, Минута, Час, Регистратор или Запись. Данное поле содержит начальную дату периода, к которому относится оборот регистра. 328 ■ Реализация прикладных задач в системе «1С:Предприятие 8.2» Регистратор – это поле имеет тип ДокументСсылка.<имя>. Оно сущес- твует только в случаях, если указано значение параметра виртуальной таблицы оборотов Периодичность: Регистратор или Запись. Данное поле содержит ссылку на документ-регистратор, к которому относится оборот регистра. ■ НомерСтроки – это поле имеет тип Число. Оно существует только в случаях, если указано значение параметра виртуальной таблицы оборотов Периодичность: Запись. Содержит значение поля НомерСтроки записи движения регистра. ■ <Измерение> – это поле может иметь произвольный тип, который определяется типом измерения. Количество таких полей равно количеству измерений регистра накопления. Каждое из этих полей содержит значения измерений регистра. Имена полей совпадают с названиями измерений, заданными для объекта конфигурации. ■ <Ресурс>Оборот – это поле имеет тип Число. Количество таких полей равно количеству ресурсов регистра накопления. Каждое из полей содержит значения, посчитанные как сумма значений ресурса регистра накопления по всем движениям внутри соответствующего периода. Имена полей составляются из названий ресурсов с добавлением слова «Оборот». Параметры виртуальной таблицы оборотов для любого регистра накопления следующие: ■ НачалоПериода – это поле может иметь тип Дата, МоментВремени или Граница. Используется для указания начала периода расчета оборотов. Значение этого параметра по умолчанию включается в период расчета оборотов. Если параметр не задан, обороты рассчитываются с самой первой записи. ■ КонецПериода – Дата, МоментВремени, Граница. Используется для указания конца периода расчета оборотов. Значение этого параметра по умолчанию включается в период расчета оборотов. Если параметр не задан, обороты рассчитываются по самую последнюю запись. ■ Периодичность – содержит конструкцию языка запросов. Задается одним из следующих вариантов: Период, Запись, Регистратор, Секунда, Минута, Час, День, Неделя, Декада, Месяц, Квартал, Полугодие, Год. Используется для указания дополнительного разворота оборотов по периодичности. При указании значения Период обороты представляются за весь период (с НачалоПериода по КонецПериода) без дополнительных разворотов. В остальных случаях с разворотом по записям, регистраторам, неделям, декадам, месяцам, кварталам, полугодиям, годам соответственно. Значение по умолчанию – Период. ■ Условие – содержит конструкцию языка запросов – условие. Строится по полям измерений, регистра накопления (или подчиненных им полям). Используется для ограничения состава исходных записей, по которым Глава 3. Реализация задач учета движения средств 329 при построении виртуальной таблицы оборотов будут собираться обороты. Если параметр не указан, для сбора оборотов будут анализироваться все активные записи регистра. Виртуальная таблица оборотов не хранится в базе данных, а строится в момент обращения к ней. В качестве иллюстрации работы виртуальной таблицы оборотов рассмотрим следующий пример. Пусть таблица движений регистра ТоварыНаСкладах заполнена так, как показано в табл. 3.49. Приход Истина 1 Приход Ложь 1 Расход 1 Приход Истина 1 Приход Истина 1 Приход Истина 1 Приход Истина Истина Количество 2 Пульт VH Пульт PW Пульт VH Пульт VH Пульт PW Пульт PW Пульт PW Пульт PW Склад Приход Истина Номенклатура 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 Номер строки Период Таблица 3.49. Таблица движений регистра «ТоварыНаСкладах» Главный 10 Главный 7 Фили-2 5 Главный 9 Фили-2 1 Фили-2 2 Фили-2 1 Фили-2 1 Для получения оборотов используется запрос, текст которого представлен в листинге 3.51. Листинг 3.51. Пример получения оборотов регистра накопления ВЫБРАТЬ ТоварыНаСкладахОбороты.Период, ТоварыНаСкладахОбороты.Номенклатура, ТоварыНаСкладахОбороты.Склад, ТоварыНаСкладахОбороты.КоличествоОборот, ТоварыНаСкладахОбороты.КоличествоПриход, ТоварыНаСкладахОбороты.КоличествоРасход ИЗ РегистрНакопления.ТоварыНаСкладах.Обороты( , , Месяц, ) КАК ТоварыНаСкладахОбороты 330 Реализация прикладных задач в системе «1С:Предприятие 8.2» Тогда в результате выполнения приведенного запроса будет получен следующий результат (табл. 3.50). Таблица 3.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 Пульт PW Пульт PW Пульт PW 1 7 1 3 1 Главный Главный Фили-2 Фили-2 Фили-2 10 7 1 3 1 9 0 0 0 0 Как видите, в данном примере при использовании дополнительного разворота итогов по месяцам в поле Период для каждой записи указывается начальная дата месяца. В случае же использования дополнительного разворота итогов по регистраторам или записям в поле Период содержится значение поля Период записи движения по регистру. Это верно даже для ситуации, когда поле Период записей движений, подчиненных одному регистратору, заполнено разными значениями. В качестве иллюстрации рассмотрим следующий пример. Пусть таблица движений регистра накопления содержит записи, приведенные в табл. 3.51. Приход 1 Приход 2 Расход 3 Расход Количество 2 Истина Пульт VH Истина Пульт PW Истина Пульт VH Истина Пульт PW Истина Пульт VH Склад Приход Номенклатура 1 Активность ПоступлениеТоваров № 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 Вид движения Регистратор 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 Номер строки Период Таблица 3.51. Таблица движений регистра накопления Главный 10 Главный 7 Фили-2 5 Главный 7 Фили-2 1 331 Глава 3. Реализация задач учета движения средств Для получения оборотов используется запрос, текст которого представлен в листинге 3.52. Листинг 3.52. Пример получения оборотов регистра накопления ВЫБРАТЬ ТоварыНаСкладахОбороты.Период, ТоварыНаСкладахОбороты.Регистратор, ТоварыНаСкладахОбороты.Номенклатура, ТоварыНаСкладахОбороты.Склад, ТоварыНаСкладахОбороты.КоличествоОборот, ТоварыНаСкладахОбороты.КоличествоПриход, ТоварыНаСкладахОбороты.КоличествоРасход ИЗ РегистрНакопления.ТоварыНаСкладах.Обороты( , , Регистратор, ) КАК ТоварыНаСкладахОбороты Тогда в результате выполнения приведенного запроса будет получен следующий результат (табл. 3.52). Количество оборот Количество приход Количество расход ПоступлениеТоваров № 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 Номенклатура Период Таблица 3.52. Результат выполнения запроса Пульт VH Главный 10 10 0 Пульт PW Главный 7 7 0 Пульт VH Фили-2 4 5 1 Пульт PW Главный -7 0 7 Для сравнения выполним запрос, текст которого приведен в листинге 3.53. Листинг 3.53. Пример получения оборотов регистра накопления ВЫБРАТЬ ТоварыНаСкладахОбороты.Регистратор, ТоварыНаСкладахОбороты.Номенклатура, ТоварыНаСкладахОбороты.Склад, ТоварыНаСкладахОбороты.КоличествоОборот, ТоварыНаСкладахОбороты.КоличествоПриход, ТоварыНаСкладахОбороты.КоличествоРасход ИЗ РегистрНакопления.ТоварыНаСкладах.Обороты( , , Регистратор, ) КАК ТоварыНаСкладахОбороты 332 Реализация прикладных задач в системе «1С:Предприятие 8.2» Результат выполнения этого запроса представлен в табл. 3.53. Количество Приход Количество Расход Пульт VH Главный 10 10 0 Пульт PW Главный 7 7 0 Пульт VH Фили-2 5 1 Пульт PW Главный -7 0 7 Количество Оборот Склад ПоступлениеТоваров № 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 Номенклатура Регистратор Таблица 3.53. Результат выполнения запроса 4 Как видите, записи результата запроса оказываются сгруппированы по полям Период и Регистратор, даже если нет выходного поля Период. Это объясняется тем, что для определения момента времени, с которого движения регистра начинают действовать на итоги, «регистратор» является уточнением «периода». Итак, результаты и методики применения виртуальной таблицы оборотов для регистров остатков и оборотных регистров весьма схожи. Но вот алгоритмы получения этих результатов средствами системы сильно разнятся. Алгоритм, применяемый системой для получения оборотов регистра накопления остатков Для построения виртуальной таблицы оборотов регистра накопления остатков всегда используются данные таблицы движений регистра (из базы данных). При этом учитываются значения параметров виртуальной таблицы оборотов. Сам алгоритм построения этой виртуальной таблицы включает в себя следующие этапы: ■ получение записей из таблицы движений регистра согласно установленным значениям параметров виртуальной таблицы; ■ группирование полученных записей согласно указанной в параметрах виртуальной таблицы периодичности. Сортировка не выполняется. И хотя зачастую порядок записей в результате оказывается соответствующим желаемому, для гарантированного упорядочивания в тексте запроса нужно указывать ключевые слова УПОРЯДОЧИТЬ ПО или АВТОУПОРЯДОЧИВАНИЕ. Глава 3. Реализация задач учета движения средств 333 Таким образом, скорость построения виртуальной таблицы оборотов регистра накопления остатков не зависит от периода рассчитанных итогов, а зависит от количества записей движений регистра, попавших в требуемый период построения таблицы. Для обеспечения максимальной скорости выполнения запроса по этой виртуальной таблице также важно правильное применение отборов по измерениям. Правила применения таких отборов описаны в разделе «Применение отборов в запросах, использующих виртуальные таблицы регистров накопления» на стр. 374. Алгоритм, применяемый системой для получения оборотов оборотного регистра накопления Для построения виртуальной таблицы оборотов оборотного регистра накопления могут использоваться или только данные таблицы движений регистра, или только таблицы итогов (из базы данных), или и данные таблицы движений, и таблицы итогов. Для эффективного применения той или иной стратегии учитываются значения параметров виртуальной таблицы оборотов. Сам алгоритм построения этой виртуальной таблицы включает в себя следующие этапы: ■ получение записей из базы данных из таблицы движений или таблицы итогов регистра согласно установленным значениям параметров виртуальной таблицы; ■ группирование полученных записей согласно указанной в параметрах виртуальной таблицы периодичности. При выполнении первого этапа анализируется, можно ли использовать данные таблицы итогов регистра для формирования запроса. В таблице итогов регистра хранятся данные месячных оборотов. Эти данные будут использованы в случаях, когда дополнительная периодичность не задана или задана равной или большей месяцу и в интервал формирования виртуальной таблицы попадают целые месяцы. Остальная информация при необходимости получается из таблицы движений. В качестве иллюстрации работы виртуальной таблицы оборотов рассмотрим следующие примеры. Пусть таблица движений оборотного регистра Продажи заполнена следующим образом (табл. 3.54). 334 Реализация прикладных задач в системе «1С:Предприятие 8.2» Номенклатура Контрагент Количество Сумма Реализация № 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 Номер строки Период Таблица 3.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 Соответственно, таблица итогов будет заполнена так, как показано в табл. 3.55. Таблица 3.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 Пульт VH Пульт VH Пульт PW 9 10 2 1 135 150 30 95 Ялта-Лтд Компания "Риона" Компания "Риона" Ялта-Лтд Рассмотрим выполнение запроса, представленного в листинге 3.54. Листинг 3.54. Пример получения оборотов регистра накопления ВЫБРАТЬ ПродажиОбороты.Номенклатура, ПродажиОбороты.КоличествоОборот КАК Количество, ПродажиОбороты.СуммаОборот КАК Сумма ИЗ РегистрНакопления.Продажи.Обороты(&НачалоПериода, &КонецПериода, , ) КАК ПродажиОбороты 1. Если параметрам запроса присвоить значения даты по умолчанию или Неопределено (листинг 3.55), то алгоритм построения виртуальной таблицы оборотов будет использовать данные только таблицы итогов (табл. 3.56). Глава 3. Реализация задач учета движения средств 335 Листинг 3.55. Пример установки параметров запроса Запрос.УстановитьПараметр("НачалоПериода", Неопределено); Запрос.УстановитьПараметр("КонецПериода", Неопределено); Таблица 3.56. Промежуточная выборка данных из таблицы итогов Номенклатура Количество Сумма Пульт VH Пульт VH Пульт VH Пульт PW 9 10 2 1 135 150 30 95 После этапа группирования результат виртуальной таблицы будет выглядеть так, как показано в табл. 3.57. Таблица 3.57. Результат выполнения запроса Номенклатура Количество Сумма Пульт VH Пульт PW 21 1 315 95 2. Если параметрам запроса присвоить значения так, что в период входит только целое число месяцев (листинг 3.56), то алгоритм построения виртуальной таблицы будет использовать данные только таблицы итогов (табл. 3.58). Листинг 3.56. Пример установки параметров запроса Запрос.УстановитьПараметр("НачалоПериода", Дата(2010, 5, 01)); Запрос.УстановитьПараметр("КонецПериода", Дата(2010, 6, 30, 23, 59, 59)); Таблица 3.58. Промежуточная выборка данных из таблицы итогов Номенклатура Количество Сумма Пульт VH Пульт VH Пульт VH 9 10 2 135 150 30 После этапа группирования результат виртуальной таблицы будет выглядеть так, как показано в табл. 3.59. Таблица 3.59. Результат выполнения запроса Номенклатура Количество Сумма Пульт VH 21 315 336 Реализация прикладных задач в системе «1С:Предприятие 8.2» 3. Если параметрам запроса присвоить значения так, что в период входит не только целое число месяцев (листинг 3.57), то алгоритм построения виртуальной таблицы оборотов будет сначала использовать данные таблицы итогов по целым месяцам (в нашем случае – за июнь), табл. 3.60. Листинг 3.57. Пример установки параметров запроса Запрос.УстановитьПараметр("НачалоПериода", Дата(2010, 5, 20)); Запрос.УстановитьПараметр("КонецПериода", Дата(2010, 6, 30, 23, 59, 59)); Таблица 3.60. Промежуточная выборка данных из таблицы итогов Номенклатура Количество Сумма Пульт VH 2 30 Затем по не поместившимся в целые месяцы движениям данные будут получены из таблицы движений (табл. 3.61). Таблица 3.61. Промежуточная выборка данных из таблицы движений Номенклатура Количество Сумма Пульт VH Пульт VH 9 10 135 150 Записи этих таблиц будут объединены, и после этапа группирования результат виртуальной таблицы будет выглядеть так, как показано в табл. 3.62. Таблица 3.62. Результат выполнения запроса Номенклатура Количество Сумма Пульт VH 315 21 Обратите внимание: результат не отличается от результата предыдущего примера. Однако из-за того, что значение параметра НачалоПериода не совпадало с началом месяца, система была вынуждена обращаться как к таблице итогов, так и к таблице движений регистра. 4. Если параметрам запроса присвоить значения так, что в период не входит целое число месяцев (листинг 3.58), то алгоритм построения виртуальной таблицы оборотов будет использовать только данные таблицы движений регистра (табл. 3.63). Листинг 3.58. Пример установки параметров запроса Запрос.УстановитьПараметр("НачалоПериода", Дата(2010, 5, 20)); Запрос.УстановитьПараметр("КонецПериода", Дата(2010, 6, 23, 23, 59, 59)); Глава 3. Реализация задач учета движения средств 337 Таблица 3.63. Промежуточная выборка данных из таблицы движений Номенклатура Количество Сумма Пульт VH Пульт VH Пульт VH Пульт VH 9 10 1 1 135 150 15 15 После этапа группирования результат виртуальной таблицы будет выглядеть так, как показано в табл. 3.64. Таблица 3.64. Результат выполнения запроса Номенклатура Количество Сумма Пульт VH 21 315 Как видите, хотя интервал между значениями параметров превышал 30 дней, он не включал в себя целых месяцев. Этого было достаточно, чтобы виртуальная таблица оборотов строилась по таблице движений. 5. Если параметр Периодичность имеет значение, меньшее месяца (листинг 3.59), то независимо от значений параметров НачалоПериода и КонецПериода виртуальная таблица оборотов будет строиться по записям таблицы движений регистра. Листинг 3.59. Пример установки параметров запроса ВЫБРАТЬ ПродажиОбороты.Номенклатура, ПродажиОбороты.КоличествоОборот КАК Количество, ПродажиОбороты.СуммаОборот КАК Сумма ИЗ РегистрНакопления.Продажи.Обороты(&НачалоПериода, &КонецПериода, Неделя, ) КАК ПродажиОбороты Таким образом, видно, что получение виртуальной таблицы оборотов оборотного регистра может выполняться гораздо быстрее, нежели виртуальной таблицы оборотов регистра остатков, за счет использования накопленных месячных итогов оборотов. Для обеспечения максимальной скорости выполнения запроса по этой виртуальной таблице также важно правильное применение отборов по измерениям. Правила применения таких отборов описаны в разделе «Применение отборов в запросах, использующих виртуальные таблицы регистров накопления» на стр. 374. 338 Реализация прикладных задач в системе «1С:Предприятие 8.2» Метод «Обороты()» В ситуациях, когда при получении данных об оборотах не применяется сложных отборов, либо эти данные впоследствии не нужно соединять с другими данными, а дополнительная периодичность оборотов не требуется, можно использовать объектную модель чтения информации – метод Обороты(). Данный метод применим только для регистров накопления, у которых включено использование итогов. При получении результата используются только записи активных движений. Например, пусть таблица движений регистра ТоварыНаСкладах заполнена следующим образом (табл. 3.65). Истина 2 Приход Истина 1 Приход Ложь 1 Расход Истина 1 Приход Истина 1 Приход Истина 1 Приход Истина 1 Приход Истина Пульт VH Пульт PW Пульт VH Пульт VH Пульт PW Пульт PW Пульт PW Пульт PW Количество Приход Склад 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.08.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.08.2010 11:00:00 Номер строки Период Таблица 3.65. Таблица движений регистра накопления Главный 10 Главный 7 Фили-2 5 Главный 9 Фили-2 1 Фили-2 2 Фили-2 1 Фили-2 1 Тогда после выполнения кода, приведенного в листинге 3.60, будет получен результат, показанный в табл. 3.66. Листинг 3.60. Пример получения оборотов регистра накопления ТаблицаОборотов = РегистрыНакопления.ТоварыНаСкладах.Обороты(); Глава 3. Реализация задач учета движения средств 339 Таблица 3.66. Результат выполнения метода «Обороты()» Номенклатура Склад Количество Приход Количество Расход Пульт VH Пульт PW Пульт PW 10 7 5 Главный Главный Фили-2 9 0 0 Кроме полных оборотов, посредством метода Обороты() возможно и получение данных в некотором временном интервале, с отбором на равенство значений измерений. Например, если требуется сообщить обороты по некой товарной позиции (ссылка на нее – в переменной ТоварОтбора) в интервале между НачалоПериода и КонецПериода (листинг 3.61). Листинг 3.61. Пример получения оборотов регистра накопления Отбор = Новый Структура("Номенклатура",ТоварОтбора); ТаблицаОборотов = РегистрыНакопления.ТоварыНаСкладах.Обороты(НачалоПериода, КонецПериода, Отбор, "Номенклатура", ); Для Каждого СтрокаТаблицы Из ТаблицаОборотов Цикл Сообщение = Новый СообщениеПользователю(); Сообщение.Текст = "Номенклатура " + СтрокаТаблицы.Номенклатура + ": Приход " + СтрокаТаблицы.КоличествоПриход + "; Расход " + СтрокаТаблицы.КоличествоРасход; Сообщение.Сообщить(); КонецЦикла; В качестве типов значения переменных, передаваемых параметрам НачалоПериода и КонецПериода, возможны те же, что использовались для виртуальной таблицы получения оборотов, то есть Дата, МоментВремени и Граница. Особенности применения различных значений и их использование системой при подсчете данных будут рассмотренным ниже, в разделе «Особенности использования периодов и моментов времени при получении оборотов» на стр. 340. Посредством параметра Отбор типа Структура можно строить простейшие отборы на равенство значений измерений. Например, так (листинг 3.62). Листинг 3.62. Пример установки отбора при получении оборотов регистра накопления Отбор = Новый Структура("Номенклатура, Склад", ТоварОтбора, СкладОтбора); Последние два параметра метода Обороты() касаются операции свертки данных в запросе СУБД перед выгрузкой в таблицу значений. Однако если значения данных параметров не указывать, то результирующая таблица значений будет содержать колонки, соответствующие всем измерениям 340 Реализация прикладных задач в системе «1С:Предприятие 8.2» и/или всем ресурсам. В приведенном примере (см. листинг 3.61) было указано только измерение Номенклатура, в результате произошла свертка по колонке Номенклатура с суммированием значений колонок КоличествоПриход и КоличествоРасход. Применение метода Обороты() для оборотного регистра практически аналогично применению этого метода для регистра остатков. Единственное отличие состоит в названии колонок таблицы значений, получаемой в результате применения метода. В данном случае их имена совпадают с именами измерений и ресурсов. Например, если требуется на основе данных регистра Продажи сообщить об объемах продаж по конкретной номенклатурной позиции (ссылка на нее – в переменной ТоварОтбора) в интервале между НачалоПериода и КонецПериода, в разрезе покупателей, то можно использовать следующий фрагмент кода (листинг 3.63). Листинг 3.63. Пример получения оборотов оборотного регистра накопления Отбор = Новый Структура("Номенклатура", ТоварОтбора); ТаблицаОборотов = РегистрыНакопления.Продажи.Обороты(НачалоПериода, КонецПериода, Отбор, "Контрагент", ); Для каждого СтрокаТаблицы Из ТаблицаОборотов Цикл Сообщение = Новый СообщениеПользователю(); Сообщение.Текст = "Покупатель " + СтрокаТаблицы.Контрагент + ": Количество " + СтрокаТаблицы.Количество + "; Сумма " + СтрокаТаблицы.Сумма; Сообщение.Сообщить(); КонецЦикла; Особенности использования периодов и моментов времени при получении оборотов Параметры НачалоПериода и КонецПериода виртуальной таблицы оборотов и метода Обороты() может получать значения типа Дата, МоментВремени и Граница, кроме того, может быть вообще не указан, иметь значение Неопределено или значение даты по умолчанию. Последние случаи (не указан, Неопределено или значение даты по умолчанию) приводят к построению таблицы оборотов с данными, учитывающими все активные записи регистра. В случае если в качестве параметра передается значение типа Дата, важно помнить следующие моменты: Глава 3. Реализация задач учета движения средств 341 Дата в системе «1С:Предприятие» включает в свой состав время. Даже если время не указано явно, оно принимает значение 00:00:00. То есть если в качестве параметра НачалоПериода передать значение 1 декабря 2009 года (данное значение может быть получено так: '20091201'), а в качестве параметра КонецПериода передать 31 декабря 2009 года ('20091231'), то в результате и виртуальная таблица получения оборотов, и результат метода Обороты() будут построены с даты 01.12.2009 00:00:00 по дату 31.12.2009 00:00:00. То есть в обороты, по сути, войдут данные продаж только первой секунды 31 декабря (рис. 3.38). Рис. 3.38. Получение оборотов на даты указанного интервала Для предотвращения возможных недоразумений по этому поводу удобно использовать функцию КонецДня(). Эта функция возвращает значение последней секунды дня, указанной в качестве параметра даты (листинг 3.64, листинг 3.65). Листинг 3.64. Пример получения оборотов регистра накопления на конец дня Запрос = Новый Запрос; Запрос.Текст = "ВЫБРАТЬ | ТоварыНаСкладахОбороты.Номенклатура, | ТоварыНаСкладахОбороты.Склад, | ТоварыНаСкладахОбороты.КоличествоОборот, | ТоварыНаСкладахОбороты.КоличествоПриход, | ТоварыНаСкладахОбороты.КоличествоРасход |ИЗ | РегистрНакопления.ТоварыНаСкладах.Обороты(&НачалоПериода, &КонецПериода) | КАК ТоварыНаСкладахОбороты"; Запрос.УстановитьПараметр("НачалоПериода", НачалоПериода); Запрос.УстановитьПараметр("КонецПериода", КонецДня(КонецПериода)); 342 Реализация прикладных задач в системе «1С:Предприятие 8.2» Листинг 3.65. Пример получения оборотов регистра накопления на конец дня ТаблицаОборотов = РегистрыНакопления.ТоварыНаСкладах.Обороты(НачалоПериода, КонецДня(КонецПериода)); В обоих случаях в результате будут получены данные оборотов с даты 01.12.2009 00:00:00 по дату 31.12.2009 23:59:59 включительно (рис. 3.39). Рис. 3.39. Получение оборотов на конец дня Таблица оборотов строится с включением записей, соответствующих граничным периодам. То есть с начала секунды значения параметра НачалоПериода по конец секунды параметра КонецПериода (рис. 3.40). Рис. 3.40. Включение граничных записей при получении оборотов Глава 3. Реализация задач учета движения средств 343 Если в вышеприведенных примерах вместо конца дня 31.12.2009 23:59:59 указать дату 01.01.2010 00:00:00 и в таблице движений регистра будут присутствовать записи со значением поля Период, равным дате 01.01.2010 00:00:00, то они будут учтены. То есть с прикладной точки зрения получится, что в результат запроса войдут данные первой секунды 2010 года. Параметры «НачалоПериода» и «КонецПериода» типа «МоментВремени» используют для получения оборотов, если требуются итоги, полученные с точностью большей, чем до секунды. Например, если несколько документов имеют одинаковое время, но для решения задачи нужно получение оборотов с начала месяца по момент времени текущего документа (рис. 3.41). Рис. 3.41. Использование момента времени при получении оборотов Данная задача может быть решена посредством метода Обороты() или применения запроса с указанием значений параметров НачалоПериода и КонецПериода, вычисляемых следующим образом (листинг 3.66). Листинг 3.66. Пример указания границ периода с использованием момента времени НачалоПериода = НачалоМесяца(СсылкаНаДокумент.Дата); КонецПериода = Новый МоментВремени(СсылкаНаДокумент.Дата, СсылкаНаДокумент); В обоих случаях обороты будут получены, включая движения документа, ссылка на который содержится в переменной СсылкаНаДокумент. Для случаев, когда необходимо получить данные об оборотах, исключая движения, относящиеся к дате или моменту времени, применяют значения параметров НачалоПериода и КонецПериода с типом значения Граница. Объект Граница получается посредством применения соответствующего конструктора. Именно в конструкторе указывается вид границы. 344 Реализация прикладных задач в системе «1С:Предприятие 8.2» Например, если требуется получить обороты в интервале дат, исключая первую и последнюю секунды, можно использовать следующий код (листинг 3.67). Листинг 3.67. Пример задания границ интервала с использованием объекта «Граница» ГраницаСДатыИсключая = Новый Граница(НачалоПериода, ВидГраницы.Исключая); ГраницаНаДатуИсключая = Новый Граница(КонецДня(КонецПериода), ВидГраницы.Исключая); Если требуется получить обороты с начала месяца (включая) по момент времени документа, исключая движения самого документа, тогда можно поступить следующим образом (листинг 3.68, рис. 3.42). Листинг 3.68. Пример задания границ интервала ГраницаСНачалаМесяца = НачалоМесяца(СсылкаНаДокумент.Дата); ГраницаНаДокумент = Новый Граница(СсылкаНаДокумент.МоментВремени(), ВидГраницы.Исключая); Рис. 3.42. Использование границы при получении оборотов Агрегаты Для оптимизации получения итоговых данных из оборотных регистров накопления, например, для быстрого получения аналитических отчетов в различных разрезах, в системе «1С:Предприятие» реализован механизм агрегатов. Агрегат – физическая таблица в базе данных, в которой хранятся сводные обороты всех ресурсов регистра за определенный период, по набору измерений и с периодичностью, соответствующими конкретному агрегату. Таблиц-агрегатов в базе данных может быть много (они отличаются друг от друга набором измерений и периодичностью), в то время как таблица итогов (она хранит обороты в разрезе всех измерений регистра) – одна. Глава 3. Реализация задач учета движения средств 345 За счет этого и обеспечивается более быстрый доступ к итоговым данным, если режим использования агрегатов включен. Однако необходимо учитывать, что: ■ Во-первых, оборотный регистр, использующий агрегаты, должен иметь не более 30 измерений. ■ Во-вторых, агрегаты рассчитаны на крупные внедрения, в которых требуется анализировать сотни и миллионы записей в регистрах. Поэтому не имеет смысла использовать их в регистрах, содержащих менее 3–5 тысяч записей. Зачем вообще использовать агрегаты? Для ответа на этот вопрос вспомним механизм получения итоговых данных оборотных регистров накопления. Для получения различных аналитических отчетов обычно используется виртуальная таблица оборотов оборотного регистра накопления. Как было рассказано выше, для построения этой таблицы в зависимости от параметров, переданных в виртуальную таблицу оборотов, могут использоваться или данные только таблицы движений регистра, или данные только таблицы итогов, или данные таблицы движений и таблицы итогов. В таблице итогов регистра хранятся данные месячных оборотов. Эти данные будут использованы в случаях, когда дополнительная периодичность не задана или задана равной или большей месяцу и в интервал формирования виртуальной таблицы попадают целые месяцы. Остальная информация при необходимости получается из таблицы движений. Самый быстрый способ получения итоговых данных из оборотного регистра – путем запроса только к таблице итогов. Но на практике зачастую большую или меньшую часть требуемых данных приходится досчитывать по таблице движений. И совсем уже катастрофический случай, когда таблицей итогов воспользоваться не удается и приходится все рассчитывать по таблице движений. При использовании агрегатов в подавляющем большинстве запросов к информационной базе система сможет выбрать один или несколько агрегатов для получения из них нужных данных, не обращаясь к таблице движений регистра. Таким образом, скорость исполнения запросов может быть значительно увеличена, следовательно, аналитические отчеты будут выполняться быстрее, что особенно важно для крупных внедрений. Нужно понимать, что использование или неиспользование агрегатов никак не сказывается на прикладном коде или тексте запросов, написанных разработчиком. Если у оборотного регистра накопления есть агрегаты и разрешено их использование, то при получении итоговых данных из регистра 346 Реализация прикладных задач в системе «1С:Предприятие 8.2» платформа будет работать в режиме агрегатов, что при больших объемах данных регистра будет эффективнее. Если агрегатов нет или их использование запрещено, платформа будет работать в режиме итогов, как было описано выше. В составе демонстрационной конфигурации «Хранение информации и учет движения средств», которая находится на прилагаемом компакт-диске, находится оборотный регистр накопления ПродажиАгрегаты, содержащий 34 тысячи записей и использующий агрегаты. Данные в этом регистре получены случайным образом и никакого прикладного значения не имеют. Но на примере этого регистра мы проиллюстрируем работу с агрегатами. Работа с агрегатами может быть представлена следующей схемой (рис. 3.43). Рис. 3.43. Общая схема работы с агрегатами 1. Сначала в конфигураторе нужно создать необходимый список агрегатов, который будет использовать оборотный регистр накопления. Сделать это можно двумя способами: □ В режиме 1С:Предприятие при помощи стандартной функции Управление итогами (Все функции Стандартные Управление итогами Полные возможности Агрегаты Оптимальные…) рассчитать оптимальные агрегаты для регистра, сохранить список агрегатов в файл Глава 3. Реализация задач учета движения средств 347 <имя регистра>.xml (рис. 3.44) и затем в конфигураторе, в диалоге редактирования агрегатов регистра загрузить их из файла командой Открыть оптимальные агрегаты. Из встроенного языка можно получить список оптимальных агрегатов методом менеджера регистра накопления ОпределитьОптимальныеАгрегаты(). При первом построении списка агрегатов платформа анализирует только таблицу движений регистра. Если агрегаты для регистра ранее использовались, то платформа анализирует также и статистику использования этих агрегатов. На основании этих данных платформа предлагает набор агрегатов для регистра, которые она считает оптимальными. Рис. 3.44. Получение списка оптимальных агрегатов ВНИМАНИЕ! Чтобы закладка Агрегаты обработки Управление итогами стала доступной, нужно создать хотя бы один агрегат вручную (при помощи команды контекстного меню оборотного регистра накопления Открыть агрегаты). □ Создать собственный список агрегатов регистра на основе анализа запросов к регистру. Для этого нужно использовать диалог редактирования агрегатов регистра. Вызвать его можно из дерева конфигурации при помощи команды контекстного меню оборотного регистра накопления Открыть агрегаты или из окна редактирования объекта конфигурации, на закладке Данные, при помощи кнопки Агрегаты. 2. После обновления конфигурации базы данных включить для регистра режим использования агрегатов. Это можно сделать в режиме 1С:Предприятие при помощи стандартной функции Управление итогами (Все функции 348 Реализация прикладных задач в системе «1С:Предприятие 8.2» Стандартные Управление итогами Полные возможности Агрегаты Режим Включить режим агрегатов). Из встроенного языка можно установить режим агрегатов методом менеджера регистра накопления УстановитьРежимАгрегатов(). 3. Далее необходимо выполнить перестроение агрегатов. Это можно сделать в режиме 1С:Предприятие при помощи стандартной функции Управление итогами (Все функции Стандартные Управление итогами Полные возможности Агрегаты Перестроить…). Из встроенного языка можно перестроить использование агрегатов методом менеджера регистра накопления ПерестроитьИспользованиеАгрегатов(). Перестроение сети агрегатов нужно для того, чтобы платформа определила, какие из агрегатов она будет использовать в ближайшее время. Для этого платформа анализирует имеющиеся агрегаты и статистику запросов к регистру. Операцию перестроения нужно производить регулярно. Особенно в случаях, если характер данных в регистре мог измениться или есть вероятность изменения состава запросов к регистру, что ведет к изменению статистики использования агрегатов. После перестроения агрегатов платформа заполняет дату перестроения и вычисляет эффект от использования агрегатов для регистра. Эффект измеряется в процентах и показывает, насколько быстрее будет выполняться запрос при использовании агрегатов по сравнению с запросом при использовании таблицы итогов. 4. Затем необходимо выполнить обновление агрегатов, так как, в отличие от таблицы итогов, агрегаты автоматически не заполняются данными. Это можно сделать в режиме 1С:Предприятие при помощи стандартной функции Управление итогами (Все функции Стандартные Управление итогами Полные возможности Агрегаты Обновить…). Из встроенного языка можно обновить данные агрегатов методом менеджера регистра накопления ОбновитьАгрегаты(). При обновлении агрегатов происходит перенос данных из таблиц движений, которые были произведены после предыдущего обновления агрегатов, в таблицы агрегатов, которые в данный момент используются платформой. Если в информационную базу постоянно вводится много новых данных, то обновлять агрегаты нужно часто (каждый час, минуту, секунду). Если в агрегатах не найдется нужных итоговых данных, система все равно досчитает их по таблице движений, что будет значительно медленнее. Поэтому обновление агрегатов влияет лишь на производительность, а не на саму возможность получения актуальных итогов. Глава 3. Реализация задач учета движения средств 349 5. Далее следует накопить статистику использования агрегатов. Для этого нужно в течение некоторого интервала времени, например, месяца, выполнять типовые задачи, использующие данные регистра, для которого включен режим использования агрегатов. В процессе работы необходимо выполнять обновление агрегатов. 6. По прошествии выбранного временного интервала, например, через месяц, следует заново рассчитать оптимальные агрегаты (метод ОпределитьОптимальныеАгрегаты()). Данная операция не является регулярной, ее можно выполнять при необходимости, когда количественные изменения в статистике использования агрегатов переходят в качественные. Судить об этом можно по существенному падению производительности на текущем списке агрегатов или по существенному изменению характера данных или состава запросов к регистру и т. п. 7. Затем необходимо определить, требуется ли изменение списка агрегатов для регистра. Если нет, то следует продолжить работу, перейдя на шаг 3. 8. Если необходимо обновить список агрегатов регистра, то в диалоге редактирования агрегатов регистра следует загрузить необходимые (или все) агрегаты из списка оптимальных командой Открыть оптимальные агрегаты. Затем нужно обновить конфигурацию базы данных и продолжить работу с шага 3. ВНИМАНИЕ! Обновление агрегатов можно выполнять в фоновом режиме, в процессе работы пользователей. При этом есть возможность обновлять агрегаты порциями, и рекомендуется использовать режим разделения итогов. Перестроение сети агрегатов и получение оптимальных агрегатов – довольно длительные и ресурсоемкие операции. Поэтому лучше их выполнять в период минимальной нагрузки на систему, например, ночью. Поскольку после получения оптимальных агрегатов может потребоваться реструктуризация базы данных, нужно быть заранее готовым к тому, что работа пользователей на это время должна быть прекращена. Следует отдельно сказать об установке свойства Использование в диалоге редактирования агрегатов регистра в конфигураторе. Стандартно это свойство устанавливается в значение Авто. Это значит, что при перестроении агрегатов платформа сама будет решать, использовать данный агрегат или нет. Если же свойство Использование агрегата установить в значение Всегда, то независимо от «желания» платформы она будет использовать данный агрегат при получении итоговых данных (рис. 3.45). 350 Реализация прикладных задач в системе «1С:Предприятие 8.2» Рис. 3.45. Свойство агрегата «Использование» Например, разработчик может создать специальный агрегат, обеспечивающий максимально быстрое получение руководителем какого-то аналитического отчета, и установить для него свойство Использование в значение Всегда. Но предположим, этот отчет выполняется довольно редко. Тогда при перестроении списка агрегатов платформа, проанализировав статистику запросов, не сможет исключить его из списка используемых агрегатов, а будет использовать его всегда в соответствии с желанием разработчика. Получение остатков и оборотов в одной таблице Для решения прикладных задач управления ресурсами предприятий система предоставляет возможности учета этих ресурсов (впрочем, как и любых других показателей) на регистрах накопления. Как правило, в подобных ситуациях речь идет о показателях остатков. Потому что именно показатели остатков позволяют ответить на вопрос, какое именно значение имел этот показатель в тот или иной момент времени. Но для полноценного контроля зачастую мало информации только о значениях остатков. Требуется видеть одновременно и статическую картину, и как она была получена (динамику развития ситуации). Например, для контроля наличия товара на складах предприятия пользователю часто необходимо видеть картину и остатков, и оборотов за некий промежуток времени (табл. 3.67). Таблица 3.67. Показатели остатков и оборотов Номенклатура Количество начальный остаток Количество конечный остаток Количество оборот Количество приход Количество расход Пульт PW Пульт VH 1 10 15 11 14 1 15 10 1 9 351 Глава 3. Реализация задач учета движения средств То есть информацию о начальном остатке значения ресурса (КоличествоНачальныйОстаток), о том, какой за указанные промежуток времени был оборот данного ресурса (КоличествоОборот), как этот оборот был получен (КоличествоПриход, КоличествоРасход), какое конечное значение ресурса после этого получилось (КоличествоКонечныйОстаток). Увидев такую картину укрупнено, пользователь может потребовать показать ее более детально, с дополнительной периодичностью до дня, когда происходили события в отношении товаров на складах (табл. 3.68). КоличествоКонечныйОстаток КоличествоОборот КоличествоПриход КоличествоРасход Пульт PW КоличествоНачальныйОстаток Период Номенклатура Таблица 3.68. Детальные показатели остатков и оборотов 1 15 14 15 1 Пульт PW Пульт PW Пульт PW Пульт VH 13.05.2010 0:00:00 17.05.2010 0:00:00 31.05.2010 0:00:00 1 8 11 10 8 11 15 11 7 3 4 1 7 3 5 10 0 0 1 9 Пульт VH Пульт VH 13.05.2010 0:00:00 27.05.2010 0:00:00 10 20 20 11 10 -9 10 0 0 9 Обратите внимание: в результате подробного варианта представления данных длина таблицы может возрастать на несколько порядков. И тогда для быстрого осмысления «локальных участков» информации важно, чтобы значение полей НачальныйОстаток и КонечныйОстаток отражали реальную картину дня и были согласованы с информацией об остатках по предыдущему и последующему периоду (дням). То есть значения полей остатков верхнего уровня группирования информации (по номенклатуре) в данном отчете не получены простым суммированием таких же полей нижнего уровня группирования информации (по дням), а скорее перенесены из соответствующих записей нижнего уровня. А ведь пользователь может потребовать еще большей детальности, уже внутри дня. 352 Реализация прикладных задач в системе «1С:Предприятие 8.2» Для построения таких отчетов можно отдельно получить остатки, отдельно получить обороты и затем каким-либо образом обработать полученные данные. Такой способ в принципе возможен, но достаточно трудоемок. Поэтому в рамках платформы системы «1С:Предприятие» предусмотрены специальные механизмы для решения подобных задач. Они основаны на применении виртуальной таблицы остатков и оборотов регистра накопления остатков и включают в себя реализацию достаточно сложных алгоритмов, решающих одновременно вопросы требуемой функциональности и возможной оптимизации с точки зрения быстродействия. Разработчик же может пользоваться уже готовыми результатами. Но для эффективного использования данных механизмов важно понимать их возможности и принципы реализации. Ниже эти вопросы рассматриваются более подробно. Виртуальная таблица остатков и оборотов Виртуальная таблица остатков и оборотов регистра накопления остатков позволяет получать итоговые значения и остатков, и оборотов ресурсов за временной интервал. Итоговые значения могут быть получены в разрезе комбинаций значений измерений и/или в развороте дополнительной периодичности. Виртуальная таблица остатков и оборотов содержит следующие поля: ■ Период – имеет тип Дата. Поле существует, только если указано значение параметра виртуальной таблицы остатков и оборотов Периодичность: Год, Полугодие, Квартал, Месяц, Декада, Неделя, Секунда, Минута, Час, День, Регистратор или Запись. Данное поле содержит начальную дату периода, к которому относится оборот регистра. ■ Регистратор – имеет тип ДокументСсылка.<имя>. Поле существует, если указано значение параметра виртуальной таблицы остатков и оборотов Периодичность: Регистратор или Запись. Данное поле содержит ссылку на документ-регистратор, к которому относится оборот регистра. ■ НомерСтроки – имеет тип Число. Это поле существует, если указано значение параметра виртуальной таблицы остатков и оборотов Периодичность: Запись. Содержит значение поля НомерСтроки записи движения регистра. ■ <Измерение> – тип произвольный, определяется типом измерения. Количество таких полей равно количеству измерений регистра накопления. Каждое из полей содержит значения измерений регистра. Имена полей совпадают с названиями измерений, заданными для объекта конфигурации. Глава 3. Реализация задач учета движения средств 353 ■ <Ресурс>Оборот – имеет тип Число. Количество таких полей равно коли- ■ <НачалоПериода> – Дата, МоментВремени или Граница. Используется честву ресурсов регистра накопления. Каждое из полей содержит значения, посчитанные как сумма приходов за минусом суммы расходов ресурса регистра по всем движениям внутри соответствующего периода. Имена полей составляются из названий ресурсов с добавлением слова «Оборот». ■ <Ресурс>Приход – имеет тип Число. Количество таких полей равно количеству ресурсов регистра накопления. Каждое из полей содержит значения, посчитанные как сумма приходов ресурса регистра по всем движениям внутри соответствующего периода. Имена полей составляются из названий ресурсов с добавлением слова «Приход». ■ <Ресурс>Расход – имеет тип Число. Количество таких полей равно количеству ресурсов регистра накопления. Каждое из полей содержит значения, посчитанные как сумма расходов ресурса регистра по всем движениям внутри соответствующего периода. Имена полей составляются из названий ресурсов с добавлением слова «Расход». ■ <Ресурс>НачальныйОстаток – имеет тип Число. Количество таких полей равно количеству ресурсов регистра накопления. Каждое из полей содержит значение остатка ресурса на начало соответствующего периода. Имена полей составляются из названий ресурсов с добавлением слова «НачальныйОстаток». ■ <Ресурс>КонечныйОстаток – имеет тип Число. Количество таких полей равно количеству ресурсов регистра накопления. Каждое из полей содержит значение остатка ресурса на конец соответствующего периода. Имена полей составляются из названий ресурсов с добавлением слова «КонечныйОстаток». Виртуальная таблица остатков и оборотов имеет следующие параметры: для указания начала периода расчета итогов. Значение начала периода по умолчанию включается в период расчета итогов. Если параметр не задан, итоги рассчитываются с самой первой записи. ■ <КонецПериода> – Дата, МоментВремени или Граница. Используется для указания конца периода расчета итогов. Значение конца периода по умолчанию включается в период расчета итогов. Если параметр не задан, итоги рассчитываются по самую последнюю запись. ■ <Периодичность> – конструкция языка запросов. Задается одним из следующих вариантов: Период, Запись, Регистратор, Секунда, Минута, Час, День, Неделя, Декада, Месяц, Квартал, Полугодие, Год. Используется для указания дополнительного разворота итогов по периодичности. При указании значения Период обороты представляются за весь период (с НачалоПериода по КонецПериода) без дополнительных разворотов. В остальных случаях с разворотами по записям, регистраторам, 354 Реализация прикладных задач в системе «1С:Предприятие 8.2» неделям, декадам, месяцам, кварталам, полугодиям, годам соответственно. Значение по умолчанию – Период. ■ <МетодДополнения> – конструкция языка запросов. Задается одним из следующих вариантов: Движения, ДвиженияИГраницыПериода. Используется для указания включения граничных периодов в состав выдаваемых виртуальной таблицей записей. Если выбирается вариант Движения, то граничные периоды не будут включаться (будут выданы записи только за те периоды, когда имели место движения). Если выбирается вариант ДвиженияИГраницыПериода, то граничные периоды будут включаться независимо от наличия или отсутствия движений в рамках интервала между НачалоПериода и КонецПериода. Значение по умолчанию – ДвиженияИГраницыПериода. ■ <Условие> – конструкция языка запросов – условие. Строится по полям измерений, регистра накопления (или подчиненным им полям). Используется для ограничения состава исходных записей, по которым при построении виртуальной таблицы будут собираться итоги. Если параметр не указан, то для сбора итогов будут анализироваться все активные записи регистра. Виртуальная таблица остатков и оборотов не хранится в базе данных, а строится в момент обращения к ней. Для построения виртуальной таблицы всегда используются данные таблицы итогов и таблицы движений регистра (из базы данных). При этом учитываются значения параметров виртуальной таблицы. Итоги ресурсов собираются только по активным записям. Виртуальная таблица может строиться только по тем регистрам, у которых использование итогов включено. При попытке выполнения запроса, в котором используется виртуальная таблица остатков для регистра накопления с отключенными итогами, выдается сообщение об ошибке. Сам алгоритм построения этой виртуальной таблицы включает в себя следующие этапы: ■ получение остатков на начало заданного периода (так же, как это выполняется для построения виртуальной таблицы остатков); ■ получение оборотов за заданный период с заданной периодичностью (так же, как это выполняется для построения виртуальной таблицы оборотов); ■ объединение полученных остатков и оборотов с учетом значения параметра МетодДополнения; ■ досчет значений остатков для каждой записи. Если дополнительная периодичность не указана, то расчет всех данных производится в рамках одного запроса, включающего подзапросы, согласно разделам алгоритма. Подзапросы при этом примерно те же, что и для получения соответствующих виртуальных таблиц получения остатков и оборотов. Глава 3. Реализация задач учета движения средств 355 В случае же использования дополнительной периодичности на каждом этапе алгоритма запросы выполняются, результаты запросов объединяются, полученная в результате объединения таблица записывается во временную таблицу базы данных, чтобы впоследствии быть использованной при выполнении основного запроса, в рамках которого была применена виртуальная таблица остатков и оборотов. Рассмотрим примеры использования виртуальной и оборотов для регистра ТоварыНаСкладах. таблицы остатков Пусть таблица движений регистра ТоварыНаСкладах заполнена так, как показано в табл. 3.69. 1 2 1 1 1 1 1 1 1 Допустим, выполняется следующий запрос (листинг 3.69). Количество 1 Склад Приход Истина Пульт PW Приход Истина Пульт VH Приход Истина Пульт VH Приход Истина Пульт PW Приход Истина Пульт PW Приход Ложь Пульт VH Расход Истина Пульт VH Приход Истина Пульт PW Приход Истина Пульт PW Расход Истина Пульт PW Приход Истина Пульт PW Номенклатура 1 Активность ПоступлениеТоваров № 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троки Период Таблица 3.69. Таблица движений регистра накопления Главный 1 Фили-2 10 Главный 10 Главный 7 Розничный 3 Фили-2 5 Главный 9 Фили-2 1 Фили-2 2 Фили-2 1 Фили-2 2 356 Реализация прикладных задач в системе «1С:Предприятие 8.2» Листинг 3.69. Пример получения остатков и оборотов регистра накопления ВЫБРАТЬ ТоварыНаСкладахОстаткиИОбороты.Номенклатура, ТоварыНаСкладахОстаткиИОбороты.Склад, ТоварыНаСкладахОстаткиИОбороты.КоличествоНачальныйОстаток, ТоварыНаСкладахОстаткиИОбороты.КоличествоКонечныйОстаток, ТоварыНаСкладахОстаткиИОбороты.КоличествоОборот, ТоварыНаСкладахОстаткиИОбороты.КоличествоПриход, ТоварыНаСкладахОстаткиИОбороты.КоличествоРасход ИЗ РегистрНакопления.ТоварыНаСкладах.ОстаткиИОбороты КАК ТоварыНаСкладахОстаткиИОбороты АВТОУПОРЯДОЧИВАНИЕ Тогда результат выполнения приведенного запроса будет выглядеть следующим образом (таб. 3.70). Номенклатура Склад КоличествоНачальныйОстаток КоличествоКонечныйОстаток КоличествоОборот КоличествоПриход КоличествоРасход Таблица 3.70. Результат выполнения запроса Пульт PW Пульт PW Пульт PW Пульт VH Пульт VH Главный Розничный Фили-2 Главный Фили-2 0 0 0 0 0 8 3 4 1 10 8 3 4 1 10 8 3 5 10 10 0 0 1 9 0 Для получения информации с дополнительным разворотом по временным периодам, например, по дням, когда были движения, можно применять следующий вариант написания запроса (листинг 3.70). Глава 3. Реализация задач учета движения средств 357 Листинг 3.70. Пример получения остатков и оборотов регистра накопления ВЫБРАТЬ ТоварыНаСкладахОстаткиИОбороты.Период, ТоварыНаСкладахОстаткиИОбороты.Номенклатура, ТоварыНаСкладахОстаткиИОбороты.Склад, ТоварыНаСкладахОстаткиИОбороты.КоличествоНачальныйОстаток, ТоварыНаСкладахОстаткиИОбороты.КоличествоКонечныйОстаток, ТоварыНаСкладахОстаткиИОбороты.КоличествоОборот, ТоварыНаСкладахОстаткиИОбороты.КоличествоПриход, ТоварыНаСкладахОстаткиИОбороты.КоличествоРасход ИЗ РегистрНакопления.ТоварыНаСкладах.ОстаткиИОбороты(&НачалоПериода, &КонецПериода, День, Движения, ) КАК ТоварыНаСкладахОстаткиИОбороты АВТОУПОРЯДОЧИВАНИЕ Если при этом значения параметров установлены так, как показано в листинге 3.71, то в результате выполнения запроса будут получены данные, представленные в табл. 3.71. Листинг 3.71. Пример установки параметров запроса Запрос.УстановитьПараметр("НачалоПериода", '20100501'); Запрос.УстановитьПараметр("КонецПериода", КонецДня('20100531')); Период Номенклатура Склад КоличествоНачальныйОстаток КоличествоКонечныйОстаток КоличествоОборот КоличествоПриход КоличествоРасход Таблица 3.71. Результат выполнения запроса 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 Пульт PW Пульт PW Пульт PW Пульт VH Пульт VH Главный Розничный Фили-2 Главный Главный 1 0 0 0 10 8 3 4 10 1 7 3 4 10 -9 7 3 5 10 0 0 0 1 0 9 358 Реализация прикладных задач в системе «1С:Предприятие 8.2» Обратите внимание: значение поля Период соответствует началу каждого дня (дополнительная периодичность была именно День). Поскольку в параметрах виртуальной таблицы был указан метод дополнения Движения, то в данном случае выходная таблица содержит записи по всем комбинациям значений измерений, по которым в периоде с НачалоПериода по КонецПериода были движения. Поэтому в рассмотренном примере в таблице результата не оказалось записей с комбинацией Пульт VH и Фили-2. Если же в выходной таблице результата должна быть информация по остаткам номенклатурных позиций на складах, несмотря на наличие или отсутствие движений внутри периода между НачалоПериода и КонецПериода, то виртуальная таблица остатков и оборотов может быть построена следующим образом (листинг 3.72). Листинг 3.72. Пример получения остатков и оборотов регистра накопления ВЫБРАТЬ ТоварыНаСкладахОстаткиИОбороты.Период, ТоварыНаСкладахОстаткиИОбороты.Номенклатура, ТоварыНаСкладахОстаткиИОбороты.Склад, ТоварыНаСкладахОстаткиИОбороты.КоличествоНачальныйОстаток, ТоварыНаСкладахОстаткиИОбороты.КоличествоКонечныйОстаток, ТоварыНаСкладахОстаткиИОбороты.КоличествоОборот, ТоварыНаСкладахОстаткиИОбороты.КоличествоПриход, ТоварыНаСкладахОстаткиИОбороты.КоличествоРасход ИЗ РегистрНакопления.ТоварыНаСкладах.ОстаткиИОбороты(&НачалоПериода, &КонецПериода, День, , ) КАК ТоварыНаСкладахОстаткиИОбороты АВТОУПОРЯДОЧИВАНИЕ Если значения параметров установлены так же (см. листинг 3.71), то благодаря тому, что параметр МетодДополнения имеет по умолчанию значение ДвиженияИГраницыПериода, получается следующий результат (табл. 3.72). Для комбинаций измерений, по которым были начальные остатки на момент НачалоПериода, добавились записи, содержащие значения этих остатков и в поле КоличествоНачальныйОстаток, и в поле КоличествоКонечныйОстаток, до записей, содержащих данные по движениям. Для комбинаций измерений, по которым были конечные остатки на момент КонецПериода, добавились записи, содержащие значения этих остатков и в поле КоличествоНачальныйОстаток, и в поле КоличествоКонечныйОстаток, после записей, содержащих записи по движениям. 359 Глава 3. Реализация задач учета движения средств КоличествоПриход КоличествоРасход Остаток на границу «КонецПериода» Остаток на границу «НачалоПериода» Остаток на границу «КонецПериода» КоличествоОборот Остаток на границу «КонецПериода» КоличествоКонечныйОстаток Остаток на границу «КонецПериода» КоличествоНачальныйОстаток Остаток на границу «КонецПериода» 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 Склад Остаток на границу «НачалоПериода» Номенклатура Период Таблица 3.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 В результате цель достигнута: в таблицу результата запроса попадают записи также и по тем комбинациям значений измерений, по которым не было движений во временном интервале построения виртуальной таблицы остатков и оборотов. С какой скоростью система получает результат виртуальной таблицы остатков и оборотов? 360 Реализация прикладных задач в системе «1С:Предприятие 8.2» Исходя из приведенного выше описания алгоритма, можно сказать, что в общем случае скорость построения виртуальной таблицы остатков и оборотов зависит от периода рассчитанных итогов (для расчета начальных остатков) и от количества записей движений регистра, попавших в требуемый период построения таблицы, а больше всего от дополнительной периодичности разворота результатов, указанной в параметрах виртуальной таблицы. От количества записей за другие периоды (например, за прошлые годы) скорость выполнения этой задачи не зависит. Для обеспечения максимальной скорости выполнения запроса по этой виртуальной таблице также важно правильное применение отборов по измерениям. Правила применения таких отборов описаны в разделе «Применение отборов в запросах, использующих виртуальные таблицы регистров накопления» на стр. 374. Особенности использования периодов и моментов времени при получении остатков и оборотов По умолчанию при использовании виртуальной таблицы остатков и оборотов итоги по остаткам и оборотам рассчитываются, включая граничные периоды (рис. 3.46). Рис. 3.46. Получение остатков и оборотов, включая границы периода Поэтому все особенности использования параметров НачалоПериода и КонецПериода аналогичны виртуальной таблице оборотов (см. раздел «Особенности использования периодов и моментов времени при получении оборотов» на стр. 340. Глава 3. Реализация задач учета движения средств 361 Расчет итогов по полям остатков при использовании виртуальной таблицы остатков и оборотов Отдельного рассмотрения заслуживает вопрос расчета итогов по полям остатков, поскольку с прикладной точки зрения не всегда они могут быть получены простым суммированием, а должны рассчитываться с привлечением специального алгоритма. Для задействования этого алгоритма система прежде всего должна распознать необходимость специфичного расчета итогов по полям остатков. Например, для запроса, текст которого приведен в листинге 3.73, итоги будут получены простым суммированием данных соответствующих записей. Листинг 3.73. Пример получения остатков и оборотов регистра накопления ВЫБРАТЬ ТоварыНаСкладахОстаткиИОбороты.Номенклатура КАК Номенклатура, ТоварыНаСкладахОстаткиИОбороты.Склад, ТоварыНаСкладахОстаткиИОбороты.КоличествоНачальныйОстаток КАК КоличествоНачальныйОстаток, ТоварыНаСкладахОстаткиИОбороты.КоличествоКонечныйОстаток КАК КоличествоКонечныйОстаток, ТоварыНаСкладахОстаткиИОбороты.КоличествоОборот КАК КоличествоОборот, ТоварыНаСкладахОстаткиИОбороты.КоличествоПриход КАК КоличествоПриход, ТоварыНаСкладахОстаткиИОбороты.КоличествоРасход КАК КоличествоРасход ИЗ РегистрНакопления.ТоварыНаСкладах.ОстаткиИОбороты(&НачалоПериода, &КонецПериода, , Движения, ) КАК ТоварыНаСкладахОстаткиИОбороты ИТОГИ СУММА(КоличествоНачальныйОстаток), СУММА(КоличествоКонечныйОстаток), СУММА(КоличествоОборот), СУММА(КоличествоПриход), СУММА(КоличествоРасход) ПО Номенклатура АВТОУПОРЯДОЧИВАНИЕ Предположим, что таблица движений регистра ТоварыНаСкладах заполнена так, как показано в табл. 3.73. 362 Реализация прикладных задач в системе «1С:Предприятие 8.2» Приход 1 Приход 2 Приход 1 Приход 1 Приход 1 Расход 1 Приход 1 Приход 1 Расход 1 Приход Количество 1 Истина Пульт PW Истина Пульт VH Истина Пульт VH Истина Пульт PW Истина Пульт PW Ложь Пульт VH Истина Пульт VH Истина Пульт PW Истина Пульт PW Истина Пульт PW Истина Пульт PW Склад Приход Номенклатура 1 Активность ПоступлениеТоваров № 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троки Период Таблица 3.73 Таблица движений регистра накопления Главный 1 Фили-2 10 Главный 10 Главный 7 Розничный 3 Фили-2 5 Главный 9 Фили-2 1 Фили-2 2 Фили-2 1 Фили-2 2 Если параметры запроса установлены так, как показано в листинге 3.74, результат выполнения запроса будет иметь вид, представленный в табл. 3.74. Листинг 3.74. Пример установки параметров запроса Запрос.УстановитьПараметр("НачалоПериода", '20100501'); Запрос.УстановитьПараметр("КонецПериода", КонецДня('20100531')); Глава 3. Реализация задач учета движения средств КоличествоОборот КоличествоПриход КоличествоРасход Главный КоличествоКонечныйОстаток Главный Розничный Фили-2 КоличествоНачальныйОстаток Пульт PW Пульт PW Пульт PW Пульт PW Пульт VH Пульт VH Склад Номенклатура Таблица 3.74. Результат выполнения запроса 1 1 0 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 Теперь изменим текст запроса так, как показано в листинге 3.75. Листинг 3.75. Пример получения остатков и оборотов регистра накопления ВЫБРАТЬ ТоварыНаСкладахОстаткиИОбороты.Номенклатура КАК Номенклатура, ТоварыНаСкладахОстаткиИОбороты.Период КАК Период, ТоварыНаСкладахОстаткиИОбороты.Склад, ТоварыНаСкладахОстаткиИОбороты.КоличествоНачальныйОстаток КАК КоличествоНачальныйОстаток, ТоварыНаСкладахОстаткиИОбороты.КоличествоКонечныйОстаток КАК КоличествоКонечныйОстаток, ТоварыНаСкладахОстаткиИОбороты.КоличествоОборот КАК КоличествоОборот, ТоварыНаСкладахОстаткиИОбороты.КоличествоПриход КАК КоличествоПриход, ТоварыНаСкладахОстаткиИОбороты.КоличествоРасход КАК КоличествоРасход ИЗ РегистрНакопления.ТоварыНаСкладах.ОстаткиИОбороты(&НачалоПериода, &КонецПериода, День, ДвиженияИГраницыПериода, ) КАК ТоварыНаСкладахОстаткиИОбороты ИТОГИ СУММА(КоличествоНачальныйОстаток), СУММА(КоличествоКонечныйОстаток), СУММА(КоличествоОборот), СУММА(КоличествоПриход), СУММА(КоличествоРасход) ПО Номенклатура АВТОУПОРЯДОЧИВАНИЕ 363 364 Реализация прикладных задач в системе «1С:Предприятие 8.2» В этом случае при расчете итогов остатков система будет действовать по следующему алгоритму: ■ Исходные записи временной промежуточной таблицы (записанной в базе данных в процессе выполнения алгоритма построения виртуальной таблицы остатков и оборотов) упорядочиваются по полям первого уровня (в нашем случае – Номенклатура и Склад), далее – хронологически. ■ При обходе упорядоченных записей: □ первые записи по каждой комбинации полей первого уровня используются для суммирования начального остатка; □ последние записи по каждой комбинации полей первого уровня используются для суммирования конечного остатка. Если использовать тот же вариант установки значений параметров виртуальной таблицы остатков и оборотов (см. листинг 3.74), то таблица результата будет выглядеть уже по-другому (табл. 3.75). Период КоличествоНачальныйОстаток КоличествоКонечный Остаток КоличествоОборот КоличествоПриход КоличествоРасход 1 15 14 15 1 Пульт PW Пульт PW Пульт PW Пульт PW Пульт PW Пульт PW Пульт PW Пульт VH Главный Главный Главный Розничный Розничный Фили-2 Фили-2 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 1 1 8 0 3 0 4 10 1 8 8 3 3 4 4 11 0 7 0 3 0 4 0 1 0 7 0 3 0 5 0 10 0 0 0 0 0 1 0 9 Пульт VH Пульт VH Пульт VH Пульт VH Пульт VH Главный Главный Главный Фили-2 Фили-2 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 0 10 1 10 10 10 1 1 10 10 10 -9 0 0 0 10 0 0 0 0 0 9 0 0 0 Номенклатура Склад Таблица 3.75. Результат выполнения запроса Пульт PW Глава 3. Реализация задач учета движения средств 365 Серым фоном отмечены те поля, которые были просуммированы при получении итогов полей остатков по номенклатуре. Аналогичным образом система поступила бы, если бы группировок итогов было больше. Главное, что они перечислены в запросе до группировки итогов Период. Если среди итогов есть группировка Период (листинг 3.76), алгоритм расчета полей остатков еще более сложный. Листинг 3.76. Пример получения остатков и оборотов регистра накопления ВЫБРАТЬ ТоварыНаСкладахОстаткиИОбороты.Номенклатура КАК Номенклатура, ТоварыНаСкладахОстаткиИОбороты.Период КАК Период, ТоварыНаСкладахОстаткиИОбороты.Склад, ТоварыНаСкладахОстаткиИОбороты.КоличествоНачальныйОстаток КАК КоличествоНачальныйОстаток, ТоварыНаСкладахОстаткиИОбороты.КоличествоКонечныйОстаток КАК КоличествоКонечныйОстаток, ТоварыНаСкладахОстаткиИОбороты.КоличествоОборот КАК КоличествоОборот, ТоварыНаСкладахОстаткиИОбороты.КоличествоПриход КАК КоличествоПриход, ТоварыНаСкладахОстаткиИОбороты.КоличествоРасход КАК КоличествоРасход ИЗ РегистрНакопления.ТоварыНаСкладах.ОстаткиИОбороты(&НачалоПериода, &КонецПериода, День, ДвиженияИГраницыПериода, ) КАК ТоварыНаСкладахОстаткиИОбороты ИТОГИ СУММА(КоличествоНачальныйОстаток), СУММА(КоличествоКонечныйОстаток), СУММА(КоличествоОборот), СУММА(КоличествоПриход), СУММА(КоличествоРасход) ПО Номенклатура, Период АВТОУПОРЯДОЧИВАНИЕ Для приведенного примера при расчете полей остатков будут выполняться следующие действия: ■ Расчет итогов для группировки (группировок) перед группировкой Период (в нашем примере это расчет для группировки Номенклатура) выполняется по тому же алгоритму, что в предыдущем примере. ■ Расчет итогов для группировки Период: □ Исходные записи временной промежуточной таблицы остатков и оборотов (записанной в базе данных в процессе выполнения алгоритма построения виртуальной таблицы остатков и оборотов) упорядочиваются по полям, использованным в группировках выше (в нашем случае это группировка Номенклатура), затем хронологически (по полю Период), далее – по оставшимся полям первого уровня (в нашем случае Склад). 366 Реализация прикладных задач в системе «1С:Предприятие 8.2» □ Внутри группировки первого уровня (Номенклатура) для каждого значения группировки Период рассчитываются значения полей остатков посредством обходов записей и суммирования значений нужных полей: ○ Для начального остатка: обход всех записей, у которых дата больше или равна значению даты группировки Период, начиная от этой даты (то есть «вниз»). При обходе выполняется суммирование значений поля НачальныйОстаток для записей, содержащих различные (ранее не встреченные в процессе обхода) комбинации значений полей первого уровня (в нашем примере Номенклатура и Склад). ○ Для конечного остатка: обход всех записей, у которых дата меньше или равна значению даты группировки Период, начиная от этой даты (то есть «вверх»). При обходе выполняется суммирование значений поля КонечныйОстаток для записей, содержащих различные (ранее не встреченные в процессе обхода) комбинации значений полей первого уровня (в нашем примере Номенклатура и Склад). Для наглядности работы алгоритма расчета итогов остатков группировки Период рассмотрим фрагмент заполнения таблицы результата. Пусть заполнение регистра будет тем же, что рассматривали раньше (см. табл. 3.73), с теми же значениями параметров НачалоПериода и КонецПериода (см. листинг 3.74). Расчет промежуточных итогов остатков товара Пульт PW для значения периода 17.05.2010 00:00:00 будет произведен по следующей схеме (табл. 3.76). 1 1 Пульт PW 13.05.2010 00:00:00 Главный 1 8 Пульт PW 17.05.2010 00:00:00 8 11 0 8 3 0 4 Упорядоченные записи из временной таблицы остатков и оборотов 3 8 3 4 4 Пульт PW Пульт PW Пульт PW Пульт PW Пульт PW 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 Склад КоличествоКонечныйОстаток Упорядоченные записи из временной таблицы остатков и оборотов Рассчитываемая запись итога по периоду Период Пульт PW 01.05.2010 00:00:00 Главный Номенклатура КоличествоНачальныйОстаток Таблица 3.76. Результат расчета промежуточных итогов Розничный Главный Розничный Фили-2 Фили-2 Глава 3. Реализация задач учета движения средств 367 Итоги по номенклатурной позиции Пульт 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 КоличествоОборот КоличествоПриход КоличествоРасход КоличествоНачальныйОстаток КоличествоКонечныйОстаток Склад Период Номенклатура Таблица 3.77. Результат выполнения запроса 1 15 14 15 1 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 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 Фили-2 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 0 0 0 Фили-2 10 10 0 0 0 Главный 1 368 Реализация прикладных задач в системе «1С:Предприятие 8.2» Серым фоном отмечены те поля, которые были просуммированы при получении итогов. В целом таблица результата запроса будет выглядеть следующим образом (табл. 3.77). Обратите внимание: «особыми» алгоритмами были рассчитаны только поля остатков, поля же оборотов рассчитываются простым суммированием в рамках требуемых группировок. Для более сложных случаев, когда среди группировочных полей итогов есть и предшествующие полю Период, и находящиеся после него, алгоритм расчета итогов включает в себя следующие этапы: ■ расчет итогов для группировок, предшествующих группировке Период; ■ расчет итогов для группировки Период; ■ расчет итогов для группировок после группировки Период; производится как для обычных полей, то есть простым суммированием. Хотелось бы еще раз подчеркнуть, что в любом случае применение этих «особых» алгоритмов происходит уже после того, как виртуальная таблица остатков и оборотов была получена и сохранена во временной таблице базы данных. Рассмотрим еще ряд особенностей различных вариантов использования полей остатков, когда система будет применять еще более сложные алгоритмы. Получение итогов по одному полю остатков Для того чтобы запрос мог рассчитать итоги по полям остатка, необходимо чтобы в запросе получались оба значения остатка за период (начальный и конечный). Если в запросе получается только один остаток и по нему ведется расчет итога, программа неявно добавит в запрос получение данных из информационной базы поле парного остатка. Например, в случае выполнения запроса, представленного в листинге 3.77, будет неявно добавлено поле ТоварыНаСкладахОстаткиИОбороты.КоличествоКонечныйОстаток, потому что иначе возникли бы сложности с расчетом итогов последних периодов, если в них не было движений. Листинг 3.77. Пример получения остатков и оборотов регистра накопления ВЫБРАТЬ ТоварыНаСкладахОстаткиИОбороты.Номенклатура КАК Номенклатура, ТоварыНаСкладахОстаткиИОбороты.Период КАК Период, ТоварыНаСкладахОстаткиИОбороты.Склад, ТоварыНаСкладахОстаткиИОбороты.КоличествоНачальныйОстаток КАК КоличествоНачальныйОстаток, ТоварыНаСкладахОстаткиИОбороты.КоличествоОборот КАК КоличествоОборот, ТоварыНаСкладахОстаткиИОбороты.КоличествоПриход КАК КоличествоПриход, Глава 3. Реализация задач учета движения средств ИЗ 369 ТоварыНаСкладахОстаткиИОбороты.КоличествоРасход КАК КоличествоРасход РегистрНакопления.ТоварыНаСкладах.ОстаткиИОбороты(&НачалоПериода, &КонецПериода, День, ДвиженияИГраницыПериода, ) КАК ТоварыНаСкладахОстаткиИОбороты ИТОГИ СУММА(КоличествоНачальныйОстаток), СУММА(КоличествоОборот), СУММА(КоличествоПриход), СУММА(КоличествоРасход) ПО Номенклатура, Период АВТОУПОРЯДОЧИВАНИЕ Аналогичным образом система поступает и в ситуации, когда поле-остаток используется в выражении (листинг 3.78). Листинг 3.78. Пример получения остатков и оборотов регистра накопления ВЫБРАТЬ ТоварыНаСкладахОстаткиИОбороты.Номенклатура КАК Номенклатура, ТоварыНаСкладахОстаткиИОбороты.Период КАК Период, ТоварыНаСкладахОстаткиИОбороты.Склад, ТоварыНаСкладахОстаткиИОбороты.КоличествоКонечныйОстаток * ТоварыНаСкладахОстаткиИОбороты.Номенклатура.ЗакупочнаяЦена КАК СуммаКонечныйОстаток, ТоварыНаСкладахОстаткиИОбороты.КоличествоОборот * ТоварыНаСкладахОстаткиИОбороты.Номенклатура.ЗакупочнаяЦена КАК СуммаОборот, ТоварыНаСкладахОстаткиИОбороты.КоличествоПриход * ТоварыНаСкладахОстаткиИОбороты.Номенклатура.ЗакупочнаяЦена КАК СуммаПриход, ТоварыНаСкладахОстаткиИОбороты.КоличествоРасход * ТоварыНаСкладахОстаткиИОбороты.Номенклатура.ЗакупочнаяЦена КАК СуммаРасход ИЗ РегистрНакопления.ТоварыНаСкладах.ОстаткиИОбороты(&НачалоПериода, &КонецПериода, День, ДвиженияИГраницыПериода,) КАК ТоварыНаСкладахОстаткиИОбороты ИТОГИ СУММА(СуммаКонечныйОстаток), СУММА(СуммаОборот), СУММА(СуммаПриход), СУММА(СуммаРасход) ПО Номенклатура, Период АВТОУПОРЯДОЧИВАНИЕ 370 Реализация прикладных задач в системе «1С:Предприятие 8.2» В этом случае будет неявно добавлено поле ТоварыНаСкладахОстаткиИОбороты.КоличествоНачальныйОстаток * ТоварыНаСкладахОстаткиИОбороты.Номенклатура.ЗакупочнаяЦена. Получение итогов по регистратору или номеру строки Поле Период записей, подчиненных одному регистратору, в общем случае может иметь неодинаковые значения. Поэтому для определения момента времени, начиная с которого запись влияет на рассчитываемые итоги, сначала учитывается значение поля Период записи, потом Регистратор, а потом – НомерСтроки. В результате из-за того, что регистратор, по сути, является уточнением периода, при расчете итогов по регистратору необходимо иметь в виду, что получать итоги по регистратору можно только внутри группировки Период. Если получить итоги по регистратору до получения итогов по периоду, они могут оказаться некорректными! Аналогично итоги по номеру строки можно получать только внутри группировки по периоду и регистратору. Получение итогов остатков в комбинации с другими полями В ситуациях, когда выходные поля запроса получаются посредством выражения, содержащего начальный или конечный остаток, действия системы аналогичны. В этом случае запрос будет манипулировать значениями, вычисленными согласно описанным правилам. То есть значение поля, представленного в листинге 3.79, будет являться произведением конечного остатка и закупочной цены. Листинг 3.79. Поле выборки запроса ТоварыНаСкладахОстаткиИОбороты.КоличествоКонечныйОстаток * ТоварыНаСкладахОстаткиИОбороты.Номенклатура.ЗакупочнаяЦена КАК СуммаКонечныйОстаток, Но если в составе выражения используется более одного поля начального или конечного остатка, то итоги по таким полям получаются уже простым суммированием. Рассмотрим запрос, представленный в листинге 3.80. Глава 3. Реализация задач учета движения средств 371 Листинг 3.80. Пример получения остатков и оборотов регистра накопления ВЫБРАТЬ ТоварыНаСкладахОстаткиИОбороты.Номенклатура КАК Номенклатура, ТоварыНаСкладахОстаткиИОбороты.Период КАК Период, ТоварыНаСкладахОстаткиИОбороты.Склад, ТоварыНаСкладахОстаткиИОбороты.КоличествоНачальныйОстаток КАК КоличествоНачальныйОстаток, ТоварыНаСкладахОстаткиИОбороты.КоличествоКонечныйОстаток КАК КоличествоКонечныйОстаток, ТоварыНаСкладахОстаткиИОбороты.КоличествоКонечныйОстаток – ТоварыНаСкладахОстаткиИОбороты.КоличествоНачальныйОстаток КАК Разница ТоварыНаСкладахОстаткиИОбороты.КоличествоКонечныйОстаток * ТоварыНаСкладахОстаткиИОбороты.КоличествоНачальныйОстаток КАК Произведение ИЗ РегистрНакопления.ТоварыНаСкладах.ОстаткиИОбороты(&НачалоПериода, &КонецПериода, День, ДвиженияИГраницыПериода, ) КАК ТоварыНаСкладахОстаткиИОбороты ИТОГИ СУММА(КоличествоНачальныйОстаток), СУММА(КоличествоКонечныйОстаток), СУММА(Разница), СУММА(Произведение) ПО Номенклатура, Период АВТОУПОРЯДОЧИВАНИЕ Если установить параметры запроса так, как показано в листинге 3.81, то результат выполнения запроса будет выглядеть так, как показано в табл. 3.78. Листинг 3.81. Установка параметров запроса Запрос.УстановитьПараметр("НачалоПериода", '20100501'); Запрос.УстановитьПараметр("КонецПериода", КонецДня('20100531')); 372 Реализация прикладных задач в системе «1С:Предприятие 8.2» КоличествоКонечныйОстаток Разница Произведение 11 98 1 0 1 Главный 1 1 1 8 0 7 1 8 13.05.2010 00:00:00 17.05.2010 00:00:00 Главный 1 8 8 11 7 3 8 0 Пульт PW Пульт PW 17.05.2010 00:00:00 31.05.2010 00:00:00 Розничный 0 11 3 15 3 4 0 89 Пульт PW Пульт PW Пульт PW Пульт PW Пульт VH 31.05.2010 00:00:00 31.05.2010 00:00:00 31.05.2010 00:00:00 31.05.2010 00:00:00 Главный Розничный Фили-2 Фили-2 8 3 0 4 10 8 3 4 4 11 0 0 4 0 1 64 9 0 16 211 Пульт VH 01.05.2010 00:00:00 10 10 0 100 Пульт VH Пульт VH 01.05.2010 00:00:00 13.05.2010 00:00:00 Фили-2 10 10 10 20 0 10 100 0 Пульт VH Пульт VH 13.05.2010 00:00:00 27.05.2010 00:00:00 Главный 0 20 10 11 10 -9 0 10 Пульт VH Пульт VH 27.05.2010 00:00:00 31.05.2010 00:00:00 Главный 10 11 1 11 -9 0 10 101 Пульт VH Пульт VH 31.05.2010 00:00:00 31.05.2010 00:00:00 Главный Фили-2 1 10 1 10 0 0 1 100 Склад 15 1 Период 1 Номенклатура КоличествоНачальныйОстаток Таблица 3.78. Результат выполнения запроса Пульт PW Пульт PW 01.05.2010 00:00:00 Пульт PW Пульт PW 01.05.2010 00:00:00 13.05.2010 00:00:00 Пульт PW Пульт PW Глава 3. Реализация задач учета движения средств 373 Использование соединений с таблицей остатков и оборотов В случае применения конструкции ИТОГИ ПО для запросов, включающих в себя соединения виртуальной таблицы остатков и оборотов с другими таблицами (например, с основной таблицей регистра), необходимо учитывать влияние наличия всех возможных комбинаций значений полей связанных таблиц (удовлетворяющих условиям соединения) на вышеописанные алгоритмы расчета полей итогов. Иначе легко получить «удивительные» с прикладной точки зрения результаты запросов. Например, рассмотрим запрос, текст которого представлен в листинге 3.82. Листинг 3.82. Пример получения остатков и оборотов регистра накопления ВЫБРАТЬ ТоварыНаСкладахОстаткиИОбороты.Номенклатура КАК Номенклатура, ТоварыНаСкладахОстаткиИОбороты.КоличествоНачальныйОстаток КАК КоличествоНачальныйОстаток, ТоварыНаСкладахОстаткиИОбороты.КоличествоПриход КАК КоличествоПриход, ТоварыНаСкладахОстаткиИОбороты.КоличествоРасход КАК КоличествоРасход, ТоварыНаСкладахОстаткиИОбороты.КоличествоКонечныйОстаток КАК КоличествоКонечныйОстаток, ТоварыНаСкладах.ВидОперации КАК ВидОперации ИЗ РегистрНакопления.ТоварыНаСкладах.ОстаткиИОбороты КАК ТоварыНаСкладахОстаткиИОбороты ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.ТоварыНаСкладах КАК ТоварыНаСкладах ПО ТоварыНаСкладахОстаткиИОбороты.Номенклатура = ТоварыНаСкладах.Номенклатура ИТОГИ СУММА(КоличествоНачальныйОстаток), СУММА(КоличествоПриход), СУММА(КоличествоРасход), СУММА(КоличествоКонечныйОстаток) ПО Номенклатура, ВидОперации В результате данные по остаткам и оборотам каждой номенклатурной позиции могут быть завышены в несколько раз или даже десятков тысяч раз в зависимости от того, сколько записей с этой номенклатурной позицией присутствует в таблице движений регистра и как они упорядочиваются по хронологии внутри вышестоящих группировок. 374 Реализация прикладных задач в системе «1С:Предприятие 8.2» Применение отборов в запросах, использующих виртуальные таблицы регистров накопления Для обеспечения максимальной скорости выполнения запросов важно правильно применять условия отборов. Например, для получения остатков по отдельной номенклатурной позиции текст запроса может выглядеть так, как показано в листинге 3.83 или в листинге 3.84. Листинг 3.83. Пример использования отбора в виртуальной таблице ВЫБРАТЬ ТоварыНаСкладахОстатки.Номенклатура КАК Номенклатура, ТоварыНаСкладахОстатки.Склад КАК Склад, ТоварыНаСкладахОстатки.КоличествоОстаток КАК КоличествоОстаток ИЗ РегистрНакопления.ТоварыНаСкладах.Остатки(&Период, Номенклатура = &НоменклатураОтбора) КАК ТоварыНаСкладахОстатки Листинг 3.84. Пример неэффективного запроса, использующего виртуальную таблицу остатков ВЫБРАТЬ ТоварыНаСкладахОстатки.Номенклатура КАК Номенклатура, ТоварыНаСкладахОстатки.Склад КАК Склад, ТоварыНаСкладахОстатки.КоличествоОстаток КАК КоличествоОстаток ИЗ РегистрНакопления.ТоварыНаСкладах.Остатки(&Период, ) КАК ТоварыНаСкладахОстатки ГДЕ ТоварыНаСкладахОстатки.Номенклатура = &НоменклатураОтбора По сравнению с первым вариантом второй является неэффективным по скорости исполнения, поскольку сначала по всем номенклатурным позициям будут проведены необходимые расчеты и получена виртуальная таблица остатков, а отбор будет использован уже после. Условия построения виртуальной таблицы могут реализовываться не только по равенству значений измерений, но и по вхождению их в массив или список значений (листинг 3.85). Листинг 3.85. Пример получения остатков регистра накопления ВЫБРАТЬ ТоварыНаСкладахОстатки.Номенклатура КАК Номенклатура, ТоварыНаСкладахОстатки.Склад КАК Склад, ТоварыНаСкладахОстатки.КоличествоОстаток КАК КоличествоОстаток ИЗ РегистрНакопления.ТоварыНаСкладах.Остатки(&Период, Номенклатура В (&МассивНоменклатурныхПозиций)) КАК ТоварыНаСкладахОстатки Глава 3. Реализация задач учета движения средств 375 Также может использоваться условие вхождения в таблицу результата вложенного запроса. Например, если при проведении документа РеализацияТоваров требуется получить данные о количестве товара в самом документе и в остатках регистра ТоварыНаСкладах на момент проведения документа, то для быстрого выполнения этой операции виртуальную таблицу остатков лучше строить только по тем номенклатурным позициям и тому складу, которые указаны в документе (листинг 3.86). Листинг 3.86. Пример получения остатков регистра накопления ВЫБРАТЬ ТаблицаДокумента.Номенклатура, СУММА(ТаблицаДокумента.Количество) КАК Количество, ТоварыНаСкладахОстатки.КоличествоОстаток, СУММА(ТаблицаДокумента.Сумма) КАК Сумма ИЗ Документ.РеализацияТоваров.Состав КАК ТаблицаДокумента ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.ТоварыНаСкладах.Остатки(&Момент, Номенклатура В (ВЫБРАТЬ РАЗЛИЧНЫЕ РеализацияТоваровТовары.Номенклатура ИЗ Документ.РеализацияТоваров.Состав КАК РеализацияТоваровТовары ГДЕ РеализацияТоваровТовары.Ссылка = &ТекущийДокумент) И Склад = &Склад) КАК ТоварыНаСкладахОстатки ПО ТаблицаДокумента.Номенклатура = ТоварыНаСкладахОстатки.Номенклатура ГДЕ ТаблицаДокумента.Ссылка = &ТекущийДокумент СГРУППИРОВАТЬ ПО ТаблицаДокумента.Номенклатура, ТоварыНаСкладахОстатки.КоличествоОстаток Кроме того, условие построения виртуальной таблицы может быть по значениям полей, подчиненных полям измерений (листинг 3.87). 376 Реализация прикладных задач в системе «1С:Предприятие 8.2» Листинг 3.87. Пример получения остатков регистра накопления ВЫБРАТЬ ТоварыНаСкладахОстатки.Номенклатура КАК Номенклатура, ТоварыНаСкладахОстатки.Склад КАК Склад, ТоварыНаСкладахОстатки.КоличествоОстаток КАК КоличествоОстаток ИЗ РегистрНакопления.ТоварыНаСкладах.Остатки(&Период, Номенклатура.ЗакупочнаяЦена > &ПороговаяЦена) КАК ТоварыНаСкладахОстатки Однако необходимо учитывать, что подобные операции «разыменования» реализуются за счет неявных дополнительных соединений с соответствующими таблицами. В данном примере в момент построения виртуальной таблицы выполняется левое соединение с таблицей справочника. Наибольшего эффекта увеличения скорости построения виртуальных таблиц за счет применения параметра условия можно добиться в том случае, если условия накладываются на первые измерения, потом вторые и так далее. В принципе сам порядок описания условий не важен, важен порядок измерений, на которые эти условия накладываются. Тогда система сможет эффективно применять индексы при выполнении запроса. В вышеописанных примерах, если не применять условие отбора по первому измерению Номенклатура, а применить условие отбора по измерению Склад (листинг 3.88), для получения данных таблицы итогов система сможет применить индекс Период + Номенклатура + Склад, а из таблицы движений регистра данные будут взяты при помощи индекса Период + Регистратор + НомерСтроки. То есть произойдет отбор всех записей соответствующего периода из таблиц регистра. А уже просматривая эти записи, система сможет отсечь из рассмотрений записи по ненужным складам. Поскольку для регистра накопления обычной является ситуация, когда количество записей движений на порядок больше количества записей итогов, для повышения скорости построения виртуальной таблицы «бороться» прежде всего нужно с движениями по «лишним» складам. Листинг 3.88. Пример получения остатков регистра накопления ВЫБРАТЬ ТоварыНаСкладахОстатки.Номенклатура КАК Номенклатура, ТоварыНаСкладахОстатки.Склад КАК Склад, ТоварыНаСкладахОстатки.КоличествоОстаток КАК КоличествоОстаток ИЗ РегистрНакопления.ТоварыНаСкладах.Остатки(&Период, Склад = &СкладОтбора) КАК ТоварыНаСкладахОстатки Глава 3. Реализация задач учета движения средств 377 Поэтому изначально, описывая данные регистра как объекта конфигурации, можно указать индексирование измерения Склад. Тогда система сможет использовать данные не только индекса Период + Регистратор + НомерСтроки, но и индекса Склад + Период + Регистратор + НомерСтроки. Необходимо заметить, что порядок применения или неприменения тех или иных индексных таблиц в каждом конкретном случае исполнения конкретного запроса берут на себя механизмы СУБД, отвечающие за доступ к информации. Однако оптимальный порядок следования измерений в структуре регистра и индексирование полей регистра помогают СУБД чаще принимать верные с точки зрения эффективности решения. Когда следует использовать запрос . вместо объектной модели обращения . при получении данных регистров накопления В случаях простейших обращений к информации базы данных удобство и быстродействие использования табличной и объектной модели чтения одинаковы. Дело в том, что запрос, написанный на языке системы «1С:Предприятие», и использование соответствующего метода, реализуются платформой посредством «перевода» этих обращений в язык запросов СУБД, зачастую совершенно (или почти) одинаковых. Исключение составляют ситуации использования механизма обращения к динамическим данным. Посредством этого механизма чтение информации осуществляется не полностью в момент обращения, а блоками. Более подробно использование данного механизма описано ниже, в разделе «Работа с регистрами при отображении динамических данных» на стр. 379. В данном же разделе обращается внимание на задачи, которые можно решить эффективно только посредством запросов. К ним относятся: ■ гибкое применение отборов и группировок; ■ соединение с информацией других объектов; ■ применение разграничения доступа на уровне записей. В случае применения методов Остатки() и Обороты() возможно применение отборов для измерений на равенство неким значениям. Более сложные отборы необходимо реализовать с помощью установки значений параметров соответствующих виртуальных таблиц запросов. Это относится, например, к условию вхождения значений измерений в определенную группу; условию неравенства некоему значению; условию превышения некоего значения (например, если измерение имеет тип Дата); условию равенства двум значениям (логическое ИЛИ) и т. д. 378 Реализация прикладных задач в системе «1С:Предприятие 8.2» В случае необходимости соединения данных нескольких объектов применение запросов также является более эффективным. Например, задачу контроля остатка для каждой номенклатурной позиции при проведении документа реализации товаров можно решить как с использованием запроса, так и с использованием объектной модели. Если рассматривать запрос, использующий левое соединение (листинг 3.89), то результатом его работы будет таблица, содержащая колонки КоличествоВДокументе и КоличествоВОстаткеРегистра. Листинг 3.89. Пример получения остатков регистра накопления с помощью запроса ВЫБРАТЬ ТаблицаДокумента.Номенклатура, СУММА(ТаблицаДокумента.Количество) КАК КоличествоВДокументе, ТоварыНаСкладахОстатки.КоличествоОстаток КАК КоличествоВОстаткеРегистра ИЗ Документ.РеализацияТоваров.Состав КАК ТаблицаДокумента ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.ТоварыНаСкладах.Остатки( , Номенклатура В (ВЫБРАТЬ РАЗЛИЧНЫЕ РеализацияТоваровТовары.Номенклатура ИЗ Документ.РеализацияТоваров.Состав КАК РеализацияТоваровТовары ГДЕ РеализацияТоваровТовары.Ссылка = &ТекущийДокумент) И Склад = &Склад) КАК ТоварыНаСкладахОстатки ПО ТаблицаДокумента.Номенклатура = ТоварыНаСкладахОстатки.Номенклатура ГДЕ ТаблицаДокумента.Ссылка = &ТекущийДокумент СГРУППИРОВАТЬ ПО ТаблицаДокумента.Номенклатура, ТоварыНаСкладахОстатки.КоличествоОстаток В данном случае виртуальная таблица остатков будет построена только по нужным товарным позициям (указанным в табличной части Состав проводимого документа), далее полученный результат соединен с записями табличной части проводимого документа. Результирующая таблица будет сгруппирована на случай упоминания одних и тех же товарных позиций в документе более одного раза. Все эти операции будут выполнены в рамках одного запроса обращения к данным базы данных. При использовании объектной модели необходимо будет выгрузить табличную часть Состав документа в таблицу значений. Затем свернуть полученную таблицу значений по колонке Номенклатура (на случай неоднократного упоминания одного и того же товара в табличной части). После этого Глава 3. Реализация задач учета движения средств 379 в цикле перебора строк полученной таблицы значений обращаться к данным регистра методом Остатки(), применяя отбор по значению конкретной номенклатурной позиции. Неэффективность данного подхода проявляется в многократных обращениях к таблицам регистра в базе данных. Модификация использования объектной модели чтения для решения данной задачи, когда метод Остатки() получается не в цикле перебора строк, а до него, также неэффективна, поскольку тогда для функциональности алгоритма придется получать остатки по всем (а не по нужным) номенклатурным позициям, а в цикле перебора товаров документа искать нужные строки в таблице значений остатков. Использование же в данной ситуации запроса позволяет получать данные из таблиц регистра только по нужным значениям измерений, причем в рамках одного обращения к базе данных. Также запросы позволяют использовать при необходимости один из двух режимов получения данных из полей базы данных: ■ получение всех записей; ■ получение только тех записей, на которые у пользователя есть права. Во втором случае в таблице результата запроса будут обработаны только те записи, что разрешены при использовании ограничений доступа на уровне записей. Неразрешенные записи будут проигнорированы. Объектная же техника обращения к информации базы данных выполняется только в режиме получения всех записей. Отдельные вопросы использования регистров накопления Работа с регистрами при отображении . динамических данных Форма списка регистра накопления Для обеспечения динамического просмотра записей регистра в таблице формы предназначен объект ДинамическийСписок. Он осуществляет считывание данных из информационной базы блоками, в процессе навигации пользователя в таблице формы или в процессе обращения к ним из встроенного языка. Это уменьшает время загрузки списка и объем отводимой для него памяти, что позволяет комфортно работать даже с очень большими списками. Например, не возникает задержек при открытии формы 380 Реализация прикладных задач в системе «1С:Предприятие 8.2» (считывается только нужный блок, а не весь список) или при переходе в конец списка (система не обязана считывать все данные регистра, будет считан блок только с нужными) и т. д. С помощью динамического списка построены все формы списка объектов конфигурации. Динамический список формируется путем запроса к основной таблице, указанной в соответствующем свойстве реквизита типа ДинамическийСписок, или путем произвольного запроса к базе данных. Форма списка регистра накопления также содержит основной реквизит типа ДинамическийСписок, который использует систему компоновки данных и позволяет задать группировку, отбор, порядок и условное оформление списка путем установки соответствующих свойств. Обычно далеко не все поля динамического списка используются для отображения в форме. Особенность использования динамического списка в том, что запросом из базы данных считываются значения только тех реквизитов, которые отображаются в форме, причем даже в том случае, если соответствующие им колонки таблицы формы невидимы. То есть система не будет считывать «ненужные» данные из базы данных. Логика проста: если не нужно показывать, то не нужно и считывать, чтобы еще больше сократить время считывания. Но иногда возникают задачи, когда может оказаться необходимым, чтобы объект ДинамическийСписок содержал некоторые колонки, которые не отображаются в таблице формы. Например, при отображении данных регистра накопления ТоварыНаСкладах для некой последующей обработки нужно, чтобы значение поля ВидДвижения динамического списка было доступно для обращения из встроенного языка (например, Элементы.Список.ТекущиеДанные.ВидДвижения). Этого можно добиться при помощи свойства полей динамического списка Использовать всегда. Установив это свойство, можно получить значения реквизитов объекта независимо от того, отображаются они в форме или нет (рис. 3.47). Такого же эффекта можно добиться, если поместить поле динамического списка в состав колонок таблицы и сделать его невидимым. Настройка динамического списка может осуществляться не только в режиме Конфигуратор (палитра свойств Настройка списка – Открыть), но и пользователем в режиме 1С:Предприятие. Это можно реализовать посредством команды Все действия Настроить список… В окне настройки динамического списка можно установить группировку, отбор, сортировку и условное оформление списка. Глава 3. Реализация задач учета движения средств 381 Рис. 3.47. Форма списка регистра накопления На закладке Сортировка изначально присутствует настройка сортировки динамического списка по возрастанию поля Период, так как платформа стандартно упорядочивает записи регистра накопления по этому полю (рис. 3.48). Рис. 3.48. Форма настройки динамического списка 382 Реализация прикладных задач в системе «1С:Предприятие 8.2» Работа с итогами при отображении динамических данных При работе с отображением динамических данных иногда возникает задача отображения и итогов регистров по значениям измерений, взятых из этих динамических данных. Например, при отображении списка справочника Номенклатура необходимо отображать остатки по номенклатурным позициям в отдельной колонке списка. Для решения данной задачи нужно установить свойство ПроизвольныйЗапрос для основного реквизита типа ДинамическийСписок формы списка номенклатуры, данные которого она отображает (рис. 3.49). Рис. 3.49. Установка произвольного запроса для динамического списка Затем, выполнив в строке Настройка списка команду Открыть, следует ввести текст запроса для получения остатков (листинг 3.90). Листинг 3.90. Запрос для определения остатков номенклатуры ВЫБРАТЬ СправочникНоменклатура.Код, СправочникНоменклатура.Наименование, СправочникНоменклатура.ЗакупочнаяЦена, СправочникНоменклатура.ПолноеНаименование, ТоварыНаСкладахОстатки.КоличествоОстаток ИЗ Справочник.Номенклатура КАК СправочникНоменклатура ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.ТоварыНаСкладах.Остатки КАК ТоварыНаСкладахОстатки ПО (ТоварыНаСкладахОстатки.Номенклатура = СправочникНоменклатура.Ссылка) Глава 3. Реализация задач учета движения средств 383 В запросе при помощи левого соединения справочника Номенклатура с виртуальной таблицей остатков регистра ТоварыНаСкладах выбираются остатки по каждой позиции номенклатуры. Таким образом, свойство ТекстЗапроса реквизита формы Список заполняется приведенным выше запросом, и при считывании данных из этого динамического списка платформа вместо автоматической генерации текста запроса к таблице справочника номенклатуры будет использовать указанный запрос. Остается только перенести поле КоличествоОстаток из доступных полей динамического списка в список колонок таблицы формы, отображающей данные этого списка (рис. 3.50). Рис. 3.50. Форма списка справочника «Номенклатура» Если требуется выделять отрицательные остатки номенклатуры в форме списка, то можно воспользоваться свойством расширения поля формы ВыделятьОтрицательные. При установке этого свойства в значение Да отрицательные остатки номенклатуры стандартно будут выделены красным цветом текста. Но если нужно использовать более гибкое выделение строк списка по какому-либо условию, то можно установить свойство УсловноеОформление динамического списка. Поскольку основной реквизит формы списка имеет тип ДинамическийСписок, который использует систему компоновки данных, то можно настроить для него отбор, порядок, группировку и условное оформление. 384 Реализация прикладных задач в системе «1С:Предприятие 8.2» Например, открыв окно настройки динамического списка Список (палитра свойств Настройка списка – Открыть, см. рис. 3.49), зададим условное оформление списка так, чтобы строки номенклатуры с остатком меньше трех выделялись розовым цветом (рис. 3.51). Рис. 3.51. Условное оформление динамического списка В результате список номенклатуры в режиме 1С:Предприятие будет выглядеть следующим образом (рис. 3.52). Рис. 3.52. Форма списка справочника «Номенклатура» В режиме 1С:Предприятие пользователь может также выполнять настройку списка по своему желанию с помощью команды Все действия Настроить список… Пример такого решения приведен в демонстрационной конфигурации «Хранение информации и учет движения средств», которая находится на прилагаемом компакт-диске. Хотелось бы все же отметить, что в решении задач автоматического отображения остатков в отдельной колонке динамического списка быстродействие Глава 3. Реализация задач учета движения средств 385 системы сильно зависит от сложности алгоритма расчета. Ведь, например, при прокрутке списка пользователем система вынуждена будет слишком часто обращаться к базе данных для расчета остатков появляющихся полей. Если быстродействие получается неприемлемым, тогда нужно рассматривать другие варианты отображения остатков, то есть изменять условия задачи. Например, нужно отображать остатки в отдельном поле в форме только для текущей строки таблицы при нажатии соответствующей кнопки. Как еще один вариант решения можно применять элементы механизма динамического просмотра данных, но с дополнительной функциональностью получения остатков. Пример такого решения приведен в демонстрационной конфигурации «Хранение информации и учет движения средств», которая находится на прилагаемом компакт-диске. В форму документа РеализацияТоваров помещена кнопка Подбор, при нажатии которой вызывается форма ФормаПодбораНоменклатуры справочника Номенклатура. Форма подбора номенклатуры включает в себя две таблицы: ДеревоНоменклатуры и ТаблицаПодбора. Таблица ДеревоНоменклатуры отображает данные динамического списка, выбирающего только группы справочника Номенклатура. При выборе пользователем группы в этой таблице в обработчике события Выбор таблица значений ТаблицаПодбора заполняется списком номенклатуры из выбранной группы и соответствующими остатками на складе, указанном в документе (рис. 3.53). Рис. 3.53. Форма подбора номенклатуры 386 Реализация прикладных задач в системе «1С:Предприятие 8.2» Для реализации данной функциональности используется обработчик события Выбор таблицы ДеревоНоменклатуры. В процедуре сначала запросом собираются данные об остатках номенклатуры, входящей в выбранную группу, на нужном складе. Далее таблица, отображаемая нижней таблицей, сначала очищается, потом заполняется необходимой информацией, полученной выборкой из результата запроса (листинг 3.91). Листинг 3.91. Обработчик события «Выбор» таблицы «ДеревоНоменклатуры» Процедура ДеревоНоменклатураВыбор(Элемент, ВыбраннаяСтрока, Колонка, СтандартнаяОбработка) // Выбрать товары группы с остатками Запрос = Новый Запрос; Запрос.Текст = " |ВЫБРАТЬ | Товары.Код, | Товары.Ссылка КАК Номенклатура, | ТоварыНаСкладахОстатки.КоличествоОстаток КАК Остаток |ИЗ | Справочник.Номенклатура КАК Товары | ЛЕВОЕ СОЕДИНЕНИЕ | РегистрНакопления.ТоварыНаСкладах.Остатки( | , | Номенклатура В (ВЫБРАТЬ | Номенклатура.Ссылка | ИЗ | Справочник.Номенклатура КАК Номенклатура | ГДЕ | Номенклатура.Родитель = &Родитель) | И | Склад = &Склад) | КАК ТоварыНаСкладахОстатки | ПО Товары.Ссылка = ТоварыНаСкладахОстатки.Номенклатура |ГДЕ | Товары.Родитель = &Родитель | И (НЕ Товары.ЭтоГруппа)"; // Установить в качестве параметра выбранную группу Запрос.УстановитьПараметр("Родитель", ВыбраннаяСтрока); Запрос.УстановитьПараметр("Склад", Склад); Результат = Запрос.Выполнить(); // Очистить таблицу подбора НоменклатураДляПодбора.Очистить(); // Заполнить таблицу подбора Выборка = Результат.Выбрать(); Пока Выборка.Следующий() Цикл НоваяСтрока = НоменклатураДляПодбора.Добавить(); НоваяСтрока.Код = Выборка.Код; НоваяСтрока.Номенклатура = Выборка.Номенклатура; НоваяСтрока.Остаток = Выборка.Остаток; КонецЦикла; КонецПроцедуры Глава 3. Реализация задач учета движения средств 387 Теперь независимо от действий пользователя (например, использование полосы прокрутки), пока не будет перевыбрана группа в верхней таблице, никаких обращений к базе данных происходить не будет. В данном примере намеренно не используется механизм динамического отображения данных. Однако обеспечивается достаточно комфортная работа пользователя. Получение остатков при проведении документов При решении бизнес-задач зачастую возникают вопросы конкурентного управления ресурсами автоматизируемого предприятия. Сам учет ресурсов, как правило, ведется посредством регистров. Поэтому рассмотрим классическую задачу и пути ее решения. Пользователи оформляют и проводят документы ЗаказПокупателя. Данный документ связан с двумя регистрами: РезервыНоменклатуры и ТоварыНаСкладах. При проведении данного документа необходимо отложить товар в резерв (выполнить движения по регистру РезервыНоменклатуры), но перед этим выполнить контроль возможности проведения данной операции. Отложить товар в резерв можно только в том случае, если его хватает, то есть если достаточно свободного (не зарезервированного другими) остатка (рис. 3.54). Рис. 3.54. Контроль наличия товара Кроме того, контроль остатка нужно проводить не только при оперативном проведении. Иначе пользователи «понарезервируют» задним числом столько, сколько компания вовек не продаст. А если заставить все 388 Реализация прикладных задач в системе «1С:Предприятие 8.2» заказы проводить только оперативно, то первый, кто возразит против такого решения, – начальник отдела продаж. Зачастую выправление ситуаций коллизий остро конкурирующих заказов он разрешает, именно управляя хронологией заказов. Мол, «вон тот заказ поставим на вчера, а Иванов пусть следующей поставки ждет…». Таким образом, при реализации алгоритма проведения документа необходимо будет читать данные остатков регистров накопления. Пример реализации данного алгоритма проведения реализован в модуле документа ЗаказПокупателя демонстрационной конфигурации «Хранение информации и учет движения средств», которая находится на прилагаемом компакт-диске (листинг 3.92). Листинг 3.92. Обработчик события «ОбработкаПроведения» Процедура ОбработкаПроведения(Отказ, РежимПроведения) // Укажем, по каким регистрам нужно записывать движения Движения.РезервыНоменклатуры.Записывать = Истина; // Создать менеджер временных таблиц МенеджерВТ = Новый МенеджерВременныхТаблиц; Запрос = Новый Запрос; // Укажем, какой менеджер временных таблиц использует этот запрос Запрос.МенеджерВременныхТаблиц = МенеджерВТ; Запрос.Текст = "ВЫБРАТЬ | ЗаказПокупателяСостав.Номенклатура, | СУММА(ЗаказПокупателяСостав.Количество) КАК КоличествоВДокументе |ПОМЕСТИТЬ НоменклатураДокумента |ИЗ | Документ.ЗаказПокупателя.Состав КАК ЗаказПокупателяСостав |ГДЕ | ЗаказПокупателяСостав.Ссылка = &Ссылка | |СГРУППИРОВАТЬ ПО | ЗаказПокупателяСостав.Номенклатура"; Запрос.УстановитьПараметр("Ссылка", Ссылка); Результат = Запрос.Выполнить(); Запрос2 = Новый Запрос; Запрос2.МенеджерВременныхТаблиц = МенеджерВТ; Запрос2.Текст = "ВЫБРАТЬ | НоменклатураДокумента.Номенклатура, | НоменклатураДокумента.КоличествоВДокументе |ИЗ | НоменклатураДокумента КАК НоменклатураДокумента"; Глава 3. Реализация задач учета движения средств 389 // Установим необходимость блокировки данных в регистре РезервыНоменклатуры Движения.РезервыНоменклатуры.БлокироватьДляИзменения = Истина; // Запишем пустые наборы записей, чтобы читать резервы без учета данных в документе Движения.РезервыНоменклатуры.Записать(); Результат = Запрос2.Выполнить(); ВыборкаДетальныеЗаписи = Результат.Выбрать(); Пока ВыборкаДетальныеЗаписи.Следующий() Цикл // Сформировать движения по регистру РезервыНоменклатуры Движение = Движения.РезервыНоменклатуры.Добавить(); Движение.ВидДвижения = ВидДвиженияНакопления.Приход; Движение.Период = Дата; Движение.Номенклатура = ВыборкаДетальныеЗаписи.Номенклатура; Движение.Количество = ВыборкаДетальныеЗаписи.КоличествоВДокументе; КонецЦикла; // Запишем движения Движения.Записать(); // Контроль остатков Запрос3 = Новый Запрос; Запрос3.МенеджерВременныхТаблиц = МенеджерВТ; Запрос3.Текст = "ВЫБРАТЬ | НоменклатураДокумента.Номенклатура, | ЕСТЬNULL(ТоварыНаСкладахОстатки.КоличествоОстаток, 0) КАК Остаток, | ЕСТЬNULL(РезервыНоменклатурыОстатки.КоличествоОстаток, 0) КАК Резерв |ИЗ | НоменклатураДокумента КАК НоменклатураДокумента | ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.ТоварыНаСкладах.Остатки( | &Момент, | Номенклатура В | (ВЫБРАТЬ | НоменклатураДокумента.Номенклатура | ИЗ | НоменклатураДокумента)) КАК ТоварыНаСкладахОстатки | ПО НоменклатураДокумента.Номенклатура = ТоварыНаСкладахОстатки.Номенклатура | ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.РезервыНоменклатуры.Остатки( | &Момент, | Номенклатура В | (ВЫБРАТЬ | НоменклатураДокумента.Номенклатура | ИЗ | НоменклатураДокумента)) КАК | РезервыНоменклатурыОстатки | ПО НоменклатураДокумента.Номенклатура = РезервыНоменклатурыОстатки.Номенклатура |ГДЕ | ЕСТЬNULL(ТоварыНаСкладахОстатки.КоличествоОстаток,0) | ЕСТЬNULL(РезервыНоменклатурыОстатки.КоличествоОстаток,0) < 0"; ГраницаПоДокумент = Новый Граница(МоментВремени(), ВидГраницы.Включая); Запрос3.УстановитьПараметр("Момент", ГраницаПоДокумент); РезультатСНехваткой = Запрос3.Выполнить(); ВыборкаРезультатаСНехваткой = РезультатСНехваткой.Выбрать(); 390 Реализация прикладных задач в системе «1С:Предприятие 8.2» Пока ВыборкаРезультатаСНехваткой.Следующий() Цикл Сообщение = Новый СообщениеПользователю(); Сообщение.Текст = "Не хватает " + Строка(- (ВыборкаРезультатаСНехваткой.Остаток ВыборкаРезультатаСНехваткой.Резерв)) + " единиц товара """ + ВыборкаРезультатаСНехваткой.Номенклатура + "." Сообщение.Сообщить(); Отказ = Истина; КонецЦикла; КонецПроцедуры Краткий комментарий: сначала в обработчике ОбработкаПроведения указывается, что движения документа по регистру РезервыНоменклатуры должны быть записаны при проведении документа. Затем данные табличной части документа ЗаказПокупателя помещаются во временную таблицу. Эти данные посредством менеджера временных таблиц будут затем использованы в запросе для формирования движений документа и в запросе к регистрам накопления для контроля свободных (не зарезервированных) остатков товаров. Заметьте, что данные табличной части документа группируются по полю Номенклатура, чтобы суммировать поле Количество при наличии в документе нескольких строк с одинаковой номенклатурой. Затем данные регистра РезервыНоменклатуры блокируются путем установки свойства БлокироватьДляИзменения в значение Истина. Чтобы обеспечить чтение количества зарезервированных товаров без учета существующих движений документа, движения данного документа в регистре очищаются путем записи пустого набора данных. Далее выполняется запрос к временной таблице, содержащей перечень заказанных товаров, и в цикле выборки результата запроса формируются движения по регистру РезервыНоменклатуры. Затем движения документа в регистрах записываются в явном виде (Движения.Записать()). После этого выполняется контроль свободного (не зарезервированного) остатка товаров. Для этого выполняется запрос для получения отрицательных свободных остатков номенклатуры, содержащейся в табличной части проводимого документа. Запрос реализован левым соединением данных временной таблицы с данными виртуальных таблиц остатков из регистров ТоварыНаСкладах и РезервыНоменклатуры. Поскольку документу запрещено оперативное проведение (свойство документа Оперативное проведение установлено в значение Запретить), остатки номенклатуры нужно контролировать на момент времени Глава 3. Реализация задач учета движения средств 391 документа, включая движения самого документа. Поэтому в качестве параметра Период при установке параметра запроса передается значение момента времени документа, включая движения самого документа (Новый Граница(МоментВремени(), ВидГраницы.Включая)). Заметьте, что виртуальные таблицы остатков получены с применением отбора только по тем номенклатурным позициям, которые входят в состав проводимого документа. Поскольку может быть ситуация, когда данные по неким номенклатурным позициям в регистре отсутствуют, для выходных полей запроса применена функция преобразования возможных Null значений в числовое значение 0. Это сделано для того, чтобы впоследствии выполнять арифметические действия с данными результата запроса без опасений, что те окажутся непригодными для подобных действий. После этого выборка записей запроса обходится в цикле, и если есть такие записи, в которых количество резерва по товару в регистре РезервыНоменклатуры превосходит его остаток в регистре ТоварыНаСкладах, сообщение о них выводятся пользователю. В этом случае параметр Отказ процедуры обработчика события получает значение Истина, что приведет к откату транзакции записи документа с проведением. Блокировка записей регистров Для «1С:Предприятия» стандартным является режим управляемых блокировок. Он задается свойством конфигурации Режим управления блокировкой данных, которое для новых конфигураций устанавливается в значение Управляемый. Блокировки данных в информационной базе выполняются менеджером блокировок «1С:Предприятия». Стандартный вариант проведения документа, при котором выполняется контроль остатков из регистров накопления остатков, предусматривает следующую последовательность действий: сначала выполняется запись движений документа, затем контролируются остатки. При записи движений регистра накопления пересчитываются также и его итоги, и при этом на таблицу движений и таблицу итогов регистра накопления накладываются управляемые блокировки. В файловом варианте работы системы при выполнении транзакции, в которую входит проведение документа, для считывания и записи данных системой автоматически применяются блокировки на уровне таблиц базы данных. Соответственно, другая транзакция при проведении другого документа не сможет прочитать или изменить остатки в регистре накопления с того момента, как записаны движения, и до того момента, как начато чтение для контроля отрицательных остатков. 392 Реализация прикладных задач в системе «1С:Предприятие 8.2» В клиент-серверном варианте для максимального быстродействия системы при использовании ее большим числом пользователей обеспечивается параллельность работы пользователей. Это реализуется за счет применения блокировок не на уровне таблиц базы данных, а на уровне записей таблиц и диапазонов записей таблиц регистров. При этом для ускорения записи в регистр и увеличения параллельности проведения документов регистры стандартно используют режим разделения итогов. Механизм разделения итогов вводит в состав хранимой таблицы итогов специальное поле (Разделитель), позволяющее распараллелить обновление записей итогов. Таким образом, при записи движений документа блокироваться будут только записи с тем разделителем, который получила текущая транзакция. Но возможна ситуация, когда другая транзакция с другим разделителем изменит остатки по тем же измерениям регистра, что первая, и еще до того момента, как первая начнет чтение для контроля отрицательных остатков (рис. 3.55). Рис. 3.55. Блокировки записей регистра накопления при проведении с использованием режима разделения итогов В тот момент, когда первый документ начнет чтение остатков из регистра, записи итогов по одинаковым измерениям будут сложены, и в результате при проведении первого документа будут получены неверные остатки. Глава 3. Реализация задач учета движения средств 393 Ведь при записи блокировалась только итоговая запись с разделителем “0” именно для того, чтобы параллельная транзакция могла записать свои итоги по тем же измерениям, но с другим разделителем. Чтобы избежать изменения итогов между моментом записи и моментом чтения остатков, еще до формирования и записи движений регистра свойство набора записей БлокироватьДляИзменения устанавливается в значение Истина. В этом случае в момент записи набора записей платформа отключит разделитель итогов в регистре. Таким образом, другая транзакция не сможет записать движения по тем же измерениям, что и текущая до окончания проведения документа. В результате после записи движений будут получены правильные остатки из регистров. Чтение данных регистра остатков при неоперативном проведении Помимо блокировок, хотелось бы еще обратить внимание на следующее: на какой момент нужно получать данные регистров при проведении документа. Для решения этого вопроса, прежде всего, важно определить, используется ли для ведения учета механизм оперативного проведения. Если механизм используется, то при получении информации остатков из регистров достаточно получать данные текущих итогов, что сильно повышает быстродействие этой операции. То есть можно применять виртуальные таблицы получения остатков без указания значения параметра Период. Подобный пример приведен в демонстрационной конфигурации «Хранение информации и учет движения средств», которая находится на прилагаемом компакт-диске, при проведении документа РеализацияТоваров. Также этот пример описан в разделе «Использование механизма оперативного проведения» на стр. 183. В приведенном выше алгоритме (см. листинг 3.92) реализована ситуация, когда по каким-то причинам не используется механизм оперативного проведения документа. Тогда для обеспечения корректности контрольных операций при проведении документов нужно будет получать не актуальные данные регистров остатков, а данные на момент времени документа посредством использования соответствующего значения для параметров виртуальных таблиц. Хочется подчеркнуть, что не на дату документа, а именно на момент времени, включая движения самого документа. Например, возможна такая ситуация. В таблице движений регистра остатков есть три записи (табл. 3.79). 394 Реализация прикладных задач в системе «1С:Предприятие 8.2» Таблица 3.79. Таблица движений регистра накопления остатков Период Регистратор Вид движения Номенклатура Количество 13.05.2010 15:00:01 ПоступлениеТоваров № 1 13.05.2010 15:00:01 Приход Пульт VX 10 23.05.2010 12:30:45 РеализацияТоваров № 1 23.05.2010 12:30:45 Расход Пульт VX 7 23.05.2010 12:30:45 РеализацияТоваров № 2 23.05.2010 12:30:45 Расход Пульт VX 2 Проводится очередной документ ЗаказПокупателя № 1, в нем указана следующая информация (табл. 3.80). Таблица 3.80. Данные документа «Заказ товаров» ЗаказПокупателя Номер: № 1 Дата: 23.05.2010 12:30:45 Номенклатура Количество Пульт VX 3 Поскольку оперативное проведение не используется, то дата документа вполне может иметь точно такое же значение, как и у предыдущего документа. В результате, если остатки регистра будут посчитаны на значение Дата, получим, что на складе 10 пультов (то есть документ ЗаказПокупателя можно провести, хотя это не так). Поэтому данные остатков нужно брать на момент времени проводимого документа (рис. 3.56). Рис. 3.56. Получение остатков на момент времени документа Глава 3. Реализация задач учета движения средств 395 Однако необходимо иметь в виду, что управлять положением документов внутри одной секунды возможности нет. То есть не факт, что новый документ (ЗаказПокупателя) займет на временной оси положение после уже введенных с той же датой документов (РеализацияТоваров). Но при получении данных на момент времени по крайней мере есть уверенность в однозначном порядке расположения документов на временной оси с точки зрения чтения информации регистров при проведении документов. Поэтому возможные коллизии в результате неоперативного проведения документов все же можно разрешать за счет перепроведения документов, в частности, с помощью последовательностей документов. Более подробно это описано в разделе «Последовательности документов» на стр. 224. 396 Реализация прикладных задач в системе «1С:Предприятие 8.2» Глава 4. Реализация задач бухгалтерского учета Эта глава нашей книги посвящена задачам бухгалтерского учета и возможностям системы «1С:Предприятие» для их решения. Говорят, что правильно поставленная задача – наполовину решенная задача. Мы считаем, что это утверждение недалеко от истины, но уделить достаточное внимание вопросам теории бухгалтерского учета не позволяет формат нашей книги. Тем не менее, мы будем стараться, где это возможно, разъяснять основные понятия и методы предметной области, задачи которой будем решать. Все примеры, рассмотренные в этой главе, содержатся в демонстрационной конфигурации «Бухгалтерский учет», которая находится на прилагаемом компакт-диске. Основная задача любой учетной системы – управление и контроль за работой объектов учета. Задача бухгалтерского учета – учет операций хозяйственной деятельности всего предприятия в целом. Цель учета – контроль за финансово-хозяйственной деятельностью и управление всем предприятием посредством замкнутой системы показателей. Далее при рассмотрении внутреннего устройства регистра бухгалтерии (основного объекта, предназначенного для реализации задач бухгалтерского учета) мы будем проводить сравнение с другим объектом – регистром накопления. Эти объекты весьма похожи, но предназначены и оптимизированы для решения разных задач. Поэтому умение выделить задачи бухгалтерского учета и задачи оперативного учета позволит значительно оптимизировать работу конфигурации. 398 Реализация прикладных задач в системе «1С:Предприятие 8.2» Диаграмма взаимодействия объектов Схему взаимодействия объектов системы «1С:Предприятие» при реализации задачи бухгалтерского учета можно представить следующим образом (рис. 4.1). Рис. 4.1. Схема взаимодействия объектов Рассмотрим объекты, участвующие в схеме, и начнем это делать с плана счетов. Бухгалтерский учет ведется на счетах, каждый из которых предназначен для группировки однородных хозяйственных операций. Все счета, используемые для ведения учета на предприятии, объединяются в план счетов. Счета – Глава 4. Реализация задач бухгалтерского учета 399 это основной разрез учета. Все остальные разрезы (аналитический учет, измерения) являются вспомогательными и необязательными. Для хранения бухгалтерских проводок по счетам используется объект конфигурации Регистр бухгалтерии. Самый простой регистр бухгалтерии, предназначенный для ведения бухгалтерского синтетического учета, может содержать всего один ресурс (для учета средств в валюте учета, в которой будет составляться вся отчетность и формироваться баланс) и более ничего. Такой регистр бухгалтерии позволит анализировать остатки и обороты по счетам, а также и обороты между счетами. Для получения оборотов между счетами регистр должен поддерживать схему учета с поддержкой корреспонденций, при которой каждая запись обязательно включает два счета: дебетуемый и кредитуемый. Дополнительными разрезами при ведении учета являются аналитические разрезы (аналитический учет) и измерения регистра бухгалтерии (с помощью которых возможно реализовать многовалютный учет, консолидированный учет и другие). Аналитический учет описывается в системе «1С:Предприятие» с помощью понятий Вид субконто и Субконто. Под видом субконто подразумевается группа однородных объектов аналитического учета (список контрагентов, номенклатуры, статей и др.). Субконто – это один конкретный объект из этого множества (объект аналитического учета, например: контрагент, карточка товара, статья затрат и др.). Для реализации аналитического учета используется «связка» объектов План видов характеристик, План счетов, Регистр бухгалтерии. План видов характеристик, использующийся для ведения аналитического учета на выбранном плане счетов, выбирается в соответствующем свойстве плана счетов. Виды характеристик «привязываются» к счетам плана счетов, требующим ведения аналитического учета. Результат этих действий – изменяющиеся таблицы регистра бухгалтерии, которые позволят хранить остатки и обороты не только по счетам, но и по счетам в разрезе субконто. Чтобы понять, как используется план видов характеристик, можно разделить название этого объекта на две части – «план» и «видов характеристик». Получаются два уровня вложенности: план, представляющий собой совокупность видов субконто, и вид субконто. Каждый вид субконто хранит информацию о типе характеристик, являющихся объектами аналитического учета, т. е. субконто. Характеристика – это один экземпляр вида характеристик, так же как субконто – это один экземпляр вида субконто. Характеристика не является самостоятельным объектом конфигурации. Для ведения аналитического учета, как правило, используются элементы справочников, значения перечисления, ссылки на документы. Виды характеристик, как правило, имеют ссылочный тип данных (хотя возможны и другие варианты). 400 Реализация прикладных задач в системе «1С:Предприятие 8.2» Решение задач консолидированного, многовалютного учета, единого для всех счетов аналитического учета, и некоторых других осуществляется с использованием измерений регистра бухгалтерии, которые так же, как правило, принимают значения ссылочных типов данных. Каждая запись (проводка) регистра бухгалтерии подчинена какому-то регистратору (документу) и, как правило, им же создана. При проектировании реквизитного состава документов, которые должны формировать записи в регистре бухгалтерии, как правило, используются ссылочные типы данных. Документ при проектировании задачи бухгалтерского учета – это, прежде всего, средство формирования движений в регистре бухгалтерии. А движения эти, как уже было сказано выше, содержат субконто и измерения, которые и заполняются обычно значениями реквизитов документа. Каждый документ имеет свойство Движения, представляющее собой коллекцию наборов записей тех регистров, регистратором для которых он является. Схема проведения документа по регистрам унифицирована для всех регистров – регистры сведений, накопления, расчетов, бухгалтерии. Она включает запись выбранных при проведении, измененных вручную, используя набор записей «ручной операции», или другим способом наборов записей в регистр при записи документа интерактивно или программно. Регистр бухгалтерии с точки зрения традиционной (бумажной) бухгалтерии можно рассматривать как собрание форм бухгалтерского учета, включающее в себя как формы для хронологической (проводки), так и для систематической (итоги по счетам, по субконто, обороты между счетами) записи. Кроме записи и хранения бухгалтерских проводок и итогов по счетам, регистр бухгалтерии предоставляет ряд методов и таблиц для выполнения запросов. И те и другие предназначены для удобного и оптимального получения остатков и оборотов по счетам и аналитикам. Так как основным методом извлечения данных в системе является запрос, то именно таблицы (в первую очередь виртуальные) используются в большинстве случаев для построения бухгалтерской отчетности, являющейся главным результатом бухгалтерского учета. План счетов и его основные свойства План счетов – центральное место любой конфигурации для ведения бухгалтерского учета. Бухгалтерский учет ведется на счетах. Все счета, входящие в один баланс, объединяются в один план счетов. По свой сути план счетов – это справочник счетов. Рассмотрим пример несложного бухгалтерского учета на небольшом предприятии. Каждое предприятие обладает каким-то имуществом (активами) и обязательствами (пассивами). Пусть у нашего предприятия будут активы: ■ наличные деньги в кассе; ■ деньги, которые нам должны наши покупатели за поставленные им товары; Глава 4. Реализация задач бухгалтерского учета 401 ■ сами товары, которые мы приготовили для продажи; ■ прочие материальные ценности для собственных нужд. Все эти активы «взялись не откуда-то», а были получены нашим предприятием или от инвестора (хозяина, владельца, которому принадлежит наше предприятие), или от сторонних по отношению к предприятию организаций и физических лиц (например, поставщиков). Таким образом, пассивы нашего предприятия складываются из обязательств перед хозяином, сторонними контрагентами и собственными сотрудниками, которые работают на нашем предприятии. Итак, наши пассивы: ■ задолженность перед сотрудниками; ■ задолженность перед поставщиками; ■ задолженность перед владельцем. Таким образом, мы имеем два ряда счетов, которые обусловлены балансом нашего предприятия1. Так как активы не могли взяться из «ниоткуда» и не могут исчезнуть в «никуда», то сумма всех активов в денежном выражении будет равна сумме всех обязательств в том же денежном выражении. В нашем учете нас интересуют и остатки, и обороты по каждому виду активов и обязательств. Поэтому для каждого из них мы заведем отдельный счет в плане счетов. По свой сути каждый счет – это один (или несколько) учетный регистр (форм). От количества и назначения счетов будет зависеть весь учетный процесс, поэтому перепроектирование плана счетов почти всегда связано с существенными изменениями конфигурации. Группировка этих счетов, их порядок в плане счетов во многом зависят от традиций, стандартов и просто предпочтений бухгалтера. Если речь идет о регламентированном учете, то эти свойства плана счетов описываются в законе и стандартах. В нашем случае мы создадим план счетов сами, и он будет включать следующие счета (табл. 4.1). Таблица 4.1. Состав плана счетов 1 Код Имя Назначение 1 1.1 Активы Касса 1.2 Покупатели 1.3 1.4 1.5 Товары Материалы Контрагенты Группа счетов, объединяет все активы нашего предприятия Наличные деньги Деньги, которые нам должны наши покупатели за поставленные им товары Товары, которые мы приготовили для продажи Прочие материальные ценности для собственных нужд Взаиморасчеты с контрагентами Для более полного понимания теории бухгалтерского учета можно рекомендовать труды д. э. н., профессора Я. В. Соколова, автора замечательных книг и не менее замечательных статей, многие из которых можно прочитать в издании «БУХ.1С». 402 Реализация прикладных задач в системе «1С:Предприятие 8.2» Код Имя Назначение 2 2.1 2.2 3 Обязательства Сотрудники Поставщики Капитал Объединяет все обязательства перед контрагентами и сотрудниками Задолженность перед сотрудниками Задолженность перед поставщиками Задолженность перед владельцем План счетов – объект конфигурации, который позволяет описать состав счетов, используемый для ведения учета на предприятии, и их свойства. Рассмотрим план счетов для ведения нашего бухгалтерского учета. Закладка Основные позволяет назначить имя, синоним и комментарий для плана счетов, а также представление объекта, представление списка и пояснение для представления плана счетов в интерфейсе «1С:Предприятия» (рис. 4.2). Рис. 4.2. Основные свойства плана счетов Следует заметить, что в одной конфигурации может быть несколько планов счетов. Для целей регламентированного учета это не требуется, но встречаются задачи управленческого учета, требующие ведения учета по разным стандартам или ведения не только бухгалтерского учета, который фиксирует свершившиеся факты, но и бюджетного учета, который учитывает планируемые операции. Закладка Данные (рис. 4.3) кроме таких свойств, как Реквизиты и Табличные части, назначение которых – хранение дополнительной информации о счете, содержит следующие свойства (табл. 4.2). Глава 4. Реализация задач бухгалтерского учета 403 Таблица 4.2. Свойства плана счетов Свойство Назначение Длина кода Максимальная длина кода счета, включая все его субсчета и знаки, используемые для отделения счета и субсчета Длина наименования Максимальная длина наименования счета Маска кода Свойство позволяет задать правила использования символов (цифровой, буквенно-цифровой код и т. д.) и иерархичность кода счета Автопорядок по коду Это свойство будет рассмотрено подробно ниже Длина порядка Максимальная длина дополнительного индексируемого поля, значение которого используется для сортировки счетов в форме списка плана счетов и запросах Основное представление Выбор основного представления счета в полях ввода документов, отчетов и др. Обычно счет принято отображать в виде кода, но в методических целях будем использовать наименование Признаки учета Дополнительное свойство счета, позволяющее определить необходимость ведения на выбранном счете дополнительного вида учета (например, валютного или количественного) Рис. 4.3. Данные плана счетов 404 Реализация прикладных задач в системе «1С:Предприятие 8.2» Закладка Нумерация позволяет определить правила нумерации счетов в плане счетов и мало отличается от подобных закладок других объектов (рис. 4.4). Рис. 4.4. Нумерация плана счетов Закладка Субконто предназначена для описания общих правил ведения аналитического учета плана счетов (рис. 4.5). Здесь устанавливается, какой из планов видов характеристик будет использоваться для хранения списка видов субконто (свойство Виды субконто), максимально возможное количество параллельных (независимых) видов субконто на любом счете плана счетов. Здесь же создаются дополнительные свойства субконто на счете – Признаки учета субконто, которые позволяют управлять необходимостью ведения того или иного вида учета для одного из видов субконто выбранного счета. Закладка Формы кроме настройки форм позволяет настроить способы выбора счета в диалогах в поле выбора. Здесь же указывается, по каким полям будет осуществляться ввод по строке в диалогах выбора (при наборе с клавиатуры кода счета или его наименования система будет осуществлять поиск счета в плане счетов), рис. 4.6. Закладка Прочее – последняя по порядку, но не по значимости. Кроме ввода справочной информации предназначена для изменения модуля объекта, модуля менеджера объекта, списка предопределенных счетов, справочной информации о плане счетов и т. п. (рис. 4.7). Глава 4. Реализация задач бухгалтерского учета Рис. 4.5. Субконто плана счетов Рис. 4.6. Формы плана счетов 405 406 Реализация прикладных задач в системе «1С:Предприятие 8.2» Рис. 4.7. Прочие свойства плана счетов А теперь рассмотрим подробнее основные из перечисленных свойств счетов и их использование при решении задач бухгалтерского учета. Коды счетов Использование кодов плана счетов во многом определяется стандартами, в соответствии с которыми ведется бухгалтерский учет. Это может быть «Закон о бухгалтерском учете» (если решается задача регламентированного учета), GAAP или другие зарубежные стандарты (при решении задачи получения бухгалтерской отчетности в соответствии с МСФО), внутренние стандарты предприятия (если необходимо ведение управленческого учета). Кроме кода, который в понимании бухгалтера «…и есть счет», необходимы и другие свойства. Эти свойства и состав счетов плана счетов позволяют определить в системе объект конфигурации План счетов. Код счета предназначен для идентификации счета пользователем и, как правило, используется как основное представление объекта. Именно код счета обычно вводит пользователь при заполнении бухгалтерской проводки, Глава 4. Реализация задач бухгалтерского учета 407 код счета выводится в качестве измерений (строк и колонок) бухгалтерских отчетов. Свойство Длина кода позволяет задать максимальную длину кода, которой будет ограничено описание кодов для счетов выбранного плана счетов. При описании максимальной длины кода счета необходимо учитывать возможную иерархичность плана счетов. Для счетов одного плана счетов можно установить (и обычно устанавливается) контроль уникальности кода, который может контролировать серии кодов или во всем справочнике, или в пределах подчинения владельцу. Основное отличие от справочника здесь заключается в том, что код счета включает в себя коды всех его родителей. Поэтому при установке уникальности в пределах подчинения владельцу мы можем добавить к счету с кодом 02 субсчет с кодом 01.1, ведь там такого еще нет. Свойство Наименование счета и его длина не требуют, с нашей точки зрения, отдельного описания, т. к. свойство не отличается по своему назначению от аналогичного свойства объектов Справочник и План видов характеристик. Так же как и в перечисленных объектах, это свойство предназначено для хранения вводимого пользователем наименования элемента плана счетов (счета). Свойство Маска кода заслуживает отдельного и более подробного описания. Это свойство предназначено для ограничения использования символов в коде счета и задания иерархической структуры плана счетов. Система позволяет описывать как линейные, так и иерархические планы счетов. Каждый план счетов может включать неограниченное число счетов первого уровня, неограниченное число субсчетов к каждому счету первого уровня и т. д. Первая задача – ограничение использования символов – решается с помощью использования при заполнении маски кода счета символов, описание которых можно найти в документации, например, в описании метода Маска(). В строке маски допустимо использование следующих специальных символов: ■ ! – любой введенный символ преобразуется в верхний регистр; ■ 9 – допустимо ввести произвольный символ цифры; ■ # – допустимо ввести произвольный символ цифры, или - (знак минус), или + (знак плюс), или пробел; ■ N – допустимо ввести любые алфавитно-цифровые символы (буквы или цифры); ■ U – допустимо ввести любые алфавитно-цифровые символы (буквы или цифры), и любой введенный символ преобразуется в верхний регистр; ■ X (латинского алфавита) – допустимо ввести произвольный символ; 408 Реализация прикладных задач в системе «1С:Предприятие 8.2» ■ @ – допустимо ввести любые алфавитно-цифровые символы (буквы или цифры) в верхнем регистре или пробел; ■ и других. Таким образом, если мы зададим маску кода счета ##, в план счетов можно будет вводить счета с кодами, состоящими только из цифр, знаков минуса, плюса и пробела. Кроме того, максимальный код счета становится равным 99 (счет с кодом 100 содержит уже три символа, что не разрешается выбранной маской). Вторая задача – задание иерархической структуры плана счетов (или, точнее, кодов счетов, потому что иерархия кодов и иерархия счетов может отличаться, и об этом пойдет речь ниже) – решается за счет использования символовразделителей в составе маски кода счета. Разделителем может выступать любой символ, не перечисленный в описании специальных символов маски. Для отделения счета верхнего уровня от субсчета, как правило, используется «.» (символ точка). Таким образом, если мы считаем, что нам будет достаточно плана счетов с двумя уровнями вложенности (счет – субсчет), нам будет достаточно задать маску кода счета ##.##, что соответствует длине кода счета, которую мы выбрали ранее (5 символов: два знака – счет, два знака – субсчет, точка-разделитель между ними). Отдельно следует остановиться на использовании символа @ в описании маски кода счета. Использование этого специального символа не только позволяет вводить любые алфавитно-цифровые символы (буквы или цифры) в верхнем регистре или пробел, как уже было отмечено выше, но и влияет на хранение кода в базе и отображение его в диалогах ввода. При использовании символа @ в маске кода счета группа знаков кода, для которой использованы символы @, при сохранении кода в базу данных упаковывается – из него вырезаются пробелы. Рассмотрим на примере нашего плана счетов, для которого мы установили в свойствах маску кода счета @@.@@, соответствующую максимальной длине кода счета. Проиллюстрируем работу маски, содержащей символы @, на примере ввода счета с кодом 1 .1 (табл. 4.3 и табл. 4.4). Таблица 4.3. Маска кода с использованием символа @ Номера символов 1 2 3 4 5 Маска @ @ . @ @ Вводится 1 пробел . 1 пробел Хранится 1 . 1 нет нет Символов 3 Глава 4. Реализация задач бухгалтерского учета 409 Таблица 4.4. Маска кода без использования символа @ (используется #) Номера символов 1 2 3 4 5 Маска # # . # # Вводится 1 пробел . 1 пробел Хранится 1 пробел . 1 пробел Символов 5 Таким образом, вводится код 1 .1 (единица, пробел, точка, единица), а в базе данных сохраняется 1.1. При редактировании счета в плане счетов код счета распаковывается до вида, подходящего под маску. При записи опять упаковывается. При работе пользователя с диалогами форм, содержащими ссылки на счет плана счетов, ввод по подстроке осуществляется по «упакованному» коду. В нашем случае пользователь должен будет набрать с клавиатуры 1.1 (без пробелов, т. е. не дополняя код до вида маски). Упорядочивание счетов в плане счетов План счетов, как и объекты Справочник и План видов характеристик, стандартно сортируется в формах списка и упорядочивается (автоупорядочивание) в запросах по основному представлению. Но, во-первых, есть вероятность, что основным представлением будет выбрано наименование (в целях управленческого учета это возможно), а упорядочить необходимо по коду. А, во-вторых, код, особенно при использовании в маске кода счета символов @, позволяющих упаковывать код счета, может не подходить для сортировки. Рассмотрим это на примере первой группы счетов плана счетов, который мы начали делать. Пользователь ввел счета со следующими кодами (табл. 4.5). Таблица 4.5. Счета, введенные пользователем Коды по порядку их ввода (как должно быть) Счета, отсортированные по коду 1.1 1.1 1.2 1.10 1.3 1.11 1.N 1.2 1.10 1.3 1.11 1.N 410 Реализация прикладных задач в системе «1С:Предприятие 8.2» Возможное решение проблемы неверной сортировки счетов – использование лидирующих нулей или пробелов при кодировании счетов в плане счетов (табл. 4.6). Таблица 4.6. Использование лидирующих нулей в коде счета Коды по порядку их ввода (как должно быть) Счета, отсортированные по коду 01.01 01.01 01.02 01.02 01.03 01.03 01.0N 01.0N 01.10 01.10 01.11 01.11 Альтернативный вариант решения проблемы сортировки – воспользоваться свойством счета Порядок. Это поле с автоматическим индексированием, предназначенное для хранения значения, по которому будет выполняться упорядочивание счетов в форме списка и результатах запроса. В отличие от кода, который для хранения в базе данных может упаковываться, порядок хранится в базе в неизменном виде. Порядок становится доступным для использования, если его длина больше нуля. При этом платформа не разрешит записать в базу данных счет с пустым порядком. Зададим длину порядка в нашем плане счетов (5 символов), порядок зададим произвольный (рис. 4.8). Рис. 4.8. Сравнение сортировки по коду и по порядку На картинке видно, что при сортировке по полю Порядок счет Капитал с кодом 3 занял первое место (порядок 01), а счет Активы переместился вниз. Глава 4. Реализация задач бухгалтерского учета 411 Если в маске кода счета используются только символы @ и символы-разделители, то для счетов, вводимых в пользовательском режиме, поле Порядок можно сформировать автоматически. Для этого в модуле формы счета или в модуле объекта (закладка Прочее, кнопка Модуль объекта) необходимо разместить процедуру-обработчик события (листинг 4.1). Листинг 4.1. Пример автоматического формирования порядка счета Процедура ПередЗаписью(Отказ) Порядок = ПолучитьПорядокКода(); КонецПроцедуры Метод ПолучитьПорядокКода() развернет упакованный код и дополнит его «лидирующими пробелами», что позволит упорядочить план счетов правильно, без использования в коде счета лидирующих нулей (табл. 4.7). Таблица 4.7. Пример использования метода «ПолучитьПорядокКода()» Номера символов 1 2 3 4 5 Вводим код счета 1 пробел . 1 пробел Маска кода счета @ @ . @ @ Хранится в базе данных 1 . 1 нет Нет ПолучитьПорядокКода() пробел 1 . пробел 1 После выполнения записи всех счетов в пользовательском режиме и установки сортировки по полю Порядок план счетов приобретет следующий вид (рис. 4.9). Рис. 4.9. Сравнение сортировки по порядку и по коду 412 Реализация прикладных задач в системе «1С:Предприятие 8.2» Мы видим, что при сортировке по полю Порядок введенный пользователем счет Новый счет с кодом 1.11 занял свое «законное» место – последним в группе Активы. Тем не менее, остается возможность отсортировать план счетов по коду. Кроме того, при вводе предопределенного счета поле Порядок автоматически не заполняется. Для автоматического заполнения поля Порядок кодом, дополненным лидирующими пробелами при вводе предопределенного счета, и для подмены сортировки по коду сортировкой по порядку используется свойство счета Автопорядок по коду. После его установки, во-первых, при вводе предопределенного счета в момент перехода с поля Код (Tab или Enter) при незаполненном порядке счета поле Порядок будет заполняться по описанным выше правилам (как при использовании метода ПолучитьПорядокКода()). А во-вторых, в формах списка и запросах при указании сортировки по полю Код сортировка будет выполняться не по полю Код, а по полю Порядок, т. е. получить порядок кодов будет невозможно (рис. 4.10). Рис. 4.10. Сравнение сортировки по коду и по порядку Две приведенные картинки отличаются между собой колонкой, по которой выполняется сортировка. Левый список отсортирован по полю Код, правый – по полю Порядок, но сортировка на обоих выполняется по полю Порядок. Это можно увидеть по положению счета 1.11, который ранее, при сортировке по полю Код, всегда занимал место после счета с кодом 1.1. Подобная же сортировка (по полю Порядок) будет выполняться и в запросах при указании в предложении УПОРЯДОЧИТЬ ПО в качестве поля сортировки Код (листинг 4.2). Листинг 4.2. Сортировка по полю «Код» в тексте запроса УПОРЯДОЧИТЬ ПО Код Глава 4. Реализация задач бухгалтерского учета 413 Иерархичность плана счетов Как уже было замечено выше, объект План счетов позволяет создавать иерархические планы счетов. Наш план счетов имеет два уровня вложенности – счета первого уровня Активы, Обязательства и Капитал и несколько субсчетов к счетам Активы и Обязательства. Платформа позволяет создавать неограниченное число счетов и уровней вложенности. Это свойство плана счетов позволяет детализировать учет, однако детализация эта будет иерархической и не позволит организовать фасетное (параллельное) деление итогов. Например, не удастся организовать учет товаров на складах с возможностью автоматического получения итогов по складу, по товару и по товару на складе. Т. е. иерархическая организация плана счетов не может в полной степени обеспечить ведение аналитического учета. Для ведения аналитического учета предназначены понятия Вид субконто и Субконто, о которых пойдет речь в разделе «Основы организации аналитического учета» на стр. 422. «Бесконечная иерархичность» плана счетов обеспечивается благодаря свойству Родитель счета. Это свойство может заполняться и для предопределенных счетов, и для счетов, вводимых пользователем. Это свойство содержит ссылку на родительский счет. Рассмотрим свойство иерархичность на схеме (рис. 4.11). Рис. 4.11. Иерархичность плана счетов 414 Реализация прикладных задач в системе «1С:Предприятие 8.2» При необходимости иерархичность плана счетов всегда можно изменить, например, разделив счет Касса на два субсчета – Рублевая касса и Валютная касса. При такой иерархичности счета первого уровня (в нашем случае Активы, Обязательства и Капитал), имеющие субсчета, не теряют возможности участвовать в проводках и выполнять те же функции, что и счета конечного уровня. И, кроме того, они позволяют сгруппировать данные в отчетах, суммируя итоги со своих субсчетов. План счетов напоминает справочник, у которого установлено свойство Иерархия элементов. Ввод проводок и формирование отчетов по счетам, содержащим подчиненные Подобная организация плана счетов позволяет перепроектировать подчинение счетов в плане счетов в процессе работы с программой. Счет, предназначенный изначально для ведения по нему учета, однажды может стать группой счетов, объединяющей в себе субсчета более низкого уровня. Рассмотрим пример на нашем плане счетов. Предположим, что до какого-то момента счета Активы и Обязательства не имели субсчетов и участвовали в проводках (рис. 4.12). Рис. 4.12. Документ «Операция» Далее было принято решение разбить счета Активы и Обязательства на субсчета и не использовать их в проводках в дальнейшем. Запрет использования в проводках можно реализовать, добавив в план счетов реквизит, принимающий два значения: разрешить или запретить использовать в проводах, и проверяя его значение при выборе счета в диалоге формы документа. Итак, решение было принято, были созданы субсчета, и все дальнейшие проводки вводились пользователем по субсчетам. На рис. 4.13 приведен фрагмент отчета, который показывает состояние остатков и оборотов по счетам после того, как в базу были введены и проводки по счетам Активы и Обязательства, и проводки по их субсчетам. Глава 4. Реализация задач бухгалтерского учета 415 Рис. 4.13. Отчет «Оборотно-сальдовая ведомость» Мы видим, что в группах счетов Активы и Обязательства появились остатки и обороты по одноименным субсчетам. Подобных субсчетов нет в плане счетов. Так платформа интерпретирует в отчетах ситуацию, когда в информационной базе присутствуют проводки по счетам, имеющим субсчета. Все проводки, сделанные по счету, имеющему субсчета, группируются системой и отображаются в отчете по «служебному» субсчету. При написании запросов к регистру бухгалтерии можно получить данные только по проводкам счета, имеющего субсчета (листинг 4.3). Листинг 4.3. Условие для получения данных по счету Счет = &Счет В приведенном примере &Счет – это параметр типа ПланСчетовСсылка.<имя>, содержащий ссылку на счет, имеющий субсчета. Если необходимо получить в отчете данные по счету и всем его субсчетам, условие будет выглядеть иначе (листинг 4.4). При этом в итоги попадут и проводки по самому счету-группе. Листинг 4.4. Условие для получения данных по счету и всем субсчетам Счет В ИЕРАРХИИ(&Счет) 416 Реализация прикладных задач в системе «1С:Предприятие 8.2» Однако приведенный пример не является руководством к действию. Если у счета есть подчиненные субсчета, то в проводках, как правило, участвуют они. А сам счет-группа предназначен для сбора итогов по всем своим субсчетам. Приведенный пример лишь демонстрирует следующее: ■ система корректно отрабатывает ситуации, когда существуют движения и по счету, и по подчиненным ему субсчетам; ■ всегда существует возможность «разбить» счет на субсчета даже на этапе промышленной эксплуатации системы без необходимости вносить изменения в проводки в закрытом отчетном периоде. Свойства счета-родителя и подчиненных ему счетов Продолжая рассматривать иерархическую организацию плана счетов, обратим внимание на такую особенность, как возможные отличия свойств счета-родителя и подчиненных ему субсчетов. Это свойство плана счетов позволяет создать у активного счета пассивные субсчета, или использовать на счете и его субсчетах различную аналитику, или задавать коды субсчетов без учета кода счета родителя. Как можно использовать, например, различную аналитику на счете и его субсчетах? Это может иметь смысл, только если ранее использовавшийся счет был разбит на субсчета и на них потребовалась другая аналитика, или если один из субсчетов выбивается из общего правила (все субсчета имеют одну детализацию и счет-родитель ее же, а один субсчет – другую). Может ли на практике счет-родитель быть активным, а его субсчета активными и пассивными? Может! Например, счет Внеоборотные активы будет, несомненно, активным (ведь это же активы!), а среди его субсчетов могут быть и активные (Первоначальная стоимость), и пассивные (Накопленная амортизация). Рис. 4.14. Счет «Касса» Глава 4. Реализация задач бухгалтерского учета 417 Схожей особенностью обладает и код счета. Каждый счет в плане счетов нумеруется в соответствии с маской кода счета и включает в себя коды «предполагаемых» родителей. Подчеркнем слово «предполагаемых». Если уникальность кода не используется, то для счета возможна смена родителя. Таким образом, счет с кодом 1.1, говорящим нам, что он располагается внутри группы счетов с кодом 1, на самом деле может оказаться в группе 3 или любой другой по усмотрению пользователя (рис. 4.14). В результате иерархичность счетов и иерархичность кодов счетов могут отличаться, что необходимо учитывать при написании кода, как в объектной модели, так и при написании запросов. Рассмотрим возможные ошибки на примере. Задача – сделать отчет Карточка счета, который позволит пользователю получить отбор всех проводок по одному счету. Воспользуемся в качестве источника данных для этого отчета виртуальной таблицей регистра бухгалтерии ДвиженияССубконто. Таблица, которая должна получиться в результате выполнения отчета, показывает все проводки по счету (или группе счетов). Отбор осуществляется по счету (или группе счетов), выбранному в диалоге пользователем. Если выбранный пользователем счет участвует в проводке по дебету, сумму проводки необходимо отобразить в колонке СуммаДт; если по кредиту – СуммаКт (рис. 4.15). Рис. 4.15. Отчет «Карточка счета» 418 Реализация прикладных задач в системе «1С:Предприятие 8.2» При построении отчета по группе счетов можно разными способами проверить, принадлежит ли выбранной группе дебетуемый или кредитуемый счет проводки. Первый вариант кода (листинг 4.5) выполняет проверку при обработке результатов запроса. Листинг 4.5. Фрагмент отчета «Карточка счета» Запрос = Новый Запрос; Запрос.Текст = "ВЫБРАТЬ | ДвиженияССубконто.Период КАК Период, | ДвиженияССубконто.Регистратор, | ПРЕДСТАВЛЕНИЕ(ДвиженияССубконто.Регистратор), | ДвиженияССубконто.СчетДт, | ДвиженияССубконто.СчетКт, | ДвиженияССубконто.Сумма |ИЗ | РегистрБухгалтерии.ОсновнойРегистрБухгалтерии.ДвиженияССубконто(&НачПериода, | &КонПериода, | Счет В ИЕРАРХИИ (&Счет)) | КАК ДвиженияССубконто | |УПОРЯДОЧИТЬ ПО | Период"; Запрос.УстановитьПараметр("КонПериода", КонПериода); Запрос.УстановитьПараметр("НачПериода", НачПериода); Запрос.УстановитьПараметр("Счет", Счет); Результат = Запрос.Выполнить(); КодКоррСчета = Счет.Код; ОборотДт = 0; ОборотКт = 0; ВыборкаДетали = Результат.Выбрать(); Пока ВыборкаДетали.Следующий() Цикл Если Найти(ВыборкаДетали.СчетДт.Код, КодКоррСчета) > 0 Тогда ОбластьДетальныхЗаписей.Параметры.СуммаДт = ВыборкаДетали.Сумма; ОборотДт = ОборотДт + ВыборкаДетали.Сумма; КонецЕсли; Если Найти(ВыборкаДетали.СчетКт.Код, КодКоррСчета) > 0 Тогда ОбластьДетальныхЗаписей.Параметры.СуммаКт = ВыборкаДетали.Сумма; ОборотКт = ОборотКт + ВыборкаДетали.Сумма; КонецЕсли; КонецЦикла; Этот вариант проверяет вхождение кода счета дебета или кода счета кредита (метод Найти()) в код счета, выбранного в диалоге. Не учитывается возмож- Глава 4. Реализация задач бухгалтерского учета 419 ность несовпадения иерархии кодов и иерархии счетов. В случае несовпадения иерархии кодов и счетов отчет будет сформирован неверно. Второй вариант (листинг 4.6) выполняет сравнение в запросе, его и рекомендуется использовать. Листинг 4.6. Фрагмент отчета «Карточка счета» Запрос = Новый Запрос; Запрос.Текст = "ВЫБРАТЬ | ДвиженияССубконто.Период КАК Период, | ДвиженияССубконто.Регистратор, | ПРЕДСТАВЛЕНИЕ(ДвиженияССубконто.Регистратор), | ВЫБОР | КОГДА ДвиженияССубконто.СчетДт В ИЕРАРХИИ (&Счет) | ТОГДА ДвиженияССубконто.Сумма | ИНАЧЕ 0 | КОНЕЦ КАК СуммаДт, | ВЫБОР | КОГДА ДвиженияССубконто.СчетКт В ИЕРАРХИИ (&Счет) | ТОГДА ДвиженияССубконто.Сумма | ИНАЧЕ 0 | КОНЕЦ КАК СуммаКт |ИЗ | РегистрБухгалтерии.ОсновнойРегистрБухгалтерии.ДвиженияССубконто(&НачПериода, | &КонПериода, | Счет В ИЕРАРХИИ (&Счет)) | КАК ДвиженияССубконто | |УПОРЯДОЧИТЬ ПО | Период |ИТОГИ | СУММА(СуммаДт), | СУММА(СуммаКт) |ПО | ОБЩИЕ"; Запрос.УстановитьПараметр("КонПериода", КонПериода); Запрос.УстановитьПараметр("НачПериода", НачПериода); Запрос.УстановитьПараметр("Счет", Счет); Результат = Запрос.Выполнить(); ВыборкаОбщийИтог = Результат.Выбрать(ОбходРезультатаЗапроса.ПоГруппировкам); ВыборкаОбщийИтог.Следующий(); // Общий итог ВыборкаДетали = ВыборкаОбщийИтог.Выбрать(); Пока ВыборкаДетали.Следующий() Цикл // … КонецЦикла; Это не означает, что нельзя проверить принадлежность группе при обходе результатов запроса. Можно. Но нужно проверять принадлежность родителю, а не «коду». 420 Реализация прикладных задач в системе «1С:Предприятие 8.2» Предопределенные и пользовательские счета План счетов может содержать счета, вводимые пользователем, и счета, введенные на этапе конфигурирования. Последние называются предопределенными и являются объектами конфигурации (имеют свое уникальное имя в рамках плана счетов). Нужно отметить, что для плана счетов, в отличие, например, от справочника, который обладает такой же возможностью, ввод счетов в режиме Конфигуратор является в большинстве случаев основным вариантом заполнения. План счетов, ну или по крайней мере его основа (счета первого уровня), создаются еще на этапе конфигурирования и во многом определяют логику учета. Ввод новых счетов (субсчетов) пользователем является скорее исключением, чем правилом. Свойства счета Предопределенные счета вводятся по кнопке Предопределенные с закладки Прочие плана счетов. При вводе для предопределенного счета есть возможность задать следующие свойства (табл. 4.8). Таблица 4.8. Свойства счета Свойство Комментарий Может изменяться пользователем Имя Имя объекта Нет Родитель Счет-родитель Да Код Код счета в соответствии с маской Да Наименование Наименование счета Да Вид счета Активный, Пассивный, Активный/Пассивный определяет Нет Забалансовый По счету не выполняется контроль двойной записи Нет Порядок Сортировка счетов в списке и запросах Да Признаки учета (сколько Участие счета в том или ином виде учета Нет Виды субконто (не более, Детализация счета в аналитическом учете Нет* Признаки учета субконто (сколько опреде- Возможность отключить ведение того или иного вида учета для одного вида субконто на счете Нет* вариант подсчета остатков по счету введено в плане счетов) чем определено в плане счетов) лено в плане счетов) Глава 4. Реализация задач бухгалтерского учета * 421 Для предопределенных счетов в режиме 1С:Предприятие можно добавлять новые виды субконто и изменять признаки учета субконто для этих видов субконто. Но нельзя удалять виды субконто счета, введенные в конфигураторе. А также нельзя изменять признаки учета субконто для этих видов субконто. Как мы видим часть свойств, которые мы задаем на этапе конфигурирования, могут изменяться пользователем при работе в информационной базе. По сути, задавая такие поля, как Код, Родитель, Наименование, Порядок, мы лишь указываем начальные стандартные значения. Пользователь сможет присвоить свой код, изменить наименование, переопределить родителя, установить новый порядок сортировки счетов. Особенности написания запросов Возможность изменения этих свойств необходимо учитывать при конфигурировании. Так, например, при написании запроса для получения остатка по одному счету можно поступить следующим образом (листинг 4.7). Листинг 4.7. Пример получения остатка по счету Запрос = Новый Запрос; Запрос.Текст = "ВЫБРАТЬ | Остатки.СуммаОстаток |ИЗ | РегистрБухгалтерии.ОсновнойРегистрБухгалтерии.Остатки( , Счет.Код = ""1.1"", , ) КАК Остатки"; Остатки = Запрос.Выполнить().Выбрать(); Остатки.Следующий(); Остаток = Остатки.СуммаОстаток; В этой процедуре выполняется запрос, получающий из виртуальной таблицы регистра бухгалтерии РегистрБухгалтерии.ОсновнойРегистрБухгалтерии.Остатки остаток по счету с кодом 1.1, который в нашем плане счетов называется Касса. Ну, или, точнее, назывался на этапе конфигурирования. Если пользователь изменит код счета, запрос или не будет выполнен, или будет выполнен не по тому счету. Поэтому всегда имеет смысл при установке отборов по счетам использовать или ссылку (полученную, например, путем выбора в диалоге элемента из плана счетов), или неизменяемое имя предопределенного счета (рис. 4.16). 422 Реализация прикладных задач в системе «1С:Предприятие 8.2» Рис. 4.16. Свойства предопределенного счета ВНИМАНИЕ! Когда мы сказали о необходимости использовать имя для получения ссылки на предопределенный счет плана счетов, имелось в виду свойство счета Имя, а не наименование счета. Имя – свойство любого объекта метаданных конфигурации, в том числе и предопределенного счета плана счетов. Имя служит для однозначной идентификации счета в плане счетов конфигурации и как следствие может использоваться для получения ссылки на объект. Листинг 4.8. Пример получения остатка по счету Запрос = Новый Запрос; Запрос.Текст = "ВЫБРАТЬ | Остатки.СуммаОстаток |ИЗ | РегистрБухгалтерии.ОсновнойРегистрБухгалтерии.Остатки( , Счет = &Счет, , ) КАК Остатки"; Запрос.УстановитьПараметр("Счет", ПланыСчетов.ОсновнойПланСчетов.Касса); Остатки = Запрос.Выполнить().Выбрать(); Остатки.Следующий(); Остаток = Остатки.СуммаОстаток; Основы организации аналитического учета Иерархический план счетов позволяет организовать детальный учет. И при желании можно организовать детальный аналитический учет, используя возможность организации иерархического плана счетов и ввода новых субсчетов пользователем. Однако эта детализация будет иерархической. При такой организации аналитического учета не представляется возможным получение итогов по нескольким параллельным срезам. Рассмотрим учет товаров на складах. Предположим, в нашей организации есть несколько складов, на каждом из которых множество видов номенклатурных позиций. Перед нами стоит задача обеспечить получение остатков и оборотов по каждому складу и товару в отдельности и сводно по всем. Задачу можно Глава 4. Реализация задач бухгалтерского учета 423 решить, используя субсчета счета Товары. Изменив длину кода счета (до 10 символов) и маску кода счета @@.@@.@.@@, мы можем завести к счету учета товаров необходимое количество субсчетов (рис. 4.17). Рис. 4.17. План счетов «Основной план счетов» Подобная организация аналитического учета возможна, но имеет ряд существенных недостатков. Во-первых, план счетов будет расти (и расти существенно) по мере изменения номенклатуры товаров (добавления новых позиций, отказа от старых и появления неиспользуемых). Во-вторых, он будет расти нелинейно, т. к. одна и та же позиция номенклатуры может храниться на разных складах; таким образом, количество субсчетов на каждую позицию будет равняться количеству складов. И самое главное – не представляется возможным автоматически сгруппировать данные по одной позиции номенклатуры, хранимой на разных складах. Организацию аналитического учета с использованием субсчетов нельзя назвать неправильной. Это вполне возможный вариант, который имеет свои ограничения (мы перечислили их выше) и свои достоинства. К достоинствам можно отнести, например, интуитивную прозрачность учета для любого бухгалтера, который ранее не сталкивался с учетом при помощи компьютерной программы, всю жизнь проработал в «бумажной бухгалтерии». Однако подавляющее большинство бухгалтеров предпочитают бухгалтерские программы с большими возможностями в части ведения аналитического учета. Для описания возможностей системы при автоматизации задач аналитического учета используются понятия Вид субконто и Субконто. Вид субконто – группа однородных объектов аналитического учета. Понятие вид субконто соответствует понятию бухгалтерского учета «аналитический счет». В демонстрационной конфигурации «Бухгалтерский учет», которая 424 Реализация прикладных задач в системе «1С:Предприятие 8.2» находится на прилагаемом компакт-диске, возможны следующие виды субконто: ■ список контрагентов для ведения учета расчетов в разрезе контрагентов; ■ список номенклатуры товаров; ■ список складов для учета товаров на складах; ■ список статей затрат для учета затрат; ■ и другие. Каждый элемент списка вида субконто представляет собой объект аналитического учета и называется Субконто. Ни субконто, ни вид субконто не имеют объектного представления в системе и существуют лишь как понятия, реализуемые с помощью других объектов. Виды субконто, как правило, бывают ссылочного типа и содержат в себе ссылку на справочник, документ или перечисление, хотя возможны и другие варианты. Если видом субконто является справочник, то субконто – один элемент этого справочника. Сами по себе виды субконто не хранят никакой информации об остатках и оборотах по счетам и являются, по сути, подключаемыми измерениями для счетов плана счетов. Использование видов субконто для организации аналитического учета можно представить в виде схемы на рис. 4.18. Рис. 4.18. Использование видов субконто для организации аналитического учета Глава 4. Реализация задач бухгалтерского учета 425 Левая часть схемы описывает наш иерархический план счетов. Каждый из счетов предназначен для ввода и хранения относительно укрупненной информации – остаток всех товаров на всех складах, долг всех покупателей, задолженность перед всеми поставщиками и др. Вместо того, чтобы развивать субсчета у названных счетов, мы открываем на них аналитический учет, используя виды субконто. Каждый счет на данной схеме можно рассматривать как учетный регистр, накапливающий остатки и обороты в денежном выражении. Виды субконто позволяют добавлять измерения в эти регистры и создают новые сущности. Так, например, один и тот же справочник Контрагенты может использоваться для организации аналитического учета как на счете Покупатели, так и на счете Поставщики. Анализируя остатки и обороты по счету Покупатели в разрезе объектов аналитического учета (контрагентов), мы получим список наших покупателей, остатки (задолженность) и обороты (увеличение, погашение) по каждому из них. Возможность системы привязать к одному счету несколько самостоятельных видов субконто позволяет нам получить фасетное (параллельное) деление: например, на одном складе могут быть разные товары, один и тот же товар может быть на разных складах. Мы всегда можем получить остаток по складу, по товару и по товару на складе. План видов характеристик для создания списка видов субконто Для хранения списка видов субконто используется объект План видов характеристик. Получаются два уровня вложенности: план, представляющий собой совокупность видов субконто, и вид субконто. Каждый вид субконто хранит информацию о типе характеристик, являющихся объектами аналитического учета, т. е. субконто. Характеристика – это один экземпляр вида характеристик, так же как субконто – это один экземпляр вида субконто. Характеристика не является самостоятельным объектом конфигурации. Для ведения аналитического учета, как правило, используются элементы справочников, значения перечисления, ссылки на документы. Виды характеристик, как правило, имеют ссылочный тип данных (хотя возможны и другие варианты). Один план видов характеристик может использоваться для организации аналитического учета для нескольких планов счетов. Можно провести следующие параллели между понятиями системы и понятиями предметной области (табл. 4.9). Таблица 4.9. Соответствие понятий системы «1С:Предприятие» и понятий предметной области Объект Понятие Планы видов характеристик Все виды субконто Вид характеристики Вид субконто Характеристика Субконто 426 Реализация прикладных задач в системе «1С:Предприятие 8.2» Начнем организацию аналитического учета с создания нового плана видов характеристик. Назовем его ВидыСубконто (рис. 4.19 и 4.20). Рис. 4.19. Основные свойства плана видов характеристик Рис. 4.20. Тип значения характеристик Так как в качестве объектов аналитики могут выступать данные разных объектов (разных справочников, как в нашем случае, или справочников, и документов, и перечислений и др.), то тип значения характеристик устанавливается составным. Фактически в диалоге редактирования типа характеристик Глава 4. Реализация задач бухгалтерского учета 427 мы выбираем объекты конфигурации, которые будут использоваться для ведения аналитического учета. Выбираем, какого типа виды субконто мы (и пользователь) сможем создавать. Нужно отметить, что поле диалога для выбора значения субконто в документах, отчетах и других механизмах будет иметь тип Характеристика.ВидыСубконто плана видов характеристик ВидыСубконто. А тип значения поля в базе данных будет составным и будет включать все выбранные в типе значения характеристик типы. ПРИМЕЧАНИЕ Не рекомендуется включать в тип значения характеристик какие-либо типы, кроме ссылочных. Это существенно повышает нагрузку на систему. В базе данных поле составного типа, включающего в себя только ссылочные типы данных, хранится в трех полях таблицы (фактический тип хранимого значения, номер таблицы, на которую ссылается значение, и идентификатор записи, на которую ссылается значение). При добавлении в составной тип данных примитивных типов на каждый из них добавляется новое поле в базу данных. Кроме увеличения объема базы данных, это имеет еще одну негативную сторону: система выполняет индексирование полей для хранения итогов по субконто таблиц регистра бухгалтерии, и количество полей в индексе ограничено в SQL-версии 16 полями, часть из которых уже занята под счет, период, измерения. Более подробно эта тема рассмотрена в разделе «Индексы таблиц итогов регистра бухгалтерии» на стр. 545. Как и счета плана счетов, виды субконто могут создаваться как в режиме Конфигуратор, так и в пользовательском режиме. Если мы не считаем необходимым предоставлять пользователю возможность создавать собственные виды субконто, то настройку закладки Общая можно на этом закончить, перейти на закладку Прочее и создать предопределенные виды характеристик (рис. 4.21). Рис. 4.21. Предопределенные виды характеристик У пользователя все равно будет возможность создавать новые виды субконто, но только тех типов данных, которые мы выбрали в качестве возможных типов значения характеристик. Например, он сможет создать еще один вид 428 Реализация прикладных задач в системе «1С:Предприятие 8.2» субконто Продавцы типа СправочникСсылка.Контрагенты, но физически эти продавцы будут находиться в справочнике Контрагенты. Маловероятно, что пользователю пригодится такая возможность. Скорее всего, он предпочел бы создать новый вид субконто и хранить в нем какие-то новые объекты аналитики, для которых не предусмотрено справочника в конфигурации. Для предоставления пользователю возможности создавать собственные виды субконто предусмотрен механизм дополнительных значений характеристик. Для этого создается новый справочник в конфигурации, который мы назовем, например, Субконто. Потом включим его в тип значения характеристик и получим таким образом «местечко про запас», где пользователь сможет хранить собственные объекты аналитики. Рис. 4.22. Владельцы справочника «Субконто» Глава 4. Реализация задач бухгалтерского учета 429 Теперь пользователь сможет создать сколько угодно видов субконто, имеющих тип этого справочника, но все его объекты аналитики будут лежать «вперемешку». Чтобы предоставить пользователю возможность создавать отдельные подмножества объектов аналитики, справочник Субконто необходимо сделать подчиненным плану видов характеристик. Подчиненность справочника Субконто плану видов характеристик – обязательное условие функционирования механизма дополнительных характеристик (рис. 4.22). Тем самым мы предоставили пользователю возможность создать сколько угодно новых видов субконто. Физически все они будут храниться в одном справочнике, но «перемешиваться» не будут, т. к. на каждый новый вид субконто в справочнике будет выделяться новое множество подчиненных ему элементов. А чтобы нумерация этих элементов была также независимой, имеет смысл на закладке Нумерация объекта конфигурации Справочник Субконто установить переключатель Серии кодов в значение В пределах подчинения владельцу. Последний штрих – выбрать справочник Субконто в качестве дополнительных значений характеристик (рис. 4.23). Теперь вновь создаваемые пользователем виды субконто (виды характеристик) по умолчанию будут иметь тип значения СправочникСсылка.Субконто. Рис. 4.23. Дополнительные значения характеристик 430 Реализация прикладных задач в системе «1С:Предприятие 8.2» Более подробно про план видов характеристик можно прочитать в разделе «Хранение дополнительных характеристик произвольного типа. Использование плана видов характеристик» на стр. 114. Детализация счета плана счетов по видам субконто Теперь, когда созданы «аналитические счета» – виды субконто, нужно, чтобы они заработали и позволили вести аналитический учет на счетах, которые ранее были синтетическими. Для этого необходимо привязать виды субконто к счетам плана счетов. Выполняется это в объекте План счетов. Начинаем настройку с закладки Субконто. На этой закладке в свойстве Виды субконто выбираем план видов характеристик, который хранит виды субконто для этого плана счетов (рис. 4.24). Рис. 4.24. Субконто плана счетов Закладка Субконто также позволяет определить максимальное количество субконто на счете. Это число параллельных аналитических срезов (видов субконто), которое можно будет выбрать для каждого счета. И число это в большинстве случаев определяется отчетными потребностями объекта автоматизации. На рисунке выбрано значение 2, в типовом решении «Бухгалтерия предприятия» выбрано значение 3, максимально возможное поддерживаемое платформой значение 50. Выбор максимального количества Глава 4. Реализация задач бухгалтерского учета 431 субконто – важный этап в проектировании системы автоматизации бухгалтерского учета, и мы остановимся на нем отдельно в разделе «Принятие решений при организации аналитического учета» на стр. 439. Пока же установка этого свойства привела к тому, что для каждого счета плана счетов было добавлено новое свойство – специализированная табличная часть Виды субконто. И содержать эта табличная часть в нашей конфигурации может максимум две строки. Подчеркнем: именно в нашей конфигурации (где в свойствах плана счетов выбрано значение максимального количества субконто равным двум) и именно для каждого счета (разные счета могут иметь различную детализацию), рис. 4.25. Рис. 4.25. Виды субконто Каждая из строк табличной части содержит ссылку на вид характеристики плана видов характеристик, выбранного в свойстве плана счетов Виды субконто, и дополнительные свойства. Каждая строка табличной части ВидыСубконто содержит следующие поля: ВидСубконто, Предопределенное, ТолькоОбороты и признаки учета субконто. ВидСубконто – свойство типа ПланВидовХарактеристикСсылка.<имя>, позволяющее получить доступ к свойствам вида характеристики плана видов характеристик. Это поле задает вид субконто, в разрезе которого будет вестись аналитический учет. Кроме того, оно может быть использовано, например, при установке типов значений для реквизитов формы или для полей построителя отчета (листинг 4.9). 432 Реализация прикладных задач в системе «1С:Предприятие 8.2» Листинг 4.9. Пример использования свойства «ВидСубконто» Для Каждого ВидСубконто Из Счет.ВидыСубконто Цикл Вид = ВидСубконто.ВидСубконто; ТипЗначения = Вид.ТипЗначения; Наименование = Вид.Наименование; ВведенВКонфигураторе = ВидСубконто.Предопределенное; Оборотный = ВидСубконто.ТолькоОбороты; Количественный = ВидСубконто.Количественный; КонецЦикла; В приведенном примере счет – переменная или поле ввода типа ПланСчетовСсылка.<имя>. Цикл по видам субконто счета позволит узнать их типы, наименования, были они введены в конфигураторе (предопределенный вид субконто был добавлен на счет в режиме Конфигуратор) или добавлены пользователем, узнать признаки учета субконто. Ввод в диалоге и хранение в базе данных объектов аналитического учета С тех пор, как нами была добавлена возможность ведения аналитического учета, в нашей конфигурации должны будут произойти изменения. Теперь пользователю будет необходимо в диалогах форм отчетов, документов, а может быть и не только, выбирать объекты аналитики, соответствующие выбранному уже в том же диалоге счету. А информационной базе придется сохранять этот сделанный пользователем выбор. Для хранения выбранного пользователем объекта аналитики в конфигурации предусмотрен специальный тип данных Характеристика.<Имя>. Этот тип данных может быть назначен реквизиту формы и реквизиту объекта, хранимому в информационной базе. Этот тип данных является составным и включает в себя все типы данных, выбранные в свойстве Тип значения характеристик плана видов характеристик. Рассмотрим первый пример, в котором пользователь должен в документе (или справочнике) выбрать сначала в первом поле ввода вид субконто, а затем в другом – объект субконто выбранного ранее вида. Для этого добавим в форму обработки два реквизита: ВидСубконто типа ПланВидовХарактеристикСсылка.ВидыСубконто и Субконто типа Характеристика.ВидыСубконто (рис. 4.26). Если этим ограничиться, то при выборе значения субконто в диалоге формы пользователю сначала будет предлагаться выбор типа из списка типов значений характеристик Виды субконто. Глава 4. Реализация задач бухгалтерского учета 433 Рис. 4.26. Реквизиты «Субконто» и «ВидСубконто» Следующая наша задача – ограничить выбор только типами выбранного пользователем вида субконто. Для этого в свойствах поля ввода Субконто необходимо установить свойство Связь по типу в значение, указывающее на реквизит Виды субконто. Теперь, если, например, пользователем выбран вид субконто Контрагенты (который в нашей конфигурации имеет тип значения СправочникСсылка.Контрагенты), то диалог выбора типа будет содержать только те типы значений, которые может принимать данный вид субконто. Также свойство Связи параметров выбора поля ввода Субконто нужно установить как Отбор.Владелец(ВидСубконто). В результате при выборе значений субконто, содержащихся в справочнике Субконто, для выбора будут предлагаться только те значения, которые относятся к выбранному виду субконто. Диалог выбора типа данных будет предлагаться в случае, если выбранный вид субконто содержит несколько типов данных. В практике создания механизмов для ведения бухгалтерского учета чаще, однако, встречается другая ситуация, когда пользователь выбирает в диалоге формы счет и далее должен выбрать значения субконто того типа данных, который выбран для видов субконто этого счета. 434 Реализация прикладных задач в системе «1С:Предприятие 8.2» В таком случае в диалоге формы размещают поле ввода для реквизита Счет (тип ПланСчетовСсылка.<имя>) и устанавливают связь между полем ввода для выбора значения субконто и счетом (минуя вид субконто, который становится не нужен). Создадим в документе следующие реквизиты: Счет (тип ПланСчетовСсылка.ОсновнойПланСчетов), Субконто1 (тип Характеристика.ВидыСубконто) и Субконто2 (тип Характеристика.ВидыСубконто). В свойствах нашего плана счетов выбрано максимальное количество субконто равным двум, поэтому более двух значений субконто для одного счета выбирать не потребуется. Установим свойства реквизитов Субконто1 и Субконто2 Связь по типу, в которых в этот раз мы укажем реквизит Счет (рис. 4.27). Рис. 4.27. Реквизиты «Субконто» и «Счет» документа «ВыборСубконтоСчета» Теперь диалог выбора типа в форме документа будет содержать только те типы значений, которые могут принимать виды субконто выбранного пользователем счета. Чтобы оставить только те типы (или один тип, если используется субконто не составного типа), которые нужны для выбора первого вида Глава 4. Реализация задач бухгалтерского учета 435 субконто, необходимо установить значение свойства Элемент связи по типу равным 1. Для реквизита Субконто2 это свойство будет равным 2. Свойство Элемент связи по типу позволяет указать порядковый номер вида субконто на счете, значение которого должно выбираться в соответствующем поле ввода. Следующая наша задача – избавиться от диалога выбора типа. Для этого создадим форму документа и напишем процедуру – обработчик события ПриИзменении поля ввода Счет (листинг 4.10). Листинг 4.10. Обработчик события «ПриИзменении» поля ввода «Счет» &НаКлиенте Процедура СчетПриИзменении(Элемент) ВыбиратьТипСубконто(); УстановитьВидимостьСубконто(); КонецПроцедуры При изменении счета вызывается сначала процедура ВыбиратьТипСубконто() и затем процедура УстановитьВидимостьСубконто() (листинг 4.11). Листинг 4.11. Процедура «ВыбиратьТипСубконто» &НаСервере Процедура ВыбиратьТипСубконто() ЧислоСубконто = Объект.Счет.ВидыСубконто.Количество(); Для Сч = 1 По ЧислоСубконто Цикл ТипСубконто = Объект.Счет.ВидыСубконто[Сч - 1].ВидСубконто.ТипЗначения; Элементы["Субконто" + Сч].ВыбиратьТип = (ТипСубконто.Типы().Количество() > 1); Если ТипСубконто.ПривестиЗначение(Объект["Субконто" + Сч]) <> Объект["Субконто" + Сч] Тогда Объект["Субконто" + Сч] = ТипСубконто.ПривестиЗначение(Объект["Субконто" + Сч]); КонецЕсли; КонецЦикла; КонецПроцедуры Прокомментируем текст этой процедуры. Процедура написана достаточно универсально и не зависит от настроек ведения аналитического учета плана счетов. Сначала мы узнаем число субконто, задействованных для ведения 436 Реализация прикладных задач в системе «1С:Предприятие 8.2» аналитического учета на выбранном счете. В цикле по количеству субконто на счете мы получаем описание типов субконто. Для этого обращаемся к табличной части счета ВидыСубконто и получаем из нее строку, обращаясь к ней по индексу (индексация строк этой табличной части начинается с нуля). Выбор типа из поля ввода субконто имеет смысл только для субконто составного типа (такие тоже могут быть). Мы определяем количество типов, входящих в описание типа, и, если этот тип составной (более одного), устанавливаем флажок элемента формы ВыбиратьТип. Наша процедура расположена в модуле формы документа. Основной реквизит этой формы ДокументОбъект. Мы стараемся писать процедуру универсально, поэтому предусматриваем возможность ее вызова не только при изменении счета, но и, например, при открытии формы. Чтобы не устанавливать флажок модифицированности при открытии формы, мы проверяем тип значения реквизита на соответствие типу субконто и приводим тип только в том случае, если тип реквизита отличается от типа описания субконто. Последний штрих в работе этого механизма – управление видимостью полей ввода субконто и заголовками для этих полей. Это связано с тем, что не на каждом счете используются оба вида субконто, могут быть счета, где задействован только один аналитический разрез или вообще ни одного (листинг 4.12). Листинг 4.12. Процедура «УстановитьВидимостьСубконто» Процедура УстановитьВидимостьСубконто() Для НомерСубконто = 1 по 2 Цикл Если (НомерСубконто <= Объект.Счет.ВидыСубконто.Количество()) и (НЕ Объект.Счет.Пустая()) Тогда Элементы["Субконто"+НомерСубконто].Заголовок = Строка(Объект.Счет.ВидыСубконто[НомерСубконто-1].ВидСубконто); Элементы["Субконто"+НомерСубконто].Видимость = Истина; Иначе Элементы["Субконто"+НомерСубконто].Видимость = Ложь; КонецЕсли; КонецПроцедуры Вызов этой процедуры из обработчика события формы ПриСозданииНаСервере и обработчика события ПриИзменении поля ввода Счет позволит скрыть неиспользуемые поля ввода субконто, а для используемых полей назначить заголовки – имена видов субконто. Глава 4. Реализация задач бухгалтерского учета 437 Признаки учета субконто Признаки учета субконто будут рассмотрены нами подробнее при изучении регистра бухгалтерии в разделе «Свойство ресурса «Признак учета субконто»» на стр. 459. Пока же рассмотрим вкратце их предназначение и создание. Признаки учета субконто дополняют специализированную табличную часть Виды субконто новыми свойствами типа Булево. Каждое свойство, связанное с ресурсом регистра бухгалтерии, позволяет управлять хранением остатков и оборотов выбранного ресурса для объектов субконто выбранного счета (рис. 4.28). Рис. 4.28. Признаки учета субконто Приведенная выше картинка демонстрирует, что для плана счетов Основной план счетов предусмотрена возможность отключать для отдельных видов субконто ведение количественного и суммового учета. Так, например, если на счете товаров необходимо учитывать номенклатурные позиции товаров 438 Реализация прикладных задач в системе «1С:Предприятие 8.2» в количественном выражении в разрезе складов, а в суммовом – по предприятию в целом (без учета складов), то настройка счета будет выглядеть как на рис. 4.28. Свойство Только обороты схоже по своему назначению с признаками учета субконто. Оно ограничивает хранение итогов по субконто счета только хранением оборотов, исключая из таблиц итогов остатки. Это может быть необходимо в случае, когда остатки по субконто просто не имеют смысла. Например, учет на счете денежных средств в разрезе статей, характеризующих виды поступления и списания средств. В таком учете остаток по статье не будет нести никакого экономического смысла. По одной статье мы получаем денежные средства, по другой – списываем. Результатом аналитического учета станут постоянно растущие и никогда не списываемые остатки по статьям, по одним из них – положительные, по другим – отрицательные. Рассмотрим программное заполнение субконто счета и их свойств. Следующий фрагмент кода (листинг 4.13) позволяет узнать, ведется ли на счете Товары учет в разрезе субконто Склады, и если нет, то добавить это субконто на счет, включив на нем признаки учета субконто – суммовой и количественный. Листинг 4.13. Пример программного заполнения субконто и их свойств Счет = ПланыСчетов.ОсновнойПланСчетов.Касса; ВидСубконто = ПланыВидовХарактеристик.ВидыСубконто.Сотрудники; Если Счет.ВидыСубконто.Найти(ВидСубконто,"ВидСубконто") = Неопределено Тогда СчетОбъект = Счет.ПолучитьОбъект(); КонецЕсли; НовыйВид = СчетОбъект.ВидыСубконто.Добавить(); НовыйВид.ВидСубконто = ВидСубконто; НовыйВид.Суммовой = Истина; НовыйВид.Количественный = Истина; СчетОбъект.Записать(); ПРИМЕЧАНИЕ Комментируя это процедуру, необходимо уточнить, что добавление вида субконто на счет возможно только в том случае, если табличная часть получена как свойство объекта Счет. Кроме того, нужно учитывать, что проверка на превышение максимального количества видов субконто для плана счетов будет выполняться только при записи счета. Глава 4. Реализация задач бухгалтерского учета 439 Принятие решений при организации аналитического учета От организации плана счетов и аналитического учета во многом зависит не только функциональность, но и производительность конфигурации. Остановимся подробнее на наиболее важных моментах организации аналитического учета в конфигурации. Как правило, организация аналитического учета определяется отчетными потребностями руководства, организационной структурой предприятия, необходимостью выполнения стандартов учета (международных, государственных, внутрифирменных и т. д.). Рассмотрим пример организации учета товаров. Пользователь изъявил желание вести учет товаров в разрезе номенклатуры товаров. Желание разумное, ведь подобная организация аналитического учета позволит ему анализировать остатки и обороты по каждой номенклатурной позиции. Список товаров существенный и незакрытый (в него добавляются новые позиции, удаляются старые). Кроме кода и наименования номенклатуры необходимо хранить и другую дополнительную, но важную информацию. Ниже приводится таблица (табл. 4.10), позволяющая в конкретном случае принять решение об оптимальности использования механизма платформы. Таблица 4.10. Решение первое. Выбор: субсчета или субконто Критерий Учет на субсчетах Учет на субконто Количество позиций От единиц до десятков От десятков до бесконечности Список позиций учета закрыт Как правило, да Может и будет расширяться Параллельные срезы возможны Только иерархический учет Несколько параллельных срезов Достаточная информативность Кода и наименования достаточно Есть дополнительные свойства Принимаем решение: вести учет на счете товаров в разрезе субконто Номенклатура типа СправочникСсылка.<имя>. Следующее желание пользователя – получать дополнительные группировки и отборы в отчетах по складам, что соответствует организационной структуре предприятия, и списывать товары методом FIFO. Дополнительно потребуется группировка в отчете Остатки товаров по годам приобретения имеющихся на складе МПЗ и видам товаров. По партиям и складам, основываясь на предыдущей таблице, принимаем решение о необходимости открытия новых видов субконто Партии и Склады на счете учета товаров. По видам товаров и годам закупки МПЗ решение может быть проще (табл. 4.11). 440 Реализация прикладных задач в системе «1С:Предприятие 8.2» Таблица 4.11. Решение второе. Выбор: новый вид субконто или новое свойство старого Критерий Новый вид субконто Новое свойство субконто Можно ли однозначно связать Связать невозможно, это Новый критерий вполне новый критерий отбора (груп- параллельный срез можно разместить как новое пировки) с существующим свойство существующего объектом аналитического вида аналитики учета Принимаем решение: вид товара – это новый реквизит справочника Номенклатура, год можно получить из партии товара. Стало быть, добавления новых видов аналитики эти два критерия не потребовали. В результате пришли к выводу, что для получения затребованной информации потребуется ведение аналитического учета на счете товаров в разрезе трех независимых видов аналитики: номенклатура, склады и партии. Следующий вопрос: порядок следования видов аналитики. Более подробно об организации регистра бухгалтерии мы расскажем потом, пока же заметим, что физическая организация таблиц позволяет наиболее быстро получать развернутые отчеты по тем аналитическим срезам, которые находятся «ближе к счету» (табл. 4.12). Таблица 4.12. Решение третье. Выбор: порядок следования видов субконто Критерий Первый на счете По какому аналитическому срезу отчеты Номенклатура чаще всего будут «разворачиваться», по какому реже Последний на счете Склады Принимаем решение: первый вид субконто на счете будет Номенклатура, второй Партии, третий Склады. Следующая наша задача – оценить возможность использования трех видов субконто на счете со стороны типового (или просто существующего) решения, которое мы адаптируем, и со стороны платформы. Любое типовое решение ориентировано, как правило, на фиксированное заданное максимальное количество субконто на счете. Так, например, конфигурация «Бухгалтерия предприятия» содержит в себе набор документов, среди которых есть универсальные, и отчетов, предназначенных для работы максимум с тремя видами субконто на счете (три поля для выбора). Кроме того, важно оценить влияние изменившейся аналитики счета на работу существующих механизмов типового решения. Любое изменение аналитики счета, задействованного в автоматических учетных схемах, может привести к существенной переделке этих схем, даже если не превышено максимальное количество субконто, установленное в свойствах плана счетов. А если к Глава 4. Реализация задач бухгалтерского учета 441 тому же требуется увеличить максимальное количество субконто, предусмотренное в плане счетов типового решения и как следствие прописанное во всех универсальных механизмах, переделка коснется и их. Формальное ограничение со стороны платформы на максимальное количество субконто составляет 50 субконто на счете. Именно формальное, так как существует особенность работы сервера базы данных при построении индексов таблиц, о которой более подробно будет рассказано в разделе «Индексы таблиц итогов регистра бухгалтерии» на стр. 545. Во многих случаях при проектировании плана счетов имеет смысл обдумать возможность вынесения отдельных разделов учета из бухгалтерии в оперативный учет, который может быть реализован с помощью регистров накопления (о регистрах см. главу «Реализация задач учета движения средств» на стр. 249). При принятии решения о необходимости вынесения раздела в оперативный учет имеет смысл учитывать критерии, перечисленные в табл. 4.13. Таблица 4.13. Решение четвертое. Выбор: оперативный или бухгалтерский учет Критерий Субконто бухгалтерии Измерения оперативного учета Максимальное количество субконто, выбранное в плане счетов демонстрационной конфигурации Максимальное количество субконто, с которыми эффективно может работать платформа Количество объектов учета Количество документов в день Измерение примитивного типа Влияние на бухгалтерский баланс Не более двух * Нет ограничения, может быть создан регистр с нужным количеством измерений * Десятки, сотни, тысячи ** Единицы, десятки ** Десятки и сотни тысяч ** Десятки, сотни ** * Настоятельно не рекомен- В принципе возможно дуется Необходимо Не рекомендуется Ее представляется возможным дать этот критерий в количественном выражении, не увидев и не проанализировав задачу, которую необходимо решить. Можно сказать лишь, что при решении одной и той же задачи автоматизации одного раздела учета наличия и движения средств регистр накопления будет эффективнее регистра бухгалтерии. Это обусловлено универсальностью регистра бухгалтерии, платой за которую является эффективность. ** Количественные оценки очень приблизительны и неточны, и причина этого все та же: невозможно дать универсальные рекомендации. Правильное решение должно быть результатом оценки каждой конкретной задачи, и осуществляется эта оценка на этапе технического проектирования задачи после детального изучения объекта автоматизации. 442 Реализация прикладных задач в системе «1С:Предприятие 8.2» Отдельно можно выделить последний критерий: влияние на бухгалтерский баланс. Разделяя учет на бухгалтерский и оперативный, в качестве критерия можно использовать необходимость включения информации с выбранной детализацией в сводные формы бухгалтерской отчетности (в первую очередь бухгалтерский баланс). Приведем пример: в бухгалтерском балансе товары входят в раздел «Оборотные активы» и отображаются там свернуто (без деления по номенклатуре, складам, партиям). Вывод: можно целиком вынести этот аналитический разрез в оперативный учет. Еще один пример: в бухгалтерском балансе задолженность контрагентов (перед контрагентами) отображается развернуто по контрагентам. Значит, ведение учета по контрагентам должно выполняться с помощью субконто плана счетов на регистре бухгалтерии, т. к. баланс должен строиться только на основании данных, введенных методом двойной записи. А если взаиморасчеты еще нужно вести в разрезе договоров? Если развернутая информация по договорам или по срокам погашения задолженности, которая хранится в договоре, используется в балансе, значит, это субконто. А если нет, значит, можно вынести учет по договорам в регистры накопления. Принимаем решение: в нашем случае учет МПЗ можно было бы «вынести» в оперативный учет. Отдельно следует рассмотреть возможность использования небалансовых измерений регистра для ведения сквозного аналитического учета для всех (или большинства) счетов. Об этих возможностях платформы рассказано в разделе «Измерения регистра бухгалтерии» на стр. 463. Предназначение регистра бухгалтерии В разрезе чего ведется бухгалтерский учет? В разрезе счетов бухгалтерского учета, управление которыми осуществляется с использованием объекта План счетов; в разрезе объектов аналитического учета, управлять списком которых позволяет объект План видов характеристик. Это как минимум. Возможны и другие разрезы. Где ведется бухгалтерский учет? Где хранятся проводки? Как эти проводки формировать и записывать? Как рассчитываются остатки и обороты по счетам и получаются бухгалтерские отчеты? На все эти вопросы отвечают свойства и методы объекта Регистр бухгалтерии. Но прежде чем приступить к их изучению, давайте договоримся, что будем иметь в виду под «бухгалтерским учетом». Глава 4. Реализация задач бухгалтерского учета 443 Можно приводить различные определения, которыми изобилуют учебники, но нам важно понять отличия этого вида учета от оперативного. У этих двух видов учета много общего: оба вида учета предназначены для решения одной и той же задачи – накопления и анализа каких-либо показателей в разрезе каких-либо измерений. Основные отличия заключаются в том, как это делается и для чего это делается. В первую очередь для чего. Задача оперативного учета – управление (часто оперативное, в реальном времени) одним (или несколькими, но не всеми) участком учета предприятия. Задача бухгалтерского учета – управление всей финансово-хозяйственной деятельностью предприятия. И решение этой задачи требует использования специфических методов, в первую очередь двойной записи на счетах, которая образует замкнутую систему показателей. Итак, приведем основные отличия двух этих видов учета (табл. 4.14) и ответим на вопрос, почему нельзя обойтись только механизмами оперативного учета. Таблица 4.14. Основные отличия оперативного и бухгалтерского видов учета Критерий Оперативный учет Бухгалтерский учет Охват деятельности предприятия Один или несколько участков Вся хозяйственная деятельность Измеритель Любой и зависит от участка В едином денежном выражении Обязательные разрезы учета Отсутствуют Счета бухгалтерского учета Показатели Независимые Взаимосвязанные Метод учета Произвольный Двойная запись Из отличий в видах учета вытекают и отличия в механизмах платформы, их реализующих. Необходимость учета всего множества хозяйственных операций предприятия исключает возможность задать однажды состав и структуру учетных регистров и не изменять их в процессе работы пользователя. В процессе работы возникают новые виды деятельности, новые хозяйственные операции и как результат новые учетные регистры, которые также должны попасть в баланс двойной записи. Причем возможность создавать эти новые учетные регистры предоставлена не только программисту, но и пользователю программного продукта. Достигается эта возможность за счет добавления новых счетов в план счетов и определения для них аналитики путем выбора вида субконто из списка существующих в конфигурации или добавления новых видов субконто в план видов характеристик. 444 Реализация прикладных задач в системе «1С:Предприятие 8.2» По своей сути регистр бухгалтерии – это «регистр регистров», совокупность регистров. Один регистр бухгалтерии содержит в себе множество учетных регистров (счетов), каждый из которых может иметь независимую аналитику (субконто), в разрезе которой и будут отражаться учетные показатели. В целях контроля все учетные регистры (счета) связаны между собой правилом двойной записи, которое образует замкнутую систему показателей: невозможно изменить значение показателя одного учетного регистра, не затронув другой, причем на ту же сумму. Счет бухгалтерского учета служит для указания, к какой области учета относится показатель, а набор субконто – измерения, в разрезе которых необходимо его учитывать. Если рассматривать только синтетическую составляющую плана счетов, который мы реализовали в нашей конфигурации, и вести учет только в денежном выражении, можно интерпретировать наш план счетов в виде совокупности регистров учета (регистров накопления). При этом каждый счет будет представлен в этой совокупности отдельным регистром учета. Дополнительно должен быть организован еще один регистр, задача которого – хранить обороты между счетами (разделами учета). Таблица Проводки (обороты) будет создана только в том случае, если используется регистр бухгалтерии с поддержкой корреспонденций (табл. 4.15). Таблица 4.15. Перечень регистров учета Регистр Измерения Ресурсы Касса Сумма Покупатели Сумма Товары Сумма Материалы Сумма Контрагенты Сумма Сотрудники Сумма Поставщики Сумма Капитал Сумма Проводки (обороты) Счет Дт Счет Кт Сумма Подобный набор регистров накопления позволит полностью реализовать бухгалтерский синтетический учет (учет в денежном выражении в валюте учета на счетах бухгалтерского учета). Пользователь сможет анализировать остатки и обороты по каждому разделу учета, а также обороты между счетами. Глава 4. Реализация задач бухгалтерского учета 445 Проводку, представленную в табл. 4.16, можно записать с помощью следующих движений в регистрах учета (табл. 4.17). Таблица 4.16. Пример проводки Дебет Кредит Сумма Касса Капитал 100 Таблица 4.17. Набор движений регистров учета Раздел учета Вид движения Касса Приход Капитал Расход Проводки Измерения Сумма 100 100 Касса Капитал 100 Полностью план счетов нашей конфигурации можно представить следующим образом (табл. 4.18 и табл. 4.19). Таблица 4.18. Перечень измерений и дополнительных измерений регистров учета Регистр Измерения Касса Организация Валюта Дополнительные измерения Касса об. Организация Валюта Покупатели Организация Контрагенты Товары Организация Номенклатура Склады Материалы Организация Склады Номенклатура Контрагенты Организация Контрагенты Сотрудники Организация Сотрудники Поставщики Организация Контрагенты Капитал Организация Проводки об. Организация Валюта Статьи Счет Дт Счет Кт 446 Реализация прикладных задач в системе «1С:Предприятие 8.2» Таблица 4.19. Перечень ресурсов регистров учета Регистр Ресурсы Касса Сумма Вал сумма Касса об. Сумма Вал сумма Покупатели Сумма Товары Сумма Количество Материалы Сумма Количество Контрагенты Сумма Сотрудники Сумма Поставщики Сумма Капитал Сумма Проводки об. Сумма Количество Вал сумма Подобный набор учетных регистров полностью повторит функциональность регистра бухгалтерии, за исключением контроля двойной записи и возможности создания новых учетных регистров (счетов) с произвольным набором дополнительных измерений (видов субконто) пользователем. Балансовое измерение регистра бухгалтерии Организация позволяет разделить учет на всех участках учета по организациям. Измерение Валюта включено только для счета Касса. Счет Касса потребовал создания двух регистров: одного для хранения остатков по счету в целом и еще одного для хранения оборотов по статьям (субконто Статьи имеет свойство Только обороты). Приведенная нами в качестве примера проводка (Дебет Касса – Кредит Капитал, см. табл. 4.16) теперь может быть интерпретирована такими движениями регистров учета (табл. 4.20). Таблица 4.20. Набор движений регистров учета Раздел учета Вид движения Измерения Касса Приход Организация Валюта Организация Валюта Касса (об) Капитал Проводки (об) Расход Ресурсы Организация Организация Статья 100 руб. 10 у.е. 100 руб. 10 у.е. 100 руб. Валюта 100 руб. 10 у.е. Подобное «раздвоение» одного счета учета на два (или более) учетных регистра применяется каждый раз, когда используются признаки учета субконто. Если представить, что на счете Товары мы решим для вида субконто Склады снять признак ведения суммового учета (это может потребоваться для выполнения правила учетной политики – расчет себестоимости должен Глава 4. Реализация задач бухгалтерского учета 447 выполняться по номенклатурному номеру без учета складов), то один счет Товары будет представлен в нашей модели двумя учетными регистрами (табл. 4.21). Таблица 4.21. Пример учетных регистров для счета «Товары» Регистр Измерения Дополнительные измерения Ресурсы Товары Организация Номенклатура Сумма Товары Организация Номенклатура Склады Количество Подобная организация регистров позволит получать количественные остатки каждого номенклатурного номера на каждом складе и суммовые остатки номенклатуры по предприятию в целом. Суммовые остатки и обороты по складу не ведутся. Рассмотренные нами свойства регистра бухгалтерии «накладывают отпечаток» на проектирование всей конфигурации. Многообразие хозяйственных операций и возможность расширения пользователем состава регистров учета и/или их измерений потребовали обязательного включения в конфигурацию документов-регистраторов типа «ручная операция», которые позволяют непосредственно редактировать движения регистра бухгалтерии, используя в проводках любые счета и аналитику. Кроме универсальных документоврегистраторов, потребуется учитывать особенности регистра бухгалтерии и в других документах, многие из которых должны предоставлять возможность выбора счета (одного или обоих) и/или аналитики. Необходимость анализировать остатки и обороты по новым учетным регистрам и по всем учетным регистрам, включая новые, привела к необходимости разработки в типовом решении универсальной отчетности. Эти отчеты, с одной стороны, являются универсальными и позволяют анализировать движения по любым счетам. С другой, сами формы отчетов устоялись за четыреста лет использования двойной записи и не могут быть произвольными по содержанию и расположению строк и колонок отчета: это оборотки, шахматки, ведомости, ордера, карточки и другие. Анализ таблицы, в которой мы выполнили реализацию нашего плана счетов с использованием регистров накопления, хорошо демонстрирует некоторую «неоптимальность»: слишком много пустых ячеек… Под измерение Валюта резервируется место и для тех учетных регистров, где валютный учет не ведется. Сделано это для того, чтобы пользователь мог в любой момент сам добавить новый учетный регистр и включить на нем валютный учет. Или же включить валютный учет на любом из предопределенных счетов (изменив настройки этого счета в конфигураторе). Та же ситуация и с ресурсами. Ресурсы ВалютнаяСумма и Количество задействованы не на всех счетах, а место под них резервируется в любом случае и с той же целью, что и для измерения Валюта. 448 Реализация прикладных задач в системе «1С:Предприятие 8.2» Для справедливости нужно заметить, что наша таблица неправильно передает способ хранения дополнительных измерений (субконто) в регистре бухгалтерии. Субконто хранятся иначе, в другой таблице (более подробно о физическом строении регистра рассказано в разделе «Реальные таблицы» на стр. 487), и хранятся компактно – пустых ячеек там нет. Но в любом случае платой за универсальность регистра бухгалтерии является некоторое снижение производительности по сравнению с регистрами накопления. Поэтому при проектировании задачи бухгалтерского учета очень важно выявить и выделить в оперативный учет те разделы учета, которые требуют хранения и обработки значительного объема информации, особенно информации разнородной (ресурсы) и с большой детализацией (измерения). Если довести эту задачу почти до абсурда, то идеальной организацией бухгалтерского учета можно считать ведение синтетического (на счетах и субсчетах) учета в денежном выражении с незначительной детализацией по видам субконто, остатки по которым требуются для формирования баланса. А все остальные виды учета (многовалютный, количественный, подробный аналитический) реализовать, используя механизмы оперативного учета. Вывод: основной результат бухгалтерского учета – баланс, и все что на него не влияет, может быть вынесено в оперативный учет. Выше нами был рассмотрен лишь один раздел науки об управлении предприятием – учет на предприятии, в котором мы выделили подвиды учета – оперативный и бухгалтерский (хочется надеяться, что выделили оптимально). Однако управление предприятием в целом намного шире и, кроме учета свершившихся фактов (чем и занимается учет) включает в себя планирование, анализ и многое другое. В этих задачах также есть место методам бухгалтерского учета и как следствие механизмам бухгалтерского учета системы «1С:Предприятие». В заключение можно сделать вывод, что любая задача, цель которой – получение взаимосвязанной системы показателей в виде баланса (в широком смысле этого слова: баланса средств и их источников, баланса оборотов и т. д.), может быть эффективно решена с использованием регистра бухгалтерии. Пример: получение прогнозного баланса в финансовом планировании, получение баланса-нетто в бухгалтерском управленческом учете и т. д. Объект «Регистр бухгалтерии» Этот раздел будет посвящен свойствам и методам объекта Регистр бухгалтерии. Причем преимущественно тем методам, которые позволяют записывать данные в регистр. Методы объекта, предназначенные для чтения данных об остатках и оборотах по счетам, будут рассмотрены нами в разделе «Методы менеджера регистра бухгалтерии» на стр. 534, посвященном таблицам регистра бухгалтерии и извлечению данных из них. Глава 4. Реализация задач бухгалтерского учета 449 Основные свойства регистра бухгалтерии Создание объекта Регистр бухгалтерии начинается с заполнения его основных свойств (рис. 4.29). Рис. 4.29. Основные свойства регистра бухгалтерии На закладке Основные выбирается план счетов и признак поддержки корреспонденций. Как планов счетов, так и регистров бухгалтерии может быть несколько, но один регистр бухгалтерии содержит проводки только между счетами одного плана счетов. В то же время на одном плане счетов могут основываться два и более регистра бухгалтерии. Пример подобного использования: в разрезе счетов одного и того же плана счетов ведется учет свершившихся хозяйственных операций (один регистр бухгалтерии) и планируемых операций (бюджетных транзакций в другом регистре бухгалтерии). Наличие между ними единого связующего звена – плана счетов – позволит получить отчеты для план-фактного анализа, а различная структура регистров позволит вести каждый вид учета удобно и эффективно. Сравнивая объекты Регистр накопления (или понятие «учетный регистр») и Регистр бухгалтерии, можно сказать, что в самом простом случае регистр бухгалтерии – это регистр, который позволяет учитывать значение какого-то (или каких-то, но как минимум одного – сумма в валюте учета) ресурса в разрезе двух «предопределенных» измерений – СчетДебета 450 Реализация прикладных задач в системе «1С:Предприятие 8.2» и СчетКредита (или Счет и Вид движения для регистра без поддержки корреспонденций). Это, скорее, образное сравнение, чем демонстрация физического строения таблиц регистра, однако, по нашему мнению, вполне имеет право на жизнь. Для того чтобы получить самый простой бухгалтерский учет (синтетический: на счетах и субсчетах в денежном выражении в валюте учета), достаточно выбрать в регистре бухгалтерии план счетов, установить (или снять) признак поддержки корреспонденции и ввести в регистр один-единственный ресурс, Сумма например, в котором и будет храниться сумма проводки. В этом случае проводка будет выглядеть так, как показано на рис. 4.30. Рис. 4.30. Реализация принципа двойной записи в регистре бухгалтерии В случае если регистр поддерживает корреспонденцию, т. е. реализует привычную для России схему учета, каждая проводка включает два корреспондирующих счета (счет дебета и счет кредита) и ресурс Сумма. При такой архитектуре регистра пользователю будут доступны для анализа остатки и обороты по каждому счету и обороты между счетами. Учетная схема без поддержки корреспонденций может считаться более гибкой и в большей степени удовлетворяющей отражению экономической сути хозяйственных операций (хотя бы потому, что не приходится «укладывать» каждую операцию в «прокрустово ложе» корреспонденций счетов, разбивая движения на корреспондирующие пары счетов). Однако отсутствие корреспонденции исключает возможность анализа оборотов между счетами (табл. 4.22). Глава 4. Реализация задач бухгалтерского учета 451 Таблица 4.22. Отличия учетных схем с поддержкой корреспонденции и без поддержки корреспонденции Критерий Поддержка корреспонденции Включена Выключена Контроль двойной записи В рамках проводки Анализ остатков по счету Анализ оборотов по счету Анализ оборотов между счетами Да Да Да В рамках набора движений регистратора Да Да Нет ПРИМЕЧАНИЕ Обращаем внимание: отсутствие поддержки корреспонденций не означает отсутствие контроля двойной записи. Если корреспонденция поддерживается, контроль двойной записи осуществляется в рамках каждой проводки. Если корреспонденция не поддерживается, то контроль двойной записи осуществляется в рамках всего набора записей, принадлежащих одному регистратору (рис. 4.31). Рис. 4.31. Контроль двойной записи 452 Реализация прикладных задач в системе «1С:Предприятие 8.2» Рассказывая о контроле двойной записи, нельзя не рассказать о свойстве ресурсов и измерений регистра бухгалтерии Балансовый. В процессе настройки регистра бухгалтерии нами был добавлен новый ресурс Сумма с установленным свойством Балансовый. Этим же свойством обладают, как видно на рис. 4.32, и измерения регистра. Счета балансовыми являются по умолчанию, но есть возможность объявить их забалансовыми. Рис. 4.32. Свойство «Балансовый» Контроль двойной записи осуществляется для балансовых счетов, балансовых измерений и балансовых ресурсов. Для регистра без поддержки корреспонденции контроль двойной записи осуществляется для балансового ресурса по балансовому измерению (всем сочетаниям балансовых измерений, если их несколько) в рамках набора записей одного регистратора. Глава 4. Реализация задач бухгалтерского учета 453 Данные регистра бухгалтерии Задача любого регистра – учет значений некоторых показателей (ресурсов) в разрезе некоторых измерений (счета проводки, измерения регистра и дополнительные измерения регистра – субконто) с возможностью оставить дополнительную информацию о каждой записи регистра (реквизиты). Закладка Данные регистра бухгалтерии позволяет определить все перечисленные свойства (рис. 4.33). Рис. 4.33. Данные регистра бухгалтерии Рис. 4.34. Реквизит «Содержание» 454 Реализация прикладных задач в системе «1С:Предприятие 8.2» Далее мы подробно рассмотрим свойства Измерения и Ресурсы регистра бухгалтерии. Реквизиты регистра, с нашей точки зрения, столь подробного описания не требуют. Реквизит характеризует лишь запись регистра бухгалтерии и, по сути, является дополнительной информацией, которую можно к этой записи прикрепить (рис. 4.34). По значению реквизита можно получить отбор движений, но нельзя получить остаток или оборот по счету или субконто. Типичный вариант использования реквизита регистра – содержание проводки, куда пользователь сможет написать краткий комментарий к сделанной им проводке. Надо предостеречь от использования большого числа реквизитов или реквизитов значительной длины. Несмотря на то, что таблицы итогов регистра не включают в себя реквизиты, таблицы первичных движений будут резервировать под них место и как результат увеличивать объем базы данных. Лучше оставлять всю дополнительную информацию в документе-регистраторе, который сделал это движение, чем в самом движении. Ресурсы регистра бухгалтерии Если единственным обязательным разрезом ведения бухгалтерского учета являются счета и субсчета, то единственное значение, которое в этом разрезе нужно учитывать, – это сумма в валюте учета (или валюте составления баланса, можно сказать и так). Для регламентированного учета этой валютой является национальная валюта. Другими словами, для ведения регламентированного бухгалтерского учета достаточно добавить в регистр бухгалтерии один ресурс, который обычно называют Сумма, в который будут записываться значения, выраженные в рублях. Если речь идет об автоматизации нерегламентированного учета, то ничто не мешает в качестве валюты учеты выбрать любую другую. Например, в качестве валюты управленческого учета стараются выбрать наиболее устойчивую валюту или валюту той страны, в которой расположены основные деловые партнеры (учредители, инвесторы). В РФ управленческий учет чаще всего ведется в долларах США и с недавних пор в евро. Рассматривая свойства первого ресурса, который был добавлен нами для ведения бухгалтерского учета, следует остановиться на его свойствах. Ресурс регистра бухгалтерии может иметь только числовой тип, его длиной и точностью мы можем управлять. Глава 4. Реализация задач бухгалтерского учета 455 Свойство ресурса «Балансовый» Свойство Балансовый влияет на структуру регистра бухгалтерии. Основная цель бухгалтерского учета – баланс. Основывается баланс на методе двойной записи, в соответствии с которым при движении в учете каждое учитываемое значение (в данном случае сумма в валюте учета) должно «проходить» по двум сторонам проводки: по дебету и по кредиту. При установке свойства Балансовый платформа создаст в регистре бухгалтерии с поддержкой корреспонденции одно новое свойство – Сумма. Таким образом, заполняя сумму проводки, пользователь указывает и сумму, на которую изменяется дебетуемый счет проводки, и ту (ее же), на которую изменяется кредитуемый. Каждый ресурс регистра бухгалтерии создает новый вид учета. Первый созданный нами ресурс «создал» в регистре «учет в денежном выражении в валюте учета». Добавляя новые ресурсы, мы можем увеличить функциональность нашей «бухгалтерии», расширив виды учета, которые можно здесь вести. Например, в случае необходимости ведения учета натуральных показателей в регистр бухгалтерии будет добавлен новый ресурс Количество. Добавляя новый ресурс, задумаемся о смысле этого учета. На отдельных счетах материальных ценностей пользователь хочет видеть остатки и обороты по этим счетам не только в стоимостном, но и в натуральном выражении. Само собой разумеется, что контролировать баланс двойной записи по этому ресурсу смысла не имеет. Во-первых, он будет задействован не для всех счетов (какой экономический смысл ресурс Количество будет иметь для счета учета наличных денег Касса, что будет в нем учитываться – монеты, бумажки, и что будет получаться в итоге от сложения монет и бумажек?). А, во-вторых, в этом ресурсе, возможно, будут учитываться движения в различных единицах измерения (учитываться в количественном выражении будут материальные ценности, которые в программе представлены объектами аналитического учета, а они могут храниться в различных единицах измерения). Вывод: баланс не нужен. Значит, ресурс будет небалансовым. Небалансовые ресурсы предназначены для ведения вспомогательных видов учета, которые по большому счету можно было бы вообще в бухгалтерии не вести, а вести, например, в отдельных учетных регистрах оперативного учета. Но если уж мы поставили перед собой задачу все виды учета вести в регистре бухгалтерии, платформа предоставляет нам инструменты для этого (рис. 4.35). Причем предоставляет возможность не только их создать, но и обеспечить пользователя возможностью добавлять новые учетные регистры, включая в них различные виды учета (универсальность регистра бухгалтерии!), например, количественный. 456 Реализация прикладных задач в системе «1С:Предприятие 8.2» Рис. 4.35. Ресурс «Количество» Экономический смысл количественного учета, рассмотренный нами выше, предполагает, что пользователь должен иметь возможность для каждого счета проводки (и дебетуемого, и кредитуемого) указать свое значение ресурса Количество. При использовании регистра бухгалтерии без поддержки корреспонденций, в котором дебетуемые и кредитуемые счета располагаются в разных записях, в регистр будет добавлено новое поле Количество. Единственным отличием его от поля Сумма будет отсутствие контроля двойной записи. То есть при записи набора движений в базу данных платформа разрешит записать набор, если итог по ресурсу Количество дебетуемых записей не будет равен итогу по этой же графе кредитуемых. В регистре бухгалтерии с поддержкой корреспонденции каждая запись включает сразу два счета, положение которых в проводке (дебетуется или кредитуется) и определяет вид движения по счету. Чтобы предоставить возможность независимого заполнения ресурса для каждой из сторон проводки, платформа добавляет на каждый небалансовый ресурс два поля регистра бухгалтерии. Они отличаются постфиксами (Дт и Кт), подсказывающими, к какому счету проводки поле относятся. В данном случае будут добавлены поля КоличествоДт и КоличествоКт. Глава 4. Реализация задач бухгалтерского учета 457 Следует заметить, что дополнительные виды учета можно создавать, добавляя не только небалансовые ресурсы регистра бухгалтерии, но и балансовые. Примером использования в регистре бухгалтерии более одного балансового ресурса может служить трехвалютный учет. При таком виде учета предприятие, входя в состав холдинга, вынуждено готовить отчетность в двух валютах учета, которыми, например, могут быть национальная (для РФ – рубли) и валюта учета холдинга (если руководство холдинга европейское, видимо, это евро). Первое решение, которое приходит в голову, – просто взять всю бухгалтерскую отчетность и пересчитать значение каждого ее показателя по курсу на сдачу отчетности. Однако на такое решение могут возникнуть замечания со стороны руководства холдинга, ведь в течение отчетного периода соотношения курсов национальной валюты и валюты холдинга менялись. И как результат необходимо пересчитывать не итоговые показатели отчетности, а сумму каждой проводки по историческому курсу (т. е. по курсу на дату проводки). Пересчитывать и где-то хранить результат, чтобы можно было быстро получить отчетность. Можно было бы пересчитывать каждый раз, а не хранить, но пересчета по историческому курсу будут требовать не только обороты за период, но и входящие остатки, т. е. считать каждый раз нужно будет с самого начала. Поэтому проще в регистр бухгалтерии добавить еще один балансовый ресурс, который, скорее всего, не будет доступен пользователю для заполнения и изменения, а будет рассчитываться при записи набора движений в регистр. И при составлении отчетности нам останется лишь обратиться к показателям остатков и оборотов по новому виду учета. Свойство ресурса «Признак учета» Как уже было замечено выше, количественный учет, почти как и любой другой дополнительный вид учета, имеет смысл не для всех счетов. Таким образом, может возникнуть необходимость в инструменте, который позволит запретить заполнять ресурс для тех счетов, по которым его ведение не имеет смысла. Это позволит сэкономить время пользователя и исключит ошибки в учете. Решением этой задачи занимается механизм признаков учета. Признаки учета вводятся в плане счетов на закладке Данные. Они всегда имеют тип Булево и, по сути, являются новыми свойствами (специальными реквизитами) счета плана счетов. Количество (и «качество») признаков учета в общем случае должно соответствовать количеству забалансовых ресурсов регистра бухгалтерии. 458 Реализация прикладных задач в системе «1С:Предприятие 8.2» Так, например, если в нашей бухгалтерии ведутся только два вида учета – Суммовой и Количественный, причем суммовой ведется по всем счетам (по нему составляется баланс), необходимо создать один признак учета Количественный (рис. 4.36). Рис. 4.36. Признак учета «Количественный» Признак учета Количественный, созданный на закладке Данные объекта План счетов, позволит отметить (и нам – предопределенные, и пользователю – те, которые он ввел в план счетов самостоятельно) счета, требующие ведения количественного учета. Пока это просто новая «галочка», новое свойство счета. Глава 4. Реализация задач бухгалтерского учета 459 Чтобы это свойство заработало, необходимо пометить ресурс регистра бухгалтерии, который зависит от этого признака учета. Для этого предназначено свойство ресурса регистра бухгалтерии Признак учета. Теперь заполнение ресурса Количество возможно только в том случае, если в проводке участвует счет, отмеченный флажком Количественный, и только по той стороне проводки регистра с поддержкой корреспонденций, в которой этот счет участвует (рис. 4.37). Рис. 4.37. Использование признака учета Свойство ресурса «Признак учета субконто» Создавая аналитический учет в нашей конфигурации, мы предусмотрели, что отдельные виды учета (количественный, валютный), которые задаются в конфигурации ресурсами регистра бухгалтерии, включаются на счетах опционально с помощью признаков учета счетов. Устанавливая такой признак учета, мы (или пользователь для пользовательских счетов) тем самым предоставляем возможность заполнять тот или иной ресурс и в дальнейшем получать остатки и обороты этого ресурса. В случае, когда на счете ведется аналитический учет (один или несколько видов субконто), может возникнуть необходимость отключить для одного из видов субконто ведение одного из видов учета. Классическим примером может служить учет материально-производственных запасов на складах. Обычно запасы учитываются по цене приобретения. При списании запасов со склада оценка производится по одной из принятых в учете методик (по стоимости приобретения каждого объекта, один из вариантов расчета – средний, FIFO, LIFO). При этом если один и тот же номенклатурный номер хранится на разных складах, то при списании с любого из них стоимость списания нужно рассчитать по предприятию в целом. 460 Реализация прикладных задач в системе «1С:Предприятие 8.2» Можно проиллюстрировать учет графически. Рассмотрим ситуацию, когда предприятие закупает один и тот же вид материально-производственных запасов (МПЗ) по разным ценам. Выполним расчет средней стоимости отдельно по каждому складу и по предприятию в целом (рис. 4.38). Рис. 4.38. Пример расчета средней себестоимости Мы видим что средняя, рассчитанная по предприятию в целом (по номенклатурному номеру), и средняя по складу отличаются. При расчете стоимости по складу для правильного ведения учета необходимо хранить информацию о суммовых и количественных (признак учета Количественный) остатках каждого вида МПЗ (аналитический разрез по субконто Номенклатура) на каждом складе (субконто Склады). При расчете стоимости по предприятию учетная схема (признак учета, аналитика) остается без изменений: нам по-прежнему необходимо видеть остатки и суммовые, и количественные по номенклатуре. И по-прежнему нужны остатки по складу, но только количественные (чтобы оценить, хватает ли номенклатуры). Если при расчете себестоимости по предприятию в целом оставить суммовой учет по складам, то в результате на них после списания всего количества будут оставаться отрицательные и положительные остатки на разницу между суммой оприходованных на склад МПЗ и списанных по средней стоимости. Глава 4. Реализация задач бухгалтерского учета 461 Учет наличия и движения средств с необходимой степенью детализации в целях расчета стоимости при списании и получение оперативной отчетности об остатках и оборотах во многих случаях имело бы смысл вынести в отдельную подсистему оперативного учета. Однако, руководствуясь особенностями учета предприятия, мы приняли решение реализовать его в регистре бухгалтерии, где предусмотрена возможность отключения отдельных видов учета с отдельных видов субконто на выбранных счетах. Рассмотрим текущую организацию аналитического учета на примере счета учета товаров (табл. 4.23). Таблица 4.23. Учетный регистр «Товары» Регистр Измерения Дополнительные измерения Ресурсы Товары Организация Номенклатура Сумма Склады Количество Счет товаров ведется, как все счета, в разрезе балансового измерения Организация и двух видов субконто – Номенклатура и Склады. На счете ведется суммовой и количественный учет. Наша задача сводится к тому, чтобы превратить один учетный регистр Товары в два учетных регистра (табл. 4.24). Таблица 4.24. Ведение количественного учета на счете «Товары» Регистр Измерения Дополнительные измерения Ресурсы Товары Организация Номенклатура Сумма Товары Организация Номенклатура Склады Количество Первый из них должен хранить остатки и обороты в суммовом выражении в разрезе номенклатуры. Второй должен хранить количественные показатели для каждого номенклатурного номера на каждом складе. Задача решается с помощью признака учета субконто. Задача признака учета субконто – отключить ведение одного из видов учета на одном виде субконто одного счета. Признаки учета субконто создаются на закладке Субконто (рис. 4.39). В общем случае количество признаков учета субконто должно быть меньше или равно количеству ресурсов регистра бухгалтерии. Меньше – потому что не все виды учета, ведущиеся в ресурсах регистра, необходимо отключать. Чтобы предоставить себе и пользователю возможность отключать два вида учета (в нашем случае суммовой и количественный) для отдельных субконто, необходимо создать два признака учета субконто. Для решения нашего примера (расчет стоимости по предприятию в целом) нам было бы достаточно одного признака учета субконто Суммовой, который бы позволил нам отключить ведение суммового учета с субконто Склады. 462 Реализация прикладных задач в системе «1С:Предприятие 8.2» Рис. 4.39. Признаки учета субконто Каждый признак учета, созданный в объекте План счетов, необходимо привязать к ресурсу регистра бухгалтерии – к тому самому, учетом в котором он будет управлять. Когда каждый признак учета «знает» свой вид учета, можно перейти к настройке счетов. Каждый признак учета субконто дополнит специальную табличную часть Виды субконто новым свойством (колонкой), которое позволит управлять ведением учета. Именно такая настройка счета Товары (см. рис. 4.39) позволит решить поставленную задачу только количественного учета товаров на складах. Глава 4. Реализация задач бухгалтерского учета 463 Измерения регистра бухгалтерии Все измерения регистра бухгалтерии можно условно разделить на собственно измерения (которым и посвящен этот раздел и которые создаются на закладке Данные свойств регистра бухгалтерии), дополнительные измерения (виды субконто) и обязательные измерения (встроенные, предопределенные, разделы учета – ни одно из этих понятий не является «штатным» описанием механизма, но позволяет понять суть явления), которыми для регистра бухгалтерии с поддержкой корреспонденции являются СчетДебета и СчетКредита, а для регистра без поддержки корреспонденции – Счет и Вид движения (рис. 4.40). Рис. 4.40. Измерения регистра бухгалтерии 464 Реализация прикладных задач в системе «1С:Предприятие 8.2» Задачи, которые решаются с помощью измерений регистра бухгалтерии, как и сами измерения из ветки Измерения закладки Данные регистра бухгалтерии, можно разделить на две группы: ведение раздельных балансов и получение сводной отчетности (балансовые измерения) и разделение отдельных (или всех, но встречается это реже) разделов учета по какому-то признаку. Свойство измерения «Балансовый» Балансовые измерения делят весь учет (все разделы учета) на самостоятельные балансы. Баланс, как известно, – замкнутая система показателей. Поэтому если в процессе конфигурирования было добавлено балансовое измерение Организация, значит, по каждой организации (в данном случае список организаций ведется в справочнике Организации) программой будет составлен свой баланс. Это значит, что у каждой организации будут свои активы (касса, расчетные счета, склады и др.), свои обязательства (перед сотрудниками, перед поставщиками) и свой собственный капитал. Именно так и никак иначе! Наличие балансового измерения в регистре бухгалтерии совершенно исключает возможность, например, переместить товары с одной организации в другую. По каждой организации ведется свой баланс. А значит, для решения задачи перемещения товаров нужно в одной организации их списать (на какой-нибудь счет расчетов с той, другой, организацией), а в другой организации их оприходовать (со счета учета расчетов с первой организацией). Рис. 4.41. Расчеты с обособленными подразделениями Глава 4. Реализация задач бухгалтерского учета 465 К слову, в хозрасчетном учете РФ такой счет имеет код 79 и называется Внутрихозяйственные расчеты. Он предназначен для расчетов с обособленными, выделенными на отдельный баланс подразделениями. Схема проводок изображена на рис. 4.41. Мы видим, что счет расчетов закроется только в балансе всего предприятия, как правило, по результатам работы за год. По отдельным же значениям разделителя задолженность будет оставаться. Эта учетная схема – всего лишь один из вариантов ведения учета, и была приведена не как руководство к действию, а как демонстрация всей серьезности шага добавления балансового измерения в регистр бухгалтерии. Балансовое измерение добавляет новое поле во все таблицы регистра бухгалтерии. При записи набора движений в регистр осуществляется контроль двойной записи по каждому значению (сочетанию значений, если балансовых измерений несколько) балансового измерения. Небалансовое измерение по своей сути напоминает субконто. Так же как и субконто, оно делит не все разделы учета на самостоятельные балансы, а, как правило, лишь некоторые, или все разделы учета, но баланса по нему получить нельзя. Для регистра с поддержкой корреспонденции добавляются два поля – по одному на каждую сторону проводки, например, ВалютаДт и ВалютаКт. Для регистра без поддержки поле добавляется одно, но при записи набора движений в регистр контроль двойной записи по каждому значению такого измерения не осуществляется. Небалансовое измерение можно сравнить с субконто, которое в обязательном порядке прикрепили ко всем счетам. Хотя хранение в физических таблицах регистра у них различное, функционально механизмы небалансовых измерений и субконто похожи (табл. 4.25). Таблица 4.25. Сравнение небалансовых измерений и субконто Критерий Небалансовое измерение Субконто Компактность хранения в базе Поле резервируется даже для счетов, где измерение не используется Любой, чаще просто ссылка на справочник Резервируется только в том случае, если субконто на счете используется Тип данных Возможность включить/отключить для конкретного счета Всегда на своем месте Да, с помощью признаков учета Да Всегда составной, причем состав определятся для плана видов характеристик Да, при подключении вида субконто на счет Может быть любым по порядку на счете и для пользовательских счетов порядок может быть задан произвольно пользователем 466 Реализация прикладных задач в системе «1С:Предприятие 8.2» Таким образом, можно предложить использование небалансового измерения вместо субконто в том случае, если данный признак аналитики используется на всех (или на подавляющем большинстве) счетах. Более того, в этом случае можно считать использование измерения более оптимальным, чем субконто, что связано с типом данных. Приведем пример: организации необходимо вести учет почти всех разделов учета в разрезе источников финансирования. Для решения этой задачи можно воспользоваться или добавлением субсчетов к нужным (почти всем) счетам, или добавлением на них нового вида субконто, или добавлением в регистр нового небалансового измерения. У каждого решения есть свои плюсы и минусы (табл. 4.26). Таблица 4.26. Сравнение субсчетов, субконто и небалансовых измерений Решение Плюсы Минусы Субсчета Может потребовать незначительного изменения типового решения, если оно с самого начала предусматривало возможность расширения субсчетов второго или третьего уровня Может потребовать незначительного изменения типового решения, если уложиться в максимальное число субконто для плана счетов Сложность получения отчетности по одному источнику финансирования и сложность ведения учета из-за значительного числа счетов в плане счетов Субконто Может потребовать значительных изменений, если все субконто для отдельных счетов уже заняты и нужно увеличивать максимальное число субконто. Увеличение максимального числа субконто может негативно повлиять на производительность Небалансовое Позволит разделить учет более Потребует значительных изменений измерение оптимально, чем в случае суб- типового решения конто, и удобно подготавливать отчетность, как по значению измерения, так и сводно Свойство измерения «Признак учета» Еще один вариант использования небалансовых измерений – добавление нового вида учета, требующего не только учета нового показателя (ресурса), но и ведения нового разреза для этого и других (например, Сумма) ресурсов. Даже если этот новый вид учета используется далеко не на всех счетах, а место под новое измерение будет все равно резервироваться для всех счетов, использование механизма небалансовых измерений оправдано необходимостью создать универсальный механизм, который сможет использовать и пользователь системы. Глава 4. Реализация задач бухгалтерского учета 467 Примером такого использования может служить валютный (многовалютый, мультивалютный) учет. Суть учета состоит в том, что для отдельных (не всех) счетов необходимо учитывать не только показатели в валюте учета (ресурс Сумма), но и в иностранных валютах. Если бы иностранная валюта была одна, этот вид учета ничем не отличался бы от учета количественного, который мы рассмотрели в разделе, посвященном признакам учета ресурса регистра бухгалтерии. Но валют может быть много, и по каждой из них мы хотим видеть остатки и обороты, как в валюте, так и валюте учета. Другими словами, нам необходим разрез по валютам. Развивая тему количественного учета и доводя его до абсурда, можно предложить схожее решение для задачи количественного учета в разрезе единиц измерения. В этом случае к небалансовому ресурсу Количество нам пришлось бы добавить небалансовое измерение Единица измерения и связать их признаком учета, чтобы пользователь мог одним щелчком мыши включить новый вид учета на счете. Подчеркнем еще раз – это именно пример абсурдного использования регистра бухгалтерии. Для решения задач наличия и движения средств с целью управления ими (а не предприятием в целом, как в нашем случае) существуют механизмы оперативного учета. Возвращаясь к задаче ведения валютного учета, который, как правило, является обязанностью бухгалтерии, заметим, что кроме справочника Валюты нам потребуется еще один связанный с ним объект – периодический регистр сведений Курсы валют. Регистр будет иметь измерение Валюта типа Ссылка на справочник Валюты и ресурс Курс типа Число, а если требуется вести учет в валютах с очень маленькими значениями курса, то два ресурса – Курс и Кратность, и для получения эквивалента в валюте учета валютную сумму нужно будет сначала умножить на курс, а затем разделить на кратность. Какие изменения коснутся механизмов бухгалтерии? Во-первых, необходимо добавить новый признак учета в плане счетов Валютный (рис. 4.42). Он позволит отметить те счета, которые требуют ведения валютного учета. Во-вторых, нужно добавить новый ресурс регистра бухгалтерии ВалютнаяСумма, где будет храниться сумма в валюте. И, в-третьих, добавить новое небалансовое измерение регистра бухгалтерии Валюта – ссылка на элемент справочника Валюты, по которому будет «разделен» учет отмеченного признаком счета. Схему взаимодействия объектов можно изобразить графически (рис. 4.43). 468 Реализация прикладных задач в системе «1С:Предприятие 8.2» Рис. 4.42. Признак учета «Валютный» Глава 4. Реализация задач бухгалтерского учета 469 Рис. 4.43. Схема взаимодействия объектов Результат: при установке одного флажка в настройках счета для счета становятся доступными для заполнения новый ресурс и новое измерение. Запись движений в регистр бухгалтерии Регистр бухгалтерии подчинен регистратору, и движения в регистре можно сделать, только указав в движении ссылку на документ-регистратор. Регистратором может являться любой документ системы. Выбрать документ как регистратор можно или на закладке Регистраторы регистра бухгалтерии (рис. 4.44), или на закладке Движения документа (рис. 4.45). Рис. 4.44. Регистраторы регистра бухгалтерии 470 Реализация прикладных задач в системе «1С:Предприятие 8.2» Рис. 4.45. Движения документа По сути, на этих закладках разных объектов отображается одна и та же информация. Движение в регистр может быть сделано разными способами (мы рассмотрим ниже), но без ссылки на документ-регистратор сделать движение невозможно (рис. 4.46). Рис. 4.46. Движения документа Глава 4. Реализация задач бухгалтерского учета 471 Документ, во-первых, требуется как «ссылка», которая будет прописана в одно из полей регистра бухгалтерии, а, во-вторых, документ обладает коллекцией наборов записей Движения, которая используется для записи движений в регистры. Коллекция Движения содержит в себе наборы записей регистров, по которым документ может делать движения. Коллекция содержит столько элементов, для скольких регистров документ является регистратором. В приведенном примере коллекция Движения документа Операция содержит всего один элемент ОсновнойРегистрБухгалтерии – это набор записей регистра бухгалтерии Основной регистр бухгалтерии. Каждый набор записей может содержать сколько угодно записей одного регистра, подчиненных документу-регистратору. Изменять набор записей регистра из коллекции Движения можно как из документа, так и из любого другого программного модуля, интерактивно или программно. В любом случае набор записей регистра позволит прочитать из базы данных существующий набор записей, изменить его и записать в базу данных одной транзакцией. Можно предложить следующие основные варианты изменения наборов записей регистра. Интерактивно: ручная операция Одно из отличий бухгалтерского учета от оперативного состоит в том, что он охватывает все предприятие в целом. Поэтому автоматизировать все операции, алгоритмизировав формирование проводок документами, фактически невозможно. Все равно останутся операции (корреспонденции счетов), про которые забыли. Поэтому, как правило, при автоматизации бухгалтерского учета автоматизируется формирование проводок документами только для регулярно встречающихся операций, а для остальных создается документ Операция, который позволяет пользователю, по сути, редактировать регистр бухгалтерии «вручную», вводя любые проводки. Во-первых, документ нам нужен как ссылка, которая будет прописана в поле Регистратор регистра бухгалтерии. А во-вторых, мы задействуем его свойство Движения, содержащее набор записей регистра бухгалтерии, который мы хотим разрешить изменять пользователю. Создадим новый документ Операция с реквизитом Организация (СправочникСсылка.Организации). В свойствах этого документа на закладке Движения мы установим следующие свойства (рис. 4.47). Документ не будет проводиться (свойство Проведение: запретить). Это означает, что при записи документа в базу данных не будет выполняться алгоритм проведения документа, расположенный в обработчике события модуля объекта Обработка проведения. 472 Реализация прикладных задач в системе «1С:Предприятие 8.2» Рис. 4.47. Движения документа «Операция» Документ будет являться регистратором для регистра бухгалтерии. Установка этого свойства привела к тому, что в коллекции Движения появился набор записей регистра бухгалтерии ОсновнойРегистрБухгалтерии, который позволит изменять этот регистр бухгалтерии. Заполнять этот набор записей проводками можно разными способами. Поставленная нами задача создания документа Операция предполагает, что набор записей будет заполняться пользователем интерактивно, т. е. в форме документа. Создавая форму документа, в окне элементов формы мы размещаем таблицу, отображающую данные Объект.Движения.ОсновнойРегистрБухгалтерии. При этом автоматически добавляем в нее колонки, соответствующие свойствам регистра бухгалтерии. Затем вручную откорректируем состав колонок таблицы движений регистра, который заполнила платформа. Удалим из таблицы колонки Период и Организация и добавим поле Активность. Часть свойств мы разместим в диалоге формы, часть будем заполнять программно, часть предоставим заполнять платформе. Глава 4. Реализация задач бухгалтерского учета 473 Рассмотрим все свойства нашего регистра подробнее. ■ Регистратор – ссылка на документ, в нашем случае на документ Операция. Поле составного типа данных, количество типов зависит от того, сколько документов могут являться регистраторами для регистра. Платформа не разрешит сделать движение в регистр «по другому регистратору». Поэтому свойство не имеет смысла включать в диалог формы и заполнять программно при проведении или записи регистра, платформа сама запишет в него документ-регистратор. ■ НомерСтроки – номер записи, нумерация начинается с 1. ■ Активность – свойство записи должно быть одинаковым для всех записей одного регистратора, в противном случае платформа не разрешит записать набор в регистр. Записи с установленным свойством отражаются в таблицах итогов и включаются в виртуальные таблицы регистра бухгалтерии. «Неактивные» записи существуют только в таблицах первичных движений и не влияют на бухгалтерскую отчетность. ■ Период – содержит дату периода, в итоги которого должна попасть проводка. Поле не может быть пустым и должно быть обязательно заполнено или интерактивно, или программно при записи набора в регистр. Периоды разных записей даже одного набора могут отличаться. Период записи может отличаться от даты документа регистратора. В регламентированном бухгалтерском учете возможность документа записывать проводки датой, отличной от даты документа, редко находит свое применение, однако можно предположить, что в других разделах учета, таких как управленческий учет и бюджетирование, использующих механизмы бухгалтерского учета для получения баланса, свойство может пригодиться. ■ СчетДт, СчетКт – ссылки на счет, который выбран в свойствах регистра. Наличие двух счетов в проводке обусловлено свойством Корреспонденция. ■ СубконтоДт1, СубконтоДт2, СубконтоКт1, СубконтоКт2 – в свойствах плана счетов установлено максимальное количество субконто равным 2. Поля составного типа данных, который определен в свойствах плана видов характеристик, выбранного в плане счетов. ■ Организация – балансовое измерение регистра, в нашем случае предназначенное для получения отчетности в разрезе самостоятельных организаций (юридических лиц или обособленных подразделений, выделенных на отдельный баланс). Измерение является свойством каждого движения, но в нашем случае мы будем исходить из предположения, что каждая операция в бухгалтерском учете должна быть подкреплена первичным документом и на нем должна быть печать. Причем печать 474 Реализация прикладных задач в системе «1С:Предприятие 8.2» одной организации. Поэтому принимаем решение заполнять поле Организация одним значением (из шапки документа) для всех записей и делать это программно. ■ ВалютаДт, ВалютаКт – небалансовое измерение регистра бухгалтерии породило два поля в регистре (для дебетовой и для кредитовой стороны проводки). ■ Сумма, СуммаХолдинга – балансовые ресурсы, единые для обеих сторон проводки. ■ КоличествоДт, КоличествоКт, ВалютнаяСуммаДт, ВалютнаяСуммаКт – небалансовые ресурсы, для каждой стороны проводки свой. ■ Содержание – реквизит регистра. Для выбора организации в шапке документа был размещен реквизит документа Организация. Записать организацию и дату документа в соответствующие поля записи регистра бухгалтерии позволит обработчик события Перед записью формы или объекта документа. Мы воспользуемся событием объекта, чтобы обрабатывать не только интерактивную, но и программную запись документа (листинг 4.14). Листинг 4.14. Обработчик события «ПередЗаписью» Процедура ПередЗаписью(Отказ, РежимЗаписи, РежимПроведения) Для Каждого Проводка Из Движения.ОсновнойРегистрБухгалтерии Цикл Проводка.Период = Дата; Проводка.Организация = Организация; КонецЦикла; КонецПроцедуры Пример заполненного документа Операция представлен на рис. 4.48. Рис. 4.48. Документ «Операция» Глава 4. Реализация задач бухгалтерского учета 475 Активность Активность – свойство записи регистра, влияющее на отражение этой записи в таблицах итогов регистра. Активные записи находят свое отражение в итогах и как следствие попадают в отчеты, неактивные – нет. Физической организации таблиц регистра посвящен отдельный раздел нашей главы, пока же можно заметить, что все таблицы регистра бухгалтерии разделяются на таблицы первичных движений (собственно проводки и значения субконто этих проводок) и таблицы итогов, которые хранят информацию об остатках и оборотах на счетах и субконто, сгруппированную по месяцам. Физические таблицы могут быть использованы разработчиком для написания запросов, но используются как источник данных редко. Таблицы итогов как источники данных запроса недоступны и являются (вместе с таблицами первичных движений) источниками данных при создании платформой виртуальных таблиц регистра бухгалтерии. Именно они и служат источниками данных для большинства отчетов. Виртуальные таблицы, как правило, включают только активные записи. Таким образом, активность – это свойство записи, позволяющее пользователю системы проанализировать, а что было бы, если этой проводки не было. Проводка с выключенной активностью не удаляется из базы данных. Если сравнивать удаление движения и отключение активности этого движения, то разница будет заметна в первую очередь на документах, которые формируют движения автоматически при проведении. Сделав такой документ непроведенным, удалив все движения, пользователь, конечно, сможет проанализировать данные отчетов «без этого документа». Но включение этого документа обратно в учет потребует его перепроведения, при котором движения будут сформированы заново и новые. То есть существует вероятность, что повторное исполнение алгоритма проведения в возможно изменившихся условиях приведет к формированию других движений. Если же воспользоваться свойством Активность, то повторное включение документа в учет не потребует его перепроведения. Старые проводки не были удалены, они просто были исключены из итогов. При включении активности в итоги будут включены те же проводки, которые были выключены, а не новые. Листинг 4.15. Пример процедуры, переключающей активность записей &НаСервере Процедура ПереключитьАктивностьПроводок() Документ = РеквизитФормыВЗначение("Объект"); Проводки = Документ.Движения.ОсновнойРегистрБухгалтерии; КоличествоПроводок = Проводки.Количество(); Если КоличествоПроводок > 0 Тогда Проводки.УстановитьАктивность(НЕ Проводки[0].Активность); КонецЕсли; ЗначениеВРеквизитФормы(Документ, "Объект"); КонецПроцедуры 476 Реализация прикладных задач в системе «1С:Предприятие 8.2» Листинг 4.15 содержит процедуру, которая может быть расположена в модуле формы документа и позволяет управлять активностью записей регистра. Процедура получает активность первой записи из набора (с индексом 0), инвертирует ее (НЕ) и устанавливает полученную в результате активность для всего набора. Рассмотрим еще один вариант использования этого свойства движения на примере документа Операция. Операция не хранит в себе движения, а лишь объединяет их одним регистратором, которым и является. Документ не проводится (не выполняет алгоритм проведения документа) и поэтому не может быть снят с проведения. Если установить на документ пометку на удаление, записи в регистре остаются неизмененными, т. е. даже удаленная операция продолжает участвовать в учете. Поставим задачу – удаленная операция не должна участвовать в учете, не должна попадать в отчеты. Но должна быть возможность, сняв пометку на удаление, вернуть ее в учет. Для этого воспользуемся свойством Активность движения регистра. При установке пометки удаления документа будем снимать активность записей, при снятии пометки на удаление – восстанавливать активность записей (листинг 4.16). Листинг 4.16. Управление активностью записей при установке/снятии пометки удаления документа Процедура ПередЗаписью(Отказ, РежимЗаписи, РежимПроведения) Проводки = Движения.ОсновнойРегистрБухгалтерии; НужноСчитатьНабор = (НЕ Ссылка.Пустая() И НЕ Проводки.Модифицированность() И НЕ Проводки.Выбран()); Если НужноСчитатьНабор Тогда Проводки.Прочитать(); КонецЕсли; КоличествоПроводок = Проводки.Количество(); Если КоличествоПроводок > 0 Тогда ТекущаяАктивностьПроводок = Проводки[0].Активность; НужнаяАктивностьПроводок = НЕ ПометкаУдаления; Если ТекущаяАктивностьПроводок <> НужнаяАктивностьПроводок Тогда Проводки.УстановитьАктивность(НужнаяАктивностьПроводок); КонецЕсли; КонецЕсли; КонецПроцедуры Глава 4. Реализация задач бухгалтерского учета 477 Прокомментируем работу процедуры. Обработчик события Перед записью объекта документа выполняется перед каждой записью документа. Отметка о проведении документа является свойством документа. После изменения этого свойства платформа производит запись документа в базу. Процедура получает в переменной Проводки набор записей регистра движений документа. Запись движений в регистр осуществляется в разных ситуациях. Это может быть интерактивная запись нового документа пользователем, запись измененного документа пользователем, удаление или снятие пометки удаления документа. Документ в момент открытия формы считывает набор записей из регистра бухгалтерии. Если форму не открывали, а установка пометки удаления осуществляется без открытия формы, необходимо прочитать из информационной базы набор записей регистра. Необходимость считывать набор из регистра определяется совпадением трех условий: ■ этот документ не новый; если он новый, то набор записей документа еще не записан в базу, а находится в документе; ■ набор записей регистра не был изменен; если он был изменен, то считывание его из базы затрет изменения пользователя; ■ набор еще не считывался из базы данных, что позволяет узнать метод Выбран(). Если все три условия присутствуют, считываем из регистра набор записей и выполняем действия с ним. Проверив количество движений в наборе записей, мы получаем текущую активность движений набора записей по первой записи и устанавливаем нужную активность для набора записей. Программно при проведении документа Формирование и запись проводок в момент проведения документа можно считать основными вариантами изменения регистра бухгалтерии. В отличие от документа Операция, запись проводок при проведении позволяет описать сложный алгоритм формирования проводок, вычисление сумм и обусловленное заполнение других свойств записей и используется для автоматизации ввода часто встречающихся в практике учета операций. В этом случае заполнение набора записей регистра осуществляется в обработчике события проведения документа ОбработкаПроведения. Несложный алгоритм проведения, использующий при заполнении свойств движений преимущественно значений реквизитов документа, можно разработать с использованием конструктора движений. 478 Реализация прикладных задач в системе «1С:Предприятие 8.2» Рассмотрим его работу на примере документа ПриходнаяНакладная. Документ предназначен для ввода проводок закупки товаров у поставщика. В шапке документа пользователь сможет выбрать организацию (из справочника Организации), поставщика (из справочника Контрагенты) и склад (из справочника Склады). В табличной части будут выбираться товары (из справочника Номенклатура), вводиться цена покупки, количество и сумма товара (рис. 4.49). Форма документа включает все перечисленные реквизиты. Рис. 4.49. Данные документа «ПриходнаяНакладная» Конструктор движений документа Алгоритм проведения такого документа может быть полностью сформирован конструктором движений документа, вызываемым по кнопке Конструктор движений с закладки Движения свойств документа (рис. 4.50). Результатом работы конструктора (убраны только комментарии) будет процедура в модуле объекта (листинг 4.17). Глава 4. Реализация задач бухгалтерского учета 479 Рис. 4.50. Конструктор движений регистров Листинг 4.17. Процедура «ОбработкаПроведения()» Процедура ОбработкаПроведения(Отказ, Режим) Движения.ОсновнойРегистрБухгалтерии.Записывать = Истина; Для Каждого ТекСтрокаТовары Из Товары Цикл Движение = Движения.ОсновнойРегистрБухгалтерии.Добавить(); Движение.СчетДт = ПланыСчетов.ОсновнойПланСчетов.Товары; Движение.СчетКт = ПланыСчетов.ОсновнойПланСчетов.Поставщики; Движение.Период = Дата; Движение.Организация = Организация; Движение.Сумма = ТекСтрокаТовары.Сумма; Движение.КоличествоДт = ТекСтрокаТовары.Количество; Движение.Содержание = "Покупка товара"; Движение.СубконтоДт[ПланыВидовХарактеристик.ВидыСубконто.Номенклатура] = ТекСтрокаТовары.Номенклатура; Движение.СубконтоДт[ПланыВидовХарактеристик.ВидыСубконто.Склады] = Склад; Движение.СубконтоКт[ПланыВидовХарактеристик.ВидыСубконто.Контрагенты] = Поставщик; КонецЦикла; КонецПроцедуры 480 Реализация прикладных задач в системе «1С:Предприятие 8.2» Сначала указываются наборы записей, содержащие движения документа по регистрам, которые должны быть записаны при проведении документа. В цикле по табличной части Товары в набор записей регистра бухгалтерии, расположенный в коллекции движений, добавляется новое движение. Далее заполняются свойства записи регистра. После выхода из обработки проведения те наборы записей, у которых свойство Записывать имеет значение Истина, будут автоматически записаны платформой. В этот типовой алгоритм, сформированный конструктором, можно было бы внести изменения. Возможен альтернативный вариант синтаксиса при заполнении субконто проводки. Вариант, используемый конструктором, является более универсальным и больше подходит для документов, где счет выбирается в диалоге пользователем (листинг 4.18). Листинг 4.18. Пример установки значения субконто Движение.СубконтоКт[ПланыВидовХарактеристик.ВидыСубконто.Контрагенты] = Поставщик; В этой строке обращение к элементу коллекции субконто кредита проводки производится с использованием оператора «[ ]», в который в качестве параметра необходимо передать ссылку на вид характеристик. В нашем случае ссылки на элементы видов субконто получаются по предопределенным (неизменяемым) именам видов субконто, и поэтому можно было бы использовать упрощенный синтаксис (листинг 4.19). Листинг 4.19. Пример установки значения субконто Движение.СубконтоКт.Контрагенты = Поставщик; Оперативное и неоперативное проведение Оперативность – это свойство документа, используемое в первую очередь при решении задач оперативного учета в реальном времени. Бухгалтерия редко работает в реальном времени. Как правило, бухгалтер работает со свершившимися событиями, обрабатывая первичные документы за отчетный период. Поэтому свойство документа Оперативное проведение обычно при решении задач бухгалтерского учета устанавливают в значение Запретить. Тем не менее, практика автоматизации учета малых предприятий показывает частое использование механизмов бухгалтерского учета для решения задач учета оперативного, поэтому мы кратко рассмотрим это свойство и возможности его использования. Подробнее об оперативном учете Глава 4. Реализация задач бухгалтерского учета 481 можно прочитать в разделе «Оперативный учет. Описание задач, решаемых регистрами накопления» на стр. 249. Свойство Оперативное проведение, установленное в значение Разрешить, позволит контролировать ввод документов задним числом и запретить ввод документов будущей датой. При попытке проведения документа будущей датой пользователю будет выдано предупреждение и отказано в проведении документа (рис. 4.51). Рис. 4.51. Предупреждение о невозможности оперативного проведения будущей датой При вводе документа задним числом платформа автоматически проведет документ неоперативно, так как свойство ИспользоватьРежимПроведения расширения формы документа стандартно установится в значение Автоматически. Если установить свойство ИспользоватьРежимПроведения в значение Оперативный и попытаться провести документ задним числом, то пользователю будет выдано предупреждение и отказано в проведении документа (рис. 4.52). Рис. 4.52. Предупреждение о невозможности оперативного проведения задним числом Если же установить свойство ИспользоватьРежимПроведения в значение Запрашивать, то пользователю будет предложено выбрать режим проведения документа (рис. 4.53). Рис. 4.53. Выбор режима проведения 482 Реализация прикладных задач в системе «1С:Предприятие 8.2» Пользователь может изменить дату документа на текущую и провести документ оперативно, выбрав режим Оперативное проведение, или отказаться от оперативного проведения, и тогда документ будет проведен неоперативно и записан в базу с существующей датой и временем. Подробно о режимах проведения документа из формы рассказывается в разделе «Установка режима проведения» на стр. 198. При проведении документа во второй параметр процедуры ОбработкаПроведения будет передано значение системного перечисления РежимПроведенияДокумента Оперативный или Неоперативный, которое и может анализировать разработчик конфигурации с целью принятия решения о способе проведения документа. Основная задача, которую может помочь решить разделение проведения документа на оперативное и неоперативное, – это сокращение времени на проведение документа, если документы вводятся в реальном времени и в правильной (реальной, соответствующей событиям в реальной жизни) хронологической последовательности. Время на проведение документа всегда является критичным фактором в оценке удобства эксплуатации системы, особенно, если в ней работает большое число пользователей, и особенно, если они работают в реальном времени. Рассматриваемая нами в качестве примера приходная накладная вряд ли может улучшить свою работу, ведь всю необходимую для проведения информацию она содержит в себе и не обращается к другим объектам базы данных. А вот, например, расходная накладная, списывая товар, обязательно должна проверить его наличие по данным учетных регистров (в нашем случае счета Товары регистра бухгалтерии), рассчитать себестоимость и многое другое. В большинстве случаев извлечение данных из базы выполняется с помощью запроса (исключение может составлять лишь получение одного значения, тогда допускается использование метода объекта). Физическая организация таблиц регистра бухгалтерии (более подробно об этом пойдет речь ниже) позволяет наиболее быстро выполнить запрос к текущим итогам. Текущие итоги хранятся в регистре и пересчитываются при любом движении в регистре. Но в каком случае мы можем воспользоваться этими текущими итогами? Только тогда, когда уверены, что, во-первых, не вводились документы будущей датой, и, во-вторых, документ вводится с текущим временем и, стало быть, нужно «снимать» текущие итоги. Если документ вводится задним числом, то для оценки возможности его проведения, расчета остатков и себестоимости обязательно нужно получать не текущие итоги, а итоги на момент времени документа, что увеличивает время проведения документа. Глава 4. Реализация задач бухгалтерского учета 483 Таким образом, если стоит задача учета документов в реальном времени и большинство документов вводятся в правильной хронологической последовательности, оперативное проведение может существенно сократить время на проведение и улучшить работу пользователей. Автоматическое удаление движений Свойство документа Удаление движений устанавливается на закладке Движения и может принимать значения Удалять автоматически при отмене проведения (стандартное значение), Удалять автоматически или Не удалять автоматически. В случае значения Удалять автоматически при отмене проведения для свойства Удаление движений движения, связанные с документом, удаляются автоматически только при удалении и отмене проведения документа. При проведении документа движения не удаляются, а перезаписываются. Такое поведение является стандартным для платформы «1С:Предприятие». Используя два других значения свойства Удаление движений, разработчик может реализовывать нестандартные сценарии проведения документа. В случае значения Удалять автоматически для свойства Удаление движений платформа автоматически удаляет старые записи движений, связанных с данным документом, при повторном проведении документа перед записью новых движений, а также при удалении и отмене проведения документа. Отключение этого режима имеет смысл, прежде всего, при решении задач оперативного учета в реальном времени. В случае же значения Не удалять автоматически для свойства Удаление движений автоматическое удаление движений для этих ситуаций производиться не будет. Один из вариантов использования документа с отключенным автоматическим удалением движений – построчное проведение документа. При решении задачи автоматизации учета продавцов товаров в реальном времени это свойство может быть актуально. Представим себе ситуацию, что два менеджера продают один и тот же товар, количество которого ограничено. Пока первый из них, удостоверившись в наличии товара на складе по данным регистра, проводит свой документ с установленным свойством Автоматическое удаление движений, второй менеджер за те мгновения, когда старые движения уже удалены, а новые еще не записаны, успевает провести свой документ. Научившись на горьком опыте, первый менеджер начинает нажимать кнопку Провести после добавления каждой строки документа. Но при проведении каждый раз удаляются все ранее сформированные записи в регистре и формируются новые. И между этими двумя событиями все равно остается временной лаг, достаточный для списания товара вторым менеджером. 484 Реализация прикладных задач в системе «1С:Предприятие 8.2» Решение этой проблемы – построчное проведение документа первым менеджером, при котором запись по новой строке добавляется в регистр без удаления всех ранее сделанных движений документа. В этом случае контроль удаления записей при проведении документа в целом, отмене проведения и удалении документа лежит на программисте, разрабатывающем этот документ. Мы рассмотрели последние две темы поверхностно по одной и той же причине: бухгалтерский учет почти никогда не требует работы пользователей в реальном времени. Программно без проведения документа Документ может иметь движения в регистре, и не будучи проведенным. Для записи движений в регистр можно использовать или свойство документа Движения, содержащее коллекцию наборов записей, или набор записей регистра бухгалтерии. Этот вариант формирования движений в регистр нельзя считать основным. Его можно рекомендовать для офф-лайнового проведения документа, когда в реальном времени документ проводится в оперативном учете, а отражение операции в бухгалтерском учете выполняется в конце отчетного периода. В этом случае можно предложить один из следующих вариантов (листинг 4.20). Листинг 4.20. Пример записи движений документа Приходные = Документы.ПриходнаяНакладная.Выбрать(); Пока Приходные.Следующий() Цикл ПриходнаяОбъект = Приходные.ПолучитьОбъект(); Проводки = ПриходнаяОбъект.Движения.ОсновнойРегистрБухгалтерии; НоваяПроводка = Проводки.Добавить(); НоваяПроводка.Период = ПриходнаяОбъект.Дата; НоваяПроводка.Организация = ПриходнаяОбъект.Организация; НоваяПроводка.СчетДт = ПланыСчетов.ОсновнойПланСчетов.Товары; НоваяПроводка.СчетКт = ПланыСчетов.ОсновнойПланСчетов.Поставщики; НоваяПроводка.Сумма = ПриходнаяОбъект.Всего; Проводки.Записать(Ложь); КонецЦикла; Предложенный выше код может располагаться в любой обработке. Программный код получает из базы данных выборку документов, и для каждого из них, создавая объект документа, выполняет заполнение набора записей Глава 4. Реализация задач бухгалтерского учета 485 движениями и запись его в регистр добавлением к тем записям, которые уже существуют в регистре. В приведенном примере для записи движений в регистр используется свойство документа Движения. Можно не использовать его, а воспользоваться набором записей регистра бухгалтерии. Следующий фрагмент кода выполняет ту же задачу, но с использованием объекта РегистрБухгалтерииНаборЗаписей.ОсновнойРегистрБухгалтерии (листинг 4.21). Листинг 4.21. Пример записи движений документа Приходные = Документы.ПриходнаяНакладная.Выбрать(); Проводки = РегистрыБухгалтерии.ОсновнойРегистрБухгалтерии.СоздатьНаборЗаписей(); Пока Приходные.Следующий() Цикл ПриходнаяСсылка = Приходные.Ссылка; Проводки.Отбор.Регистратор.Установить(ПриходнаяСсылка); НоваяПроводка = Проводки.Добавить(); НоваяПроводка.Период = ПриходнаяСсылка.Дата; НоваяПроводка.Организация = ПриходнаяСсылка.Организация; НоваяПроводка.СчетДт = ПланыСчетов.ОсновнойПланСчетов.Товары; НоваяПроводка.СчетКт = ПланыСчетов.ОсновнойПланСчетов.Поставщики; НоваяПроводка.Сумма = ПриходнаяСсылка.Всего; Проводки.Записать(Ложь); КонецЦикла; При использовании набора записей регистра от документа нам нужна ссылка, чтобы по ней установить отбор в наборе записей. Затем, используя методы набора записей регистра, мы добавляем нужную запись в набор записей и записываем его с добавлением. Оба варианта кода предусматривают возможность непроведенного документа иметь движения. Необходимо, однако, учитывать, что повторное проведение документа штатным способом (интерактивно из формы или программно методом документа Записать(РежимЗаписиДокумента.Проведение)) не будет учитывать наличие добавленной нами записи. Так, например, если в свойствах документа установлено свойство автоматического удаления движения, будет удалено и дополнительное, сделанное обработкой, движение. А при формировании движений из процедуры ОбработкаПроведения не будет добавлено движение, описанное в обработке. 486 Реализация прикладных задач в системе «1С:Предприятие 8.2» Чтение данных регистра бухгалтерии Для чтения данных регистра бухгалтерии в системе «1С:Предприятие» предусмотрены методы объекта РегистрБухгалтерии и набор таблиц, используемых запросом как источники данных. Основным способом извлечения данных в системе является запрос. Мы полагаем, что это утверждение актуально и для регистра бухгалтерии, поэтому начнем изучение подходов к извлечению данных об остатках и оборотах на счетах с изучения таблиц регистра – источников данных запроса. Методы объекта, которые можно считать вспомогательным механизмом, будут рассмотрены позднее. Таблицы регистра бухгалтерии Регистр бухгалтерии – сложный объект, представленный в табличной модели данных рядом таблиц (рис. 4.54). Рис. 4.54. Таблицы запросов регистра бухгалтерии Все таблицы регистра бухгалтерии можно разделить на две группы: реальные и виртуальные. Реальные таблицы предоставляют доступ посредством запроса к физически существующим в информационной базе таблицам. Глава 4. Реализация задач бухгалтерского учета 487 У регистра бухгалтерии таких таблиц две: основная таблица и таблица значений субконто, которая создается в информационной базе после добавления в конфигурацию механизмов аналитического учета. Реальные таблицы Имя основной таблицы регистра бухгалтерии содержит имя регистра. И для использования ее в качестве источника данных в нашем случае необходимо написать следующее предложение (листинг 4.22). Листинг 4.22. Обращение к таблице записей регистра бухгалтерии ИЗ РегистрБухгалтерии.ОсновнойРегистрБухгалтерии Основная таблица регистра бухгалтерии с поддержкой корреспонденции содержит следующие поля (табл. 4.27). Таблица 4.27. Поля основной таблицы регистра бухгалтерии Поле Период Регистратор НомерСтроки Активность СчетДт СчетКт <Измерение> Тип Дата ДокументСсылка.����� <���� имя� > Число Булево ПланыСчетовСсылка.����� <���� имя� > ПланыСчетовСсылка.����� <���� имя� > Определяется типом измерения <Измерение>Кт Определяется типом измерения Определяется типом измерения <Ресурс> Число <Ресурс>Дт Число Число <Измерение>Дт <Ресурс>Кт <Реквизит> Определяется типом реквизита Комментарий Дата движения Документ движения Номер движения в наборе записей Участвует ли запись в таблицах итогов Дебетуемый счет Кредитуемый счет Балансовое измерение регистра бухгалтерии Небалансовое измерение регистра бухгалтерии создает два поля в регистре Балансовый ресурс регистра бухгалтерии Небалансовый ресурс регистра бухгалтерии создает два поля в регистре Характеристика движения регистра Основная таблица регистра бухгалтерии без поддержки корреспонденции отличается отсутствием корреспонденции счетов и отсутствием деления измерений на балансовые и небалансовые, которые в таблице регистра с поддержкой корреспонденции были представлены двумя полями – свое для дебета и свое для кредита. 488 Реализация прикладных задач в системе «1С:Предприятие 8.2» В регистре без поддержки корреспонденции также присутствуют поля ВидДвижения и Счет. Основная таблица хранит проводки (движения регистра бухгалтерии) без данных аналитического учета. Для хранения данных аналитического учета предназначена вторая реальная таблица регистра бухгалтерии – таблица значений субконто. Эта таблица не содержит числовых характеристик и вряд ли может использоваться самостоятельно. В таблице хранится информация о виде и значении каждого субконто проводки. Для получения полной информации о проводке (включая данные аналитического учета) система соединяет данные таблицы движений и таблицы значений субконто по периоду, регистратору и виду движения. Субконто хранятся платформой компактно, и количество полей этой таблицы не зависит от количества субконто на счете. Чем больше субконто описано в проводке, тем больше записей будет содержать таблица значений субконто. Одной проводке из основной таблицы может соответствовать несколько записей таблицы значений субконто. Обращение к таблице значений субконто в нашем случае будет выглядеть так (листинг 4.23). Листинг 4.23. Обращение к таблице значений субконто ИЗ РегистрБухгалтерии.ОсновнойРегистрБухгалтерии.Субконто Таблица значений субконто регистра бухгалтерии содержит следующие поля (табл. 4.28). Таблица 4.28. Поля таблицы значений субконто Поле Период Регистратор НомерСтроки ВидДвижения Вид Значение Тип Комментарий ВидДвиженияБухгалтерии ПланВидовХарактеристикСсылка.<имя> Характеристика.<имя> Дата движения Документ движения Номер движения в наборе записей Дебет или Кредит Вид субконто Значение субконто Дата ДокументСсылка.<имя> Число В регистре без поддержки корреспонденции отсутствует поле ВидДвижения. Виртуальные таблицы Реальные таблицы регистра бухгалтерии малопригодны для формирования большинства бухгалтерских отчетов и являются скорее вспомогательным механизмом. Для построения отчетов и анализа данных в большинстве случаев используются виртуальные таблицы. Эти таблицы не хранятся Глава 4. Реализация задач бухгалтерского учета 489 в информационной базе и создаются системой при обращении к ним. По своей сути это вложенные запросы. Запросы выполняются системой к физическим таблицам регистра бухгалтерии, о которых мы расскажем ниже. Виртуальные таблицы параметризированы: обращаясь к ним, мы можем передать в качестве параметров условия выполнения запроса. Виртуальные таблицы узкоспециализированные, предназначены для решения конкретных задач, поэтому проще изучать их исходя из задач, которые с их помощью можно решить. Таблица остатков Для получения остатков по счетам в разрезе субконто и измерений используется таблица остатков. Эта таблица позволяет решить такие задачи, как получение количественных и суммовых остатков материально-производственных запасов при их списании, определение остатка задолженности для выполнения зачета аванса, расчет амортизации и курсовых разниц и многие другие, где требуется узнать остаток какого-либо ресурса по счету, субконто или измерению, свернутый или развернутый. Таблица не отличается для регистра с поддержкой и без поддержки корреспонденции. Использование таблицы остатков в качестве источника запроса представлено в листинге 4.24. Листинг 4.24. Обращение к таблице «Остатки» ИЗ РегистрБухгалтерии.ОсновнойРегистрБухгалтерии.Остатки После имени таблицы в круглых скобках могут (и в большинстве случаев будут) указываться параметры, задающие условия отбора данных из физических таблиц информационной базы. Рассмотрим поля виртуальной таблицы остатков. ■ Счет – это поле имеет тип ПланСчетовСсылка.<имя>. Поле позволяет получить остатки, сгруппированные по счетам. ■ Субконто<N> – это поле имеет тип Характеристика.<имя>. Количество полей Субконто зависит от максимального количества субконто на счете плана счетов. Поле позволяет получить остатки, сгруппированные по значениям субконто. ■ <Измерение> – тип этого поля задается при создании измерения регистра. Количество полей зависит от количества измерений, объявленных в регистре бухгалтерии. На поле не влияет свойство измерения Балансовый. Поле позволяет получить остатки, сгруппированные по измерениям регистра. 490 ■ Реализация прикладных задач в системе «1С:Предприятие 8.2» <Ресурс>Остаток – это поле имеет тип Число. Абсолютный остаток (как он хранится в физических таблицах информационной базы) без учета вида счета: дебетовый остаток показывается положительным числом, кредитовый – отрицательным. ■ <Ресурс>ОстатокДт – это поле имеет тип Число. Дебетовый остаток с учетом вида счета. Если счет пассивный, значение этого поля всегда равно нулю. Если счет активный, значение поля равно значению поля Остаток. Если счет активно-пассивный, значение поля равно значению поля Остаток, если Остаток больше или равен нулю. Если Остаток меньше нуля, значит – ноль. ■ <Ресурс>ОстатокКт – это поле имеет тип Число. Кредитовый остаток с учетом вида счета. Если счет активный, значение этого поля всегда равно нулю. Если счет пассивный, равно «- Остаток». Если счет активнопассивный, значение поля равно нулю, если значение поля Остаток больше или равно нулю. Если значение поля Остаток меньше нуля, значение этого поля равно «- Остаток». ■ <Ресурс>РазвернутыйОстатокДт – это поле имеет тип Число. Развернутый дебетовый остаток. Имеет смысл только при использовании в запросе итогов. Для детальной записи значение этого поля равно значению поля ОстатокДт. Для итоговой записи равно сумме дебетовых остатков всех детальных записей. ■ <Ресурс>РазвернутыйОстатокКт – это поле имеет тип Число. Развернутый кредитовый остаток. Имеет смысл только при использовании в запросе итогов. Для детальной записи значение этого поля равно значению поля ОстатокКт. Для итоговой записи равно сумме кредитовых остатков всех детальных записей. В физических таблицах регистра хранится абсолютный остаток (поле <Ресурс>Остаток), все остальные рассчитываются при формировании системой виртуальной таблицы остатков. Алгоритм расчета полей ОстатокДт и ОстатокКт можно представить в виде схемы (рис. 4.55). При обращении к полям ОстатокДт или ОстатокКт система в первую очередь проверяет наличие в запросе группировки (или отбора) по счету. Если такой разрез в запросе есть и этот счет один, вычисление полей зависит от вида счета. Если используемый в запросе счет активный, система отображает в поле ОстатокДт значение поля Остаток, кредитовый остаток для активного счета всегда равен нулю. Если используемый в запросе счет пассивный, значение поля ОстатокКт будет равно значению поля Остаток с обратным знаком («- Остаток»), дебетовый остаток для пассивного счета всегда равен нулю. Глава 4. Реализация задач бухгалтерского учета 491 Рис. 4.55. Алгоритм расчета полей «ОстатокДт» и «ОстатокКт» При расчете полей остатков активно-пассивного счета система дополнительно будет анализировать знак остатка. Если поле Остаток содержит положительное число, остаток будет интерпретирован системой как ОстатокДт; если отрицательное – как ОстатокКт. В случае если в запросе нет разреза по счету или в качестве условия используется отбор по списку счетов, поля ОстатокДт и ОстатокКт рассчитываются по правилам активно-пассивного счета. Алгоритм формирования развернутых остатков счета мы рассмотрим более подробно ниже. Параметры виртуальной таблицы остатков позволяют задать условие отбора данных из информационной базы. Параметры следует задавать строго в порядке их описания. ■ Период – имеет тип значения Дата, МоментВремени или Граница. На этот момент будут рассчитаны остатки виртуальной таблицы. Если параметр не задан, будут получены актуальные остатки, включающие движения последнего проведенного документа. Физическая организация таблиц позволяет максимально быстро получить остатки за месяц (на начало следующего месяца) и актуальные остатки. 492 Реализация прикладных задач в системе «1С:Предприятие 8.2» ■ УсловиеСчета – содержит конструкцию языка запросов. Позволяет установить фильтр по счету или счетам. Как правило, содержит следующие условия: Счет = (В ИЕРАРХИИ, В) &Счет. ■ Субконто – имеет тип ПланВидовХарактеристикСсылка.<имя> или содержит массив значений типа ПланВидовХарактеристикСсылка.<имя>. В этот параметр таблицы можно передать ссылку на вид субконто для получения отбора по этому виду или массив видов для установки отбора и упорядочивания видов субконто в результате запроса. ■ Условие – содержит конструкцию языка запросов. Позволяет устанавливать отбор данных виртуальной таблицей по значениям субконто и измерений регистра бухгалтерии. Рассмотрим примеры построения запросов к таблице остатков регистра бухгалтерии. При необходимости получить количественный остаток конкретного товара со счета товаров можно использовать следующий код (листинг 4.25). Листинг 4.25. Пример получения остатка товара ВЫБРАТЬ Остатки.КоличествоОстаток ИЗ РегистрБухгалтерии.ОсновнойРегистрБухгалтерии.Остатки(&Момент, Счет = &СчетТоваров, , Организация = &Организация И Субконто1 = &Номенклатура) КАК Остатки В приведенном тексте запроса используются параметры: ■ Момент – Дата, МоментВремени или Граница, на которую необходимо получить остаток. ■ СчетТоваров – ПланСчетовСсылка.<имя>. Ссылку для предопределенного счета можно получить по имени, например: СчетТоваров = ПланыСчетов.ОсновнойПланСчетов.Товары. ■ Организация – ссылка на элемент справочника Организации, который используется как измерение регистра. ■ Номенклатура – ссылка на элемент справочника Номенклатура, который используется на счете товаров как первый вид субконто. Результат запроса будет содержать одну строку в одном поле: абсолютный остаток по ресурсу регистра Количество. Следующий запрос позволяет отобрать остатки по всем счетам, по которым ведется валютный учет, и в разрезе валют проанализировать остатки в валюте сделки и в валюте учета (листинг 4.26). Глава 4. Реализация задач бухгалтерского учета 493 Листинг 4.26. Пример получения остатков регистра бухгалтерии ВЫБРАТЬ Остатки.Счет, Остатки.Валюта, Остатки.ВалютнаяСуммаОстаток, Остатки.СуммаОстаток ИЗ РегистрБухгалтерии.ОсновнойРегистрБухгалтерии.Остатки( , Счет.Валютный = ИСТИНА, , ) КАК Остатки В результате выполнения этого запроса будет получена, например, следующая таблица (табл. 4.29). Таблица 4.29. Результат выполнения запроса Счет Валюта ВалютнаяСуммаОстаток СуммаОстаток Касса Касса Касса Новый счет Рубль Доллар Евро Доллар 100 100 100 10 470 2850 3500 285 Таблица оборотов Для получения оборотов по счету, по счету в разрезе субконто и измерений и оборотов счета с корреспондирующими счетами (как дебетуемыми, так и кредитуемыми) используется таблица оборотов. Таблица присутствует как у регистра с поддержкой, так и без поддержки корреспонденции, хотя и с небольшими отличиями. Таблица оборотов может быть использована при решении задач получения оборотных показателей таких отчетов, как анализ счета/субконто/по датам и др., журнальный ордер, ведомость по счету. Использование таблицы оборотов в качестве источника запроса представлено в листинге 4.27. Листинг 4.27. Обращение к таблице «Обороты» ИЗ РегистрБухгалтерии.ОсновнойРегистрБухгалтерии.Обороты После имени таблицы в круглых скобках могут (и в большинстве случаев будут) указываться параметры, задающие условия отбора данных из физических таблиц информационной базы. Рассмотрим поля виртуальной таблицы оборотов. ■ Счет – это поле имеет тип ПланСчетовСсылка.<имя>. Поле позволяет получить обороты выбранного счета. 494 ■ Реализация прикладных задач в системе «1С:Предприятие 8.2» КорСчет – это поле имеет тип ПланСчетовСсылка.<имя>. Поле позволяет получить обороты выбранного счета, указанного в параметре Счет с выбранным корреспондирующим счетом. ■ Субконто<N> – это поле имеет тип Характеристика.<имя>. Количество полей Субконто зависит от максимального количества субконто на счете плана счетов. Поле позволяет получить обороты, сгруппированные по значениям субконто. ■ КорСубконто<N> – это поле имеет тип Характеристика.<имя>. Количество полей КорСубконто зависит от максимального количества субконто на счете плана счетов. Поле позволяет получить обороты, сгруппированные по значениям субконто корреспондирующего счета. ■ <Измерение> – тип поля задается при создании измерения регистра. Количество полей зависит от количества измерений, объявленных в регистре бухгалтерии. Поле существует как для балансовых, так и для небалансовых измерений. ■ <Измерение>Кор – тип поля задается при создании измерения регистра. Количество полей зависит от количества измерений, объявленных в регистре бухгалтерии. Поле создается только для небалансовых измерений. ■ Период – тип Дата, Регистратор – тип ДокументСсылка.<имя>, НомерСтроки – тип Число. Поля создаются в том случае, если в параметрах виртуальной таблицы задана периодичность и она отличается от значения Период. ■ <Ресурс>Оборот – это поле имеет тип Число. Разница оборотов выбранного счета (дебетовый оборот минус кредитовый оборот). ■ <Ресурс>ОборотДт – это поле имеет тип Число. Дебетовый оборот счета. ■ <Ресурс>ОборотКт – это поле имеет тип Число. Кредитовый оборот счета. ■ <Ресурс>КорОборот – это поле имеет тип Число. Содержит разницу оборотов (кор. оборот дебета минус кор. оборот кредита) для небалансового ресурса корреспондирующего счета. ■ <Ресурс>КорОборотДт – это поле имеет тип Число. Дебетовый оборот для небалансового ресурса корреспондирующего счета. ■ <Ресурс>КорОборотКт – это поле имеет тип Число. Кредитовый оборот для небалансового ресурса корреспондирующего счета. Параметры виртуальной таблицы оборотов позволяют задать условие отбора данных из информационной базы. Параметры следует задавать строго в порядке их описания. ■ НачалоПериода, КонецПериода – имеет тип Дата, МоментВремени или Граница. Период времени, за который будут получены обороты. Глава 4. Реализация задач бухгалтерского учета 495 ■ Периодичность – содержит конструкцию языка запросов. Позволяет задать дополнительную группировку данных по стандартным периодам. Возможные значения: Период, Год, Полугодие, Квартал, Месяц, Декада, Неделя, День, Час, Минута, Секунда, Регистратор, Запись. Если периодичность не задана или задана как Период, дополнительная группировка не выполняется. ■ УсловиеСчета – содержит конструкцию языка запросов. Позволяет установить фильтр по счету или счетам. Как правило, содержит следующие условия: Счет = (В ИЕРАРХИИ, В) &Счет. ■ Субконто – имеет тип ПланВидовХарактеристикСсылка.<имя> или содержит массив значений типа ПланВидовХарактеристикСсылка.<имя>. В этот параметр таблицы можно передать ссылку на вид субконто для получения отбора по этому виду или массив видов для установки отбора и упорядочивания видов субконто в результате запроса. ■ Условие – содержит конструкцию языка запросов. Позволяет устанавливать отбор данных виртуальной таблицей по значениям субконто и измерений регистра бухгалтерии. ■ УсловиеКорСчета – содержит конструкцию языка запросов. Позволяет установить фильтр по корреспондирующему счету или счетам. Как правило, содержит следующие условия: КорСчет = (В ИЕРАРХИИ, В) &КорСчет. ■ КорСубконто – имеет тип ПланВидовХарактеристикСсылка.<имя> или содержит массив значений типа ПланВидовХарактеристикСсылка.<имя>. В этот параметр таблицы можно передать ссылку на вид субконто для получения отбора по этому виду или массив видов для установки отбора и упорядочивания видов субконто в результате запроса. Рассмотрим примеры построения запросов к таблице оборотов регистра бухгалтерии. Все запросы обращаются к итогам за весь период, который есть в регистре (не указываются параметры НачалоПериода и КонецПериода). Во всех запросах в качестве параметра передается условие по счету, где СчетТоваров – ссылка на счет Товары плана счетов. Запрос, который покажет, сколько было куплено и списано товаров разных видов в количественном выражении, представлен в листинге 4.28. Листинг 4.28. Пример использования таблицы «Обороты» ВЫБРАТЬ Обороты.Субконто1, Обороты.КоличествоОборотДт, Обороты.КоличествоОборотКт ИЗ РегистрБухгалтерии.ОсновнойРегистрБухгалтерии.Обороты(, , , Счет = &СчетТоваров, , , , ) КАК Обороты Результат такого запроса представлен в табл. 4.30. 496 Реализация прикладных задач в системе «1С:Предприятие 8.2» Таблица 4.30. Результат запроса Субконто1 КоличествоОборотДт КоличествоОборотКт Комплект Паркер Школьная Цветной 1 15 10 3 10 Таблица показывает, какие из товаров в каком количестве были оприходованы (КоличествоОборотДт) и списаны (КоличествоОборотКт). Если требуется узнать, с какого корреспондирующего счета (субконто корреспондирующего счета) были получены те или иные товары, необходимо воспользоваться полями таблицы оборотов КорСчет и КорСубконто (листинг 4.29). Листинг 4.29. Пример использования таблицы «Обороты» ВЫБРАТЬ Обороты.Субконто1, Обороты.КорСчет, Обороты.КорСубконто1, Обороты.КоличествоОборотДт ИЗ РегистрБухгалтерии.ОсновнойРегистрБухгалтерии.Обороты(, , , Счет = &СчетТоваров, , , , ) КАК Обороты Результат запроса представлен в табл. 4.31. Таблица 4.31. Результат запроса Субконто1 КорСчет КорСубконто1 КоличествоОборотДт Комплект Паркер Паркер Школьная Школьная Цветной Товары Поставщики Поставщики Сотрудники Поставщики Поставщики Паркер СтройТоргВсе Дисконт центр Иванов Дисконт центр МонтажДоставка 1 10 5 5 5 3 Таблица демонстрирует, какой именно товар (Субконто1) с какого корреспондирующего счета (КорСчет), от какого контрагента (первое субконто корреспондирующего счета) и в каком количестве был получен. Как мы видим, большинство товаров было получено со счета Поставщики, от разных контрагентов. Однако есть и такие, которые были получены со счета Сотрудники и счета Товары. Именно эта корреспонденция может нас заинтересовать. Глава 4. Реализация задач бухгалтерского учета 497 Количество является небалансовым ресурсом регистра бухгалтерии. Регистр, который мы рассматриваем, поддерживает корреспонденцию, поэтому для каждого небалансового ресурса создаются два поля в таблице записей регистра бухгалтерии. Таким образом, допускается ситуация, когда корреспондируют два счета, поддерживающих вид учета, ведущийся в небалансовом ресурсе (в нашем случае Количество), и эти счета будут иметь различные обороты. То есть дебетовый оборот счета дебета проводки не будет равен кредитовому обороту счета кредита проводки. Как пример можно привести комплектацию (рис. 4.56). Рис. 4.56. Комплектация В приведенном примере дебетуется счет Товары с аналитикой Комплект и кредитуется счет Товары с другой аналитикой (Паркер). При этом ресурс Сумма балансирует (балансовый ресурс регистра бухгалтерии), а количество дебета и кредита отличается: было списано десять «Паркеров», и оприходован один «Комплект». Воспользовавшись полем ОборотДт виртуальной таблицы оборотов, мы сможем проанализировать, сколько Комплектов было оприходовано на счет Товары в количественном (КоличествоОборотДт) и суммовом выражении (СуммаОборотДт). Для балансового ресурса этой информации более чем достаточно. Ресурс небалансовый, как мы убедились, может быть заполнен для основного и для корреспондирующего счета проводки и заполнен независимо. Если потребуется проанализировать, из какого количества авторучек Паркер какое количество Комплектов было собрано, нам пригодится поле с постфиксом КорОборот. Напишем запрос, в котором для виртуальной таблицы оборотов установим фильтр по полям Счет и КорСчет и получим таким образом в качестве итогов обороты по всем проводкам, где корреспондировали между собой счет Товары и счет Товары (листинг 4.30). 498 Реализация прикладных задач в системе «1С:Предприятие 8.2» Листинг 4.30. Пример использования таблицы «Обороты» ВЫБРАТЬ Обороты.Субконто1, Обороты.КоличествоОборотДт, Обороты.КорСубконто1, Обороты.КоличествоКорОборотДт ИЗ РегистрБухгалтерии.ОсновнойРегистрБухгалтерии.Обороты( , , , Счет = &СчетТоваров, , , КорСчет = &СчетТоваров, ) КАК Обороты Результат запроса приведен в табл. 4.32. Таблица 4.32. Результат запроса Субконто1 КоличествоОборотДт КорСубконто1 КоличествоКорОборотДт Комплект 1 Паркер 10 Аналогичное назначение имеет поле виртуальной таблицы оборотов <Измерение>Кор, которое позволит сгруппировать или отобрать данные, например, по валюте корреспондирующего счета. Таблица оборотов регистра без поддержки корреспонденции отличается отсутствием в ней полей, содержащих слово Кор. Таблица остатков и оборотов Основное предназначение таблицы остатков и оборотов – формирование оборотно-сальдовых ведомостей, отчетов, где для каждой строки необходимо показать остаток на начало периода, обороты за период и остаток на конец периода. Нужно сразу заметить, что функционально таблица остатков и оборотов не является соединением таблицы остатков с таблицей оборотов (табл. 4.33). Таблица 4.33. Сравнение функциональности таблиц регистра бухгалтерии Функциональность Соединение таблицы Таблица остатков . остатков и таблицы и оборотов оборотов Получить остатки Обороты по счету (субконто, измерению счета) Обороты счета с корреспондирующими (счетами, субконто, измерениями) Да Да Да Да Да Нет Как видно из таблицы, таблица остатков и оборотов позволяет получить обороты по счету аналогично таблице оборотов, однако не предоставляет возможности анализировать обороты с корреспондирующими счетами, Глава 4. Реализация задач бухгалтерского учета 499 субконто, измерениями. По этой причине, например, не представляется возможным использовать ее для получения отчета Анализ счета. Использование таблицы в качестве источника запроса потребует следующего обращения (листинг 4.31). Листинг 4.31. Обращение к таблице остатков и оборотов ИЗ РегистрБухгалтерии.ОсновнойРегистрБухгалтерии.ОстаткиИОбороты Рассмотрим поля виртуальной таблицы остатков и оборотов: ■ ■ ■ ■ ■ ■ ■ Счет – это поле имеет тип ПланыСчетовСсылка.<имя>. Поле содержит счет, для которого получены остатки и обороты. Субконто<N> – это поле имеет тип Характеристика.<имя>, тип этого поля определяется типом субконто. Количество таких полей зависит от максимального количества субконто на счете плана счетов. Поле позволяет получить остатки и обороты, сгруппированные по значениям субконто. <Измерение> – тип этого поля определяется типом измерения регистра накопления. Количество таких полей зависит от количества измерений, объявленных в регистре бухгалтерии. Поле существует как для балансовых, так и для небалансовых измерений. Период, Регистратор, НомерСтроки – эти поля имеют тип соответственно Дата, ДокументСсылка.<имя> и Число. Поля создаются в том случае, если в параметрах виртуальной таблицы задана периодичность и она отличается от Период. <Ресурс>Оборот, <Ресурс>ОборотДт, <Ресурс>ОборотКт – эти поля имеют тип Число. Поля аналогичны полям таблицы оборотов. Подробнее можно прочитать в разделе «Таблица оборотов» на стр. 493. <Ресурс>НачальныйОстаток, <Ресурс>НачальныйОстатокДт, Ресурс>НачальныйОстатокКт, <Ресурс>НачальныйРазвернутыйОстатокДт, <Ресурс>НачальныйРазвернутыйОстатокКт – эти поля имеют тип Число. Поля аналогичны полям таблицы остатков (подробнее можно прочитать в разделе «Таблица остатков» на стр. 489), рассчитываются на дату начала интервала, указанного в параметре таблицы остатков и оборотов НачалоПериода. <Ресурс>КонечныйОстаток, <Ресурс>КонечныйОстатокДт, <Ресурс>КонечныйОстатокКт, <Ресурс>КонечныйРазвернутыйОстатокДт, <Ресурс>КонечныйРазвернутыйОстатокКт – эти поля имеют тип Число. Поля аналогичны полям таблицы остатков (подробнее можно прочитать в разделе «Таблица остатков» на стр. 489), рассчитываются на дату окончания интервала, указанного в параметре таблицы остатков и оборотов КонецПериода. 500 Реализация прикладных задач в системе «1С:Предприятие 8.2» Параметры виртуальной таблицы остатков и оборотов позволяют задать условие отбора данных из информационной базы. Параметры следует задавать строго в порядке их описания: ■ НачалоПериода, КонецПериода – эти параметры имеют тип соответственно Дата, МоментВремени и Граница. Период времени, за который будут получены обороты. ■ Периодичность – этот параметр содержит конструкцию языка запросов. Позволяет задать дополнительную группировку данных по стандартным периодам. Возможные значения: Период, Год, Полугодие, Квартал, Месяц, Декада, Неделя, День, Час, Минута, Секунда, Регистратор или Запись. Если периодичность не задана или задана как Период, то дополнительная группировка не выполняется. ■ МетодДополнения – этот параметр содержит конструкцию языка запросов. Возможны два значения: Движения или ДвиженияИГраницыПериода. Управляет включением в отчет периодов, не имеющих оборотов, но имеющих остатки. ■ УсловиеСчета – этот параметр содержит конструкцию языка запросов. Позволяет установить фильтр по счету или счетам. Как правило, содержит следующие условия: Счет = (В ИЕРАРХИИ, В) &Счет. ■ Субконто – этот параметр имеет тип ПланВидовХарактеристикСсылка.<имя> или может содержать массив значений типа ПланВидовХарактеристикСсылка.<имя>. В этот параметр таблицы можно передать ссылку на вид субконто для получения отбора по этому виду или массив видов для установки отбора и упорядочивания видов субконто в результате запроса. ■ Условие – этот параметр содержит конструкцию языка запросов. Позволяет устанавливать отбор данных виртуальной таблицей по значениям субконто и измерений регистра бухгалтерии. Примером использования таблицы может быть отчет «Оборотно-сальдовая ведомость», текст которого приведен в листинге 4.32. Листинг 4.32. Пример отчета «Оборотно-сальдовая ведомость» ВЫБРАТЬ ОстаткиИОбороты.Счет КАК Счет, ПРЕДСТАВЛЕНИЕ(ОстаткиИОбороты.Счет), ОстаткиИОбороты.СуммаНачальныйОстатокДт КАК НачОстДт, ОстаткиИОбороты.СуммаНачальныйОстатокКт КАК НачОстКт, ОстаткиИОбороты.СуммаОборотДт КАК ОборотДт, ОстаткиИОбороты.СуммаОборотКт КАК ОборотКт, ОстаткиИОбороты.СуммаКонечныйОстатокДт КАК КонОстДт, ОстаткиИОбороты.СуммаКонечныйОстатокКт КАК КонОстКт ИЗ РегистрБухгалтерии.ОсновнойРегистрБухгалтерии.ОстаткиИОбороты(&НачПериода, &КонПериода, , , , , ) КАК ОстаткиИОбороты Глава 4. Реализация задач бухгалтерского учета 501 УПОРЯДОЧИТЬ ПО ОстаткиИОбороты.Счет.Код ИТОГИ СУММА(НачОстДт), СУММА(НачОстКт), СУММА(ОборотДт), СУММА(ОборотКт), СУММА(КонОстДт), СУММА(КонОстКт) ПО Счет ИЕРАРХИЯ В результате выполнения этого запроса будут получены данные, представленные в табл. 4.34. Таблица 4.34. Результат выполнения запроса Счет Активы Активы Касса Покупатели Товары Материалы НачОстДт НачОстКт ОборотДт ОборотКт КонОстДт 8804 100 6961 95 350 1000 7511 1293 100 58 -395 250 1000 6903 490 100 КонОстКт Контрагенты 13 18 5 Обязательства Обязательства Сотрудники Поставщики 2 1352 100 50 1202 1350 100 48 1202 Капитал 6810 6753 -57 2 Другой пример использования таблицы остатков и оборотов – получение детальных аналитических отчетов схожей структуры, т. е. содержащих колонки «Остаток на начало периода», «Обороты за период», «Остаток на конец периода». Пример такого отчета – «Оборотно-сальдовая ведомость по счету товаров» (листинг 4.33). Листинг 4.33. Пример отчета «Оборотно-сальдовая ведомость по счету товаров» ВЫБРАТЬ ОстаткиИОбороты.Субконто1 КАК Товар, ОстаткиИОбороты.КоличествоНачальныйОстаток КАК НачОст, ОстаткиИОбороты.КоличествоОборотДт КАК Приход, ОстаткиИОбороты.КоличествоОборотКт КАК Расход, ОстаткиИОбороты.КоличествоКонечныйОстаток КАК КонОст ИЗ РегистрБухгалтерии.ОсновнойРегистрБухгалтерии.ОстаткиИОбороты(&НачПериода, &КонПериода, , , Счет = &СчетТоваров, , ) КАК ОстаткиИОбороты 502 Реализация прикладных задач в системе «1С:Предприятие 8.2» В данном случае запрос выполняется к таблице остатков и оборотов с фильтром за интервал дат и только по одному счету – счету учета товаров, на котором в качестве первого субконто используется Номенклатура товаров. Результатом запроса будет таблица, демонстрирующая количественные остатки и обороты каждой позиции номенклатуры (табл. 4.35). Таблица 4.35. Результат выполнения запроса Товар Комплект Паркер Школьная Цветной НачОст Приход Расход 1 15 10 3 10 КонОст 1 5 10 3 ВНИМАНИЕ! Не нужно считать таблицу остатков и оборотов панацеей и использовать для построения всех отчетов. Таблица универсальна и содержит поля, необходимые во многих отчетах. Однако платой за универсальность всегда является производительность. Использование таблицы имеет смысл только в случаях, когда в одной группировке отчета требуется получение и остатков на начало, и оборотов, и остатков на конец периода. Если требуются только остатки, или только обороты, или все три составляющие, но в разных группировках строках отчета, стоит задуматься о возможности написания нескольких запросов к таблице остатков и таблице оборотов. Таблица движений с субконто Для получения отборов проводок используется таблица движений с субконто. Таблица включает в себя все поля основной таблицы и таблицы значений субконто и получается их соединением. Поэтому таблица отличается для регистра с поддержкой и без поддержки корреспонденции. Таблицу можно использовать для решения задач формирования отчетов «Карточка счета/субконто», «Отчет по проводкам». Таблица является виртуальной, но получается соединением двух реальных таблиц (основная таблица и таблица значений субконто), поэтому одна из отличительных особенностей этой таблицы состоит в том, что в нее попадают неактивные записи. Другая отличительная особенность таблицы – несовпадение полей таблицы, которые можно использовать для группировки данных, и полей, на которые можно ставить условие в параметре виртуальной таблицы. Таблица движений с субконто регистра с поддержкой корреспонденций содержит следующие поля (табл. 4.36). Виртуальная таблица движений с субконто имеет следующие параметры: ■ НачалоПериода, КонецПериода – эти параметры имеют тип Дата, МоментВремени или Граница. Период времени, за который будут отобраны проводки. Глава 4. Реализация задач бухгалтерского учета 503 ■ Условие – этот параметр содержит конструкцию языка запросов. Конструкция позволяет установить условие на любое поле виртуальной таблицы. ■ Порядок – этот параметр содержит конструкцию языка запросов. Конструкция позволяет задать упорядочивание проводок. ■ Первые – этот параметр имеет тип Число. С его помощью задается ограничение максимального количества записей. Ниже приводятся два рисунка, демонстрирующие поля виртуальной таблицы «Движения с субконто» демонстрационной конфигурации «Бухгалтерский учет», которая находится на прилагаемом компакт-диске. Рис. 4.57 показывает поля таблицы, доступные для группировки. Рис. 4.58 – поля таблицы, доступные для установки на них условия в параметре Условие. Рис. 4.57. Поля, доступные для группировки Рис. 4.58. Поля, доступные для использования в параметре «Условие» Определяется типом субконто СубконтоДт<N> СубконтоКт<N> ВидСубконтоКт<N> ПланВидовХарактеристикСсылка.<имя> Определяется типом реквизита регистра бухгалтерии Число ВидСубконтоДт<N> <Реквизит> <Ресурс>Кт <Ресурс>Дт <Ресурс> <Измерение>Кт <Измерение>Дт <Измерение> СчетКт СчетДт Активность НомерСтроки МоментВремени Регистратор Балансовый ресурс регистра бухгалтерии Небалансовый ресурс регистра бухгалтерии создает два поля в регистре Характеристика движения регистра Количество полей зависит от настройки плана счетов Количество полей зависит от настройки плана счетов Дата движения Документ движения Момент времени документа Номер движения в наборе записей Участвует ли запись в таблицах итогов Дебетуемый счет Кредитуемый счет Определяется типом измерения регистра бухгалтерии Балансовое измерение регистра бухгалтерии Небалансовое измерение регистра бухгалтерии создает два поля в регистре Комментарий Период Дата ДокументСсылка.<имя> МоментВремени Число Булево ПланСчетовСсылка.<имя> ПланСчетовСсылка.<имя> Тип Поле Таблица 4.36. Поля виртуальной таблицы движений с субконто 504 Реализация прикладных задач в системе «1С:Предприятие 8.2» Глава 4. Реализация задач бухгалтерского учета 505 Видно, что перечень полей, на которые можно устанавливать условия, существенно шире. Если для включения в отчет нам доступны только физически существующие поля, полученные виртуальной таблицей из реальных таблиц первичных движений, то для выполнения отборов доступны также и виртуальные поля, такие как Счет (без указания стороны проводки), Субконто, ВидСубконто, КорСчет, <Ресурс>Кор. Пример запроса, использующий таблицу движений с субконто, приводится в разделе «Свойства счета-родителя и подчиненных ему счетов» на стр. 416. Таблица оборотов Дт Кт Таблица оборотов Дт Кт предназначена для получения оборотов между корреспондирующими счетами. Таблица присутствует только у регистра с поддержкой корреспонденции и позволяет узнать оборот в дебет счета с кредита счета (субконто, измерения). Если рассматривать таблицу с точки зрения ее возможного использования при разработке отчетов, то, вероятнее всего, это будут отчеты «Шахматный баланс (шахматка)» и «Сводные проводки». Основное отличие таблицы оборотов Дт Кт от таблицы оборотов состоит в том, что таблица оборотов Дт Кт позволяет анализировать обороты между счетами, где заранее известно, какой счет дебетуется, а какой кредитуется. В то время как таблица оборотов, кроме того что позволяет анализировать обороты по счету (без указания второго), позволяет анализировать обороты между счетом и корсчетом. При этом одним обращением к таблице можно получить как дебетовые, так и кредитовые корреспонденции. Рассмотрим поля этой виртуальной таблицы (табл. 4.37). Таблица 4.37. Поля виртуальной таблицы оборотов Дт Кт Поле Тип Дата ДокументСсылка.<имя> Число Комментарий Поля существуют в таблице, только если значение параметра Периодичность задано и отличается от Период ПланыСчетовСсылка.<имя> Дебетуемый счет СчетДт СчетКт Кредитуемый счет <Измерение> Определяется типом измерения Балансовое измерение регистра регистра бухгалтерии бухгалтерии <Измерение>Дт Небалансовое измерение регистра бухгалтерии создает два поля <Измерение>Кт в таблице СубконтоДт<N> Определяется типом субконто Количество полей зависит от настройки плана счетов СубконтоКт<N> Число <Ресурс>Оборот Оборот балансового ресурса регистра бухгалтерии <Ресурс>ОборотДт Число Обороты небалансового ресурса регистра бухгалтерии <Ресурс>ОборотКт Период Регистратор НомерСтроки 506 Реализация прикладных задач в системе «1С:Предприятие 8.2» Виртуальная таблица оборотов Дт Кт использует следующие параметры: ■ НачалоПериода, КонецПериода – эти параметры имеют тип Дата, Момент времени или Граница. Период времени, за который будут отобраны обороты. ■ Периодичность – этот параметр содержит конструкцию языка запросов. Позволяет задать дополнительную группировку данных по стандартным периодам. Возможные значения: Период, Год, Полугодие, Квартал, Месяц, Декада, Неделя, День, Час, Минута, Секунда, Регистратор, Запись. Если периодичность не задана или задана как Период, то дополнительная группировка не выполняется. ■ УсловиеСчетаДт – этот параметр содержит конструкцию языка запросов. Отбор по дебетуемому счету, как правило, содержит следующие условия: СчетДт = (В ИЕРАРХИИ, В) &СчетДт. ■ СубконтоДт – этот параметр имеет тип ПланВидовХарактеристикСсылка.<имя> или содержит массив значений типа ПланВидовХарактеристикСсылка.<имя>. В этот параметр таблицы можно передать ссылку на вид субконто для получения отбора по этому виду для дебетовых оборотов или массив видов для установки отбора и упорядочивания видов субконто в результате запроса. ■ УсловиеСчетаКт – этот параметр содержит конструкцию языка запросов. Отбор по дебетуемому счету, как правило, содержит следующие условия: СчетКт = (В ИЕРАРХИИ, В) &СчетКт. ■ СубконтоКт – этот параметр имеет тип ПланВидовХарактеристикСсылка.<имя> или содержит массив значений типа ПланВидовХарактеристикСсылка.<имя>. В этот параметр таблицы можно передать ссылку на вид субконто для получения отбора по этому виду для кредитовых оборотов или массив видов для установки отбора и упорядочивания видов субконто в результате запроса. ■ Условие – этот параметр содержит конструкцию языка запросов. Конструкция позволяет установить условие на субконто и измерения. Примером отчета, который может быть построен с использованием таблицы оборотов Дт Кт, может послужить отчет «Сводные проводки», показывающий сводные обороты между дебетуемыми и кредитуемыми счетами. Простейший запрос, который позволяет получить этот отчет, приводится в листинге 4.34. Листинг 4.34. Пример отчета «Сводные проводки» ВЫБРАТЬ ОборотыДтКт.СчетДт, ОборотыДтКт.СчетКт, ОборотыДтКт.СуммаОборот ИЗ РегистрБухгалтерии.ОсновнойРегистрБухгалтерии.ОборотыДтКт КАК ОборотыДтКт Глава 4. Реализация задач бухгалтерского учета 507 При выполнении этого запроса будет получен следующий результат (табл. 4.38). Таблица 4.38. Результат выполнения запроса СчетДт СчетКт СуммаОборот Товары Касса Товары Новый счет Материалы Сотрудники Контрагенты Покупатели Активы Товары Касса Покупатели Касса Капитал Товары Покупатели Поставщики Капитал Поставщики Поставщики Касса Касса Обязательства Сотрудники Капитал Капитал Контрагенты Касса 100 490 200 285 1000 2 13 80 100 50 6453 15 18 6810 Разницу между таблицей оборотов и таблицей оборотов Дт Кт может показать следующий пример. Решим задачу: необходимо получить оборот между счетами, свидетельствующий об объеме выручки, полученной в кассу от покупателей. Другими словами, нам необходимо получить обороты за период в дебет счета Касса с кредита счета Покупатели в разрезе контрагентов (субконто Контрагенты привязано к счету Покупатели плана счетов). Во всех приведенных ниже запросах используются следующие параметры (табл. 4.39). Таблица 4.39. Параметры запросов Параметр запроса Тип Значение НачПериода КонПериода СчетКассы СчетПокупателей Дата Дата ПланыСчетовСсылка.<имя� > ПланыСчетовСсылка.<имя� > Начало интервала отбора итогов Конец интервала отбора итогов Счет Касса Счет Покупатели Решим эту задачу, используя таблицу оборотов Дт Кт (листинг 4.35). 508 Реализация прикладных задач в системе «1С:Предприятие 8.2» Листинг 4.35. Пример запроса, использующего таблицу оборотов Дт Кт ВЫБРАТЬ ОборотыДтКт.СубконтоКт1 КАК Покупатель, ОборотыДтКт.СуммаОборот КАК Выручка ИЗ РегистрБухгалтерии.ОсновнойРегистрБухгалтерии.ОборотыДтКт(&НачПериода, &КонПериода, , СчетДт = &СчетКассы, , СчетКт = &СчетПокупателей, , ) КАК ОборотыДтКт ИТОГИ СУММА(Выручка) ПО ОБЩИЕ В результате выполнения этого запроса будут получены следующие данные (табл. 4.40). Таблица 4.40. Результат выполнения запроса Покупатель Выручка СтройТоргВсе МонтажДоставка Дисконт центр Итог 200 150 100 450 Эта же таблица отчета может быть получена с помощью таблицы оборотов следующим способом (листинг 4.36). Листинг 4.36. Пример запроса, использующего таблицу оборотов ВЫБРАТЬ Обороты.КорСубконто1 КАК Покупатель, Обороты.СуммаОборотДт КАК Выручка ИЗ РегистрБухгалтерии.ОсновнойРегистрБухгалтерии.Обороты(&НачПериода, &КонПериода, , Счет = &СчетКассы, , , КорСчет = &СчетПокупателей, ) КАК Обороты ИТОГИ СУММА(Выручка) ПО ОБЩИЕ В приведенном примере выполняется запрос с отбором по счетам Касса (основной счет) и Покупатели (корреспондирующий счет). Нужно сразу отметить, что можно сделать и наоборот: основным счетом запроса сделать счет Покупатели, а корреспондирующим – счет Касса. При этом данные Глава 4. Реализация задач бухгалтерского учета 509 группируются по первому субконто корреспондирующего счета. Отчетом анализируется дебетовый оборот (дебетовый относительно основного счета запроса, т. е. относительно счета Касса, оборот в дебет счета Касса). Теперь усложним задачу. Необходимо узнать не только, сколько было получено денег от покупателей в кассу за выбранный период, но и сумму возвращенных покупателям средств и разницу между выручкой и возвратами. Для получения прямой и обратной корреспонденции в одном запросе с использованием в качестве источника данных таблицы остатков и оборотов придется обратиться к источнику дважды: для получения оборота в дебет счета Касса с кредита Покупатели и в дебет Покупатели с кредита счета Касса. С помощью таблицы оборотов эта же задача может быть решена с однократным обращением к таблице (листинг 4.37). Листинг 4.37. Пример запроса, использующего таблицу оборотов ВЫБРАТЬ Обороты.КорСубконто1 КАК Покупатель, Обороты.СуммаОборотДт КАК Выручка, Обороты.СуммаОборотКт КАК Возвраты, Обороты.СуммаОборотДт - Обороты.СуммаОборотКт КАК Результат ИЗ РегистрБухгалтерии.ОсновнойРегистрБухгалтерии.Обороты(&НачПериода, &КонПериода, , Счет = &СчетКассы, , , КорСчет = &СчетПокупателей, ) КАК Обороты ИТОГИ СУММА(Выручка), СУММА(Возвраты), СУММА(Результат) ПО ОБЩИЕ Результат выполнения запроса приведен в табл. 4.41. Таблица 4.41. Результат выполнения запроса Покупатель Выручка СтройТоргВсе МонтажДоставка Дисконт центр Итог 200 150 100 450 Возвраты Результат 80 80 200 150 20 370 510 Реализация прикладных задач в системе «1С:Предприятие 8.2» Общие приемы работы с виртуальными таблицами Все рассмотренные виртуальные таблицы имеют ряд общих параметров, полей и просто подходов, которые не имеет смысла описывать для каждой таблицы. Для начала сгруппируем параметры, которые используются в виртуальных таблицах (табл. 4.42). Параметр Таблица оборотов Таблица оборотов Дт Кт Таблица остатков Таблица остатков . и оборотов Таблица движений . с субконто Таблица 4.42. Параметры виртуальных таблиц регистра бухгалтерии Период, НачалоПериода, КонецПериода Условие УсловиеСчета, УсловиеКорСчета, УсловиеСчетаДт, УсловиеСчетаКт Субконто, КорСубконто, СубконтоДт, СубконтоКт Периодичность Да Да Да Да Да Да Да Да Да Да Да Да Да Да Да Да Да Да Да Да МетодДополнения Да Да Поля, используемые в виртуальных таблицах регистра бухгалтерии, представлены в табл. 4.43. Теперь перейдем к рассмотрению отдельных полей и параметров таблиц. Параметр «Субконто»: отбор и упорядочивание по виду субконто В этом разделе пойдет речь о параметрах виртуальных таблиц (остатков, оборотов, оборотов Дт Кт, остатков и оборотов) типа ПланыВидовХарактеристикСсылка.<имя>. В разных таблицах параметр называется по-разному (табл. 4.44). Таблица 4.44. Параметры различных таблиц Таблица Имя параметра Оборотов Оборотов Дт Кт Остатков Остатков и оборотов Субконто, КорСубконто СубконтоДт, СубконтоКт Субконто Субконто Регистратор. Да Да Да Да* Да* Да* Да Да Да Да Да Да Да Да Да Да** Да** Да** Да* Да* Да* Да Да Да Таблица остатков Таблица остатков . и оборотов Да Да Да Да Да Да Да Да Да Да Да Да Да Таблица движений . с субконто Поля присутствуют в таблице при установленном значении параметра Периодичность; поле НомерСтроки доступно, если периодичность равна Запись; поле Регистратор доступно, если периодичность равна Запись или Да Да Да Да Да* Да* Да* Да Да Да Да Таблица оборотов Дт Кт ** В таблице присутствуют поля для получения остатков на начало и конец периода, заданного в параметрах таблицы. * Да Да Счет КорСчет Счет Дт/Кт <���������� Измерение� > <������������� Измерение���� >��� Кор <��������������� Измерение������ >����� Дт/Кт Субконто��� <N> КорСубконто��� <�� N� > СубконтоДт��������� <�������� N������� >������ /Кт��� <�� N� > Период Регистратор НомерСтроки МоментВремени Активность <��������� Реквизит� > ВидСубконтоДт��������� <N>������ /Кт��� <N> <������� Ресурс� > <������������� Ресурс������� >������ Дт/Кт <�������������� Ресурс�������� >������� Остаток <������������������� Ресурс������������� >������������ ОстатокДт/Кт <Ресурс>РазвернутыйОстаток Дт/Кт <������������� Ресурс������� >������ Оборот <������������������ Ресурс������������ >����������� ОборотДт/Кт <���������������� Ресурс���������� >��������� КорОборот <��������������������� Ресурс��������������� >�������������� КорОборотДт/Кт Да Да Таблица оборотов Параметр Таблица 4.43. Поля виртуальных таблиц регистра бухгалтерии Глава 4. Реализация задач бухгалтерского учета 511 512 Реализация прикладных задач в системе «1С:Предприятие 8.2» Все перечисленные параметры могут принимать значения ПланыВидовХарактеристикСсылка.<имя> или содержать массив, состоящий из значений указанного типа данных. Назначение этих параметров для всех таблиц схоже. Рассмотрим возможные варианты использования этих параметров на примере таблицы остатков. Начнем с того, что это не субконто в том смысле слова, который мы обычно вкладываем в него. В этом параметре можно передать не значение субконто, а значение вида субконто или массив видов субконто. Следует заметить, что для отбора по значению субконто используется другой параметр виртуальных таблиц. Для всех таблиц он называется Условие. В нем же можно устанавливать отбор по измерению регистра. Какое же назначение у параметра Субконто? Их как минимум два: ■ отбор итогов по виду субконто; ■ упорядочивание субконто в результате запроса (в особенности, если запрос выполняется по нескольким счетам). Рассмотрим подробнее каждый из перечисленных вариантов. Задача отбора по виду субконто может быть сформулирована следующим образом: необходимо получить отчет по остаткам товарно-материальных запасов. При этом в одной строке отчета нужно показать сумму стоимостных остатков одного вида номенклатуры со всех счетов учета материальных ценностей. Такая постановка вопроса, разумеется, возможна только при условии, что на всех счетах учета материальных ценностей в качестве аналитики используется один и тот же вид субконто. Применительно к демонстрационной конфигурации «Бухгалтерский учет», которая находится на прилагаемом компакт-диске, можно уточнить задачу. В конфигурации два счета учета материальных ценностей: Товары и Материалы. Предположим, что на обоих счетах первым субконто привязан вид субконто Номенклатура типа СправочникСсылка.Номенклатура. Для получения отчета, приведенного ниже, потребуется написать следующий код (листинг 4.38). Листинг 4.38. Пример получения остатков регистра бухгалтерии Запрос = Новый Запрос; Запрос.Текст = "ВЫБРАТЬ | Остатки.Субконто1 КАК Товар, | Остатки.СуммаОстаток КАК Остаток |ИЗ | РегистрБухгалтерии.ОсновнойРегистрБухгалтерии.Остатки(&Дата, , &ВидСубконто,) КАК Остатки |ИТОГИ | СУММА(Остаток) |ПО | ОБЩИЕ"; Запрос.УстановитьПараметр("ВидСубконто", ПланыВидовХарактеристик.ВидыСубконто.Номенклатура); Запрос.УстановитьПараметр("Дата", Дата); Глава 4. Реализация задач бухгалтерского учета 513 В параметр ВидСубконто запроса передается ссылка на вид характеристик Номенклатура. Результатом подобного запроса может быть таблица, представленная в табл. 4.45. Таблица 4.45. Результат выполнения запроса Товар Остаток Итог Комплект Паркер Школьная Цветной 1250 100 1050 75 25 В колонке Остаток будет отображаться сумма остатков со счетов Товары и Материалы, т. к. только на этих счетах нашей конфигурации используется субконто Номенклатура. При желании в запрос можно добавить и отбор по списку счетов. При необходимости разделить отчет по счетам (Товары и Материалы) запрос может быть видоизменен (листинг 4.39). Листинг 4.39. Пример получения остатков регистра бухгалтерии Запрос = Новый Запрос; Запрос.Текст = "ВЫБРАТЬ | Остатки.Субконто1 КАК Товар, | Остатки.Счет, | Остатки.СуммаОстаток КАК Остаток |ИЗ | РегистрБухгалтерии.ОсновнойРегистрБухгалтерии.Остатки(&Дата, , &ВидСубконто,) КАК Остатки |ИТОГИ | СУММА(Остаток) |ПО | ОБЩИЕ, | Товар"; Запрос.УстановитьПараметр("ВидСубконто", ПланыВидовХарактеристик.ВидыСубконто.Номенклатура); Запрос.УстановитьПараметр("Дата", Дата); В запрос было добавлено еще одно группировочное поле Счет, а по субконто был подведен итог. Результатом запроса будет таблица, позволяющая увидеть не только итоговый остаток по виду номенклатуры в целом по всем счетам, но и по каждому в отдельности (табл. 4.46). 514 Реализация прикладных задач в системе «1С:Предприятие 8.2» Таблица 4.46. Результат выполнения запроса Товар Счет Остаток Итог 1250 Комплект 100 Товары Паркер 100 1050 Товары 50 Материалы 1000 Школьная 75 Товары Цветной 75 25 Товары 25 При необходимости отчету можно придать «шахматный» вид, переведя вторую группировку (счета) в колонки отчета. Если мы еще усложним задачу, то нам может понадобиться второе назначение параметра Субконто – упорядочивание по виду субконто. Аналитика счетов Товары и Материалы настроена следующим образом (табл. 4.47). Таблица 4.47. Аналитика счетов «Товары» и «Материалы» Код Счет Субконто1 Субконто2 1.3 1.4 Товары Материалы Номенклатура Склады Склады Номенклатура Задача остается той же: получить в одной строке отчета остаток с двух счетов, причем строками отчета должны быть номенклатурные позиции. Если при подобной настройке плана счетов мы выполним запрос без указания параметра Субконто, но с отбором по списку счетов в параметре таблицы УсловиеСчета (листинг 4.40), то результат выполнения этого запроса будет таким, как показано в табл. 4.48. Листинг 4.40. Пример получения остатков регистра бухгалтерии Запрос = Новый Запрос; Запрос.Текст = "ВЫБРАТЬ | Остатки.Субконто1 КАК Товар, | Остатки.СуммаОстаток КАК Остаток |ИЗ | РегистрБухгалтерии.ОсновнойРегистрБухгалтерии.Остатки(&Дата, Счет В (&СчетТоваров, &СчетМатериалов),,) | КАК Остатки |ИТОГИ | СУММА(Остаток) Глава 4. Реализация задач бухгалтерского учета 515 |ПО | ОБЩИЕ"; Запрос.УстановитьПараметр("Дата", Дата); Запрос.УстановитьПараметр("СчетТоваров", ПланыСчетов.ОсновнойПланСчетов.Товары); Запрос.УстановитьПараметр("СчетМатериалов", ПланыСчетов.ОсновнойПланСчетов.Материалы); Таблица 4.48. Результат выполнения запроса Товар Остаток Итог Комплект Паркер Школьная Цветной Филиал 1250 100 50 75 25 1000 Обратите внимание на последнюю строку отчета «Филиал = 1000». Она говорит нам, во-первых, о том, что на складе Филиал есть остаток материалов на 1000, а, во-вторых, что этот самый Филиал (субконто Склады) является первым субконто счета, который мы и анализируем нашим запросом. Если добавить в виртуальную таблицу регистра источник запроса, параметр Субконто и передать туда ссылку на вид субконто Номенклатура, ситуация будет исправлена (листинг 4.41). Листинг 4.41. Пример получения остатков регистра бухгалтерии Запрос = Новый Запрос; Запрос.Текст = "ВЫБРАТЬ | Остатки.Субконто1 КАК Товар, | Остатки.СуммаОстаток КАК Остаток |ИЗ | РегистрБухгалтерии.ОсновнойРегистрБухгалтерии.Остатки(&Дата, | Счет В (&СчетТоваров, &СчетМатериалов), | &ВидыСубконто,) КАК Остатки |ИТОГИ | СУММА(Остаток) |ПО | ОБЩИЕ"; Запрос.УстановитьПараметр("Дата", Дата); Запрос.УстановитьПараметр("СчетТоваров", ПланыСчетов.ОсновнойПланСчетов.Товары); Запрос.УстановитьПараметр("СчетМатериалов", ПланыСчетов.ОсновнойПланСчетов.Материалы); Запрос.УстановитьПараметр("ВидыСубконто", ПланыВидовХарактеристик.ВидыСубконто.Номенклатура); Продолжим усложнять задачу. Предположим, нужно включить в отчет две группировки по субконто: сначала пользователь хочет увидеть итоги по номенклатуре, а потом детализацию по складам, на каком сколько числится. Решение будет напоминать ранее сделанное решение для группировки 516 Реализация прикладных задач в системе «1С:Предприятие 8.2» по счетам, проблема только в настройке плана счетов: субконто Номенклатура прикреплено первым на счет товаров и вторым на счет материалов. А обращаемся мы к ним в запросе именно по номеру (Субконто1, Субконто2). Чтобы добиться в результате запроса нужного порядка следования субконто на счетах (без изменения настройки плана счетов), необходимо воспользоваться все тем же параметром Субконто (листинг 4.42). Листинг 4.42. Пример получения остатков регистра бухгалтерии Запрос = Новый Запрос; Запрос.Текст = "ВЫБРАТЬ | ОсновнойРегистрБухгалтерииОстатки.Субконто1 КАК Товар, | ОсновнойРегистрБухгалтерииОстатки.Субконто2 КАК Склад, | ОсновнойРегистрБухгалтерииОстатки.СуммаОстаток КАК СуммаОстаток |ИЗ | РегистрБухгалтерии.ОсновнойРегистрБухгалтерии.Остатки(&Дата, | Счет В (&СчетТоваров, &СчетМатериалов), | &ВидыСубконто, ) | КАК ОсновнойРегистрБухгалтерииОстатки |ИТОГИ | СУММА(СуммаОстаток) |ПО | ОБЩИЕ, | Товар, | Склад"; Запрос.УстановитьПараметр("Дата", Дата); Запрос.УстановитьПараметр("СчетТоваров", ПланыСчетов.ОсновнойПланСчетов.Товары); Запрос.УстановитьПараметр("СчетМатериалов", ПланыСчетов.ОсновнойПланСчетов.Материалы); мВидыСубконто = Новый Массив; мВидыСубконто.Добавить(ПланыВидовХарактеристик.ВидыСубконто.Номенклатура); мВидыСубконто.Добавить(ПланыВидовХарактеристик.ВидыСубконто.Склады); Запрос.УстановитьПараметр("ВидыСубконто", мВидыСубконто); Результатом выполнения этого запроса будет следующая таблица (табл. 4.49). Таблица 4.49. Результат выполнения запроса Товар Склад Итог Комплект Офис Паркер Офис Филиал Школьная Офис Цветной Офис Филиал СуммаОстаток 1250 100 100 1050 -50 1100 75 75 25 10 15 Глава 4. Реализация задач бухгалтерского учета 517 Таким образом, нам удалось «расставить субконто по местам»: первым субконто в нашем запросе является Номенклатура, вторым – Склады. Причем если мы хотим изменить последовательность группировок в запросе (сначала группировать по складам, потом внутри склада – по номенклатурным позициям), нам достаточно изменить порядок следования элементов массива, который передается в параметр виртуальной таблицы Субконто. Параметры «Период», «НачалоПериода» и «КонецПериода» Все виртуальные таблицы регистра позволяют устанавливать отбор итогов или на момент времени, или за период. Для установки такого отбора итогов можно использовать значения типа Дата, МоментВремени или Граница. Использование в запросе параметра типа МоментВремени в большинстве случаев ограничивается обработками проведения документов, когда важно получить итоги с точностью «до ссылки». Этот объект, предназначенный для получения и хранения момента времени для объекта в базе данных, можно считать самым точным указанием для отбора итогов. Рассмотрим использование этих объектов в параметре Период виртуальной таблицы остатков. Исходная ситуация будет описана нами в виде журнала проводок. Было сделано несколько проводок разными датами по счету Касса. Мы рассматриваем период за июнь 2010 года. Входящий остаток составил 15 рублей, и было сделано четыре проводки за первое и второе июня по 10 рублей каждая. Исходящий остаток – 55 рублей (табл. 4.50). Таблица 4.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 Для анализа остатка мы воспользуемся следующим несложным запросом (листинг 4.43). 518 Реализация прикладных задач в системе «1С:Предприятие 8.2» Листинг 4.43. Пример получения остатков регистра бухгалтерии Запрос = Новый Запрос; Запрос.Текст = "ВЫБРАТЬ | Остатки.СуммаОстаток |ИЗ | РегистрБухгалтерии.ОсновнойРегистрБухгалтерии.Остатки(&Момент, Счет = &Счет, , ) КАК Остатки"; Запрос.УстановитьПараметр("Момент", Момент); Запрос.УстановитьПараметр("Счет", ПланыСчетов.ОсновнойПланСчетов.Касса); Если Результат.Пустой() Тогда Возврат 0; КонецЕсли; Остатки = Результат.Выбрать(); Остатки.Следующий(); Возврат Остатки.СуммаОстаток; Запрос будет получать остаток по счету Касса на тот момент времени, который будет передан ему в качестве параметра. А передавать мы туда будем разные значения. Наша задача – получить остаток на счете Касса, который там сформировался к концу 1 июня (или, другими словами, к началу дня 2 июня). Вариант первый (листинг 4.44). Листинг 4.44. Первый вариант установки параметра запроса Момент = Дата(2010, 6, 1); Полученный результат представлен в табл. 4.51. Таблица 4.51. Полученный результат и комментарий Момент равен Остаток равен Комментарий 01.06.10 0:00:00 15,00 Не было учтено время, получили остаток на начало дня Вариант второй (листинг 4.45). Листинг 4.45. Второй вариант установки параметра запроса Дата = Дата(2010, 6, 1); Момент = КонецДня(Дата); Полученный результат представлен в табл. 4.52. Таблица 4.52. Полученный результат и комментарий Момент равен Остаток равен Комментарий 01.06.10 23:59:59 25,00 Получили остаток на конец дня, но в остатки не попала последняя проводка, сделанная в 23:59:59 Глава 4. Реализация задач бухгалтерского учета 519 ВНИМАНИЕ! В бухгалтерском учете проводка в 23:59:59 не редкость. Для счета Касса такая проводка маловероятна, но все счета, по которым выполняются регламентные операции, попадают «в группу риска», ведь, например, закрытие месяца наверняка будет выполнено именно последним документом в этой дате. Вариант третий (листинг 4.46). Листинг 4.46. Третий вариант установки параметра запроса Дата = Дата(2010, 6, 1); ОдинДень = 60 * 60 * 24; Момент = НачалоДня(Дата + ОдинДень); Полученный результат представлен в табл. 4.53. Таблица 4.53. Полученный результат и комментарий Момент равен Остаток равен 02.01.06 0:00:00 35,00 Комментарий Правильно! Вариант четвертый (листинг 4.47). Листинг 4.47. Четвертый вариант установки параметра запроса Дата = Дата(2010, 6, 1); КонДня = КонецДня(Дата); Момент = Новый Граница(КонДня, ВидГраницы.Включая); Полученный результат представлен в табл. 4.54. Таблица 4.54. Полученный результат и комментарий Момент равен Остаток равен Комментарий Граница 35,00 Правильно! Подведем итоги (табл. 4.55). Таблица 4.55. Сводная таблица полученных результатов № 1 Метод Момент Остаток Комментарий 01.06.10 0:00:00 15,00 35,00 Не было учтено время, получили остаток на начало дня Получили остаток на конец дня, но в остатки не попала последняя проводка, сделанная в 23:59:59 Правильно! 35,00 Правильно! 2 Конец текущего дня 01.06.10 23:59:59 25,00 3 Начало следующего 02.06.10 0:00:00 дня Граница (включая) Граница 4 520 Реализация прикладных задач в системе «1С:Предприятие 8.2» Итак, правильные результаты были получены в третьем и четвертом вариантах. Для получения правильного остатка на конец периода, включающего все операции, необходимо или получать остатки на начало следующего периода, или использовать объект Граница с параметром ВидГраницы.Включая. Теперь рассмотрим этот же пример для таблицы оборотов (табл. 4.56). Таблица 4.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 Ниже приведен запрос, который будет анализировать обороты (листинг 4.48). Листинг 4.48. Пример получения оборотов регистра бухгалтерии Запрос = Новый Запрос; Запрос.Текст = "ВЫБРАТЬ | Обороты.СуммаОборот |ИЗ | РегистрБухгалтерии.ОсновнойРегистрБухгалтерии.Обороты(&НачПериода, | &КонПериода, , | Счет = &Счет, , , , | КАК Обороты"; Запрос.УстановитьПараметр("НачПериода", НачПериода); Запрос.УстановитьПараметр("КонПериода", КонПериода); Запрос.УстановитьПараметр("Счет", ПланыСчетов.ОсновнойПланСчетов.Касса); Результат = Запрос.Выполнить(); Если Результат.Пустой() Тогда Возврат 0; КонецЕсли; Обороты = Результат.Выбрать(); Обороты.Следующий(); Оборот = Обороты.СуммаОборот; Запрос получает обороты по счету Касса, за период с НачПериода по КонПериода. С оборотами все проще. Нам достаточно использовать функции НачалоДня() и КонецДня(), чтобы получить все обороты за указанный интервал, включая указанные дни (листинг 4.49). Глава 4. Реализация задач бухгалтерского учета 521 Листинг 4.49. Пример установки начала и конца периода при получении оборотов Дата = Дата(2010, 6, 1); НачПериода = НачалоДня(Дата); КонПериода = КонецДня(Дата); Результатом работы функции будет значение 20, соответствующее обороту за первое июня 2010 года. Таблица остатков и оборотов рассчитывает исходящий остаток на основании входящего и оборотов (более подробно о работе виртуальных таблиц с данными информационной базы рассказано в разделе «Построение виртуальных таблиц регистра бухгалтерии» на стр. 552), поэтому особенного внимания к себе не требует. Для получения корректных остатков и оборотов за 1 июня 2010 года достаточно передать в качестве параметров даты начала и конца дня. Параметры виртуальной таблицы не являются обязательными. Если момент или период отбора итогов не будет указан, результат запроса вернет текущие итоги. Более подробно об этом рассказано в разделе «Механизм текущих итогов» на стр. 552. Пока же упомянем лишь, что в таблицах итогов регистра бухгалтерии хранятся не только рассчитанные итоги по месяцам, но и текущие итоги с учетом последнего проведенного документа. Периодичность «оборотных» таблиц Таблица оборотов, таблица оборотов и остатков и таблица оборотов Дт Кт содержат параметр Периодичность. Этот параметр позволяет задать дополнительную группировку данных таблицей – по стандартным периодам. Параметр может принимать одно из значений (табл. 4.57). Таблица 4.57. Значения, которые может принимать параметр «Периодичность» Период Период или пусто Год Полугодие Квартал Месяц Декада Неделя День Час Минута Секунда Регистратор Запись Комментарий Дополнительная группировка данных не выполняется Все проводки за год Все проводки за полгода Все проводки за квартал Все проводки за календарный месяц Все проводки за декаду Все проводки за неделю Все проводки за день Все проводки за час Все проводки за минуту Все проводки за секунду Все проводки одного документа (регистратора) группируются Движение регистра Значение по умолчанию, если параметр не заполнен, – Период. 522 Реализация прикладных задач в системе «1С:Предприятие 8.2» При установке в параметре Периодичность виртуальной таблицы значения, отличного от Период, в таблице появляются новые поля, по которым можно сгруппировать данные. Покажем это на примере таблицы остатков и оборотов и таблицы оборотов Дт Кт регистра бухгалтерии демонстрационной конфигурации «Бухгалтерский учет», которая находится на прилагаемом компакт-диске. Колонки таблицы – значения параметра Периодичность. В таблице перечислены поля, добавляемые к тем, которые существуют по умолчанию (когда значение параметра Периодичность равно Период), табл. 4.58. Таблица 4.58. Поля, добавляемые в виртуальную таблицу остатков Дт Кт Период Секунда и более Регистратор Запись Период Период Регистратор Период Регистратор НомерСтроки Как мы видим, по мере того как мы задаем большую детализацию в параметре таблицы, появляются новые поля таблицы. В случае если периодичность равна Секунда или больше (Секунда – Год), появляется возможность группировать данные по периодам. Поле Период будет содержать дату начала периода. Например, если выбрана периодичность Год, то все обороты за 2010 год будут сгруппированы в период 01.01.2010 00:00:00; если выбрана периодичность Месяц, то в таблице появятся первые числа всех месяцев, за которые были обороты. Если периодичность равна Регистратор, то кроме периода появляется возможность получить доступ к документу, сделавшему движения в регистре. Если периодичность равна Запись, мы получаем доступ к еще одному полю таблицы – НомерСтроки, номеру записи в наборе. Ниже приведен текст запроса, с помощью которого система компоновки данных извлекает данные из таблицы оборотов Дт Кт для отчета Сводные проводки с периодичностью – Месяц (листинг 4.50). Листинг 4.50. Пример отчета «Сводные проводки периодичностью Месяц» ВЫБРАТЬ ОборотыДтКт.СчетДт, ОборотыДтКт.СчетКт, ОборотыДтКт.СуммаОборот, ОборотыДтКт.Период ИЗ РегистрБухгалтерии.ОсновнойРегистрБухгалтерии.ОборотыДтКт(, , Месяц, , , , , ) КАК ОборотыДтКт Перед формированием отчета задается отчетный период (данные берутся на конец дня конца периода) и отбор по корреспондирующим счетам дебета и кредита. Глава 4. Реализация задач бухгалтерского учета 523 При периодичности запроса Месяц поле Период будет содержать дату начала каждого месяца. Как мы видим на рисунке внизу, часть проводок по корреспондирующим счетам Касса и Покупатели сделаны в мае 2010 года на сумму 450, а часть – в июне 2010 года, на сумму 40 (рис. 4.59). Рис. 4.59. Результат отчета при периодичности «Месяц» Если периодичность сделать равной Запись, каждая строка отчета будет отображать свою проводку, ее дату и время (рис. 4.60). Рис. 4.60. Результат отчета при периодичности «Запись» 524 Реализация прикладных задач в системе «1С:Предприятие 8.2» В результате более детального отчета выяснится, например, что 40 рублей первого отчета состояли из четырех проводок по 10 рублей каждая, сделанных первого и второго июня 2010 года. Таким же образом устроена таблица оборотов. А вот таблица остатков и оборотов имеет свою особенность. Как видно из приведенных выше отчетов, в запрос попадают только те периоды, которые содержали обороты, соответствующие отборам, установленным в других параметрах таблицы. В нашем случае были фильтры на счет дебета и счет кредита, но в отчет попали только те периоды, где обороты между выбранными счетами были. Иначе говоря, в первый отчет не попал апрель 2010 года, потому что в нем не было никаких проводок, а во второй отчет не попало 3 июня по той же причине. Таблица остатков и оборотов позволяет в одной группировке запроса получить и остатки (входящие и исходящие), и обороты. Поэтому в таблице присутствует еще один параметр, позволяющий указывать, будут ли включены в результат отчета периоды, которые имели обороты или еще и границы интервала, если на эти даты были остатки. Параметр МетодДополнения может принимать два значения: ДвиженияИГраницыПериода (по умолчанию) и Движения. Рассмотрим отличия на примере запроса, приведенного ниже (листинг 4.51). Листинг 4.51. Пример получения остатков и оборотов регистра бухгалтерии ВЫБРАТЬ ОсновнойРегистрБухгалтерииОстаткиИОбороты.Период, ОсновнойРегистрБухгалтерииОстаткиИОбороты.СуммаНачальныйОстаток КАК НачальныйОстаток, ОсновнойРегистрБухгалтерииОстаткиИОбороты.СуммаОборотДт КАК ОборотДт, ОсновнойРегистрБухгалтерииОстаткиИОбороты.СуммаОборотКт КАК ОборотКт, ОсновнойРегистрБухгалтерииОстаткиИОбороты.СуммаКонечныйОстаток КАК КонечныйОстаток ИЗ РегистрБухгалтерии.ОсновнойРегистрБухгалтерии.ОстаткиИОбороты(, , День, ДвиженияИГраницыПериода, Счет В ИЕРАРХИИ (&Счет), , ) КАК ОсновнойРегистрБухгалтерииОстаткиИОбороты Отчет формируется с помощью системы компоновки данных. Перед формированием отчета задается отчетный период (данные берутся на конец дня конца периода) и отбор по счету (в нашем примере – по счету Товары). Параметр Периодичность в запросе установлен в значение День, а параметр МетодДополнения – в значение ДвиженияИГраницыПериода. Исходные данные: существуют проводки по счету Товары, сделанные до 1 июня 2010 года, 23 и 25 июня 2010 года. Запрос выполняется по счету Товары за интервал с 01.06.2010 по 30.06.2010 года с периодичностью День. Результат выполнения запроса показан на рис. 4.61. Глава 4. Реализация задач бухгалтерского учета 525 Рис. 4.61. Результат выполнения запроса Если параметр МетодДополнения принимает значение ДвиженияИГраницыПериода или если он не задан, то в отчет включаются дата начала интервала отбора итогов (01.06.2010, так как на эту дату был входящий остаток) и дата конца интервала (30.06.2010, по той же причине), см. рис. 4.61. Если бы параметр МетодДополнения принимал значения Движения, в отчет попали только те даты, за которые были обороты по счету Товары (рис. 4.62). Рис. 4.62. Результат выполнения запроса 526 Реализация прикладных задач в системе «1С:Предприятие 8.2» ВНИМАНИЕ! Наличие в таблице остатков и оборотов наиболее часто встречающихся показателей (остатки на начало и конец интервала и обороты) и возможность формирования ее с периодичностью до проводки включительно не должны приводить к ее использованию для решения любых задач. Таблица остатков и оборотов является виртуальной, т. е. одна не хранится в базе данных и формируется системой при обращении к ней. Формирование таблицы может включать в себя выполнение до трех запросов. По каждому периоду (мы рассматриваем сейчас использование таблицы с заполненным параметром Периодичность) будут рассчитаны и обороты, и входящие остатки, и исходящие остатки. Если поставленная задача не требует получения всех этих показателей по каждой группировке (строке) отчета (например, отчет «Карточка счета»), то использование таблицы можно считать неоптимальным. Поэтому стоит обдумать возможность использования для решения другой таблицы (например, таблицы движений с субконто) для получения отбора проводок и таблицы остатков для получения остатков на начало периода. Развернутые остатки Мы знаем, что все счета бухгалтерского учета делятся на активные, пассивные и активно-пассивные (в стандартах учета, принятых в РФ). Активные счета предназначены для группировки операций о движении средств (имущества, активов) предприятия. Остатки по активным счетам всегда дебетовые и показывают, каким имуществом обладает предприятие. Пассивные счета предназначены для группировки операций об изменении источников средств (пассивов) организации. Остатки по пассивным счетам всегда кредитовые и демонстрируют, откуда было получено имущество предприятия. Самые простые примеры активных счетов – счета учета денежных средств (касса, банк) и материальных запасов (товары, материалы). Пример пассивных счетов – капитал собственника (т. е. задолженность перед хозяином предприятия) и расчеты с поставщиками. Таким образом, если на счете учитываются операции расчетов с тем, кто должен нам (например, с покупателями за поставленный им товар), то такой счет является активным (долг «нам» является нашим имуществом), и остаток по счету должен быть всегда дебетовым (дебиторская задолженность). Если на счете учитываются операции расчетов с тем, кому должны мы (например, с поставщиками за поставленный нам товар), то такой счет является пассивным (мы должны), и остаток будет всегда кредитовым (кредиторская задолженность). Сложившаяся в РФ теория и практика учета предусматривают и третий вид счетов: активно-пассивные. Это счета расчетов, на которых группируются операции с прочими контрагентами, как внутренними (по отношению Глава 4. Реализация задач бухгалтерского учета 527 к предприятию), так и внешними. Такой прочий контрагент, с которым могут совершаться самые разные операции, может оказаться как дебитором, так и кредитором. Пример такого счета в хозрасчетной бухгалтерии коммерческой организации РФ – расчеты с прочими дебиторами и кредиторами (счет 76). Рассмотрим несложный пример учета расчетов с прочими контрагентами. В методических целях будем использовать для учета расчетов счет «Прочие контрагенты» (имя счета – Контрагенты). В методических целях мы сократим количество возможных операций по этому счету до двух: мы будем отдавать им деньги и получать от них деньги. В реальной практике учета есть вероятность, что среди прочих дебиторов и кредиторов окажутся контрагенты, которым мы продаем товар, от которых мы получаем внеоборотные активы, и многие другие. Но нам сейчас интересен учет остатков, и то, какие обороты сформировали эти остатки, нам не принципиально. Итак, предположим, что у нас есть один Прочий контрагент, которому мы выдали 10 рублей (табл. 4.59). Таблица 4.59. Первая проводка № Счет дт Аналитика Счет кт Контрагенты Иванов Касса Аналитика Сумма 10 Кроме этого, есть еще один контрагент, который решил дать нам 10 рублей (табл. 4.60). Таблица 4.60. Вторая проводка № Счет дт Аналитика Счет кт Касса Аналитика Контрагенты Петров Сумма 10 Если на счете Контрагенты не ведется аналитический учет, то, анализируя остаток по счету Контрагенты, можно прийти к выводу: никто никому ничего не должен (рис. 4.63), хотя контрагенты между собой о взаимозачете не договаривались. Рис. 4.63. Анализ счета «Контрагенты» 528 Реализация прикладных задач в системе «1С:Предприятие 8.2» Поэтому на счете Контрагенты будем вести учет в разрезе списка контрагентов. Тогда на каждого контрагента будет открыт свой маленький аналитический счет (рис. 4.64). Рис. 4.64. Обороты по аналитическим счетам Теперь, когда мы открыли на счете Контрагенты аналитический учет по контрагентам, с одной стороны, можем вести учет расчетов и анализировать задолженности по каждому контрагенту, что очень удобно. С другой стороны, мы получаем возможность видеть развернутый остаток по счету Контрагенты. Теперь у счета Контрагенты есть два типа остатков: свернутый (синтетический) остаток, который в нашем примере равен нулю, и развернутый (аналитический), который в нашем примере равен 10 руб. по дебету и 10 руб. по кредиту. Если свернутый (синтетический или просто остаток) остаток у счета всегда один, зависит от типа счета (активный, пассивный или активно-пассивный) и рассчитывается системой (и в теории бухгалтерского учета) по правилам, которые мы рассматривали в разделе «Таблица остатков» на стр. 489, то развернутый остаток может быть и дебетовый, и кредитовый одновременно. В приведенном выше простом примере развернутый остаток счета соответствует оборотам счета, т. к. отсутствует входящий остаток. На самом деле они могут отличаться и наверняка отличаются. Рассмотрим более сложную ситуацию. Добавим для счета Контрагенты входящие остатки. Иванов был нашим кредитором, и мы были ему должны 8 рублей. В текущем отчетом периоде мы заплатили ему 10 рублей. Переплатили 2 рубля, и теперь он наш дебитор (он нам должен 2 рубля), рис. 4.65. Рис. 4.65. Остатки и обороты на аналитических счетах Глава 4. Реализация задач бухгалтерского учета 529 Петров, наоборот, был дебитором (был нам должен 3 рубля), в текущем отчетном периоде он сделал платеж на 10 рублей. Переплатил нам 7 рублей. Теперь мы ему должны 7 рублей. Мы видим, что при подсчете остатков по синтетическому счету Контрагенты мы учитываем входящее (свернутое) сальдо (5 рублей) и обороты по счету в целом (рис. 4.66). При расчете развернутого сальдо по счету в разрезе аналитики (рис. 4.67) мы делаем следующее: ■ ■ ■ ■ ■ выполняем расчет по каждому объему аналитики; по каждому объекту аналитики получаем входящее (развернутое) сальдо; по каждому объекту аналитики подсчитываем обороты; по каждому объекту аналитики рассчитываем исходящее сальдо; суммируем отдельно остатки по всем объектам аналитики дебетовые и отдельно кредитовые; ■ получаем развернутый дебетовый остаток и развернутый кредитовый остаток по счету. Рис. 4.66. Синтетический счет «Контрагенты» Рис. 4.67. Аналитический счет «Контрагенты» Развернутый остаток не имеет смысла без критерия, по которому он будет «разворачиваться». В практике учета чаще всего получают развернутые остатки счета с разворотом по аналитике этого счета. Хотя возможны и другие варианты, например, развернутые остатки счета-группы с разворотом по субсчетам. Наиболее часто развернутые остатки требуется получать именно по активнопассивным счетам, счетам расчетов и, чаще всего, при составлении баланса. По стандартам учета расчеты при включении в баланс не должны «сворачиваться»: в активе баланса нужно показать полную сумму дебиторской задолженности, а в пассиве – кредиторской. Возвращаясь к нашему примеру, правильно показать в активе баланса 2 рубля, а в пассиве – 7 рублей. Неправильно показать в пассиве 5 рублей. 530 Реализация прикладных задач в системе «1С:Предприятие 8.2» В системе «1С:Предприятие» для подсчета развернутых остатков используются специальные поля виртуальных таблиц. В таблице остатков это поля: ■ <Ресурс>РазвернутыйОстатокДт, ■ <Ресурс>РазвернутыйОстатокКт. В таблице остатков и оборотов такими полями являются следующие поля: ■ <Ресурс>НачальныйРазвернутыйОстатокДт, ■ <Ресурс>КонечныйРазвернутыйОстатокДт, ■ <Ресурс>НачальныйРазвернутыйОстатокКт, ■ <Ресурс>КонечныйРазвернутыйОстатокКт. Реализуем в конфигурации описанный выше пример учета на счете Контрагенты и напишем запрос для анализа развернутого остатка по счету. При решении задачи получения развернутых остатков всегда нужно исходить из формулы: Остаток по <Итог> развернутый по <ПоляДетальнойВыборки>. Поля развернутых остатков, присутствующие в виртуальных таблицах в детальной выборке запроса, полностью повторяют содержимое полей остатков (свернутых). Развернутые остатки имеют смысл только при наличии в запросе итогов. Построим несколько элементарных запросов к таблице остатков. Во все запросы будем передавать только один параметр Счет, который равен ссылке на счет Контрагенты. Первый запрос получит все остатки с отбором по счету (листинг 4.52). Листинг 4.52. Пример получения остатков регистра бухгалтерии ВЫБРАТЬ Остатки.Счет, Остатки.СуммаОстатокДт КАК СвернутыйДт, Остатки.СуммаОстатокКт КАК СвернутыйКт, Остатки.СуммаРазвернутыйОстатокДт КАК РазвернутыйДт, Остатки.СуммаРазвернутыйОстатокКт КАК РазвернутыйКт ИЗ РегистрБухгалтерии.ОсновнойРегистрБухгалтерии.Остатки(, Счет = &Счет, , ) КАК Остатки Результат этого запроса – одна строка. Свернутые и развернутые остатки равны. Причина – мы не указали, по какому полю разворачивать (табл. 4.61). Таблица 4.61. Результат выполнения запроса Счет Контрагенты СвернутыйДт СвернутыйКт 5 РазвернутыйДт РазвернутыйКт 5 Изменим запрос, включим в поля выборки новое поле Субконто1, т. е. контрагента (листинг 4.53). Глава 4. Реализация задач бухгалтерского учета 531 Листинг 4.53. Пример получения остатков регистра бухгалтерии ВЫБРАТЬ Остатки.Счет, Остатки.Субконто1 КАК Контрагент, Остатки.СуммаОстатокДт КАК СвернутыйДт, Остатки.СуммаОстатокКт КАК СвернутыйКт, Остатки.СуммаРазвернутыйОстатокДт КАК РазвернутыйДт, Остатки.СуммаРазвернутыйОстатокКт КАК РазвернутыйКт ИЗ РегистрБухгалтерии.ОсновнойРегистрБухгалтерии.Остатки(, Счет = &Счет, , ) КАК Остатки Результатом запроса будет таблица из двух строк: счет повторяется, но остатки мы получили по каждому контрагенту. Свернутые остатки и развернутые попрежнему равны (табл. 4.62). Таблица 4.62. Результат выполнения запроса Счет Контрагент СвернутыйДт СвернутыйКт РазвернутыйДт РазвернутыйКт Контрагенты Иванов Контрагенты Петров 2 2 7 7 Однако в этом запросе мы уже видим, что если подвести итоги по колонкам, мы получим тот самый развернутый остаток по счету, который нас и интересует. Давайте это сделаем. Подводим итоги по Счет, суммируя все числовые поля (листинг 4.54). Листинг 4.54. Пример получения остатков регистра бухгалтерии ВЫБРАТЬ Остатки.Счет КАК Счет, Остатки.Субконто1 КАК Контрагент, Остатки.СуммаОстатокДт КАК СвернутыйДт, Остатки.СуммаОстатокКт КАК СвернутыйКт, Остатки.СуммаРазвернутыйОстатокДт КАК РазвернутыйДт, Остатки.СуммаРазвернутыйОстатокКт КАК РазвернутыйКт ИЗ РегистрБухгалтерии.ОсновнойРегистрБухгалтерии.Остатки(, Счет = &Счет, , ) КАК Остатки ИТОГИ СУММА(СвернутыйДт), СУММА(СвернутыйКт), СУММА(РазвернутыйДт), СУММА(РазвернутыйКт) ПО Счет Результат выполнения этого запроса представлен в табл. 4.63. 532 Реализация прикладных задач в системе «1С:Предприятие 8.2» Таблица 4.63. Результат выполнения запроса Счет Контрагенты Контрагент СвернутыйДт СвернутыйКт РазвернутыйДт РазвернутыйКт Иванов Петров 2 5 7 2 2 7 7 Мы получили свернутые и развернутые остатки по счету. При подведении итогов поля <Ресурс>ОстатокДт и <Ресурс>ОстатокКт сворачиваются по правилам, которые определяет вид счета (активный, пассивный, активно-пассивный), а поля <Ресурс>РазвернутыйОстатокДт и <Ресурс>РазвернутыйОстатокКт суммируются раздельно: отдельно подводится итог по элементам выборки, имеющим дебетовый остаток, отдельно по элементам, имеющим кредитовый остаток. Можно ли было в нашем случае не включать в запрос поле Счет? Да, можно. Мы могли бы ограничиться включением в детальную выборку поля Субконто1 и подвести общие итоги. Таким образом, итоги разворачиваются по всем полям детальной выборки (в нашем примере по двум: Счет и Субконто1) и рассчитываются по итоговому полю. Методы менеджера регистра бухгалтерии Основным способом чтения данных в системе является запрос, и это оправданно. Однако для извлечения данных может применяться и объектная техника. Менеджер регистра бухгалтерии имеет три метода, позволяющих получать остатки и обороты. Необходимо сразу же оговориться, что при обращении к этим методам система все равно выполнит запрос. Разница между использованием запроса к виртуальным таблицам регистра бухгалтерии и использованием методов объекта лишь в синтаксисе. У менеджера регистра бухгалтерии существует три метода извлечения остатков и оборотов: ■ Остатки(), ■ Обороты(), ■ ОборотыДтКт(). Каждый из них по своему назначению и функциональности похож на одноименную виртуальную таблицу. Результат, возвращаемый этими методами, – таблица значений, содержащая затребованные при выполнении метода поля выборки. Такой же результат может быть получен с помощью запроса и последующей выгрузки результата запроса в таблицу значений (листинг 4.55). Глава 4. Реализация задач бухгалтерского учета 533 Листинг 4.55. Выполнение запроса и выгрузка результата запроса в таблицу значений Таблица = Запрос.Выполнить().Выгрузить(); Рассмотрим работу метода Остатки(). Задача – получить остаток одного товара на выбранную пользователем дату. Пользователь выбирает в диалоге формы следующие параметры: ■ Дата, ■ Организация, ■ Товар. Решим сначала задачу с помощью запроса (листинг 4.56). Листинг 4.56. Получение остатков с помощью запроса Момент = Новый Граница(КонецДня(Дата), ВидГраницы.Включая); СчетТоваров = ПланыСчетов.ОсновнойПланСчетов.Товары; Запрос = Новый Запрос; Запрос.Текст = "ВЫБРАТЬ | Остатки.КоличествоОстатокДт |ИЗ | РегистрБухгалтерии.ОсновнойРегистрБухгалтерии.Остатки(&Момент, | Счет = &Счет, , | Субконто1 = &Субконто1 | И | Организация = &Организация) | КАК Остатки"; Запрос.УстановитьПараметр("Момент", Момент); Запрос.УстановитьПараметр("Счет", СчетТоваров); Запрос.УстановитьПараметр("Субконто1", Товар); Запрос.УстановитьПараметр("Организация", Организация); Результат = Запрос.Выполнить(); Остатки = Результат.Выбрать(); Остатки.Следующий(); ОстатокТовара = Остатки.КоличествоОстатокДт; Эта же задача с помощью метода Остатки() менеджера регистра бухгалтерии может быть решена следующим образом (листинг 4.57). Листинг 4.57. Получение остатков с помощью метода «Остатки()» Момент = Новый Граница(КонецДня(Дата), ВидГраницы.Включая); СчетТоваров = ПланыСчетов.ОсновнойПланСчетов.Товары; Регистр = РегистрыБухгалтерии.ОсновнойРегистрБухгалтерии; Отбор = Новый Структура("Счет, Субконто1, Организация", СчетТоваров, Товар, Организация); ТаблицаРезультат = Регистр.Остатки(Момент, ,Отбор, "" , "Количество"); ОстатокТовара = ТаблицаРезультат.Итог("КоличествоОстатокДт"); 534 Реализация прикладных задач в системе «1С:Предприятие 8.2» Сравним параметры виртуальной таблицы остатков регистра бухгалтерии и параметры метода Остатки() (табл. 4.64). Таблица 4.64. Сравнение параметров таблицы остатков и метода «Остатки()» Метод Остатки() № Параметр 1 2 3 МоментВремени ВидыСубконто Отбор 4 5 Измерения Ресурсы Запрос к виртуальной таблице остатков № Параметр Период 1 Субконто 3 УсловиеСчета 2 Условие 4 Выбранные поля-измерения запроса Выбранные поля-ресурсы запроса Первый параметр метода – МоментВремени – по своему назначению и использованию полностью идентичен первому параметру Период виртуальной таблицы остатков. Второй параметр – ВидыСубконто – позволяет установить отбор по виду субконто или упорядочить поля Субконто<N> запроса, в точности как параметр Субконто виртуальной таблицы. Более подробно о назначении параметра можно посмотреть в разделе «Параметр «Субконто»: отбор и упорядочивание по виду субконто» на стр. 513. Третий параметр метода – Отбор – имеет тип Структура. Каждый элемент структуры описывает одно условие отбора. В этом элементе ключ соответствует полю, по которому можно выполнить отбор в виртуальной таблице (Счет, Субконто<N>, <Измерение>). А значение элемента – это значение, по которому нужно отобрать. Этот параметр объединяет в себе второй (УсловиеСчета) и четвертый (Условие) параметры виртуальной таблицы. Четвертый (Измерения) и пятый (Ресурсы) параметры метода позволяют указать в виде строки одно или несколько (через запятую) полей таблицы, которые будут включены в детальную выборку запроса. Как измерения могут быть указаны поля Счет, Субконто<N>, <Измерение>. В качестве ресурсов указываются имена ресурсов регистра бухгалтерии. Ниже приводится пример использования параметров метода Остатки() для получения таблицы остатков товаров (листинг 4.58). Листинг 4.58. Пример получения остатков регистра бухгалтерии Момент = Новый Граница(КонецДня(Дата), ВидГраницы.Включая); СчетТоваров = ПланыСчетов.ОсновнойПланСчетов.Товары; Регистр = РегистрыБухгалтерии.ОсновнойРегистрБухгалтерии; Отбор = Новый Структура("Счет, Организация", СчетТоваров, Организация); ТаблицаРезультат = Регистр.Остатки(Момент, ,Отбор, "Субконто1, Субконто2", "Количество, Сумма"); Глава 4. Реализация задач бухгалтерского учета 535 Результат исполнения кода приведен в табл. 4.65. Таблица 4.65. Результат выполнения запроса Субконто1 Субконто2 Количество ОстатокДт Комплект Паркер Паркер Школьная Цветной Цветной Офис Офис Филиал Офис Офис Филиал 1 -5 10 10 Количество ОстатокКт 3 Сумма ОстатокДт Сумма ОстатокКт 100 -50 100 75 10 15 Такой же результат может быть получен с помощью запроса (листинг 4.59). Листинг 4.59. Пример получения остатков регистра бухгалтерии Момент = Новый Граница(КонецДня(Дата), ВидГраницы.Включая); СчетТоваров = ПланыСчетов.ОсновнойПланСчетов.Товары; Запрос = Новый Запрос; Запрос.Текст = "ВЫБРАТЬ | Остатки.Субконто1, | Остатки.Субконто2, | Остатки.КоличествоОстатокДт, | Остатки.КоличествоОстатокКт, | Остатки.СуммаОстатокДт, | Остатки.СуммаОстатокКт |ИЗ | РегистрБухгалтерии.ОсновнойРегистрБухгалтерии.Остатки(&Момент, | Счет = &Счет, , | Организация = &Организация) | КАК Остатки"; Запрос.УстановитьПараметр("Момент", Момент); Запрос.УстановитьПараметр("Счет", СчетТоваров); Запрос.УстановитьПараметр("Организация", Организация); Результат = Запрос.Выполнить(); ТаблицаРезультат = Результат.Выгрузить(); 536 Реализация прикладных задач в системе «1С:Предприятие 8.2» Вопросы производительности регистра бухгалтерии Этот раздел посвящен внутреннему устройству объекта Регистр бухгалтерии и предназначен для более глубокого понимания работы системы и более оптимального написания запросов к виртуальным таблицам регистра. Авторы не рекомендуют использования знание физической организации таблиц для непосредственного доступа к таблицам. Все примеры и вопросы, рассмотренные в разделе, подразумевают использование системы «1С:Предприятие» в клиент-серверном варианте работы, при котором информационная база хранится в формате таблиц SQL Server. Физические таблицы регистра бухгалтерии Все физические таблицы регистра бухгалтерии можно разделить на две группы: таблицы первичных движений и таблицы итогов (рис. 4.68). Рис. 4.68. Физические таблицы регистра бухгалтерии Глава 4. Реализация задач бухгалтерского учета 537 Таблицы первичных движений доступны для выполнения запроса и поэтому знакомы нам – это основная таблица и таблица значений субконто. Эти две таблицы хранят полную информацию о проводке. Таблицы итогов скрыты от прикладного разработчика и не могут выступать как источники запроса. И таблицы первичных движений, и таблицы итогов служат источниками данных для виртуальных таблиц регистра, которые по своей сути являются вложенными запросами. Таблицы первичных движений рассмотрены в разделе «Реальные таблицы» на стр. 487, поэтому перейдем сразу к описанию таблиц итогов. Остатки и обороты по счетам Физическая таблица остатков и оборотов по счетам имеет следующую структуру (табл. 4.66). Таблица 4.66. Структура таблицы остатков и оборотов по счетам Период Счет <���������� Измерения� > <�������� Ресурсы� > Остаток ОборотДт ОборотКт Рассмотрим подробнее поля этой таблицы (табл. 4.67). Таблица 4.67. Поля таблицы остатков и оборотов по счетам Поле Комментарий Период Итоги хранятся помесячно, поле содержит дату (первое число месяца) Ссылка на счет плана счетов Количество полей зависит от измерений, которые созданы в регистре бухгалтерии Для каждого ресурса регистра бухгалтерии создается три поля таблицы итогов: Остаток, ОборотДт, ОборотКт. Хранит абсолютный остаток (дебет-кредит) на начало месяца, за который рассчитаны итоги (т.е. на конец прошлого месяца). При построении виртуальных таблиц служит основой для расчета полей ОстатокДт, ОстаткокКт, РазвернутыйОстатокДт, РазвернутыйОстатокКт и зависит от вида счета (активный, пассивный, активно-пассивный) Дебетовый оборот счета за рассчитанный месяц Кредитовый оборот счета за рассчитанный месяц Общий оборот счета за рассчитанный месяц Количество полей зависит от настройки плана счетов Разделитель итогов (для обеспечения параллельности проведения документов) Счет <Измерения> <Ресурсы> Остаток ОборотДт ОборотКт Оборот Субконто<�� N� > Разделитель Таблица хранит итоги по всем счетам. И при любом движении в регистре бухгалтерии эта таблица обновляется. 538 Реализация прикладных задач в системе «1С:Предприятие 8.2» ВНИМАНИЕ! Наличие этой таблицы – одно из оснований, позволяющих утверждать, что регистры накопления более производительны по сравнению с регистрами бухгалтерии. По своей сути регистр бухгалтерии – это «регистр регистров», где каждый счет можно сравнить с регистром накопления. Однако таблица остатков и оборотов по счетам одна на все счета, и изменяется при записи любого документа, делающего движение по любым счетам. Таблицы остатков и оборотов по счетам и субконто Физические таблицы остатков и оборотов по счетам и субконто появляются, когда хотя бы на один счет плана счетов был добавлен хотя бы один вид субконто. Количество таблиц соответствует максимальному количеству субконто, используемых на счетах. Структура таблиц напоминает структуру физической таблицы остатков и оборотов по счетам. В случае если на счетах задействовано только два вида субконто, будет создано две таблицы (табл. 4.68 и табл. 4.69). Таблица 4.68. Структура первой таблицы остатков и оборотов по счетам и субконто при использовании двух видов субконто Период Счет <���������� Измерения� > <��������� Субконто� > <�������� Ресурсы� > Субконто1 Остаток ОборотДт ОборотКт Таблица 4.69. Структура второй таблицы остатков и оборотов по счетам и субконто при использовании двух видов субконто Период Счет <���������� Измерения� > <��������� Субконто� > <�������� Ресурсы� > Ск1 Остаток Ск2 ОборотДт ОборотКт Если мы увеличим максимальное количество субконто и добавим хотя бы на один счет третье субконто, в базу данных будет добавлена еще одна таблица (табл. 4.70). Таблица 4.70. Структура третьей таблицы остатков и оборотов по счетам и субконто при использовании трех видов субконто Период Счет <���������� Измерения� > <��������� Субконто� > Ск1 Ск2 <�������� Ресурсы� > Ск3 Остаток ОборотДт ОборотКт При записи движения в регистр изменяется только одна из этих таблиц (для регистра без поддержки корреспонденций). Для регистра с поддержкой корреспонденций может потребоваться изменение двух таблиц (для счета дебета и счета кредита проводки, если на них различное количество субконто). Глава 4. Реализация задач бухгалтерского учета 539 Запись производится лишь в ту таблицу, количество субконто которой соответствует количеству субконто счета проводки. Например, пусть записывается проводка, представленная в табл. 4.71. Таблица 4.71. Пример проводки № Счет дт Субконто 1 Субконто 2 Счет кт 1 Поставщики Иванов Касса Субконто 1 Субконто 2 Сумма 10 В этом случае будет внесено изменение в одну из таблиц остатков и оборотов по счетам и субконто. В ту из них, где остатки и обороты учитываются в разрезе одного субконто (и по счету Поставщики, и по счету Касса), будет сделана запись в таблицу, которая хранит итоги в разрезе Субконто1. Теперь рассмотрим другую проводку (табл. 4.72). Таблица 4.72. Пример проводки № Счет дт Субконто 1 Субконто 2 Счет кт Субконто 1 Субконто 2 Сумма 2 Товары Авторучка Склад № 1 Поставщики Иванов 10 В этом случае будут изменены две таблицы: по счету Поставщики будет сделана запись в таблицу, которая хранит итоги в разрезе Субконто1, по счету Товары будет сделана запись в таблицу, которая хранит итоги в разрезе Субконто 1 и Субконто 2. Кроме того, для двух проводок для каждого счета будут сделаны записи в физическую таблицу остатков и оборотов по счетам, рассмотренную нами в разделе «Остатки и обороты по счетам» на стр. 539. Обороты между счетами Для регистра с поддержкой корреспонденций создается физическая таблица для хранения оборотов в разрезе корреспондирующих счетов (таблица оборотов между счетами), табл. 4.73. Таблица 4.73. Структура таблицы оборотов между счетами Период СчетДт СчетКт <���������� Измерения� > <�������� Ресурсы� > Оборот 540 Реализация прикладных задач в системе «1С:Предприятие 8.2» Таблица хранит обороты между счетами без детализации по субконто. Поэтому для извлечения любых оборотов между субконто используются физические таблицы первичных движений. Управление итогами Управление итогами регистра бухгалтерии осуществляется интерактивно с помощью системной команды Управление итогами. Для этого нужно вызвать стандартную функцию Управление итогами (Все функции Стандартные) и переключить ее в режим Полные возможности (рис. 4.69). Рис. 4.69. Диалог управления итогами Период рассчитанных итогов – месяц. На рисунке видно, что последний рассчитанный месяц итогов регистров бухгалтерии – июль 2010 года. Строка в таблице итогов имеет период – 01.07.2010 и хранит остатки на начало июля 2010 года и обороты за июль. Расчет итогов можно выполнить программно, используя метод регистра бухгалтерии УстановитьПериодРассчитанныхИтогов() (листинг 4.60). Листинг 4.60. Пример использования метода «УстановитьПериодРассчитанныхИтогов()» РегистрыБухгалтерии.ОсновнойРегистрБухгалтерии.УстановитьПериодРассчитанныхИтогов(Дата); В качестве параметра в метод передается дата месяца, за который необходимо выполнить расчет итогов. ВНИМАНИЕ! Расчет итогов не является обязательным, но представляется нам очень желательным. Рассчитанные итоги влияют на скорость получения остатков Глава 4. Реализация задач бухгалтерского учета 541 и оборотов по счетам: при построении виртуальных таблиц система всегда, когда есть возможность, обращается к таблицам итогов. Если затребованных данных в таблицах итогов нет, система обращается к таблицам первичных движений. Рассмотрим структуру физической таблицы остатков и оборотов по счетам, соответствующей приведенному выше диалогу расчета итогов (итоги рассчитаны по 31.07.2010 года), табл. 4.74. Таблица 4.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 Таким образом, каждая строка таблицы итогов регистра бухгалтерии как указание месяца итогов хранит дату начала месяца. Хранится счет и измерения, и для каждого ресурса регистра бухгалтерии хранится абсолютный остаток (дебетовый остаток минус кредитовый остаток) на начало рассчитанного месяца (т. е. на конец прошлого месяца) и обороты за месяц. 542 Реализация прикладных задач в системе «1С:Предприятие 8.2» Дополнительно создается строка, маркированная периодом 01.11.3999, предназначенная для хранения текущих итогов регистра с учетом всех его записей. Получение данных из таблиц итогов рассмотрено в разделе «Виртуальные таблицы» на стр. 488. Режим разделения итогов Использование режима разделения итогов обеспечивает более высокую параллельность работы при записи в регистр, что позволяет ускорить запись в регистр и избежать блокировок в тех случаях, когда разные пользователи записывают данные с одинаковым набором значений полей (Период + Счет + Измерение + Субконто). При использовании режима разделения итогов система при одновременной записи движений несколькими сеансами не будет обновлять одни и те же записи итогов, а будет записывать изменения итогов в отдельные записи. При получении итогов эти данные складываются. Таким образом обеспечивается и поддержание в актуальном состоянии итогов (например, для быстрого получения отчетов), и параллельность записи движений. Как уже говорилось, при записи движений в регистр записи в таблице итогов автоматически пересчитываются. Считываемые записи таблицы итогов в момент пересчета блокируются. Таким образом, документы, содержащие движения по одинаковым комбинациям значений полей (Период + Счет + Измерение + Субконто), не могут быть проведены параллельно. Механизм разделения итогов вводит в состав хранимой таблицы итогов специальное поле (Разделитель), позволяющее распараллелить обновление записей итогов. Новые записи (с новым разделителем) с уже существующими комбинациями значений полей (Период + Счет + Измерение + Субконто) создаются системой только в том случае, если параллельно выполняются две и более транзакции. Таким образом, увеличение количества записей итогов зависит от количества одновременно выполняемых транзакций. При получении итогов регистра бухгалтерии или при пересчете итогов записи сворачиваются по комбинациям измерений. Чтобы управлять работой данного механизма, предусмотрены две возможности. В конфигурации для регистров введено свойство Разрешить разделение итогов. Для новых регистров бухгалтерии, создаваемых в конфигурации, это свойство стандартно включено. Установка этого свойства позволяет включить или отключить возможность разделения итогов для конкретного регистра. Отключение свойства полностью исключает влияние данного механизма Глава 4. Реализация задач бухгалтерского учета 543 на работу регистра, так как само поле, используемое для разделения итогов, не включается в структуру регистра. Отключение данной возможности полезно, например, для регистров, которые не используются при параллельной работе пользователей (например, для регистров, всегда заполняемых специальными регламентными обработками). Признак использования разделения итогов для регистров (для которых разделение итогов разрешено в конфигурации) может быть получен и установлен программно методами менеджера регистра бухгалтерии ПолучитьРежимРазделенияИтогов() и УстановитьРежимРазделенияИтогов(), а также в стандартной функции управления итогами (Все функции Стандартные Управление итогами Полные возможности Разделение итогов Включить разделение итогов/Выключить разделение итогов). Такая возможность позволяет включать или выключать режим разделения итогов в зависимости от условий работы пользователей в конкретной организации. Например, при интенсивном параллельном вводе информации этот режим может быть полезен. Но если с системой работает небольшое количество пользователей, то выигрыш от его применения будет небольшой, а некоторое замедление при получении отчетов и лишние записи в таблицах итогов фактически будут лишними (неоправданными). В целом механизм разделения итогов для регистров бухгалтерии аналогичен такому же механизму для регистров накопления остатков. Подробно он описан в разделе «Режим разделения итогов» на стр. 296. Индексы таблиц итогов регистра бухгалтерии Для ускорения поиска нужных записей в физических таблицах создаются индексы. Система создает индексы автоматически в соответствии со свойствами объектов. Нас интересует количество и состав полей в индексах, их зависимость от свойств объектов и их влияние на производительность системы. Так как производительность подсистемы бухгалтерского учета во многом определяется эффективностью хранения и получения данных из таблиц итогов регистра бухгалтерии, мы уделим им особое внимание. В индекс таблиц итогов регистра бухгалтерии входят следующие поля: Период + Счет + Измерение1 + [Измерение2…] + ЗначениеСубконто1 + [ЗначениеСубконто2…] Индексы, создаваемые платформой для физических таблиц итогов регистра бухгалтерии, влияют на производительность системы с двух сторон: влияние на скорость записи движений при проведении документа и влияние на скорость получения данных при обращении к итогам (табл. 4.75). 544 Реализация прикладных задач в системе «1С:Предприятие 8.2» Таблица 4.75. Влияние индексов на производительность Критерий Влияние на производительность Запись Количество Обновление индексов при записи Да индексов движений. Чем больше индексов создано для таблиц регистра, тем дольше они будут обновляться в момент записи движений в таблицы регистра, что существенно увеличит время проведения документа Количество Чем больше полей попало в индекс, Да полей тем точнее будет выполнен захват в индексе строк (диапазона строк) таблицы итогов, который нужно обновить при записи движений в регистр Поля, не включенные в индекс, увеличат диапазон строк таблиц итогов на количество всех возможных комбинаций этих полей. Поиск нужных строк в этой выборке будет осуществляться перебором Чтение Ограничение Не более 128 индексов для таблицы Не более 16 полей в индексе Да Рассмотрим подробнее перечисленные критерии. Тип значения субконто и его влияние на количество индексов Количество индексов существенно зависит от типов полей, которые были использованы при создании измерений и/или субконто регистра. Рассмотрим несложный пример: в плане счетов установлено максимальное количество субконто, равное «2». Используются субконто примитивного типа данных (Дата и Строка). При использовании примитивных типов данных для каждого включенного примитивного типа в составной тип данных значения субконто создается свое поле в информационной базе (рис. 4.70). Индекс будет создан на каждое сочетание полей (табл. 4.76). Глава 4. Реализация задач бухгалтерского учета 545 Рис. 4.70. Поля записи Таблица 4.76. Создаваемые индексы Номер индекса Поля в индексе 1 2 3 4 … + Субконто1 (Дата) + Субконто2 (Дата) … + Субконто1 (Дата) + Субконто2 (Строка) … + Субконто1 (Строка) + Субконто2 (Дата) … + Субконто1 (Строка) + Субконто2 (Строка) Несложно представить, к чему приведет увеличение максимального количества субконто до трех или включение еще одного примитивного типа данных (например, Булево) в состав составного типа данных значения субконто. СОВЕТ Категорически не рекомендуется включать в составной тип данных плана видов характеристик, используемого в качестве видов субконто, примитивные типы данных. Количество полей в индексе SQL Server имеет ограничение на количество полей в индексе, равное 16. Поиск по полям, участвующим в индексе, осуществляется системой быстро. Если есть поля, которые должны были бы участвовать в индексе (измерения, значения субконто), но не были включены в него по причине ограничения длины, система сможет быстро получить выборку, включающую в себя поля, участвующие в индексе, и все сочетания полей, в индекс не вошедших. Полученная выборка будет обрабатываться построчно с целью поиска нужной строки итогов. 546 Реализация прикладных задач в системе «1С:Предприятие 8.2» Рассмотрим это на примере физической таблицы остатков и оборотов по счетам и субконто регистра бухгалтерии демонстрационной конфигурации «Бухгалтерский учет», которая находится на прилагаемом компакт-диске (рис. 4.71). Рис. 4.71. Свойства, влияющие на количество полей в индексе Индекс будет включать следующие поля (табл. 4.77). Таблица 4.77. Поля, входящие в индекс № Поле Комментарий 1 2 3 Период 4 Валюта 5 6 7 8 9 10 Субконто1 Дата начала месяца периода итогов (Дата) Счет плана счетов (ПланСчетовСсылка.<имя>) Измерение регистра бухгалтерии Организация (СправочникСсылка.<имя>) Измерение регистра бухгалтерии Валюта (СправочникСсылка.<имя>) Счет Организация Субконто1 Субконто1 Субконто2 Субконто2 Субконто2 Тип Таблица Запись Тип Таблица Запись Фактический тип значения поля составного типа Тип ссылки Значение ссылки Фактический тип значения поля составного типа Тип ссылки Значение ссылки Прокомментируем таблицу: для хранения значений типа Дата, ПланСчетовСсылка.<имя>, СправочникСсылка.<имя> система создает одно поле в таблице базы данных, и, следовательно, каждое из них занимает одно поле в индексе. Глава 4. Реализация задач бухгалтерского учета 547 Для описания субконто используется составной тип данных. В демонстрационной конфигурации «Бухгалтерский учет», которая находится на прилагаемом компакт-диске, и в типовой конфигурации для описания составного типа данных, определяющего тип значения характеристик ВидыСубконто, применяются только ссылочные типы данных. Для хранения одного значения составного типа данных (содержащего только ссылки) системой используются три поля базы данных: фактический тип значения, имя таблицы и идентификатор записи в этой таблице. Если включить в составной тип данных примитивные, то кроме опасностей, описанных в разделе «Тип значения субконто и его влияние на количество индексов» на стр. 546, возникает еще одна: для хранения каждого примитивного типа данных (Число, Дата, Строка, Булево) в таблицу базы данных будет добавлено еще одно поле. Другими словами, если добавить в составной тип данных все четыре примитивных типа, то для хранения одного значения субконто будет использоваться семь полей (из них три для ссылки). И как следствие при той же максимальной длине индекса (16 полей) в него попадут только период, счет, измерение и первое субконто. Подробнее можно прочитать в разделе «Хранение значений полей составного типа» на стр. 686. Продолжая рассматривать физическую таблицу остатков и оборотов по счетам и субконто регистра бухгалтерии демонстрационной конфигурации «Бухгалтерский учет», которая находится на прилагаемом компакт-диске, мы можем сделать вывод, что все десять полей помещаются в индексе. Мы можем увеличить максимальное количество субконто на счете, не рискуя потерять производительность, до четырех. При таком максимальном количестве субконто мы как раз «укладываемся» в 16 полей индекса. Увеличение количества субконто в нашей конфигурации более чем до четырех приведет к тому, что последнее субконто не будет участвовать в индексе. Конфигурация с такой настройкой регистра бухгалтерии и аналитического учета может и будет функционировать, но теряется производительность как при записи движений в регистр, так и при формировании отчетов. Рассмотрим особенности функционирования демонстрационной конфигурации «Бухгалтерский учет», которая находится на прилагаемом компакт-диске, в случае увеличения максимального количества субконто на счете до пяти (табл. 4.78). 548 Реализация прикладных задач в системе «1С:Предприятие 8.2» Таблица 4.78. Поля, входящие в индекс № поля Поле 1 2 3 Период 4 Валюта 5, 6, 7 8, 9, 10 11, 12, 13 14, 15, 16 Комментарий Обязательное поле Счет плана счетов (ПланСчетовСсылка.<имя>) Организация Измерение регистра бухгалтерии Организация (СправочникСсылка.<имя>) Счет Субконто1 Субконто2 Субконто3 Субконто4 Субконто5 Измерение регистра бухгалтерии Валюта (СправочникСсылка.<имя>) Три поля для хранения составного типа данных (только ссылки) Три поля для хранения составного типа данных (только ссылки) Три поля для хранения составного типа данных (только ссылки) Три поля для хранения составного типа данных (только ссылки) Три поля для хранения составного типа данных (только ссылки) Мы видим, что последнее субконто не включается в индекс таблицы. К чему это приведет? Давайте сравним работу таблицы итогов для демонстрационной конфигурации «Бухгалтерский учет», которая находится на прилагаемом компакт-диске, с максимальным количеством субконто, равным четырем и пяти. Итак, работа таблиц итогов, если все поля помещаются в индекс, представлена на рис. 4.72. Рис. 4.72. Получение итогов при четырех субконто Когда система осуществляет поиск в таблице итогов, она обращается к индексу и получает точное указание на строку, которая хранит затребованные остатки и обороты. При увеличении количества субконто до пяти последний вид субконто не попадает в индекс, и работа системы изменяется (рис. 4.73). Глава 4. Реализация задач бухгалтерского учета 549 Рис. 4.73. Получение итогов при пяти субконто На приведенной выше схеме видно, что в индексе участвуют только первые четыре субконто. Как результат система при поиске итогов по затребованному набору полей получает не одну строку, а диапазон строк, содержащий строки со всеми хранимыми вариантами (в нашем примере ВидN – Вид3). Далее поиск строки с нужным видом осуществляется перебором. Получение диапазона строк вместо одной строки итогов, во-первых, увеличит время формирования отчетов, в которых требуется получить отбор по последнему (не включенному в индекс) виду субконто, а, во-вторых, увеличит время записи и объем блокируемых транзакцией строк таблицы во время записи движений в регистр. Во время записи движений в регистр блокируются строки таблицы итогов для внесения в них изменений. Если индекс охватывает все поля регистра, блокируется одна изменяемая и соседние (блокировка соседних строк связана с особенностями работы SQL) строки. Пока выполняется транзакция, другие пользователи не могут выполнять запись движений с таким же набором полей (Период + Счет + Измерение + Субконто). Если вместо одной строки итогов был получен диапазон строк, блокируется весь диапазон (плюс соседние строки). Вероятность, что пользователи «столкнутся» при проведении документов, увеличивается. СОВЕТ Если анализ поставленной задачи учета выявляет необходимость создания регистра, количество полей таблиц итогов которого больше, чем может включить в себя индекс, имеет смысл переосмыслить выбор объекта 550 Реализация прикладных задач в системе «1С:Предприятие 8.2» системы «1С:Предприятие» для решения этой задачи. Можно предположить, что ее решение с помощью регистров накопления будет рациональнее. Подходы к отнесению учетной задачи к бухгалтерскому или оперативному учету приводятся в разделе «Принятие решений при организации аналитического учета» на стр. 439. Если же постановка задачи исключает возможность решить ее с помощью объекта Регистр накопления, следует располагать субконто с малой селективностью (обладающие малым количеством значений и редко используемые для отбора в отчетах) последними на счетах. Это сократит диапазон полученных по индексу строк и время на поиск в нем нужной строки. Построение виртуальных таблиц регистра бухгалтерии Как уже не раз говорились, виртуальные таблицы регистра представляют собой запросы, которые собирают данные из физических таблиц регистра бухгалтерии. Рассмотрим правила построения виртуальных таблиц. Механизм текущих итогов При описании физических таблиц итогов регистра мы упоминали, что итоги хранятся помесячно. Подобная организация физических таблиц позволяет быстро получать остатки на первое число месяца и обороты за календарный месяц. Хранение итогов помесячно обосновано особенностью ведения учета: как правило, стандартными бухгалтерскими интервалами для составления отчетности являются месяц, квартал и месяц и квартал нарастающим итогом с начала года. Бухгалтерский учет «историчен» – как правило, обрабатываются документы, свидетельствующие об уже свершившихся фактах хозяйственной деятельности, после ввода всех документов за стандартный бухгалтерский интервал формируется отчетность. Однако существуют и задачи учета в реальном времени. Тогда необходимо получать данные по еще не закрытому отчетному периоду, «на сейчас», т. е. с учетом последней записанной в информационную базу проводки. Для быстрого получения актуальных на текущий момент времени данных и предназначен механизм текущих итогов. Рассмотрим несложный пример работы механизма для одного счета. В методических целях будем считать, что: ■ ■ ■ ■ ведется только синтетический учет (нет учета по субконто); только в валюте учета; без измерений; нет входящих остатков. Глава 4. Реализация задач бухгалтерского учета 551 Итак, были сделаны следующие проводки в таблице записей (табл. 4.79). Таблица 4.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 Можно представить также этот журнал проводок в виде оборотной ведомости по счету касса в разрезе дней (табл. 4.80). Это пригодится нам в дальнейшем. Период Счет Дт Счет Кт Сумма Остаток . на начало Оборот Дт Оборот Кт Остаток . на конец Таблица 4.80. Представление журнала проводок в виде оборотной ведомости по счету 01.01.2010 Касса Капитал 10 0 10 0 10 12.01.2010 Касса Покупатели 5 10 5 0 15 18.01.2010 Сотрудники Касса 3 15 0 3 12 05.02.2010 Касса Покупатели 8 12 8 0 20 13.02.2010 Поставщики Касса 6 20 0 6 14 20.02.2010 Касса Сотрудники 1 14 1 0 15 01.03.2010 Касса Покупатели 7 15 7 0 22 08.03.2010 Сотрудники Касса 9 22 0 9 13 16.03.2010 Касса Покупатели 4 13 4 0 17 01.04.2010 Касса Сотрудники 2 17 2 0 19 10.04.2010 Касса Покупатели 1 19 1 0 20 20.04.2010 Сотрудники Касса 2 20 0 2 18 552 Реализация прикладных задач в системе «1С:Предприятие 8.2» О расчете итогов рассказывается в разделе «Управление итогами» на стр. 542. Результатом расчета итогов стали физическая таблица остатков и оборотов по счетам и физическая таблица оборотов между счетами за эти же два месяца, но в нашем примере мы не будем ее учитывать. Можно представить также этот журнал проводок в виде оборотной ведомости по счету «Касса» в разрезе календарных месяцев (табл. 4.81). Таблица 4.81. Представление журнала проводок в виде оборотной ведомости по счету в разрезе месяцев Период Остаток на начало Оборот Дт Оборот Кт Остаток на конец Январь 2010 Февраль 2010 Март 2010 Апрель 2010 0 12 15 17 15 9 11 3 3 6 9 2 12 15 17 18 Итоги рассчитаны за январь и февраль. Ячейки, выделенные серым цветом, в физической таблице итогов не хранятся. Это остатки на конец месяца и еще не рассчитанные месяцы: пользователи уже начали вводить операции за апрель, однако и март, и апрель еще не рассчитаны. Чтобы не использовать физические таблицы первичных движений каждый раз, когда требуется узнать последние (текущие) итоги по счету с учетом всех движений (включая проводки за март и апрель), в физических таблицах итогов создается еще одна строка для хранения текущих итогов. Поэтому на самом деле физическая таблица остатков и оборотов по счетам хранит не два (январь и февраль), а три «месяца» (январь, февраль, текущие итоги) и выглядит следующим образом (табл. 4.82). Таблица 4.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 можно увидеть, например, сформировав запрос к виртуальной таблице остатков и оборотов без указания интервала дат с периодичностью Месяц или более детально. Используя шкалу времени, можно представить хранение итогов в виде схемы, приведенной на рис. 4.74. Глава 4. Реализация задач бухгалтерского учета 553 Рис. 4.74. Схема хранения итогов Пример формирования запроса без указания интервала дат был приведен не случайно. Именно в случае, если обращение к виртуальной таблице остатков производится без указания интервала дат, система обращается непосредственно к строкам, где хранятся текущие итоги. Текущие итоги используются и при обращении к итогам на произвольную дату месяца, который не был рассчитан (на схеме – март и апрель). В нижней части схемы изображены различные варианты получения остатков и оборотов. Актуальному остатку соответствует элемент схемы «Остаток 5». Остальные элементы (варианты) будут рассмотрены ниже. В нашем примере, чтобы получить актуальный остаток по счету Касса, необходимо выполнить запрос к виртуальной таблице остатков без указания первого параметра таблицы Момент. Или воспользоваться методом менеджера регистра бухгалтерии Остатки(), передав в качестве первого параметра метода значение Неопределено. 554 Реализация прикладных задач в системе «1С:Предприятие 8.2» Таблица остатков Источниками данных виртуальной таблицы остатков в базе данных являются физическая таблица остатков и оборотов по счетам, физическая таблица остатков и оборотов по счетам и субконто и, в ситуациях, когда физические таблицы итогов использовать невозможно, физическая таблица движений. Рассмотрим все возможные варианты работы виртуальной таблицы остатков. В первую очередь рассмотрим варианты выбора системой источника данных: физические таблицы итогов или физические таблицы первичных движений. Критерием выбора в данном случае является момент времени, на который затребован остаток. Вариант 1. При обращении к виртуальной таблице остатков указан момент времени, соответствующий началу календарного месяца, и этот месяц рассчитан. На приведенной схеме (рис. 4.74, вариант Остаток 1) это может быть начало января 2010 года (01.01.2010 0:00:00 или граница от конца дня 31.12.2009, включая последнюю секунду) или начало февраля 2010 года. В этом варианте система обращается к физической таблице итогов и получает готовый остаток. Такой запрос будет выполнен максимально быстро. Вариант 2. Требуется получить остаток на произвольный момент времени месяца. Важные замечания: этот месяц рассчитан, и этот месяц не последний рассчитанный, т. е. существует следующий рассчитанный месяц, и, таким образом, есть остаток на конец того месяца, за произвольную дату которого нужно получить остаток. В нашем случае (рис. 4.74, вариант Остаток 2) это может быть любая дата января (на рис. 4.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 руб. Вариант 3. Требуется получить остаток на произвольный момент последнего рассчитанного месяца. В физических таблицах итогов нет следующей строки со следующим рассчитанным месяцем, где бы хранились остатки на конец выбранного нами. На рис. 4.74, вариант Остаток 3, это 15 февраля (итоги рассчитаны по февраль включительно). Система получит итоги на начало февраля из физических таблиц итогов, далее из той же строки физической таблицы итогов получит дебетовый и кредитовый оборот и, таким образом, сможет быстро получить остаток на конец Глава 4. Реализация задач бухгалтерского учета 555 февраля (начало марта). Получив этот остаток, она вычтет из него «проводки» с 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. Требуется получить остаток на произвольный момент времени любого не рассчитанного месяца. В нашем примере (рис. 4.74, вариант Остаток 4) это могут быть и 15 марта, и 15 апреля. В этом случае система воспользуется готовыми текущими итогами и отнимет от них проводки за интервал дат с 15 марта (15 апреля) до последней записи. Остаток на 15.03.2010 = Итоги остаток (актуальный) - Проводки (15.03.2010 - последняя проводка). В нашем примере это будет: 18 руб. - (7 руб. - 2 руб.) = 13 руб. Вариант 5. Требуется получить актуальный остаток. Момент времени при обращении к виртуальной таблице не указывается, система получает актуальный остаток из физических таблиц итогов (рис. 4.74, вариант Остаток 5). Актуальный остаток = Итоги остаток (актуальный). В нашем примере это будет: 18 руб. Если первым критерием, влияющим на выбор источника запроса для виртуальной таблицы (физическая таблица итогов или физическая таблица проводок), можно считать момент времени, то вторым – были ли затребованы в отборах или списке выбранных полей субконто. Если аналитика встречалась, в качестве физической таблицы итогов (их может быть несколько, если запрос выполняется по нескольким счетам) будет использоваться физическая таблица остатков и оборотов по счетам и субконто. Если требуются только синтетические остатки – физическая таблица остатков и оборотов по счетам. Таблица оборотов В основе построения виртуальной таблицы оборотов лежит тот же принцип: если данные можно взять из физических таблиц итогов, используются они. То, что из физических таблиц итогов взять нельзя, получается из физических таблиц первичных движений. Но у виртуальной таблицы оборотов есть и свои особенности. Если при обращении к виртуальной таблице параметр Периодичность установлен меньше месяца или используются поля, содержащие в своем название Кор, виртуальная таблица строится только на основании физических таблиц 556 Реализация прикладных задач в системе «1С:Предприятие 8.2» первичных движений. Во всех остальных случаях обороты за календарные месяцы виртуальная таблица получает из физических таблиц итогов (рис. 4.75). Рис. 4.75. Алгоритм использования физических таблиц при построении виртуальной таблицы оборотов Рассмотрим возможные варианты. Вариант 1. Затребован оборот за рассчитанный календарный месяц с 01.01.2010 по 31.01.2010 (рис. 4.74, вариант Оборот 1). Система обратится к строке физической таблицы итогов, маркированной периодом «01.01.2010», и получит дебетовый или кредитовый оборот. Оборот за календарный месяц Январь = Итоги оборот дт / кт (01.01.2010 - 31.12.2010). В нашем примере это будет: оборот дт = 15 руб., оборот кт = 3 руб. Вариант 2. Требуется получить оборот с 20.12.2009 по 20.02.2010 (рис. 4.74, вариант Оборот 2). Система получит готовые обороты за январь, как в предыдущем случае, а интервалы дат с 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). В нашем примере это будет: оборот дт = 15 руб. + 0 + 9 руб. = 24 руб. Вариант 3. Так же поступит система и в случае, если требуется получить оборот за период, в котором есть не рассчитанные интервалы (рис. 4.74, вариант Оборот 3). Рассчитанные, полностью включенные в период запроса Глава 4. Реализация задач бухгалтерского учета 557 календарные месяцы будут взяты из таблиц итогов, а оставшиеся «куски» дат будут собраны системой по таблицам проводок. Отдельно следует упомянуть про расчет полей с постфиксом Оборот. Поля виртуальной таблицы оборотов <имя>ОборотДт и <имя>ОборотКт рассчитываются таблицей «в один приход» – такие поля есть в физических таблицах итогов, и достаточно одного «прохода» по физической таблице записей. Поля виртуальной таблицы <имя>Оборот рассчитываются «в два прохода» – сначала рассчитывается дебетовый оборот, потом из него вычитается кредитовый оборот (рис. 4.76). Рис. 4.76. Алгоритм расчета полей оборотов Таблица остатков и оборотов Формирование виртуальной таблицы остатков и оборотов можно представить в виде следующий схемы (рис. 4.77). Рис. 4.77. Алгоритм формирования таблицы остатков и оборотов 558 Реализация прикладных задач в системе «1С:Предприятие 8.2» Виртуальную таблицу остатков и оборотов система получает в несколько проходов. Остатки на начало периода рассчитываются по той же схеме, по которой рассчитывается виртуальная таблица остатков. Обороты за период рассчитываются как виртуальная таблица оборотов с условием, что в ней не используются фильтры и группировки по <…>Кор полям. Далее система самостоятельно (не используя ресурсы SQL-сервера) подсчитывает остатки на конец периода. Если используется параметр Периодичность, то результаты запросов по остаткам на начало и оборотам помещаются во временную таблицу на сервер, к которой и выполняется запрос для получения виртуальной таблицы остатков и оборотов. Таблица оборотов Дт Кт Построение виртуальной таблицы оборотов Дт Кт выполняется системой по алгоритму, напоминающему виртуальную таблицу оборотов. Отличия есть, и они являются следствием физической таблицы итогов (физическая таблица оборотов между счетами), которая может использоваться при построении виртуальной таблицы (рис. 4.78). Рис. 4.78. Алгоритм построения таблицы оборотов Дт Кт При условии, что периодичность не меньше месяца (как и в виртуальной таблице оборотов) и в запросе не упоминается аналитика (физическая таблица оборотов между счетами не хранит информацию в разрезе субконто), используется физическая таблица итогов, в противном случае запрос выполняется к физическим таблицам первичных движений. Физическая таблица оборотов между счетами хранит ресурс Оборот, поэтому получение этого ресурса не требует двух проходов (как в виртуальной таблице оборотов). Глава 4. Реализация задач бухгалтерского учета 559 Таблица движений с субконто Виртуальная таблица движений с субконто формируется системой с использованием только физических таблиц первичных движений, чем и обусловлена возможность получения этой виртуальной таблицей неактивных записей (рис. 4.79). Рис. 4.79. Алгоритм формирования виртуальной таблицы движений с субконто Использование текущих итогов Чтобы поддерживать текущие итоги в актуальном состоянии, при записи набора активных записей в таблице движений всегда рассчитываются и перезаписываются текущие итоги в таблице итогов, если у регистра установлен признак использования итогов. Однако пересчет текущих итогов при параллельной записи движений несколькими пользователями может быть неэффективным. Например, если период рассчитанных итогов регулярно устанавливается обработкой и есть уверенность в хранении посчитанных итогов на начало каждого месяца, может быть выгоднее «досчитывать» остатки от хранимых итогов. В таком случае можно не устанавливать использование текущих итогов для регистра бухгалтерии – УстановитьИспользованиеТекущихИтогов(Ложь). Если использование текущих итогов выключено, то расчет актуальных остатков будет производиться следующим образом: сначала будут получены остатки на самые поздние хранимые итоги, а потом по движениям за оставшийся период будут получены актуальные остатки. Данный подход позволяет увеличить параллельность при записи наборов записей данного регистра, так как не требуется обновления текущих итогов. Получить признак использования текущих итогов из встроенного языка можно методом менеджера регистра бухгалтерии ПолучитьИспользованиеТекущихИтогов(). Включить или выключить использование текущих итогов можно методом УстановитьИспользованиеТекущихИтогов(Истина/Ложь), а также в стандартной функции управления итогами 560 Реализация прикладных задач в системе «1С:Предприятие 8.2» (Все функции Стандартные Управление итогами Полные возможности Текущие итоги Включить использование текущих итогов/Выключить использование текущих итогов). Зависимость производительности . от настроек субконто счета Производительность системы при формировании виртуальных таблиц зависит от многих факторов. Часть из них мы перечислили, описывая индексирование таблиц, часть – при описании конкретных виртуальных таблиц. Остались те, которые влияют на работу всех таблиц и которые мы считаем необходимыми учитывать при проектировании плана счетов и написании запросов. Во всех виртуальных таблицах отбор по полю Счет (СчетДт, СчетКт, КорСчет) вынесен в отдельное поле. Сделано это не случайно. При формировании таблицы система анализирует настройку видов субконто для каждого счета и выбирает соответствующую физическую таблицу итогов для получения остатков и оборотов. Например, если запрос выполняется сразу по трем счетам и на первом из них подключен один вид субконто (значение которого используется в запросе для фильтра или группировки), на втором – два вида субконто (один из них тот же), а на третьем – три, источниками данных запроса будут три физические таблицы остатков и оборотов по счетам и субконто регистра бухгалтерии (рис. 4.80). Рис. 4.80. Пример использования физических таблиц Глава 4. Реализация задач бухгалтерского учета 561 Еще один вопрос, связанный аналитикой и производительностью при работе виртуальных таблиц, – это порядок, в котором «прикреплены» субконто к счету. Наиболее быстро система сможет получить итоги по тем субконто, которые прикреплены к счету первыми. Можно порекомендовать располагать субконто на счете с учетом следующего правила: ■ те из них, по которым наиболее часто нужно выполнять отбор, имеет смысл располагать «ближе к счету»; ■ те, которые реже участвуют в отборе и чаще предназначены для группировки, имеет смысл поместить «в конец» (рис. 4.81). Рис. 4.81. Пример зависимости скорости выполнения запроса от расположения субконто Также на производительность влияет и то, в каком порядке привязаны на разные счета одни и те же виды субконто, если запрос выполняется сразу по нескольким счетам. Возможность упорядочить виды субконто в запросе, используя параметр виртуальной таблицы Субконто, описана в разделе «Параметр «Субконто»: отбор и упорядочивание по виду субконто» на стр. 513. 562 Реализация прикладных задач в системе «1С:Предприятие 8.2» Если один и тот же субконто прикреплен к разным счетам в различном порядке (на одной счете он первый, на другом второй), виртуальная таблица для сбора данных по этому субконто выполнит два подзапроса (рис. 4.82). Рис. 4.82. Схема формирования виртуальной таблицы Глава 5. Реализация сложных периодических расчетов Помимо задач оперативного и бухгалтерского учета, платформа «1С:Предприятие» предоставляет широкие возможности для создания решений, предполагающих выполнение сложных периодических расчетов. Наибольшее распространение механизмы периодических расчетов получили в решениях по расчету заработной платы. Однако сфера применения этих возможностей платформы значительно шире. Задачи сложных периодических расчетов имеют ряд особенностей, отличающих их от задач оперативного и бухгалтерского учета. Эти виды учета отличаются как по предназначению, так и по основным методам, используемым для их реализации. Так, оперативный учет служит для непрерывного учета состояния и движения средств в различных аналитических разрезах. Реализация подобных задач предполагает четкую привязку всех регистрируемых событий к непрерывной оси времени (каждое событие имеет так называемый момент времени, то есть точку на оси времени). Задачи бухгалтерского учета в целом схожи с оперативным учетом, но предполагают более сложную систему регистрации событий с возможностью использования корреспонденции счетов. Бухгалтерский учет также является по сути непрерывным. Отличительной особенностью периодических расчетов является отсутствие однозначной привязки событий к точке на оси времени. Регистрируемые события в этом виде учета имеют отношение не к моменту времени, а к периоду в целом. При этом периодом расчета может быть день, месяц, квартал или год в зависимости от специфики решаемой задачи. Так, если для 564 Реализация прикладных задач в системе «1С:Предприятие 8.2» регистрации факта поступления товара важен точный момент его прихода, то при начислении премии важен период расчета (например, месяц), в котором она была начислена. Еще одним отличием периодических расчетов является протяженность некоторых регистрируемых событий во времени. Например, при регистрации отпуска сотрудника указывается дата начала и дата окончания отпуска. В прочих видах учета регистрация подобных записей невозможна. Таким образом, помимо задач расчета зарплаты, механизм периодических расчетов может быть использован и в других областях, предполагающих периодическую регистрацию протяженных во времени событий, например, в задаче расчета аренды за помещения выставочного центра. Пример, который будет рассматриваться в рамках данной главы, приводится в демонстрационной конфигурации «Сложные периодические расчеты», которая находится на прилагаемом компакт-диске. В качестве примера выбрана задача по расчету зарплаты как наиболее часто реализуемая на практике. Технология реализации расчетных задач Основные понятия Вид расчета Одним из основных понятий механизма периодических расчетов является вид расчета. Любой расчет, выполняемый в системе, регистрируется с обязательным указанием вида расчета, под которым может пониматься как способ расчета данной записи, так и дополнительные свойства, характеризующие сущность именно этого расчета. Например, для целей расчета зарплаты различными видами расчета могут быть оклад, надбавка за вредность, оплата сверхурочных. В данном случае каждая из этих записей имеет свой алгоритм расчета, поэтому для каждого вида начисления сотрудникам вводится отдельный вид расчета. Тем не менее, оплата дежурства, например, может иметь тот же алгоритм расчета, что и оклад, но при этом это будет отдельный вид расчета, так как у него другой смысл. В общем случае список видов расчета, используемых в системе, зависит от специфики решаемой задачи. Расчетные инструменты платформы «1С:Предприятие» устроены таким образом, что пользователь может самостоятельно создавать и настраивать виды расчета, которые ему необходимы для решения прикладной задачи, в режиме 1С:Предприятие. Для организации системы взаимосвязанных видов расчета в платформе предусмотрен объект конфигурации План видов расчета. План видов расчета определяет структуру хранения данных о видах расчета, используемых в прикладном решении для определенных целей. Разработчик может создать в конфигурации несколько планов видов Глава 5. Реализация сложных периодических расчетов 565 расчета для различный целей, в каждый из которых пользователь в режиме 1С:Предприятие сможет внести неограниченное количество видов расчета, а также настроить их взаимосвязь. Принципы регистрации записей Все записи о расчетах регистрируются в системе в привязке к периоду расчета и конкретному виду расчета. Для хранения записей о расчетах в системе предусмотрен объект метаданных Регистр расчета. Каждый регистр расчета имеет определенную периодичность (день, месяц, квартал или год), рис. 5.1. В зависимости от периодичности записи в этом регистре имеют соответствующий период регистрации (подробнее о периоде регистрации ниже). Рис. 5.1. Периодичность регистров расчета Все записи регистра расчета, помимо периода регистрации, содержат информацию о виде расчета, примененном в данной записи. В одном регистре расчета могут содержаться виды расчетов только из одного плана видов расчетов. При этом регистров расчета, использующих один и тот же план видов расчета, может быть несколько. Например, виды расчета из плана видов расчета Начисления могут использоваться в двух разных регистрах – Управленческие начисления и Регламентированные начисления (рис. 5.2). Рис. 5.2. Использование видов расчета в разных регистрах расчета 566 Реализация прикладных задач в системе «1С:Предприятие 8.2» В данном примере один и тот же план видов расчета Начисления используется как в регистре расчета Управленческие начисления для учета зарплаты работников в долларах для целей управленческого учета, так и в отдельном независимом регистре расчета Регламентированные начисления, предназначенном для учета начислений в рублях для целей регламентированного учета. Записи в регистрах расчета могут быть определенным образом взаимосвязаны между собой. Вид этой взаимосвязи определяется настройками используемых видов расчета. Взаимосвязь, установленная для видов расчета, действует во всех регистрах, где эти виды расчета используются. Структура регистров расчета будет подробно рассмотрена позднее. Период регистрации Все расчеты в системе фиксируются в привязке к периоду расчета, в котором они зарегистрированы. Этот период называется периодом регистрации расчета. В зависимости от специфики задачи расчеты могут фиксироваться с периодичностью день, месяц, квартал и год. Период регистрации всегда существует у любой записи о расчете. При этом запись не может быть зарегистрирована сразу в нескольких периодах расчета. Например, при ведении ежемесячных периодических расчетов записи о расчетах могут быть привязаны к периоду регистрации следующим образом (рис. 5.3). В данном примере периодом регистрации оклада, начисленного в январе, будет являться месяц январь. Важно понимать, что периодом регистрации квартальной премии будет тот месяц, в котором она начислена (в данном случае март), а не весь первый квартал. Рис. 5.3. Привязка записей расчета к периоду регистрации Глава 5. Реализация сложных периодических расчетов 567 Период действия Записи о расчетах, зарегистрированные в системе, могут быть как протяженными во времени, так и нет. Например, командировка является протяженной во времени, так как для ее расчета важен период, в течение которого сотрудник находился в отъезде (рис. 5.4). В то же время, например, начисленный штраф не является протяженным во времени, а относится в целом к периоду, в котором он был начислен. Интервал, в течение которого длится протяженная во времени запись, называется периодом действия этой записи. Рис. 5.4. Записи расчета, протяженные во времени Период действия представляет собой непрерывный интервал времени, определяемый датой начала периода и датой его окончания. В приведенном примере периода действия записи о командировке – это интервал с 8 по 24 февраля. Период действия одной записи регистра расчета может лежать только в рамках одного периода расчетов. Если необходимо ввести расчет, который длится в рамках нескольких расчетных периодов, его нужно разбить на несколько записей (рис. 5.5). Рис. 5.5. Ввод расчета, который длится в нескольких периодах 568 Реализация прикладных задач в системе «1С:Предприятие 8.2» Так, если установлена периодичность расчетов месяц, то нельзя ввести командировку с периодом действия с 10 января по 15 февраля, так как такой период не лежит в рамках одного месяца. Вместо этого вводятся две записи, у одной из которых период действия с 10 по 31 января, у другой – с 1 по 15 февраля. У протяженных во времени записей период действия может не принадлежать периоду регистрации и лежать как в прошлом, так и в будущем относительно периода регистрации. Например, если работник болел в феврале, а оформленный больничный лист принес только в марте, то оплата больничного будет начислена в марте, так как за февраль зарплата уже рассчитана (рис. 5.6). Рис. 5.6. Период действия раньше периода регистрации В этом случае периодом регистрации этой записи будет март, хотя расчет длился с 10 по 22 февраля. Обратный случай возможен, например, когда начисление за предстоящую в следующем месяце командировку производится текущим месяцем (рис. 5.7). Рис. 5.7. Период действия позже периода регистрации Глава 5. Реализация сложных периодических расчетов 569 В этом случае периодом регистрации этого начисления будет февраль, а периодом действия – интервал с 9 по 25 марта. Вытесняющие расчеты и фактический период действия Протяженные во времени записи регистров расчета могут конкурировать между собой за период действия. Это означает, что они не могут действовать одновременно. Такая конкуренция необходима, когда виды расчета являются по сути взаимоисключающими. Например, виды расчета Оклад и Командировка не могут действовать в один и тот же момент, так как сотрудник не может одновременно работать на основном месте и находиться в командировке. При вводе записи о командировке на определенный интервал времени система должна исключать действие оклада в этом интервале. Такие виды расчетов, которые исключают одновременное действие записей других видов расчетов, называются вытесняющими (рис. 5.8). Рис. 5.8. Вытеснение по периоду действия В данном случае у записей о командировке и окладе возникает конкуренция за период действия в интервале с 10.03 по 15.03 (т. е. в интервале действия командировки). Как уже было отмечено, эти записи не могут действовать одновременно, поэтому в указанном интервале происходит вытеснение оклада командировкой. Таким образом, вид расчета Командировка по сути является вытесняющим по отношению к виду расчета Оклад. Это означает, что записи с видом расчета Командировка будут вытеснять записи с видом расчета Оклад. При вытеснении одного расчета другим период действия вытесняемого расчета не изменяется. Результат вытеснения влияет на так называемый фактический период действия вытесняемого расчета. Под фактическим периодом действия записи понимается совокупность интервалов времени в рамках 570 Реализация прикладных задач в системе «1С:Предприятие 8.2» периода действия, на протяжении которых расчет действует с учетом всех вытеснений. Если никаких вытеснений не происходило, фактический период действия совпадает с периодом действия (рис. 5.9). Рис. 5.9. Фактический период действия Таким образом, до вытеснений фактический период действия записи об окладе содержал только один интервал, совпадающий с периодом действия. В результате вытеснения период действия оклада не изменился, а конкуренция выразилась в разбиении фактического периода действия оклада на три интервала. ПРИМЕЧАНИЕ При формировании фактического периода действия принимаются во внимание также сторно-записи, о которых будет сказано ниже. Поскольку конкуренция и вытеснение взаимоисключающих записей происходят на интервалах пересечения периодов действия, то фактический период действия таких расчетов никогда не будет пересекаться. Тем самым они никогда не будут действовать одновременно. Глава 5. Реализация сложных периодических расчетов 571 Важно учитывать, что вытеснение срабатывает только при вводе вытесняющих расчетов текущим или будущим периодом. При вводе расчетов за предыдущий период (задним числом) механизм вытеснения не действует. Это связано с тем, что записи, введенные в систему раньше (т. е. с меньшим периодом регистрации), имеют больший приоритет в конкуренции за период действия, чем более поздние записи (с большим периодом регистрации), причем это не зависит от настройки списка вытесняющих расчетов (рис. 5.10). Рис. 5.10. Записи ранних периодов не вытесняются В данном случае больничный за февраль зарегистрирован в марте, то есть период регистрации позднее периода действия. В такой ситуации вытеснения оклада не произойдет, так как запись об окладе имеет более ранний период регистрации, чем запись о больничном, поэтому механизм вытеснения не действует. В результате ввода такой записи фактический период действия больничного будет пустым, так как записи не могут действовать одновременно, а вытеснения не происходит. Для того чтобы восстановить фактический период действия больничного, применяется механизм сторнирования, который будет описан позже. Зависимость по базовому периоду В определенных случаях результат одного расчета может зависеть от результата других расчетов, введенных в систему. Например, квартальная премия может зависеть от суммы начисленного за квартал заработка по окладу. В этом случае говорят, что оклад входит в базу расчета премии, а вид расчета Оклад является базовым по отношению к виду расчета Квартальная премия. При этом один вид расчета может иметь несколько базовых видов расчета, то есть зависеть одновременно от нескольких других расчетов. При расчете результата расчета по базе анализируется сумма базовых видов расчета за определенный период, который называется базовым периодом. Базовый 572 Реализация прикладных задач в системе «1С:Предприятие 8.2» период – это произвольный непрерывный интервал дат, который может покрывать несколько расчетных периодов. Например, при расчете оплачиваемого отпуска, как правило, производится расчет среднего заработка за 3 месяца, предшествующих отпуску. Этот интервал и будет базовым периодом расчета отпуска (рис. 5.11). Рис. 5.11. Базовый период В приведенном примере виды расчетов Оклад и Надбавка являются базовыми по отношению к отпуску. Если начисляется оплата отпуска за апрель, то базовым периодом этой записи будет интервал времени с 1 января по 31 марта (3 целых месяца, предшествующие отпуску). В этом случае в базу расчета отпуска войдут все базовые начисления, входящие в базовый период записи об отпуске. В данном случае база расчета отпуска составляет 33 000 рублей и состоит из суммы начислений по окладу за 3 месяца и начисленной в феврале надбавки. Исходя из этой базы, будет производиться расчет начисления отпускных в соответствии с алгоритмом расчета. То есть расчетная база – это еще не результат расчета, а лишь исходные данные, которые участвуют в алгоритме расчета. В данном случае предположим, что отпускные рассчитываются как среднее арифметическое заработков за 3 предыдущих месяца. В этом случае расчет отпуска производится следующим образом: Результат расчета = База расчета / 3 = 33 000 / 3 = 11 000 Расчет по базе может применяться ко всем видам расчетов, независимо от того, являются они протяженными во времени или нет. Например, квартальная премия, которая не имеет периода действия, может иметь базовый период (например, I квартал). Глава 5. Реализация сложных периодических расчетов 573 Ведущие расчеты и перерасчет Ведущими называют виды расчетов, при вводе или изменении которых необходимо перерассчитать результат уже существующих расчетов. Например, если работнику начислена премия за март в размере 10 % от заработка, то при вводе нового начисления в марте размер этой премии теряет актуальность. Премию необходимо пересчитать, чтобы учесть новое начисление (рис. 5.12). Рис. 5.12. Необходимость перерасчета при изменении базового вида расчета В данном случае премия изначально была рассчитана как 10 % от суммы оклада. При вводе за март надбавки в размере 3000 рублей результат расчета премии становится неверным, так как не учитывает этой надбавки. Виды расчетов Оклад и Надбавка являются ведущими по отношению к премии, так как влияют на ее расчет. В случае изменения этих расчетов или ввода новых результат премии необходимо перерасcчитать. Под понятием перерасчет понимается повторный расчет результата записи с учетом произошедших изменений. Система позволяет автоматически отслеживать изменения расчетов, которые могут повлечь перерасчет других записей, и формировать список расчетов, которые необходимо перерасcчитать. Для этого система при вводе расчета анализирует, по отношению к каким другим видам расчета данный вид расчета является ведущим. По сути, все виды расчета, являющиеся базовыми по отношению к данному виду расчета, должны быть одновременно и ведущими по отношению к нему. Это связано с тем, что если данный вид расчета использует результаты базовых расчетов, то при изменении этой базы запись необходимо перерасcчитать. В указанном случае оклад и надбавка составляют базу расчета премии, поэтому логично, что при их изменении нужно заново рассчитать премию. 574 Реализация прикладных задач в системе «1С:Предприятие 8.2» В то же время ведущими расчетами могут быть не только базовые. Ведущими могут быть также расчеты, влияющие на результат данного вида расчета косвенно. Например, вид расчета Невыход, который вытесняет оклад, косвенно влияет на расчет премии, так как при вводе невыхода может измениться сумма оклада. В этом случае Невыход является ведущим по отношению к премии. Такая же ситуация возникает при косвенной зависимости по базе (рис. 5.13). Рис. 5.13. Ведущие виды расчета В данном случае командировка напрямую не входит в базу расчета премии, но влияет на доплату за разъезды, которая, в свою очередь, входит в базу расчета премии. Таким образом, изменение суммы за командировку косвенным образом повлияет на премию. И хотя сама премия не рассчитывается на базе командировки, Командировка будет ведущим видом расчета по отношению к премии. Сторнирование Как уже отмечалось, записи с более поздним периодом регистрации ни при каких обстоятельствах не могут вытеснить по периоду действия записи с более ранним периодом регистрации. Больничный за февраль, введенный в марте, не изменит фактического периода действия февральского оклада. При этом указанные записи в силу настройки вытесняющих видов расчета не могут действовать одновременно, то есть их фактические периоды действия не должны пересекаться. В результате фактический период действия больничного будет пустым. Тем не менее эта ситуация должна быть както учтена, поскольку в этом случае работнику начислен завышенный оклад за февраль. Для решения этой задачи необходимо: ■ в текущем периоде регистрации отменить неправильно начисленную часть оклада; Глава 5. Реализация сложных периодических расчетов 575 ■ позволить больничному иметь непустой фактический период действия, чтобы правильное начисление могло вступить в силу. Эта задача решается вводом в систему корректирующих записей, которые называются сторно-записями. Процесс такой корректировки называется сторнированием. Как было отмечено выше, при формировании фактического периода действия записи учитывается наличие сторно-записей по конкурирующим видам расчета. Ввод в систему таких записей позволит больничному иметь непустой фактический период действия на интервале действия сторнозаписи (рис. 5.14). Рис. 5.14. Сторно-записи В указанном примере изначально был начислен оклад в размере 10 000 рублей за февраль. В марте становится очевидным, что совершена ошибка, так как в середине месяца сотрудник болел. Если просто ввести больничный за февраль с периодом регистрации март, он будет иметь пустой фактический период действия. Чтобы этого избежать, вводится сторно-запись по окладу, которая решает две задачи: ■ отменяет начисление оклада за период болезни (за этот период сотруднику было ошибочно начислено 4 000 рублей по окладу); ■ позволяет больничному иметь непустой фактический период действия, в результате чего сотруднику начисляется 3 000 рублей по больничному листу. В результате этих действий общий результат записей становится верным. Важно понимать, что периодом регистрации сторно-записи будет тот же месяц, которым введен больничный (в данном случае март). Иными словами, если в текущем периоде обнаружена ошибка и нужно внести изменения в предыдущий период, то соответствующая корректирующая запись будет 576 Реализация прикладных задач в системе «1С:Предприятие 8.2» зарегистрирована в текущем периоде. При этом вид расчета сторно-записи такой же, как и в ошибочно введенной записи прошлого периода (в данном случае Оклад). В этой связи стоит еще раз остановиться на принципах формирования фактического периода действия записей. В данном случае при определении фактического периода действия больничного учитывался не только период действия оклада, но и период действия сторно-записи. Таким образом, при формировании фактического периода действия учитывается наличие сторно-записей конкурирующих видов расчета. Этот механизм можно пояснить на следующем примере (рис. 5.15). Рис. 5.15. Учет сторно-записей при формировании фактического периода действия В данном случае больничный, имеющий более поздний период регистрации, имел бы пустой фактический период действия на интервале пересечения с периодом действия дежурства (с 07.03 по 22.03). Однако наличие сторнозаписи позволяет больничному действовать параллельно с дежурством на интервале действия сторно-записи (с 07.03 по 15.03). При этом на интервале с 16.03 по 22.03 фактический период действия больничного будет по-прежнему прерываться, так как на этом интервале не действует сторнозапись по дежурству. Поэтому для того, чтобы больничный мог занять весь свой период действия, сторно-запись должна быть введена с периодом действия 07.03–22.03, то есть на всем интервале пересечения периодов действия дежурства и больничного. Подробнее формирование таких сторнозаписей рассмотрено в разделе «Сторнирование» на стр. 612. Глава 5. Реализация сложных периодических расчетов 577 Планы видов расчета Назначение планов видов расчета Планы видов расчета представляют собой прикладные объекты конфигурации, предназначенные для описания структур данных, в которых хранятся однотипные виды расчета. Для создания и настройки этих объектов предусмотрена отдельная ветка дерева конфигурации Планы видов расчета (рис. 5.16). Рис. 5.16. Планы видов расчета Каждый план видов расчета определяет отдельную структуру данных, где пользователь в режиме 1С:Предприятие может создавать неограниченное число элементов (видов расчета). Созданные виды расчета пользователь впоследствии может изменять и удалять из базы данных. Кроме этого, в режиме Конфигуратор в плане видов расчета можно создать неограниченное количество предопределенных видов расчета. Эти виды расчета также будут доступны для использования в режиме 1С:Предприятие, но со следующими ограничениями: ■ предопределенный вид расчета не может быть удален в режиме 1С:Предприятие; ■ в режиме 1С:Предприятие не могут быть удалены и изменены некоторые свойства предопределенного вида расчета, заданные в режиме Конфигуратор. Об этих свойствах будет подробнее рассказано ниже. В конфигурации может быть создано неограниченное количество планов видов расчета. Планы видов расчета могут различаться между собой по свойствам или по назначению использования. В демонстрационной конфигурации «Сложные периодические расчеты», которая находится на прилагаемом компакт-диске, присутствуют 3 плана видов расчета: ■ ОсновныеНачисления – в этом плане видов расчета хранятся виды расчета, характеризующие начисления, которые являются протяженными во времени, то есть имеют период действия; ■ ДополнительныеНачисления – виды расчетов, хранящиеся в этом плане видов расчета, отражают начисления, не являющиеся протяженными во времени; 578 ■ Реализация прикладных задач в системе «1С:Предприятие 8.2» Удержания – в этом плане видов расчета хранятся виды расчетов, характе- ризующие удержания из зарплаты работников. Таким образом, планы видов расчета ОсновныеНачисления и ДополнительныеНачисления отличаются друг от друга по свойствам, а план видов расчета Удержания отличается еще и назначением использования. Свойства планов видов расчета При создании и настройке плана видов расчета разработчик может влиять на его свойства. Для каждого плана видов расчета задается его Имя, по которому можно обращаться к этому объекту конфигурации, и Синоним, а также Представление объекта, Представление списка и т. п. для представления плана видов расчета в интерфейсе «1С:Предприятия» (рис. 5.17). Рис. 5.17. Имя, синоним и представление объекта плана видов расчета При настройке необходимо указать длину кода и наименования видов расчета, содержащихся в данном плане видов расчета (рис. 5.18). Кроме этого, указывается тип кода (строка или число) и основное представление видов расчета данного плана видов расчета для пользователя: в виде кода или в виде наименования. В зависимости от этой настройки в режиме 1С:Предприятие будет отображаться код или наименование вида расчета в полях, хранящих ссылку на этот вид расчета. Глава 5. Реализация сложных периодических расчетов 579 Рис. 5.18. Код и наименование плана видов расчета Использование указанных выше свойств аналогично их роли при настройке справочников. Кроме этого, у плана видов расчета существуют специфические свойства, определяющие расчетные свойства соответствующих видов расчета. К таким свойствам относятся: ■ Использует период действия. Если в плане видов расчета установлено свойство Использует период действия, то все виды расчета, хранящиеся в данном плане, будут рассматриваться как протяженные во времени (рис. 5.19). Для таких видов расчета применима настройка вытеснения по периоду действия. Планы видов расчета, использующие период действия, можно использовать в регистрах расчета с периодом действия (настройка регистров расчета будет рассмотрена позже). Рис. 5.19. Период действия и зависимость от базы Если свойство не установлено, все виды расчета данного плана видов расчета будут рассматриваться как непротяженные во времени, для них нет смысла настраивать вытеснение. Такие планы видов расчета не могут быть использованы в регистрах расчета с периодом действия. 580 Реализация прикладных задач в системе «1С:Предприятие 8.2» ■ Зависимость от базы. Эта настройка определяет, будет ли в видах расчета данного плана видов расчета использоваться зависимость по базовому периоду. Если переключатель установлен в положение Не зависит, то виды расчета данного плана видов расчета не смогут зависеть по базовому периоду от других видов расчета. Установка переключателя в положение Зависит по периоду действия или Зависит по периоду регистрации позволит устанавливать в видах расчета зависимость по базовому периоду. Различие этих двух вариантов зависимости будет рассмотрено позже. При этом любой вид расчета данного плана видов расчета теоретически может зависеть по базовому периоду от любых других видов расчета, в том числе из других планов видов расчета. Поэтому при настройке зависимости от базы необходимо указать, какие виды расчета могут выступать базовыми для видов расчета данного плана. При этом базовые виды расчета могут принадлежать данному плану счетов или другому плану счетов. Например, виды расчета из плана видов расчета Дополнительные начисления могут зависеть от любых видов расчета этого же плана видов расчета, а также от плана видов расчета Основные начисления. В частности, вид расчета Годовая премия может зависеть по базовому периоду от оклада, принадлежащего плану видов расчета Основные начисления, и премии за месяц, принадлежащей плану видов расчета Дополнительные начисления (рис. 5.20). Рис. 5.20. Зависимость от видов расчета других планов видов расчета Структура планов видов расчета Структура плана видов расчета может существенно меняться в зависимости от его свойств. Общая структура плана видов расчета представлена на рис. 5.21. Если свойство плана видов расчета Длина кода больше 0, все виды расчетов этого плана видов расчета будут иметь предопределенный реквизит Код, тип Глава 5. Реализация сложных периодических расчетов 581 кода будет установлен в зависимости от соответствующей настройки. Если свойство Длина наименования больше 0, то у всех видов расчета будет существовать предопределенный реквизит Наименование типа Строка. Рис. 5.21. Структура плана видов расчета Если у плана видов расчета установлено свойство Использует период действия и одновременно установлена зависимость от базы, у всех видов расчета данного плана видов расчета будет доступен предопределенный реквизит ПериодДействияБазовый (Период действия является базовым периодом) типа Булево. Установка этого свойства у вида расчета будет означать, что при использовании механизма зависимости по базовому периоду вместо базового периода записи с этим видом расчета будет использоваться фактический период действия записи. Для предопределенных видов расчета реквизиты Код, Наименование и ПериодДействияБазовый можно указывать в конфигураторе (рис. 5.22). Рис. 5.22. Создание предопределенного вида расчета 582 Реализация прикладных задач в системе «1С:Предприятие 8.2» При этом код и наименование предопределенных видов расчета пользователь сможет изменить в режиме 1С:Предприятие, а признак Период действия является базовым периодом будет доступен для изменения только в конфигураторе. Помимо указанных реквизитов, разработчик может добавлять в план видов расчета произвольное количество других реквизитов любых типов. Для всех видов расчета, в том числе предопределенных, дополнительные реквизиты могут редактироваться только в режиме 1С:Предприятие. Предопределенные табличные части У всех планов видов расчета независимо от настройки существует предопределенная табличная часть ВедущиеВидыРасчета. Эта табличная часть позволяет для любого вида расчета данного плана видов расчета указать список ведущих расчетов. При этом ведущие расчеты могут выбираться из всех планов видов расчета конфигурации независимо от их настройки. Например, для уже упоминавшейся годовой премии ведущими могут быть виды расчета Оклад из основных и Премия за месяц из дополнительных начислений. У планов видов расчета, использующих период действия, существует также предопределенная табличная часть ВытесняющиеВидыРасчета, в которой для каждого вида расчета задается список вытесняющих видов расчета. В качестве вытесняющих могут выступать только виды расчетов данного плана видов расчета. Если у плана видов расчета установлена зависимость от базы, в его структуре будет присутствовать еще одна предопределенная табличная часть БазовыеВидыРасчета, в которой для каждого вида расчета можно указать список базовых видов расчета. При этом в качестве базовых могут выступать только виды расчета тех планов видов расчета, которые отмечены в качестве базовых в свойствах данного плана видов расчета на закладке Расчет. Все три предопределенные табличные части имеют единственный предопределенный реквизит (колонку) – ВидРасчета. Состав реквизитов (колонок) предопределенных табличных частей не может быть изменен. Для предопределенных видов расчета эти табличные части могут быть заполнены в режиме Конфигуратор, но только видами расчета, также являющимися предопределенными. Эта настройка производится на соответствующих закладках формы предопределенного вида расчета (рис. 5.23). Глава 5. Реализация сложных периодических расчетов 583 Рис. 5.23. Настройка базовых, вытесняющих и ведущих видов расчета Чтобы добавить в одну из предопределенных табличных частей вид расчета, не являющийся предопределенным, необходимо перейти в режим 1С:Предприятие. Помимо предопределенных табличных частей разработчик может создать произвольное количество дополнительных табличных частей с любым составом реквизитов (колонок). Редактирование таких табличных частей, в том числе для предопределенных видов расчета, доступно только в режиме 1С:Предприятие. Проверки, выполняемые при записи вида расчета При записи вида расчета система производит ряд проверок на отсутствие конфликтов при заполнении свойств и предопределенных табличных частей. Проверки в предопределенных видах расчета Если вид расчета является предопределенным (введен в конфигураторе), то при записи объекта в режиме 1С:Предприятие система будет выполнять следующие проверки: ■ Проверка изменения свойства ПометкаУдаления. Как уже отмечалось, пользователь в режиме 1С:Предприятие не может интерактивно установить или снять пометку удаления с предопределенного вида расчета. Эти изменения доступны только средствами встроенного языка. При попытке изменить это свойство интерактивно будет выдано предупреждение «Пометка на удаление предопределенного вида расчета запрещена». ■ Проверка изменения свойства ПериодДействияБазовый. Для предопределенных видов расчета свойство Период действия является базовым периодом может быть изменено только из конфигуратора либо средствами встроенного языка. При попытке изменить его интерактивно в режиме 1С:Предприятие будет выдано предупреждение «Изменены свойства предопределенного вида расчета». 584 Реализация прикладных задач в системе «1С:Предприятие 8.2» ■ Проверка модификации предопределенных табличных частей. У предопределенного вида расчета в режиме 1С:Предприятие не допускается модификация или удаление строк табличных частей ведущих, вытесняющих и базовых видов расчетов, заданных в конфигураторе. В режиме 1С:Предприятие можно добавлять новые строки в эти таблицы. Проверки предопределенных табличных частей Во всех видах расчета (не только предопределенных) при записи производятся следующие системные проверки табличных частей ВедущиеВидыРасчета, БазовыеВидыРасчета и ВытесняющиеВидыРасчета. Проверка повторяющихся строк. В каждой из предопределенных табличных частей производится проверка дублирующихся значений колонки ВидРасчета. Недопустимо, например, в список базовых видов расчета внести несколько раз один и тот же вид расчета. В этом случае будет выдано предупреждение «Дублирование базовых видов расчета». Проверка «зацикливания» вытесняющих видов расчета. В таблице ВытесняющиеВидыРасчета производится проверка отсутствия конфликтов при настройке вытеснения одного расчета другим. Если в списке вытесняющих указан вид расчета, который прямо или косвенно вытесняется текущим (записываемым) видом расчета, то механизм вытеснения по периоду действия не сможет сработать, так как непонятно, как будут конкурировать за период действия эти виды расчета. Например, если для оклада указан вытесняющий вид расчета Командировка, то при попытке указать оклад как вытесняющий в командировке возникнет ошибка «Вытесняющий вид расчета вытесняется текущим!» (рис. 5.24). Рис. 5.24. Проверка «зацикливания» вытесняющих видов расчета При этом проверяются табличные части всех видов расчета, являющихся вытесняющими (в данном плане счетов), а не только тех, которые указаны для данного вида расчета. Дело в том, что текущий вид расчета может вытесняться не напрямую, а опосредованно, через другие виды расчета. Глава 5. Реализация сложных периодических расчетов 585 Например, вытеснение видов расчета может быть настроено так, как показано на рис. 5.25. Рис. 5.25. Проверка «зацикливания» вытесняющих видов расчета В данном случае система не позволит указать оклад в списке вытесняющих для командировки, так как сама командировка вытесняет оклад косвенно через вытеснение вида расчета Дежурство. Таким образом, проверка выполняется рекурсивно, и будет выявлена сколь угодно длинная цепочка взаимного вытеснения. Проверка полноты списка вытесняющих видов расчета. При записи вида расчета система требует указания полного списка вытесняющих расчетов. Это означает, что в списке должны присутствовать все виды расчета, вытесняющие текущий не только напрямую, но и косвенно. Например, если в список вытесняющих для оклада включен вид расчета Дежурство, который, в свою очередь, вытесняется командировкой, то система потребует включить в список еще и командировку. В противном случае при записи элемента возникнет ошибка «Неполный список вытесняющих расчетов» (рис. 5.26). Рис. 5.26. Проверка полноты списка вытесняющих видов расчета Таким образом, все виды расчетов, вытесняющие текущий косвенно, необходимо также включить в табличную часть ВытесняющиеВидыРасчета. Проверка полноты списка ведущих расчетов. По аналогичной схеме проверяется табличная часть ВедущиеВидыРасчета. Если в табличной части 586 Реализация прикладных задач в системе «1С:Предприятие 8.2» не указан вид расчета, который является ведущим косвенно (через влияние на другой вид расчета), то система выдаст ошибку «Неполный список ведущих видов расчета». Так как ведущими могут быть виды расчета любого плана видов расчета, при проверке полноты списка будут анализироваться данные всех планов видов расчета конфигурации. Проверка правильного заполнения предопределенных табличных частей производится в момент записи вида расчета. При этом запись вида расчета может быть инициирована в следующих случаях: ■ При интерактивной записи вида расчета в режиме 1С:Предприятие. ■ При записи вида расчета средствами встроенного языка (использование метода Записать() объекта ПланВидовРасчетаОбъект). ■ При реструктуризации базы данных после изменения конфигурации. Так как для предопределенных видов расчета возможно редактирование табличных частей в конфигураторе, при обновлении конфигурации базы данных должна производиться проверка табличных частей всех видов расчета. При этом учитываются не только предопределенные строки этих таблиц, но и введенные в режиме 1С:Предприятие. Структура таблиц базы данных Для каждого плана видов расчета в системе хранится основная таблица, а также отдельные таблицы на каждую табличную часть (как предопределенную, так и добавленную разработчиком). Основная таблица содержит все виды расчета данного плана видов расчета с указанием предопределенных свойств, а также реквизитов, добавленных разработчиком. Основная таблица имеет структуру, представленную в табл. 5.1. ПериодДействияБазовый ЛОЖЬ ЛОЖЬ ИСТИНА ЛОЖЬ ЛОЖЬ ЛОЖЬ ЛОЖЬ ЛОЖЬ ЛОЖЬ ЛОЖЬ ИСТИНА ЛОЖЬ Реквизит N ПометкаУдаления Оклад Командировка Сдельный Больничный … Предопределенный 00001 00002 00003 00004 Реквизит 1 Наименование * * * * Код Ссылка Таблица 5.1. Структура основной таблицы плана видов расчета Глава 5. Реализация сложных периодических расчетов 587 Независимо от настройки плана видов расчета в основной таблице будут присутствовать поля Ссылка, Предопределенный и ПометкаУдаления. Поле Ссылка хранит внутренний уникальный идентификатор каждого вида расчета в базе данных. В полях Предопределенный и ПометкаУдаления, имеющих тип Булево, хранится информация о том, является ли данный вид расчета предопределенным и помечен ли он на удаление. Поля Код и Наименование присутствуют в таблице в том случае, если в свойствах плана видов расчета для соответствующих полей установлена ненулевая длина. Поле ПериодДействияБазовый присутствует в таблицах тех планов видов расчета, которые используют период действия и зависят от базы. Кроме этого, в основной таблице могут присутствовать дополнительные поля любых типов для каждого реквизита, введенного разработчиком. Для каждой из предопределенных табличных частей в базе хранится отдельная таблица. Для всех предопределенных табличных частей структура таблицы одинакова (на примере табличной части ВытесняющиеВидыРасчета), табл. 5.2. Таблица 5.2. Таблица предопределенной табличной части «ВытесняющиеВидыРасчета» Ссылка Номер cтроки ВидРасчета Предопределенный *Оклад *Оклад *Оклад *Дежурство 1 2 3 1 *Больничный *Дежурство *Командировка *Командировка ЛОЖЬ ЛОЖЬ ЛОЖЬ ЛОЖЬ Набор полей этих таблиц не зависит от настроек плана видов расчета и одинаков для всех предопределенных табличных частей. В поле Ссылка хранится ссылка на вид расчета (строку основной таблицы), которому данная строка табличной части принадлежит, то есть внутренний идентификатор этого вида расчета (здесь условно обозначен как наименование со знаком *). Таким образом, все строки этой таблицы со ссылкой на оклад представляют собой предопределенную табличную часть вида расчета Оклад. Строка табличной части не является ссылочным типом, поэтому собственной ссылки не имеет. Значение поля НомерСтроки формируется системой автоматически как порядковый номер строки табличной части в рамках данной ссылки. В рамках одного вида расчета (ссылки) номера строк таблицы уникальны. При помощи этого поля можно отличить одну строку табличной части от другой. Кроме этого, номер строки определяет порядок следования строк в табличной части. 588 Реализация прикладных задач в системе «1С:Предприятие 8.2» В поле ВидРасчета хранится ссылка на вид расчета (строку основной таблицы), выбранный в табличной части. Например, в приведенном примере для вида расчета Оклад в качестве вытесняющих указаны виды расчета Больничный, Дежурство и Командировка. Тип поля ВидРасчета для всех предопределенных табличных частей может быть разным. Для таблицы ВытесняющиеВидыРасчета – это ссылка на текущий план видов расчета; ВедущиеВидыРасчета – составной тип, включающий ссылку на любой план видов расчета; БазовыеВидыРасчета – составной тип, определяемый настройками зависимости от базы текущего плана видов расчета. Поле Предопределенный хранит информацию о том, является ли данная строка табличной части заданной предопределенно в конфигураторе. Таблица ВедущиеВидыРасчета формируется в базе данных для всех планов видов расчета. Наличие таблиц для остальных предопределенных табличных частей определяется настройками плана видов расчета, о которых было сказано выше. Таблицы для табличных частей плана видов расчета, введенных разработчиком, будут иметь структуру, показанную в табл. 5.3. Таблица 5.3. Таблица табличной части плана видов расчета Ссылка Номер cтроки *Оклад *Оклад *Дежурство 1 2 1 Реквизит 1 … Реквизит N Поля Ссылка и НомерСтроки будут присутствовать во всех таких таблицах и выполнять такие же функции, как и для предопределенных табличных частей. Кроме этого, для каждого реквизита табличной части, введенного разработчиком, в таблице будет предусмотрено соответствующее поле. Регистры расчета Назначение регистров расчета Регистры расчета – это прикладные объекты конфигурации, предназначенные для периодической регистрации данных о произведенных расчетах для определенных целей. Регистров расчета может быть неограниченное количество. Для их создания и настройки предусмотрена отдельная ветка дерева объектов конфигурации (рис. 5.27). Глава 5. Реализация сложных периодических расчетов 589 Рис. 5.27. Регистры расчета Помимо собственно регистрации записей, регистры расчета обеспечивают правильное отображение взаимосвязей расчетов, о которых шла речь выше. Именно регистры расчета позволяют рассчитывать записи по базе, производить вытеснение записей, формировать сторно-записи. Кроме этого, регистры расчета обеспечивают учет протяженных во времени расчетов, хранят период действия и фактический период действия записей. Для расчетов, зависящих от базового периода, регистр расчета также хранит данные о базовом периоде. Иными словами, хотя взаимозависимость видов расчета настраивается в планах видов расчета, расчетные механизмы платформы заложены именно в регистры расчета. Свойства регистров расчета Настройка свойств регистра расчета определяет его способность использовать описанные выше расчетные механизмы платформы (рис. 5.28). Рис. 5.28. Свойства регистра расчета 590 Реализация прикладных задач в системе «1С:Предприятие 8.2» Основная задача регистра расчетов – периодическая регистрация записей о расчетах. Поэтому главными свойствами регистра являются его периодичность, а также виды расчетов, которые в нем будут регистрироваться. Свойство Периодичность регистра расчетов определяет размерность периодов, для которых будет вестись учет в этом регистре. При настройке регистра доступны следующие виды периодичности: Год, Квартал, Месяц и День. Соответственно, записи в таком регистре будут фиксироваться в привязке к конкретному году, кварталу, месяцу или дню. Периодичность регистра определяет вид периода регистрации записей и зависит от задачи, которую он решает. Для целей расчета зарплаты, как правило, применяют регистры с периодичностью Месяц. В одном регистре расчета могут регистрироваться записи только с видами расчета из одного плана видов расчета. Используемый в данном регистре план видов расчета указывается в свойстве регистра План видов расчета. При этом регистров, использующих один план видов расчета, может быть несколько. Свойство Период действия определяет, можно ли будет в данном регистре учитывать записи, протяженные во времени. Установленное свойство Период действия позволяет для каждой записи хранить не только период регистрации, но и период действия, отражающий протяженность этой записи. Кроме этого, установка этого свойства означает, что в данном регистре будет задействован механизм вытеснения и будет формироваться фактический период действия записей. Для того чтобы учитывать протяженные во времени записи, в плане видов расчета, используемом в данном регистре, должно быть установлено свойство Использует период действия. Если свойство регистра расчета Период действия не установлено, то регистрируемые записи не будут иметь периода действия и, соответственно, протяженности во времени. В таком регистре не будет использоваться механизм вытеснения. Тем не менее, в регистре без периода действия может быть назначен план видов расчета, использующий период действия. Например, план видов расчета ОсновныеНачисления, использующий период действия, может регистрироваться как в регистре, где будет происходить расчет зарплаты (в этом регистре период действия необходим для расчета), так и в регистре, где начисления учитываются для целей налогообложения (в этом регистре период действия не нужен), рис. 5.29. В данном случае один и тот же вид расчета из плана видов расчета, использующего период действия, зарегистрирован в двух разных регистрах, в одном из которых период действия учитывается, в другом – нет, так как в нем нет необходимости. Глава 5. Реализация сложных периодических расчетов 591 Рис. 5.29. Использование плана видов расчета разными регистрами расчета Если в регистре будут учитываться записи, протяженные во времени, то необходимо настроить для данного регистра свойство График. При расчете записей, являющихся протяженными во времени, часто значимость периода действия этих записей не является равномерной, то есть отдельные его части имеют различную значимость. Например, если человек дежурил с 1 по 15 сентября, то этот интервал будет периодом действия этой записи. Однако в рамках этого периода не все дни могут являться одинаковыми. Например, человек работает различное количество часов в разные дни, а в какие-то дни у него выходные. Неравномерность значимости периода описывается при помощи графика. График хранит определенное значение для каждой даты года, соответственно, используя график, можно оценить значимость любого периода (рис. 5.30). Рис. 5.30. Неоднородность периода 592 Реализация прикладных задач в системе «1С:Предприятие 8.2» В приведенном примере график хранит количество рабочих часов в рамках каждого календарного дня. В данном случае количество часов и есть число, отражающее значимость каждого дня в периоде. Полные рабочие дни имеют значимость 8 (рабочих часов), сокращенные дни – 6, а выходные и праздничные дни имеют нулевую значимость. График в системе должен быть создан разработчиком самостоятельно как непериодический регистр сведений, у которого как минимум одно измерение типа Дата и как минимум один ресурс типа Число (рис. 5.31). Рис. 5.31. График регистра расчета Разработчик может создавать и более сложную структуру регистра, но указанные измерение и ресурс там должны присутствовать обязательно. Для того чтобы привязать график к регистру расчета, необходимо в поле График свойств регистра указать нужный регистр сведений. После этого в поле Значение графика нужно указать ресурс этого регистра сведений, который является значением графика. В поле Дата графика указывается измерение регистра, которое является датой графика. Необходимость указания этих полей связана с тем, что в регистре может быть более одного измерения и более одного ресурса, поэтому поля даты и значения графика должны быть указаны явно. Подробнее работа с графиками описана в разделе «Настройка протяженных во времени расчетов» на стр. 602. Свойство регистра расчета Базовый период позволяет хранить в регистре базовый период записей и, соответственно, использовать механизм зависимости по базовому периоду. Только для записей регистров расчета с установленным свойством Базовый период возможно получение значения базы. При этом свойство Базовый период устанавливается независимо от свойства Зависимость от базы выбранного плана видов расчета. Даже если в плане видов расчета установлена зависимость от базы, в регистре свойство Базовый период может быть не установлено. В этом случае в данном регистре использование зависимости по базовому периоду будет недоступно. Глава 5. Реализация сложных периодических расчетов 593 Структура регистров расчета В зависимости от настроек регистра расчетов его структура будет различной. Общая схема структуры регистра расчета показана на рис. 5.32. Рис. 5.32. Структура регистра расчета Предопределенные поля Таким образом, в простейшем регистре расчета без периода действия и базового периода всегда будут присутствовать следующие поля: ■ Регистратор – ссылка на документ, который ввел запись в регистр. ■ Период регистрации – период регистра расчета, к которому относится данная запись. Размер периода определяется периодичностью регистра расчета. ■ Вид расчета – ссылка на вид расчета, используемый в данной записи. ■ Номер строки – порядковый номер записи в рамках данного регистратора. В рамках одного документа-регистратора номера строк уникальны, таким образом, совокупность значений Регистратор и НомерСтроки позволяет идентифицировать конкретную запись регистра расчета. ■ Активность – признак активности данной записи. Запись влияет на учет только в том случае, если активность установлена в значение Истина. Данное поле используется в документах прямой записи в регистр. 594 Реализация прикладных задач в системе «1С:Предприятие 8.2» В таких документах не хранятся данные, необходимые для формирования движений по регистру. Ввод записей производится напрямую в регистр, через вывод на форму документа таблицы с привязкой к набору записей этого регистра. В демонстрационной конфигурации «Сложные периодические расчеты», которая находится на прилагаемом компакт-диске, таким документом является РучнойВводНачислений. Типичным примером использования такого же принципа является документ Операция в решениях по бухгалтерскому учету. При пометке на удаление такого документа нельзя удалять записи из регистра, так как их нельзя будет восстановить. Вместо этого у записей регистра расчета, введенных этим документом, свойство Активность устанавливается в значение Ложь. При этом записи не удаляются из базы данных, но перестают влиять на учет. При необходимости снова задействовать эти записи достаточно установить свойство Активность в значение Истина. Именно это происходит при снятии пометки на удаление с такого документа. ■ Сторно – это признак типа Булево, который обозначает, является ли данная запись сторно-записью. Сторно-записи записываются в регистр со значением Истина в этом поле. Если у регистра установлено свойство Период действия, то в структуре появляются следующие предопределенные поля: ■ ПериодДействияНачало – дата, обозначающая начало интервала периода ■ ПериодДействияКонец – дата, обозначающая конец интервала периода действия записи. действия записи. ПериодДействия – дата, отражающая период регистра расчета, в котором действовала запись. Эта дата всегда имеет значение начала первого дня соответствующего периода (по аналогии с полем ПериодРегистрации). Примеры заполнения этих полей для регистров разной периодичности приведены на рис. 5.33. Таким образом, запись с одним и тем же интервалом периода действия при записи в регистры разной периодичности будет иметь различное значение поля ПериодДействия. Это будет начало месяца в случае помесячного расчета, начало квартала при поквартальном расчете и т. д. ■ У регистров, для которых установлено свойство Базовый период, в структуре будут присутствовать следующие поля: ■ БазовыйПериодНачало – дата начала интервала базового периода. ■ БазовыйПериодКонец – дата окончания интервала базового периода. Глава 5. Реализация сложных периодических расчетов 595 Рис. 5.33. Пример заполнения полей «ПериодДействияНачало», «ПериодДействияКонец» и «ПериодДействия» Поля, добавляемые при разработке Для каждого регистра расчета необходимо продумать структуру измерений, ресурсов и реквизитов, исходя из особенностей учетной задачи. Регистр расчета может и не иметь ни измерений, ни ресурсов, ни реквизитов. В этом случае в регистре можно вести периодический учет записей с различными видами расчета без привязки к конкретным объектам (например, сотрудникам) и без сохранения числовых результатов расчетов (например, суммы начисления). При этом в регистре можно использовать период действия, будут работать механизмы вытеснения записей и перерасчетов, а также механизм зависимости по базовому периоду. При этом механизм зависимости по базовому периоду не позволит получить расчетную базу. Возможности регистра расчета в такой ситуации сильно ограничены, поэтому для решения прикладных задач, как правило, необходимо задать измерения, ресурсы и реквизиты регистра. 596 Реализация прикладных задач в системе «1С:Предприятие 8.2» Измерения регистров расчета Ввод измерений регистров расчета позволяет обозначить объект учета и расчета. При отсутствии измерений регистра расчетные механизмы действуют в рамках всех записей. Например, в этом случае любая запись о больничном приведет к вытеснению всех записей об окладе, для которых произойдет пересечение периодов действия. В результате добавления в регистр измерения ФизЛицо работа регистра изменится следующим образом: при вводе больничного по сотруднику Иванов будут вытеснены только записи об окладе по сотруднику Иванов за соответствующий период действия. На рис. 5.34 представлен регистр без измерений, где ссылка на сотрудника хранится в реквизите, а также регистр, где ссылка на сотрудника хранится в измерении ФизЛицо. Сплошными стрелками указано вытеснение записей. Рис. 5.34. Использование измерений регистра расчета Такое же разделение произойдет и для механизма зависимости по базовому периоду. Так, при расчете месячной премии конкретного сотрудника в базу расчета можно будет включить оклады только этого сотрудника за базовый период расчета. Измерения регистров расчета могут иметь произвольный тип. К формированию структуры измерений нужно подходить аккуратно, так как они имеют специфику, отличную, например, от регистров накопления. Измерения регистров расчета не связаны с получением аналитики в определенных разрезах. Глава 5. Реализация сложных периодических расчетов 597 ВНИМАНИЕ! Например, если необходимо учитывать все начисления в разрезе статей затрат, не нужно добавлять измерение СтатьяЗатрат! Это приведет к нарушению учета, потому что, например, оклад со статьей затрат Основная з/п в этом случае не будет вытеснен командировкой со статьей затрат Командировочные, так как у этих записей разные значения измерений. Статья затрат в данном случае должна быть реквизитом регистра расчета. Свойство «Базовое» измерения регистра расчета Состав измерений регистра расчета имеет существенное значение при использовании механизма зависимости по базовому периоду. В разделе «Настройка зависимости по базовому периоду» на стр. 618 будут подробно рассмотрены методы получения базы для записи регистра расчета. При этом существует возможность получать базу с учетом значений определенных измерений регистра расчета. Это означает, что система при получении базы будет связывать таблицу регистра расчета вычисляемой записи с таблицами базовых регистров расчета, и в этих связях будет использоваться соединение по измерениям текущего регистра. Например, при получении базы для премии системой может быть выполнено следующее соединение таблиц (рис. 5.35). Рис. 5.35. Пример соединения таблиц при получении базы 598 Реализация прикладных задач в системе «1С:Предприятие 8.2» В данном случае таблица регистра расчета дополнительных начислений будет соединена с таблицей регистра основных начислений для получения базы. При этом помимо соединения по измерениям будет присутствовать соединение по периодам, но при изучении данного вопроса мы его опускаем. На больших объемах данных такое соединение может выполняться достаточно долго. Для того чтобы ускорить выполнение такого запроса, необходимо создать индексы по полям, входящим в условие соединения, в данном случае это измерения ФизЛицо и Организация. Если бы такое измерение было только одно, то эта проблема решалась бы установкой свойства Индексирование у соответствующего измерения, однако в данном случае необходим составной индекс, включающий оба поля. Для оптимизации получения базы по двум и более измерениям предусмотрено свойство Базовое измерения регистра расчета. При установке этого свойства у измерений система создаст дополнительные индексы таблицы регистра расчета следующей структуры (табл. 5.4). Таблица 5.4. Дополнительные индексы таблицы регистра расчета Состав индекса Пояснение ПериодРегистрации + [БазовоеИзмерение1]+[БазовоеИзмерение2]+… Если базовые измерения не заданы, то просто ПериодРегистрации Если базовые измерения не заданы, то отсутствует Если базовые измерения не заданы, то просто ПериодДействия Если базовые измерения не заданы, то отсутствует [БазовоеИзмерение1]+[БазовоеИзмерение2]+ ПериодРегистрации +… ПериодДействия + [БазовоеИзмерение1]+[БазовоеИзмерение2]+… [БазовоеИзмерение1]+[БазовоеИзмерение2]+ ПериодДействия +… При этом базовые измерения в индексе будут следовать в том порядке, в котором они заданы в конфигураторе. Такая структура индекса позволяет оптимизировать выполнение запросов на получение базы с соединением таблиц по набору измерений, которые отмечены как базовые. Поэтому для оптимизации работы решения следует отмечать как базовые те измерения регистров расчета, которые наиболее часто будут использованы при получении базы. Таким образом, свойство Базовое измерения регистра расчета не влияет на логику работы конфигурации, а влияет только на производительность запросов, получающих базу. Глава 5. Реализация сложных периодических расчетов 599 Ресурсы регистров расчета Состав ресурсов регистра расчета влияет на возможность получения расчетной базы по данному регистру для записей данного регистра или других регистров. Например, если в регистре основных начислений есть ресурс Результат, хранящий рассчитанную сумму начисления, то для записей этого или другого регистра можно получить расчетную базу по этому полю, то есть сумму начислений всех записей по базовым видам расчета за базовый период. Если числовой показатель необходимо хранить в регистре, но в расчете по базе он не участвует, то такой показатель должен быть введен в структуру регистра как реквизит. Например, поле Размер начисления, отражающее тариф, по которому был рассчитан оклад или размер процента для начисления премии, не должно вводиться в регистр как ресурс, так как получать базу по этому полю бессмысленно. Ресурсы регистров расчета всегда имеют тип Число (рис. 5.36). Рис. 5.36. Ресурсы регистра расчета В приведенном примере база расчета премии будет содержать данные по всем ресурсам регистра основных начислений. В данном случае можно получить сумму базовых начислений (ресурс Результат) и общее количество отработанных дней в зачет (ресурс Дни). В данном примере в ресурсе Дни сохраняется значение количества отработанных дней для целей последующего расчета оплаты по среднему заработку. При расчете по среднему через механизм зависимости по базовому периоду можно будет получить как данные о сумме заработка, так и о количестве дней, засчитанных в отработанное время. 600 Реализация прикладных задач в системе «1С:Предприятие 8.2» Реквизиты регистров расчета Реквизиты регистра расчета – это произвольные дополнительные поля, которые необходимо хранить в регистре. Эти данные могут использоваться как при расчете записи, так и для формирования отчетов по регистру расчета. Например, реквизит РазмерНачисления участвует в формуле расчета записей, а реквизит СтатьяЗатрат может использоваться как группировка или отбор в отчете по начислениям. Добавление в регистр нового реквизита не оказывает принципиального влияния на учет и работу данного регистра (за исключением случаев, когда реквизит связан с графиком, см. раздел «Настройка протяженных во времени расчетов» на стр. 602). Структура таблиц базы данных Данные каждого регистра расчета в базе данных хранятся в виде одной основной таблицы. Структура таблицы определяется настройками регистра. В зависимости от настроек таблица будет содержать предопределенные поля, а также поля, добавленные разработчиком (табл. 5.5). Какими настройками определяется существование в таблице этих полей, а также их предназначение описано в разделе «Структура регистров расчета» на стр. 593. 2 Командировка *Начисление зарплаты № 1 3 Оклад *Начисление зарплаты № 2 1 Оклад *Начисление зарплаты № 2 2 Надбавка БазовыйПериодКонец 28. 02. 10 24. 02. 10 28. 02. 10 31. 03. 10 31. 03. 10 БазовыйПериодНачало 01. 02. 10 14. 02. 10 01. 02. 10 01. 03. 10 01. 03. 10 01. 28. 02. 02. 10 10 Сторно *Начисление зарплаты № 1 01. 02. 10 01. 02. 10 01. 02. 10 01. 03. 10 01. 03. 10 Активность Оклад ПериодДействияКонец 1 ПериодДействияНачало ВидРасчета Номер cтроки *Начисление зарплаты № 1 ПериодДействия 01. 02. 10 01. 02. 10 01. 02. 10 01. 03. 10 01. 03. 10 Регистратор ПериодРегистрации Таблица 5.5. Таблица регистра расчета ИСТИНА ЛОЖЬ ИСТИНА ЛОЖЬ ИСТИНА ЛОЖЬ ИСТИНА ЛОЖЬ ИСТИНА ЛОЖЬ Глава 5. Реализация сложных периодических расчетов 601 В данной таблице поля ПериодРегистрации, Регистратор, НомерСтроки, ВидРасчета, Активность и Сторно присутствуют в таблице регистра независимо от его настроек. Поля ПериодДействия, ПериодДействияНачало, ПериодДействияКонец, БазовыйПериодНачало и БазовыйПериодКонец будут присутствовать в таблице в зависимости от настроек, указанных выше. Кроме указанных полей, в таблице присутствуют дополнительные поля на каждое добавленное разработчиком измерение, ресурс и реквизит. Важно помнить, что в полях ПериодРегистрации и ПериодДействия хранятся даты начала соответствующего расчетного периода. Это нужно учитывать при построении отчетов. Например, при построении отчета по начислениям с условием по периоду действия с 03.02.2010 по 28.02.2010 в выборку не попадет ни одна запись, так как все записи, у которых период действия приходится на февраль, будут в поле ПериодДействия содержать значение 01.02.2010 00:00:00. Для регистров, использующих период действия, данные о фактическом периоде действия записей не хранятся в основной таблице. Для хранения этих данных для каждого такого регистра существует отдельная физическая таблица следующей структуры (табл. 5.6). Таблица 5.6. Таблица фактического периода действия Регистратор Дата начала Номер строки интервала *Начисление зарплаты № 1 1 *Начисление зарплаты № 1 1 *Начисление зарплаты № 1 2 01.02.2010 25.02.2010 01.02.2010 Дата окончания интервала 13.02.2010 28.02.2010 28.02.2010 Названия полей приведены условно, так как таблица не предназначена для работы напрямую средствами встроенного языка. Заполнение таблицы производится системой автоматически при записи в регистр расчета с формированием фактического периода действия. Чтение данных этой таблицы доступно в запросе через виртуальную таблицу ФактическийПериодДействия или специальными методами встроенного языка. Работа с этими методами подробно рассмотрена в разделе «Использование механизма вытеснения», на стр. 602. Значения полей Регистратор и Номер строки однозначно указывают на запись основной таблицы, то есть запись регистра расчета. Для каждой записи основной таблицы, то есть для каждой пары значений регистратора и номера строки, в таблице могут храниться несколько непересекающихся интервалов фактического периода действия, даты начала и окончания которых хранятся в соответствующих полях таблицы. Если запись имеет пустой фактический период действия, в физической таблице даты начала и окончания интервала фактического периода действия для такой записи будут равны значению даты по умолчанию ('01.01.0001 00:00:00'). 602 Реализация прикладных задач в системе «1С:Предприятие 8.2» Настройка протяженных во времени расчетов Использование механизма вытеснения Настройка планов видов расчета и регистров расчета Для организации учета протяженных во времени расчетов у плана видов расчета должно быть установлено свойство Использует период действия. Это позволит настраивать в видах расчета взаимное вытеснение путем заполнения предопределенной табличной части ВытесняющиеВидыРасчета. В используемом регистре расчета должно быть установлено свойство ПериодДействия, а также привязан график. При такой настройке все записи регистра помимо периода регистрации будут хранить данные о периоде действия, то есть о протяженности во времени. Формирование фактического периода действия При формировании записи в регистре расчета, поддерживающем период действия, происходит анализ конкуренции за период действия вводимого вида расчета с существующими в регистре записями. Результатом такой конкуренции будет изменение фактического периода действия вводимой или существующих записей. Понятие фактического периода действия применимо только к конкретной записи регистра расчета. При этом данные о фактическом периоде действия не хранятся в основной таблице регистра расчета, но могут быть получены системными средствами, о которых речь пойдет ниже. Фактический период действия записи можно представить в виде таблицы следующего вида (табл. 5.7). Таблица 5.7. Фактический период действия ДатаНачала ДатаОкончания 01.02.2010 18.02.2010 13.02.2010 28.02.2010 Каждая строка этой таблицы представляет собой один интервал фактического периода действия. При отсутствии вытесняющих записей результатом формирования фактического периода действия будет одна строка таблицы. Интервал, заданный в этой строке, будет совпадать с периодом действия записи. При изменении фактического периода действия в результате ввода вытесняющих записей содержимое таблицы меняется, в ней остаются только интервалы, на которых запись не вытеснена другими записями. Пример изменения фактического периода действия приведен на рис. 5.37. Глава 5. Реализация сложных периодических расчетов 603 Рис. 5.37. Изменение фактического периода действия Таким образом, при вытеснении записи период действия не меняется, изменяется только состав таблицы фактического периода действия. При формировании фактического периода действия происходит анализ конкуренции записей только в рамках данного регистра расчета. Иными словами, запись регистра расчета может вытеснять только записи этого же регистра. При анализе конкуренции видов расчета на пересечении периодов действия учитывается период регистрации записей. Если запись с вытесняющим видом расчета имеет более поздний период регистрации, чем запись с вытесняемым видом расчета, механизм вытеснения работать не будет. При этом конкурирующие записи все равно не могут иметь пересекающийся период действия, поэтому фактический период действия записи с более поздним периодом регистрации будет пустым на интервале пересечения. При формировании фактического периода действия учитывается наличие в анализируемом периоде сторно-записей по конкурирующим видам расчета. Если на интервале пересечения конкурирующих видов расчета присутствуют сторно-записи, то фактический период действия записи с более поздним периодом регистрации будет непустым на интервале периода действия сторно-записи конкурирующего вида расчета. Получение фактического периода действия при помощи запроса Для получения фактического периода действия при помощи запроса предусмотрена виртуальная таблица фактического периода действия. Структура полей этой таблицы полностью идентична структуре основной таблицы регистра расчета. Единственное ее отличие от основной таблицы состоит в том, что поля ПериодДействияНачало и ПериодДействияКонец обозначают не собственно период действия, а интервал фактического периода действия. 604 Реализация прикладных задач в системе «1С:Предприятие 8.2» Если фактический период действия записи задается несколькими интервалами, то в виртуальной таблице такая запись будет представлена несколькими строками (рис. 5.38). Рис. 5.38. Фактический период действия В каждой из этих строк все данные повторяют данные строки основной таблицы, за исключением полей ПериодДействияНачало и ПериодДействияКонец, которые обозначают границы интервалов фактического периода действия. Пример запроса, который считает количество календарных дней фактического периода действия каждой записи документа, представлен в листинге 5.1. Листинг 5.1. Получение количества календарных дней фактического периода действия запросом Запрос = Новый Запрос; Запрос.Текст = " |ВЫБРАТЬ | ФактическийПериод.НомерСтроки, | СУММА(РАЗНОСТЬДАТ(ФактическийПериод.ПериодДействияНачало, | КОНЕЦПЕРИОДА(ФактическийПериод.ПериодДействияКонец, ДЕНЬ), | ДЕНЬ)) + 1 КАК КоличествоДней |ИЗ | РегистрРасчета.ОсновныеНачисленияРегл.ФактическийПериодДействия( | Регистратор = &Регистратор) КАК ФактическийПериод | |СГРУППИРОВАТЬ ПО | ФактическийПериод.НомерСтроки"; Запрос.УстановитьПараметр("Регистратор", Ссылка); Выборка = Запрос.Выполнить().Выбрать(); Пока Выборка.Следующий() Цикл Сообщение = Новый СообщениеПользователю(); Сообщение.Текст = "Количество дней фактического периода для строки № " + Выборка.НомерСтроки + " : " + Выборка.КоличествоДней; Сообщение.Сообщить(); КонецЦикла; Глава 5. Реализация сложных периодических расчетов 605 ВНИМАНИЕ! В запросе при получении фактического периода действия используется функция КонецПериода(). Но лучше сразу при записи движений в регистр расчета обеспечить попадание в регистр даты с «правильным» (на конец дня) временем. Для этого при записи движений в регистр расчета нужно написать, например, Движение.ПериодДействияКонец = КонецДня(ТекСтрокаНачисления.ДатаОкончания). Этот фрагмент присутствует в обработке ДанныеРегистраРасчета в демонстрационной конфигурации «Сложные периодические расчеты», которая находится на прилагаемом компакт-диске. Необходимо очень внимательно подходить к установке параметров виртуальных таблиц. Виртуальная таблица по сути представляет собой запрос, который платформа самостоятельно строит по таблицам базы данных. Виртуальная таблица фактического периода действия формируется запросом по основной таблице регистра расчета и таблице фактического периода действия. У этой таблицы присутствует единственный параметр Условие. Если его заполнить, можно передать определенное условие в запрос платформы, формирующий виртуальную таблицу. В данном случае нас интересует фактический период действия только по движениям одного документа, поэтому в параметр Условие необходимо передать текст Регистратор = &Регистратор, после чего указать ссылку на документ как значение параметра Регистратор. В этом случае в виртуальную таблицу попадет только фактический период действия для записей этого документа. Если то же самое условие задать не в виртуальной таблице, а в самом запросе через конструкцию ГДЕ, то результат будет аналогичным, но производительность существенно снизится, так как сначала будет сформирована виртуальная таблица фактического периода действия для всех записей регистра расчета, а потом запрос отберет из них те, которые относятся к нужному документу. Таким образом, в запросе будет обработано большое количество лишней информации. Использование графиков Протяженные во времени расчеты тесно связаны с данными графика, используемого в регистре расчета. Как уже отмечалось, данные графика содержат определенные значения для каждого календарного дня периода. Регистр расчета рассматривает график как таблицу следующего вида (табл. 5.8). 606 Реализация прикладных задач в системе «1С:Предприятие 8.2» Таблица 5.8. Таблица графика Дата графика 01.02.2010 Значение графика 1 02.02.2010 03.02.2010 04.02.2010 1 ... 1 28.02.2010 1 Эти данные хранятся в системе в виде регистра сведений, созданного при разработке конфигурации. При этом дату графика платформа получает из измерения, заданного в свойствах регистра расчета в поле Дата графика, а значение графика – из ресурса, указанного в поле Значение графика. Рассмотрим использование данных графика на примере. Пусть в регистре сведений ГрафикиРаботы хранятся следующие значения для календарных дней февраля (табл. 5.9). Таблица 5.9. Календарный график февраля 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 Фактически этот график представляет собой пятидневный график работы с двумя выходными и праздником 23 февраля. Рабочие дни в качестве значения имеют 1, выходные и праздники – 0. Использование данных графика для расчета записей Пример записи, расчет которой зависит от данных графика, – оклад по месячной тарифной ставке. Для расчета этой записи используется размер тарифа, а также данные о количестве рабочих дней в периоде и количестве фактически отработанных дней в этом периоде. Роль графика состоит в том, чтобы данные о фактически отработанных днях и норме дней могли быть получены системой автоматически. Формула расчета результата начисления в данном случае выглядит следующим образом: Результат = Тариф * Кол-во отработанных дней / Кол-во рабочих дней периода Тариф может быть получен, например, из реквизита Размер регистра расчетов (например, 5 000 рублей). Для получения количества отработанных и рабочих дней будут необходимы данные графика. Количество рабочих дней можно получить, просуммировав значения графика за период действия записи. Таким образом, если оклад назначен за месяц, будут просуммированы значения графика за весь месяц. Количество фактически отработанных часов может быть получено путем суммирования значений графика за все интервалы фактического периода действия данной записи (рис. 5.39). Глава 5. Реализация сложных периодических расчетов 607 Рис. 5.39. Получение данных графика Полученные таким образом данные могут быть использованы в формуле расчета оклада: Результат = 5000 * 12 / 19 = 3157,89 Использование данных графика для вычисления части записи В определенных ситуациях для протяженных во времени записей возникает необходимость вычислить значения ресурсов только части записи, попавшей в определенный интервал. Такая задача, в частности, возникает при частичном пересечении записью базового периода другой записи (рис. 5.40). Рис. 5.40. Частичное пересечение с записью базового периода В данном случае вводится запись о премии на первую половину месяца. Следовательно, начисленный за месяц оклад в размере 10 000 рублей попадает в базовый период премии только частично. Таким образом, регистр расчета должен включить в базу расчета премии только часть из начисленных 608 Реализация прикладных задач в системе «1С:Предприятие 8.2» 10 000 рублей. Делить сумму по количеству календарных дней, в данном случае поровну, было бы некорректно, так как в первой половине месяца могло быть больше рабочих дней, чем во второй. Поэтому для вычисления части записи, попадающей в определенный период, используются данные графика, которые служат относительным весом каждого дня этого периода. Иными словами, база расчета премии в данном случае будет рассчитана системой следующим образом: База расчета = Результат оклада * (Значения графика, попавшие в базовый период / Значения графика за период действия оклада) Рис. 5.41. Получение данных графика Расчетная база премии по окладу в этом случае составит (рис. 5.41): База расчета = 10 000 * 11 / 19 = 5 789,47 Настройка использования нескольких графиков в одном регистре расчета Выше было описано, каким образом можно привязать данные графика, хранящиеся в регистре сведений, к регистру расчета. Однако, как правило, при расчете записей используются различные данные графика. Например, один из сотрудников получает оклад по дням, и для его расчета нужен график, где рабочие дни отмечены значением 1, как в приведенных выше графиках. Другой сотрудник может получать оклад по часам, и для расчета нужен график, значением которого является количество рабочих часов в каждом календарном дне. Более того, сотрудники могут работать по разным графикам работы. Например, бухгалтер работает по пятидневке, а охранник – в режиме сутки через двое. Иными словами, для каждого сотрудника необходимо задавать различное значение графика для одной даты. При этом все эти начисления рассчитываются в одном регистре, а система позволяет привязать к регистру только один график. Глава 5. Реализация сложных периодических расчетов 609 Для реализации хранения разных вариантов графика необходимо в соответствующем регистре сведений добавить новые измерения. Так, для хранения различных графиков для целей расчета зарплаты по дням или по часам можно ввести в регистр сведений новое измерение ВидУчетаВремени, тип которого – перечисление ВидыУчетаВремени с двумя возможными значениями – ПоДням и ПоЧасам. В этом случае для каждой даты графика можно будет указать два разных значения, каждое из которых будет соответствовать определенному виду учета времени. Для того чтобы реализовать возможность хранения различных графиков работы (пятидневка, шестидневка и т. д.), можно добавить в регистр сведений еще одно измерение ГрафикРаботы, имеющее тип СправочникСсылка.ГрафикиРаботы. Такая настройка позволит в режиме 1С:Предприятие создавать неограниченное количество графиков работы и вводить данные по ним в регистр сведений. Для каждого графика работы можно будет заполнить график как по дням, так и по часам. Эти данные могут быть использованы в последующих расчетах. Структура регистра сведений после этих изменений показана на рис. 5.42. Рис. 5.42. Структура регистра сведений «ГрафикиРаботы» Такая структура обеспечивает хранение в одном регистре сведений неограниченного количества различных графиков. После разработки структуры регистра необходимо указать регистру расчета, какой конкретно график должен быть использован для расчета каждой записи. Для этого необходимо связать измерения или ресурсы регистра расчета с измерениями регистра сведений графиков. Иными словами, в каждой записи регистра расчета должна содержаться информация, необходимая для построения отборов по измерениям регистра сведений графиков. На основании данных записи регистра расчета должен быть определен конкретный график работы. Например, для регистра сведений приведенной выше структуры в регистре расчета должны фиксироваться данные о конкретном графике работы и виде учета времени, которые должны быть использованы в данной 610 Реализация прикладных задач в системе «1С:Предприятие 8.2» записи. Для этого нужно добавить в структуру регистра расчета дополнительные поля (измерения или реквизиты в зависимости от специфики задачи), после чего связать эти поля с измерениями регистра сведений графиков (рис. 5.43). Рис. 5.43. Записи регистра расчета В этом случае для расчета оклада сотруднику Иванов будет использован график работы Пятидневка с видом учета времени По дням, а сотруднику Петров оклад будет рассчитан по часам по графику работы Сутки через двое. Соответствующие графики будут получены системой из регистра сведений с отбором по указанным в записи значениям измерений ГрафикРаботы и ВидУчетаВремени. Связь измерений и реквизитов регистра расчета с измерениями регистра сведений производится через свойство Связь с графиком соответствующих полей регистра расчета (рис. 5.44). Рис. 5.44. Связь измерения с графиком В данном примере для реквизита ГрафикРаботы регистра расчета в свойстве Связь с графиком указано соответствующее измерение регистра сведений, в котором хранятся данные графика. Глава 5. Реализация сложных периодических расчетов 611 Получение данных графика при помощи запроса Для получения данных графика при помощи запроса используется виртуальная таблица данных графика регистра расчета. Эта виртуальная таблица имеет единственный параметр – Условие, позволяющий передать произвольное условие в запрос, который платформа формирует по таблицам базы данных для получения виртуальной таблицы. Виртуальная таблица данных графика расширяет структуру основной таблицы, добавляя для каждой ее строки данные графика за все возможные виды периодов (рис. 5.45). Рис. 5.45. Виртуальная таблица «ДанныеГрафика» Количество строк в виртуальной таблице равно количеству записей регистра расчета, удовлетворяющих условию, заданному в параметр виртуальной таблицы. Первая часть полей виртуальной таблицы данных графика полностью совпадает с полями основной таблицы регистра. Дополнительные поля добавляются по числу ресурсов регистра сведений графиков. На каждый ресурс в виртуальной таблице данных графика будет добавлено 4 поля, в которых будут рассчитаны значения графика по данному ресурсу за каждый из возможных периодов: период действия, фактический период действия, базовый период и период регистрации. Использование виртуальной таблицы данных графика позволяет получить данные графика не только по ресурсу регистра сведений, являющемуся значением графика, но и по любым другим ресурсам этого регистра. Виртуальная таблица также позволяет получить данные графика для набора записей с произвольным условием, например, не принадлежащих одному регистратору. 612 Реализация прикладных задач в системе «1С:Предприятие 8.2» Ниже приведен текст модуля, позволяющий получить данные графика за фактический период действия для всех записей документа (листинг 5.2). Этот фрагмент присутствует в демоконфигурации в обработке ДанныеРегистраРасчета. Листинг 5.2. Получение данных графика запросом Запрос = Новый Запрос; Запрос.Текст = " |ВЫБРАТЬ | ДанныеГрафика.НомерСтроки, | ДанныеГрафика.ЗначениеФактическийПериодДействия КАК Данные |ИЗ | РегистрРасчета.ОсновныеНачисленияРегл.ДанныеГрафика | (Регистратор = &Регистратор) КАК ДанныеГрафика"; Запрос.УстановитьПараметр("Регистратор", Ссылка); Выборка = Запрос.Выполнить().Выбрать(); Пока Выборка.Следующий() Цикл Сообщение = Новый СообщениеПользователю(); Сообщение.Текст = "Данные графика по фактическому периоду для строки № " + Выборка.НомерСтроки + " : " + Выборка.Данные; Сообщение.Сообщить(); КонецЦикла; Сторнирование Конкуренция с записями более раннего периода регистрации Возможность указать для записи период действия, отличный от периода регистрации, существует только у регистров, поддерживающих период действия. В этом случае, если у записи период действия раньше периода регистрации (то есть запись зарегистрирована «с опозданием»), эта запись может вступать в конкуренцию за период действия с записями более раннего периода регистрации. При этом механизм вытеснения действовать не будет, так как запись имеет более поздний период регистрации, но конкуренция видов расчета останется. В результате у записи с более поздним периодом регистрации может образоваться меньший фактический период действия в силу того, что она не может действовать одновременно с конкурирующими видами расчета. Например, больничный за март, введенный в апреле, вступает в конкуренцию с дежурством, зарегистрированным и действовавшим в марте. В результате фактический период действия больничного будет меньше периода действия, так как записи не могут пересекаться по фактическому периоду действия (рис. 5.46). Глава 5. Реализация сложных периодических расчетов 613 Рис. 5.46. Конкуренция в прошлом периоде В данном случае фактический период действия больничного на интервале с 15 по 22 марта будет пустым, так как этот интервал уже занят конкурирующим расчетом, введенным ранее. Наличие сторно-записи по виду расчета Дежурство позволит записи о больничном занять весь свой период действия. При формировании фактического периода действия больничного будет учтен период действия сторно-записи по дежурству (рис. 5.47). Рис. 5.47. Использование сторно-записей Таким образом, при формировании записей, которые вступают в конкуренцию с записями более раннего периода регистрации, необходимо ввести также сторно-записи по конкурирующим видам расчета, иначе фактический период действия будет пустым на интервалах пересечения периода действия конкурирующих записей. 614 Реализация прикладных задач в системе «1С:Предприятие 8.2» Формирование сторно-записей. Метод «ПолучитьДополнение()» Сторно-записи, «прикрывающие» фактический период действия вводимой записи с более поздним периодом регистрации, могут быть сформированы вручную стандартными методами формирования записей регистра расчета. В этом случае разработчик должен самостоятельно предусмотреть алгоритм, по которому будут сформированы сторно-записи, исходя из первоначального набора записей. Это достаточно сложный путь, предполагающий самостоятельный анализ взаимодействия периодов действия конкурирующих записей. Вместо формирования собственных алгоритмов можно воспользоваться методом ПолучитьДополнение() объекта РегистрРасчетаНаборЗаписей. Суть его состоит в том, что система самостоятельно анализирует возможные конфликты формируемого набора записей с записями, имеющими более ранний период регистрации. Если обнаруживается пересечение периодов действия с конкурирующими записями, на каждое такое пересечение система предложит сформировать сторно-запись, которая позволит вводимому набору записей сохранить фактический период действия. При этом система укажет, по каким видам расчета необходимо ввести сторно-записи и какой период действия они должны иметь. Метод ПолучитьДополнение() применяется к набору записей регистра расчета, поддерживающего период действия, и не требует указания параметров. Данный метод возвращает значение типа ТаблицаЗначений, в котором содержатся все необходимые данные для формирования сторнозаписей. Таблица включает значение всех полей записей, для которых должны быть введены сторно-записи (кроме полей Регистратор и НомерСтроки, которые не нужны для формирования сторно-записей), а также дополнительные поля – период регистрации сторно-записи и даты начала и окончания периода действия сторно-записи. В приведенном примере для набора записей, состоящего из одной записи о больничном, метод ПолучитьДополнение() вернет таблицу следующего вида (табл. 5.10). Таблица 5.10. Запись дополнения Период регистрации Вид расчета Период действия 01.03.2010 Дежурство 01.03.2010 … Период Период Период регистрации действия действия сторно начало сторно конец сторно 01.04.2010 15.03.2010 22.03.2010 Полученная таблица позволяет ввести необходимые сторно-записи без дополнительных вычислений. Ниже приведен текст модуля, в котором используется метод ПолучитьДополнение() и формируются сторно-записи в регистре расчета (листинг 5.3). Пример использования данного метода можно также посмотреть в демоконфигурации в обработке ДанныеРегистраРасчета. Глава 5. Реализация сложных периодических расчетов 615 Листинг 5.3. Получение дополнения // Получить набор записей текущего документа НаборЗаписей = РегистрыРасчета.ОсновныеНачисленияРегл.СоздатьНаборЗаписей(); НаборЗаписей.Отбор.Регистратор.Установить(Ссылка, Истина); НаборЗаписей.Прочитать(); // Получить таблицу сторно-записей для набора записей текущего документа ТаблицаСторно = НаборЗаписей.ПолучитьДополнение(); // Сформировать сторно-записи в регистре расчета Для Каждого СтрокаСторно из ТаблицаСторно Цикл Запись = Движения.ОсновныеНачисленияРегл.Добавить(); Запись.ВидРасчета = СтрокаСторно.ВидРасчета; Запись.ПериодРегистрации = СтрокаСторно.ПериодРегистрацииСторно; Запись.ПериодДействияНачало = СтрокаСторно.ПериодДействияНачалоСторно; Запись.ПериодДействияКонец = СтрокаСторно.ПериодДействияКонецСторно; // Заполнить измерения и реквизиты записи // ... Запись.Сторно = Истина; КонецЦикла; Таким образом, сторно-записи имеют те же значения полей, что и исходные записи, за исключением периода регистрации и периода действия. Сторно-записи отличаются от обычных записей значением ИСТИНА в предопределенном поле Сторно. Так, сторно-запись по дежурству будет выглядеть следующим образом (табл. 5.11). Таблица 5.11. Сторно-запись по дежурству Период Регистрации ВидРасчета ПериодДействия Начало ПериодДействия Конец 01.04.2010 Дежурство 15.03.2010 22.03.2010 … Сторно ИСТИНА Значения ресурсов сторно-записи не переносятся из исходной записи. Сторнозаписи должны рассчитываться в том же порядке, что и обычные записи. Расчет записей подробно рассмотрен в разделе «Технология формирования и расчета записей регистра расчета» на стр. 626. 616 Реализация прикладных задач в системе «1С:Предприятие 8.2» Настройка зависимости по базовому периоду Настройка планов видов расчета и регистров расчета Настройка зависимости от базы Для возможности ввода и расчета записей, зависимых по базовому периоду от других записей, необходимо настроить свойства соответствующих планов видов расчета и регистров расчета. В плане видов расчета, виды расчета которого будут зависеть по базовому периоду от других видов расчета, необходимо настроить зависимость от базы. Для этого свойство Зависимость от базы плана видов расчета должно быть установлено в одно из значений Зависит по периоду действия или Зависит по периоду регистрации. Зависимость по периоду действия предполагает анализ пересечения фактического периода действия записей базовых видов расчета с базовым периодом текущей записи. При такой зависимости возможно частичное попадание какой-либо записи в базу расчета текущей записи. Если у записи по базовому виду расчета нет периода действия, то будет проанализировано попадание периода регистрации этой записи в базовый период текущей записи. Рассмотрим механизм зависимости от базы по периоду действия на примере начисления премии за 3 месяца, у которой базовый период установлен с 15.01.2010 по 15.04.2010 (рис. 5.48). В список базовых видов расчета этой премии входят виды расчета Оклад и Премия за месяц. Рис. 5.48. Зависимость от базы по периоду действия Для базовых расчетов, имеющих период действия (в данном случае Оклад), будет анализироваться пересечение их фактического периода действия с базовым периодом премии. В данном случае оклад за январь и за апрель попадут в базовый период частично, а оклады на февраль и март – полностью. Если расчет попал в базу частично, в расчетную базу попадет только Глава 5. Реализация сложных периодических расчетов 617 часть значения ресурсов этой записи. При вычислении этой части будут использованы данные графика записей об окладе. Подробно расчет части записи рассмотрен в разделе «Настройка протяженных по времени расчетов» на стр. 602. Для базовых расчетов, не имеющих периода действия (в данном случае Премия за месяц), будет проанализировано попадание периода регистрации в базовый период премии. Так как период регистрации – это фиксированная дата начала расчетного периода, такая запись либо полностью попадет в базовый период, либо не попадет совсем. В данном случае премия за январь вообще не будет учтена при расчете базы, а премия за апрель будет учтена полностью. Зависимость по периоду действия может быть установлена независимо от того, использует ли данный план видов расчета период действия или нет. В данном случае важен период действия не рассчитываемой записи, а базовых записей, на основании которых она рассчитывается. В приведенном примере премия не использует период действия, при этом она зависит по периоду действия от других записей, например, начисленных окладов. В случае зависимости по периоду регистрации у базовой записи берется ее период, отсчитываемый от значения поля ПериодРегистрации. Например, при периодичности базового регистра Месяц будет анализироваться пересечение периода от даты ПериодРегистрации плюс месяц записей базовых видов расчета с базовым периодом текущей записи. Период действия базовых записей в данном случае значения не имеет. Такой формат зависимости часто используется при расчете удержаний, так как удержания, как правило, рассчитываются с начисленных за период сумм, независимо от того, когда они действовали. В таких случаях важен период регистрации базовых записей, а не период действия. Например, при расчете удержания по исполнительному листу за март будет учтена оплата больничного, начисленная в марте, даже если работник реально болел в феврале (рис. 5.49). Рис. 5.49. Расчет удержания по исполнительному листу 618 Реализация прикладных задач в системе «1С:Предприятие 8.2» В данном случае в базу расчета удержания попадет оклад за март, а также больничный за февраль, зарегистрированный в марте. При этом мартовская надбавка, зарегистрированная в апреле, в базу расчета не попадет. При настройке расчетов, зависимых от базы по периоду регистрации, необходимо помнить, что период регистрации – это всегда дата начала периода, поэтому базовый период должен заполняться с учетом этого. После настройки зависимости от базы необходимо указать, от каких видов расчета могут зависеть по базовому периоду виды расчета текущего плана видов расчета. Для этого нужно указать список базовых планов видов расчета в свойствах текущего плана видов расчета. В результате этой настройки в любом виде расчета текущего плана видов расчета в табличной части БазовыеВидыРасчета можно будет выбрать любой вид расчета отмеченных планов видов расчета. В данном случае расчет дополнительных начислений может базироваться на данных основных и дополнительных начислений. При такой настройке для вида расчета Премия за 3 месяца в списке базовых можно будет указать оклад из основных начислений и премию за месяц из дополнительных (рис. 5.50). Рис. 5.50. Настройка зависимости по базовому периоду Указанная настройка плана видов расчета будет действовать во всех регистрах расчета, где участвует этот план видов расчета. В данном случае рассчитывать Глава 5. Реализация сложных периодических расчетов 619 премии от оклада можно будет как в регламентированном, так и в управленческом учете. Более того, можно будет рассчитать, например, управленческую премию по окладам, начисленным в регламентированном учете. Ввод записей, зависимых по базовому периоду Для того чтобы можно было рассчитать запись по базе других записей, у этой записи в регистре должен быть указан базовый период, либо у соответствующего вида расчета должно быть установлено свойство Период действия является базовым периодом. В противном случае базовый период будет пустым, и определить расчетную базу будет невозможно. Записи, зависимые по базовому периоду, могут формироваться только в регистре расчета, у которого установлено свойство Базовый период. Базовый период записи задается двумя датами БазовыйПериодНачало и БазовыйПериодКонец. В качестве базового периода можно указать произвольный интервал, в том числе перекрывающий несколько расчетных периодов. Запись о премии за 3 месяца будет выглядеть следующим образом (табл. 5.12). Таблица 5.12. Запись с указанием базового периода Период ВидРасчета Регистрации 01.05.2010 Премия за 3 месяца … БазовыйПериодНачало БазовыйПериодКонец … 15.01.2010 15.04.2010 В базу расчета данной записи входят все записи любых регистров по видам расчета Оклад и Премия за месяц, у которых фактический период действия пересекает интервал с 15 января по 15 апреля. Наиболее сложным вариантом зависимости по базовому периоду является установка у вида расчета свойства Период действия является базовым периодом. В этом случае в качестве базового периода система будет использовать фактический период действия записи с этим видом расчета. Это свойство является предопределенным и может быть задано только у видов расчета из плана видов расчета, использующего период действия, с установленным свойством Зависимость от базы по периоду действия или по периоду регистрации. Рассмотрим действие этого свойства на примере вида расчета Надбавка за вахту. Этот вид расчета предусматривает процентную надбавку к окладу на период работы на вахте. При этом надбавка за вахту не начисляется, если в это же время человек получает надбавку руководителю. Таким образом, вид расчета Надбавка за вахту зависит по базовому периоду от вида расчета Оклад. Кроме этого, надбавка за вахту вытесняется видом расчета Надбавка руководителю. То есть у вида расчета Надбавка за вахту в списке базовых указан Оклад, а в списке вытесняющих – Надбавка руководителю. 620 Реализация прикладных задач в системе «1С:Предприятие 8.2» Для расчета этой надбавки необходимо рассчитать сумму оклада за фактический период действия надбавки, так как нужно учитывать вытеснение надбавкой руководителю. То есть базовым периодом надбавки должен быть ее фактический период действия. Такой базовый период нельзя задать только двумя датами БазовыйПериодНачало и БазовыйПериодКонец, так как фактический период действия может состоять из нескольких интервалов. Поэтому для вида расчета Надбавка за вахту необходимо установить свойство Период действия является базовым периодом (рис. 5.51). Рис. 5.51. Расчет надбавки за вахту То есть база расчета надбавки за вахту будет получена только за те интервалы, в которых она не была вытеснена надбавкой руководителю. Для того чтобы рассчитать сумму оклада за эти интервалы, будут использованы данные графика записи об окладе. При установке свойства Период действия является базовым периодом принципы работы механизма зависимости по базовому периоду не меняются, только вместо свойств записи, определяющих базовый период, система использует фактический период действия записи. В зависимости от варианта зависимости (по периоду действия или по периоду регистрации) система проанализирует пересечение соответственно периодов действия или периодов регистрации базовых записей с фактическим периодом действия текущей записи. В записи, формируемой в регистре по виду расчета с установленным свойством Период действия является базовым периодом, поля БазовыйПериодНачало и БазовыйПериодКонец не заполняются (табл. 5.13). Таблица 5.13. Структура записи регистра расчета Период ВидРасчета Регистрации 01.03.2010 Надбавка за вахту … БазовыйПериодНачало БазовыйПериодКонец … Глава 5. Реализация сложных периодических расчетов 621 Получение базы при помощи запроса Для получения базы расчетов при помощи запроса используются виртуальные таблицы регистров расчета, поддерживающих базовый период. У каждого регистра таких таблиц может быть несколько. Их число определяется количеством регистров расчета, использующих планы видов расчета, которые являются базовыми по отношению к плану видов расчета данного регистра. Например, план видов расчета ДополнительныеНачисления зависит по базе от планов видов расчета ОсновныеНачисления и ДополнительныеНачисления. Эти планы видов расчета, в свою очередь, используются в регистрах регламентированного и управленческого учета (рис. 5.52). Рис. 5.52. Взаимосвязь планов видов расчета и регистров расчета Это означает, что любые записи регистра Дополнительные начисления (регл) могут зависеть по базовому периоду от записей любого из четырех регистров. В этом случае у регистра Дополнительные начисления (регл) будет 4 виртуальные таблицы базовых данных (рис. 5.53). Рис. 5.53. Виртуальные таблицы базы Имя виртуальной таблицы формируется по следующей схеме: <ИмяОсновногоРегистра>.База<ИмяБазовогоРегистра> Таким образом, например, таблица ДополнительныеНачисленияРегл.БазаОсновныеНачисленияРегл позволяет получить записи регистра Основные 622 Реализация прикладных задач в системе «1С:Предприятие 8.2» начисления (регл), входящие в базу расчета записей регистра Дополнительные начисления (регл). Если необходимо получить базу по нескольким регистрам, нужно будет использовать в запросе несколько виртуальных таблиц базовых данных. Виртуальные таблицы базовых данных требуют указания параметров, которые позволяют указать, какие именно данные в каких разрезах нужно получить. ИзмеренияОсновногоРегистра – в этот параметр нужно передать массив, элементами которого являются строки с названиями измерений основного регистра, по которым нужно будет отбирать записи в базовых регистрах (рис. 5.54). Рис. 5.54. Связь с данными базовых регистров Для отбора данных по сотруднику и организации в этот параметр нужно передать массив (табл. 5.14). Таблица 5.14. Структура массива «ФизЛицо» «Организация» Названия измерений основного регистра указываются без указания имени регистра, так как в данном случае понятно, что речь идет об основном регистре. ИзмеренияБазовогоРегистра – в этот параметр передается массив, элементами которого являются названия измерений базового регистра, соответствующие измерениям, переданным в параметр ИзмеренияОсновногоРегистра. Число элементов этого массива должно совпадать с числом элементов массива измерений основного регистра. Важен также порядок следования измерений: он должен быть таким же, как и в массиве измерений основного регистра. По измерениям, указанным в параметре ИзмеренияБазовогоРегистра будет произведен отбор записей в базовом регистре. При этом в качестве Глава 5. Реализация сложных периодических расчетов 623 значений отбора будут использованы значения соответствующих измерений основного регистра. Например, при получении базы по основным начислениям для премии, начисленной сотруднику Иванов в организации Ромашка, в виртуальную таблицу базы попадут только базовые записи с аналогичными значениями измерений. Если названия измерений одинаковы, в параметры ИзмеренияОсновногоРегистра и ИзмеренияБазовогоРегистра можно передать один и тот же массив. Если названия различаются, нужно будет создать два массива (рис. 5.55). Рис. 5.55. Получение базы по основным начислениям Разрезы – в этот параметр передается массив, содержащий названия полей базового регистра, по которым необходимо получить разрез базы. В запросе можно получить разрез не только по измерениям и реквизитам, но и по следующим предопределенным полям базового регистра: НомерСтроки, Регистратор, ВидРасчета, ПериодРегистрации, ПериодДействия. Например, для получения базы в разрезе периода регистрации и вида расчета в параметр Разрезы необходимо передать следующий массив (табл. 5.15). Таблица 5.15. Структура массива «ПериодРегистрации» «ВидРасчета» Параметр Разрезы можно не указывать, в этом случае база будет получена общей суммой по каждому ресурсу базового регистра. В массиве недопустимо указание измерений, которые переданы в параметр ИзмеренияБазовогоРегистра, так как в этом случае на эти измерения будет наложен отбор, и получать по ним разрез не имеет смысла. Условие – в этот параметр можно передать произвольное условие на записи основного регистра. База будет получена только для записей, удовлетворяющих этому условию. В отличие от метода ПолучитьБазу(), условия могут 624 Реализация прикладных задач в системе «1С:Предприятие 8.2» быть заданы произвольные. В запросе не обязательно отбирать данные по регистратору, теоретически можно вообще не указывать условий, тогда база будет получена для всех записей основного регистра. Виртуальная таблица базовых данных расширяет данные основной таблицы регистра расчета и имеет следующую структуру (рис. 5.56). Рис. 5.56. Виртуальная таблица базы В виртуальной таблице базовых данных будут присутствовать все данные основной таблицы основного регистра, а также отдельные поля для получения базы по всем ресурсам базового регистра, названия которых формируются по схеме <ИмяРесурса>База. Если параметр Разрезы не задан, то в таблице не будет других полей, и для каждой записи основного регистра, удовлетворяющей условию, будет рассчитана база общей суммой по каждому ресурсу базового регистра. Если разрезы заданы, то в виртуальной таблице будут присутствовать дополнительные поля по числу элементов массива разрезов. Названия этих полей в виртуальной таблице базовых данных будут формироваться по схеме <ИмяПоля>Разрез. Так, если в параметр Разрезы переданы значения ПериодРегистрации и ВидРасчета, то в виртуальной таблице будут доступны поля ПериодРегистрацииРазрез и ВидРасчетаРазрез. Остальные поля, выводимые в конструкторе запроса, не будут доступны, и при выборе таких полей запрос не будет выполнен. Например, в запросе можно получить итоги по значениям разрезов и использовать его для построения отчета следующего вида по базовым начислениям для расчета отпуска (рис. 5.57). Глава 5. Реализация сложных периодических расчетов 625 Рис. 5.57. Отчет по базовым начислениям Ниже приведен текст запроса, который может служить основой для построения такого отчета (листинг 5.4). Этот фрагмент присутствует в демоконфигурации в обработке ДанныеРегистраРасчета. Листинг 5.4. Отчет по базовым начислениям Запрос = Новый Запрос; Запрос.Текст = " |ВЫБРАТЬ | База.ПериодРегистрацииРазрез КАК ПериодРегистрацииРазрез, | База.ВидРасчетаРазрез, | СУММА(База.РезультатБаза) КАК РезультатБаза |ИЗ | РегистрРасчета.ДополнительныеНачисленияРегл.БазаОсновныеНачисленияРегл( | &Измерения, | &Измерения, | &Разрезы, | Регистратор = &Регистратор И НомерСтроки = &НомерСтроки) КАК База | |СГРУППИРОВАТЬ ПО | База.ПериодРегистрацииРазрез, | База.ВидРасчетаРазрез |ИТОГИ | СУММА(РезультатБаза) | ПО | ОБЩИЕ, | ПериодРегистрацииРазрез"; // Сформировать массив измерений основного и базового регистров // (названия измерений совпадают, поэтому используется один массив) Измерения = Новый Массив(2); Измерения[0] = "ФизЛицо"; Измерения[1] = "Организация"; // Сформировать массив разрезов Разрезы = Новый Массив(2); Разрезы[0] = "ПериодРегистрации"; Разрезы[1] = "ВидРасчета"; 626 Реализация прикладных задач в системе «1С:Предприятие 8.2» // Передать параметры в запрос Запрос.УстановитьПараметр("Измерения", Измерения); Запрос.УстановитьПараметр("Разрезы", Разрезы); // Запрос строится по конкретной записи документа // с номером ТекущийНомерСтроки Запрос.УстановитьПараметр("Регистратор", Ссылка); Запрос.УстановитьПараметр("НомерСтроки", ВыбранныйНомерСтроки); Результат = Запрос.Выполнить(); Технология формирования и расчета записей регистров расчета Формирование записей регистра расчета Регистры расчета не поддерживают независимого формирования записей без использования документа-регистратора. Поэтому ввод записей в регистр расчета должен быть организован с применением документов. В документе должны быть указаны все данные, необходимые для заполнения всех полей записи регистра расчета, кроме ресурсов. Такой документ заполняется пользователем в режиме 1С:Предприятие и формирует записи регистра расчета при проведении. В демонстрационной конфигурации «Сложные периодические расчеты», которая находится на прилагаемом компакт-диске, для формирования записей в регистрах расчета предусмотрен документ НачислениеЗарплаты (рис. 5.58). Рис. 5.58. Документ «Начисление зарплаты» В шапке документа пользователь должен указать организацию, по которой будет производиться начисление, а также расчетный период, в который должны попасть записи, то есть период регистрации. Для ввода записей в каждый из регистров расчета в документе предусмотрена отдельная табличная часть. Так, для ввода записей в регистр расчета ОсновныеНачисленияРегл предусмотрена закладка Основные начисления. На этой закладке пользователь Глава 5. Реализация сложных периодических расчетов 627 должен ввести начисления различным сотрудникам, указав физическое лицо, вид расчета, период действия записи и значения реквизитов регистра расчета. В данном случае пользователь должен указать значения реквизитов Размер и Подразделение. В реквизите Размер указывается размер начисления, который будет влиять на его расчет. Например, для оклада размером является тарифная ставка, для премии – количество процентов премии. Для некоторых видов расчета размер указывать не нужно, так как он не влияет на расчет (например, сдельный заработок). В реквизите Подразделение указывается подразделение, на затраты которого должно быть отнесено данное начисление. Реквизит регистра ГрафикРаботы будет заполнен значением, указанным в соответствующем реквизите выбранного физического лица. Это и будет график работы, по которому должна рассчитываться данная запись. Как правило, график работы у всех записей по одному сотруднику один и тот же. В приведенном примере реквизиты регистра ВидУчетаВремени и СтатьяЗатрат не вводятся в документ напрямую, а указываются как реквизиты вида расчета. Ресурсы регистра расчета не всегда заполняются из документа, они могут рассчитываться при проведении. Технология расчета записей будет подробно рассмотрена в следующем разделе. Для формирования записей регистра расчета используется метод Добавить() объекта РегистрРасчетаНаборЗаписей (листинг 5.5). Листинг 5.5. Формирование записей регистра расчета // Процедура добавляет запись в регистр основных начислений Процедура ДобавитьСтрокуОсновныхНачислений(ДанныеСтроки, НаборЗаписей) Движение = НаборЗаписей.Добавить(); // Предопределенные поля Движение.ПериодРегистрации = ПериодРегистрации; Движение.ПериодДействияНачало = ДанныеСтроки.ДатаНачало; Движение.ПериодДействияКонец = ДанныеСтроки.ДатаКонец; Движение.ВидРасчета = ДанныеСтроки.ВидРасчета; Движение.Сторно = ДанныеСтроки.Сторно; // Измерения Движение.ФизЛицо = ДанныеСтроки.ФизЛицо; Движение.Организация= Организация; // Ресурсы Движение.Результат = ДанныеСтроки.Результат; // Реквизиты Движение.ГрафикРаботы = ДанныеСтроки.ФизЛицо.ГрафикРаботы; Движение.Размер = ДанныеСтроки.Размер; Движение.ВидУчетаВремени = ДанныеСтроки.ВидРасчета.ВидУчетаВремени; Движение.Подразделение = ДанныеСтроки.Подразделение; Движение.СтатьяЗатрат = ДанныеСтроки.ВидРасчета.СтатьяЗатрат; 628 Реализация прикладных задач в системе «1С:Предприятие 8.2» КонецПроцедуры // ДобавитьСтрокуОсновныхНачислений // Обработка проведения Процедура ОбработкаПроведения(Отказ) Движения.ОсновныеНачисленияРегл.Записывать = Истина; Движения.ДополнительныеНачисленияРегл.Записывать = Истина; // Сформировать запрос по табличной части при помощи функции общего модуля ВыборкаОсновныеНачисления = ОбщегоНазначения .СформироватьЗапросПоТабличнойЧасти(ЭтотОбъект, "ОсновныеНачисления").Выбрать(); // По каждой строке табличной части сформировать запись в регистр Пока ВыборкаОсновныеНачисления.Следующий() Цикл ДобавитьСтрокуОсновныхНачислений(ВыборкаОсновныеНачисления, Движения.ОсновныеНачисленияРегл); КонецЦикла; // Запись дополнительных начислений в регистр ВыборкаДополнительныеНачисления = ОбщегоНазначения .СформироватьЗапросПоТабличнойЧасти(ЭтотОбъект, "ДополнительныеНачисления").Выбрать(); Пока ВыборкаДополнительныеНачисления.Следующий() Цикл ДобавитьСтрокуДополнительныхНачислений(ВыборкаДополнительныеНачисления , Движения.ДополнительныеНачисленияРегл); КонецЦикла; КонецПроцедуры // ОбработкаПроведения Настройка алгоритмов расчета Настройка способов расчета Способ расчета ресурсов записи может быть различным в зависимости от выбранного вида расчета и дополнительных реквизитов записи. Как уже было отмечено, технология периодических расчетов в системе «1С:Предприятие» предоставляет пользователю возможность самостоятельно вводить новые виды расчета в режиме 1С:Предприятие. Поэтому прописать в конфигураторе алгоритмы расчета каждого вида расчета нельзя. Пользователю должна быть предоставлена возможность настроить способ расчета того или иного вида расчета в режиме 1С:Предприятие. Под способом расчета подразумевается алгоритм или формула, по которой будут вычислены значения ресурсов записи регистра, исходя из параметров этой записи. При этом различные виды расчета могут иметь один и тот же способ расчета. Например, виды расчета Премия и Надбавка за вахту по сути имеют один и тот же способ расчета, предполагающий умножение расчетной базы записей с этими видами расчета на определенный процент. Так как все способы расчета должны быть прописаны разработчиком, их набор должен быть фиксированным и для их описания логичнее всего Глава 5. Реализация сложных периодических расчетов 629 использовать перечисление. В демонстрационной конфигурации «Сложные периодические расчеты», которая находится на прилагаемом компакт-диске, все доступные способы расчета описаны в перечислении СпособыРасчета. При необходимости ввести в систему новый способ расчета не обойтись без изменения конфигурации, так как алгоритм расчета нужно будет прописать в модулях. Для настройки способа расчета для видов расчета в режиме 1С:Предприятие необходимо добавить в план видов расчета реквизит СпособРасчета, имеющий тип ПеречислениеСсылка.СпособыРасчета. В этом случае в любом виде расчета данного плана видов расчета можно будет указать одно из значений перечисления, определив тем самым способ расчета записей с этим видом расчета. В демонстрационной конфигурации «Сложные периодические расчеты», которая находится на прилагаемом компакт-диске, предусмотрены следующие способы расчета (табл. 5.16). Настройка приоритета видов расчета При расчете нескольких записей в одном документе очень важен порядок расчета этих записей. Если рассчитывать записи в произвольном порядке, то может получиться, что запись, зависимая по базовому периоду, будет рассчитана раньше, чем базовая запись. Например, запись с видом расчета Надбавка руководителю будет рассчитана раньше, чем запись с видом расчета Оклад. В этом случае база этой надбавки будет равна 0, так как оклад еще не рассчитан и не записан в регистр. В результате часть записей будет рассчитана неправильно. Для того чтобы такой набор записей был рассчитан правильно, необходимо рассчитывать эти записи в правильной последовательности. При этом разработчик должен самостоятельно продумать механизм, который будет упорядочивать расчет записей регистра. Рассмотрим принципы упорядочивания расчетов на примере следующего набора записей, рассчитываемого в одном документе (рис. 5.59). Рис. 5.59. Набор рассчитываемых записей ПоМесячнойСтавке Алгоритм расчета Пример использования Результат = Размер * Отработанное время / Норматив Используется для расчета окладов. В качестве отрарабочего времени ботанного времени используются данные графика работы за фактический период действия, норматив рабочего времени – данные графика за период действия. В поле Размер указывается тарифная ставка ПроцентомОтБазы Результат = Размер * Расчетная база / 100 Можно использовать для расчета премий. В поле Размер указывается процент премии. Расчетная база складывается из суммы по ресурсу Результат базовых записей за базовый период ФиксированнойСуммой Результат = Размер Простейший способ, может использоваться для начисления фиксированных надбавок ПоСдельнойВыработке Результат = Сдельная выработка за период действия Используется для начисления зарплаты производственным рабочим. Сдельная выработка собирается по регистру накопления СдельнаяВыработка за интервал периода действия записи Имя Таблица 5.16. Назначение видов расчета 630 Реализация прикладных задач в системе «1С:Предприятие 8.2» Глава 5. Реализация сложных периодических расчетов 631 В данном примере производится расчет нескольких записей регистра расчета. При этом существует зависимость по базовому периоду этих записей между собой. В частности, Надбавка руководителю зависит по базовому периоду от оклада, а вид расчета Индексация заработка зависит от всех перечисленных видов расчета (Оклад, Командировка, Надбавка руководителю), так как предполагает начисление доплаты в размере 10 % от заработка. Если рассчитывать эти записи в том порядке, который приведен на схеме, результат расчета записей, зависимых по базовому периоду, будет неверным. В частности, надбавка руководителю будет равна 0, так как на момент расчета в регистре не будет данных об окладе. При расчете записи по индексации заработка не будет учтена командировка, а надбавка руководителю будет учтена с неверной суммой. Таким образом, для того чтобы определить, в каком порядке должны следовать записи, необходимо проанализировать взаимную зависимость по базовому периоду видов расчета, участвующих в этих записях. Виды расчета Оклад и Командировка не являются зависимыми по базовому периоду (табличная часть БазовыеВидыРасчета не содержит строк), поэтому они должны быть рассчитаны в первую очередь. Для их расчета не требуется наличия в регистре других рассчитанных записей. Такие виды расчета можно назвать первичными, приоритет их расчета равен 1, то есть они должны быть рассчитаны в первую очередь. Вид расчета Надбавка руководителю является зависимым по базовому периоду, при этом в его табличной части БазовыеВидыРасчета содержатся только первичные виды расчета (в данном случае Оклад). Запись с таким видом расчета можно записывать сразу после расчета первичных записей, так как в этот момент база их расчета сформирована полностью. Такие виды расчета можно назвать зависимыми от первого уровня, приоритет их расчета равен 2 (то есть они рассчитываются во вторую очередь). Наконец, вид расчета Индексация заработка в списке базовых видов расчета содержит не только первичные виды расчета (Оклад, Командировка), но и зависимые первого уровня (Надбавка руководителю). Поэтому эта запись может быть рассчитана только после того, как рассчитаны первичные записи и зависимые первого уровня. Такой вид расчета можно назвать зависимым второго уровня, приоритет его расчета равен 3. Таким образом, приоритет вида расчета определяется составом его базовых видов расчета (рис. 5.60). Если текущий вид расчета в списке базовых содержит хотя бы один вид расчета, который является зависимым первого уровня, то такой вид расчета является зависимым второго уровня и должен иметь меньший приоритет. Количество уровней зависимости теоретически не ограничено. 632 Реализация прикладных задач в системе «1С:Предприятие 8.2» Рис. 5.60. Приоритет видов расчета Если применить полученные значения приоритета к исходному набору записей, результат их расчета окажется правильным (рис. 5.61). Рис. 5.61. Приоритет расчета записей Записи в рамках одного приоритета могут быть рассчитаны в произвольном порядке. Так, оклад и командировка могут быть рассчитаны в любой последовательности. После расчета записей каждого приоритета полученные значения ресурсов должны быть записаны в регистр расчета перед началом расчета следующих записей. Это связано с тем, что механизм зависимости по базовому периоду реализован в регистре расчета. Запись значений ресурсов в регистр формирует базу для расчета записей со следующим приоритетом. Настройка приоритета видов расчета должна быть доступна пользователю в режиме 1С:Предприятие. Вид этой настройки разработчик определяет самостоятельно. Например, можно добавить в план видов расчета реквизит Приоритет, который будет иметь тип Число. В этом случае пользователь должен указать приоритет видов расчета в этом реквизите. В дальнейшем при расчете записей разработчик должен предусмотреть модуль расчета таким образом, чтобы сначала были рассчитаны записи с видами расчета приоритета 1, затем 2, 3, 4 и так далее. Глава 5. Реализация сложных периодических расчетов 633 Расчет записей регистра расчета Расчет записей регистра расчета может производиться в любой момент, определенный разработчиком. Например, расчет записей может производиться при проведении документа регистрации записей. В этом случае значения ресурсов будут рассчитываться в момент проведения, и пользователь не сможет вручную изменить результат расчетов. Также можно инициировать расчет записей из формы документа. Для этого можно создать на форме кнопку Рассчитать, при нажатии которой будет производиться расчет. В этом случае результат расчета можно поместить в табличную часть документа, для того чтобы пользователь мог скорректировать его вручную. При проведении такого документа записи регистра расчета будут сформированы с учетом ручных корректировок (рис. 5.62). Рис. 5.62. Формирование записей регистра расчета В том и другом случае схема расчета модулей будет схожа (рис. 5.63). Рис. 5.63. Схема расчета 634 Реализация прикладных задач в системе «1С:Предприятие 8.2» Таким образом, расчет записей без проведения документа отличается только наличием двух дополнительных этапов. Рассчитанные значения ресурсов необходимо поместить в табличную часть документа в соответствующие поля, для того чтобы пользователь мог их изменить. После этого необходимо удалить созданные в процессе расчета записи регистров расчета, так как пользователь в данном случае не просил проводить документ. Тем не менее, расчет не может быть выполнен без временной записи данных в регистр расчета, так как все расчетные механизмы платформы (вытеснение, зависимость по базовому периоду, расчет по графику, перерасчет) применимы только к записям регистров расчета. Если в документе настроен расчет записей без проведения, то в момент проведения такого документа собственно расчета уже не происходит. В ресурсы регистра расчета попадают значения из табличной части документа, которые пользователь мог скорректировать после расчета. Рассмотрим основные этапы расчета записей более подробно. Далее будет рассмотрен вариант расчета без проведения документа на примере регистра расчета ОсновныеНачисленияРегл. Все рассматриваемые процедуры доступны в демоконфигурации в документе НачислениеЗарплаты, а также в общих модулях Расчеты и ОбщегоНазначения. Формирование набора записей по данным документа Для расчета записей необходимо сначала сформировать набор этих записей в регистре расчета. Это позволит использовать расчетные механизмы платформы. Формирование записей при расчете аналогично рассмотренному выше модулю формирования записей при проведении. Однако если при проведении в качестве набора записей выступали движения документа по регистру (Движения.ОсновыеНачисленияРегл), то при расчете без проведения такой набор необходимо создать. Ниже приведен модуль, позволяющий сформировать набор записей регистра расчета по данным документа (листинг 5.6). В тексте используется процедура ДобавитьСтрокуОсновныхНачислений(), описанная выше. Этот модуль является начальным этапом процедуры РассчитатьОсновныеНачисления(), которая вызывается при нажатии кнопки Рассчитать в форме документа. Глава 5. Реализация сложных периодических расчетов 635 Листинг 5.6. Формирование набора записей регистра расчета Процедура РассчитатьОсновныеНачисления() Экспорт // Расчет записей выполняется в транзакции НачатьТранзакцию(); // Создать набор записей регистра расчета НаборОсновныеНачисления = РегистрыРасчета.ОсновныеНачисленияРегл. СоздатьНаборЗаписей(); НаборОсновныеНачисления.Отбор.Регистратор.Значение = Ссылка; ВыборкаОсновныеНачисления = ОбщегоНазначения .СформироватьЗапросПоТабличнойЧасти(ЭтотОбъект, "ОсновныеНачисления").Выбрать(); Пока ВыборкаОсновныеНачисления.Следующий() Цикл ДобавитьСтрокуОсновныхНачислений(ВыборкаОсновныеНачисления, НаборОсновныеНачисления); КонецЦикла; // Расчет записей набора // ..... ЗафиксироватьТранзакцию(); КонецПроцедуры // РассчитатьОсновныеНачисления При формировании набора записей значения ресурсов не играют роли, так как они будут в дальнейшем изменены при расчете. В том числе эти значения могут быть пустыми. Добавление в набор сторно-записей Если в рассчитываемом регистре установлено свойство Период действия, в сформированном наборе могут присутствовать записи, у которых период действия принадлежит более раннему периоду, чем период регистрации. В этом случае они могут вступать в конкуренцию на этом периоде действия с записями более раннего периода регистрации. Чтобы такие записи могли иметь непустой фактический период действия, необходимо дополнить сформированный набор соответствующими сторно-записями. Подробнее механизм сторнирования был рассмотрен в разделе «Сторнирование» на стр. 612. Добавление сторно-записей происходит с использованием метода ПолучитьДополнение() набора записей регистра. Ниже приведен текст модуля, позволяющий добавить в набор сторно-записи. Добавление записи происходит при помощи вызова процедуры ДобавитьСтрокуСторноОсновныхНачислений(), которая должна быть описана в процедуре РассчитатьОсновныеНачисления(). При этом для каждой сторно-записи необходимо добавить новую строку в табличную часть документа, чтобы при проведении эта запись попала в регистр (листинг 5.7). 636 Реализация прикладных задач в системе «1С:Предприятие 8.2» Листинг 5.7. Добавление сторно-записей // Добавить сторно-записи в набор и в табличную часть Процедура ДобавитьСтрокуСторноОсновныхНачислений(ДанныеСтроки, НаборЗаписей, ТабличнаяЧасть = Неопределено) Движение = НаборЗаписей.Добавить(); // Предопределенные поля Движение.ПериодРегистрации = ДанныеСтроки.ПериодРегистрацииСторно; Движение.ПериодДействияНачало = ДанныеСтроки.ПериодДействияНачалоСторно; Движение.ПериодДействияКонец = ДанныеСтроки.ПериодДействияКонецСторно; Движение.ВидРасчета = ДанныеСтроки.ВидРасчета; Движение.Сторно= Истина; // Измерения Движение.ФизЛицо = ДанныеСтроки.ФизЛицо; Движение.Организация = ДанныеСтроки.Организация; // Реквизиты Движение.ГрафикРаботы = ДанныеСтроки.ГрафикРаботы; Движение.Размер = ДанныеСтроки.Размер; Движение.ВидУчетаВремени = ДанныеСтроки.ВидУчетаВремени; Движение.Подразделение = ДанныеСтроки.Подразделение; Движение.СтатьяЗатрат = ДанныеСтроки.СтатьяЗатрат; Если Не ТабличнаяЧасть = Неопределено Тогда НоваяСтрока = ТабличнаяЧасть.Добавить(); НоваяСтрока.ФизЛицо = ДанныеСтроки.ФизЛицо; НоваяСтрока.ВидРасчета = ДанныеСтроки.ВидРасчета; НоваяСтрока.ДатаНачало = ДанныеСтроки.ПериодДействияНачалоСторно; НоваяСтрока.ДатаКонец = ДанныеСтроки.ПериодДействияКонецСторно; НоваяСтрока.Размер = ДанныеСтроки.Размер; НоваяСтрока.Подразделение = ДанныеСтроки.Подразделение; НоваяСтрока.Сторно = Истина; КонецЕсли; КонецПроцедуры // ДобавитьСтрокуСторноОсновныхНачислений // Процедура расчета основных начислений Процедура РассчитатьОсновныеНачисления() Экспорт НачатьТранзакцию(); // Сформировать набор записей // … // Сформировать таблицу сторно-записей ТаблицаСторно = НаборОсновныеНачисления.ПолучитьДополнение(); // Добавить сторно-записи в набор Для Каждого СтрокаСторно из ТаблицаСторно Цикл ДобавитьСтрокуСторноОсновныхНачислений(СтрокаСторно, НаборОсновныеНачисления, ОсновныеНачисления); КонецЦикла; // … ЗафиксироватьТранзакцию(); КонецПроцедуры // РассчитатьОсновныеНачисления Глава 5. Реализация сложных периодических расчетов 637 При формировании сторно-записей данные всех измерений и реквизитов записи указаны в строке дополнения. Также в этой строке содержатся данные о периоде регистрации и периоде действия сторно-записи. Ресурсы сторнозаписи не заполняются, так как запись будет рассчитана в общем порядке. Расчет набора записей в общем модуле Сформированный документом набор записей регистра расчета рекомендуется рассчитывать в процедурах общего модуля. Это связано с тем, что формирование записей, как правило, происходит в нескольких документах, тогда как модуль расчета этих записей один и тот же. Например, оплата отпусков может вводиться отдельным документом конфигурации, при этом записи об отпуске рассчитываются в общем порядке. Таким образом, функция документов в решениях по периодическим расчетам сводится, как правило, к формированию первоначального набора записей в регистре, а все сложные алгоритмы расчета должны быть расположены в общем модуле как единые для всех документов. Ниже приведен пример вызова процедуры общего модуля РассчитатьЗаписиРегистраРасчета() (листинг 5.8). Сама процедура будет описана позже. Листинг 5.8. Пример процедуры «РассчитатьОсновныеНачисления()» Процедура РассчитатьОсновныеНачисления() Экспорт // Расчет записей выполняется в транзакции НачатьТранзакцию(); // Сформировать набор и добавить сторно-записи // … … … … … // Передать набор записей в процедуру общего модуля для расчета Расчеты.РассчитатьЗаписиРегистраРасчета("ОсновныеНачисленияРегл", НаборОсновныеНачисления, ОсновныеНачисления); // Удалить движения по регистру НаборОсновныеНачисления.Очистить(); НаборОсновныеНачисления.Записать(); ЗафиксироватьТранзакцию(); КонецПроцедуры // РассчитатьОсновныеНачисления В качестве параметров в процедуру расчета в данном случае передается название регистра, набор записей для расчета, а также табличная часть документа, в которую будут возвращены результаты расчетов. После получения результатов расчетов происходит удаление записей регистра расчета, так как документ рассчитывался без проведения. 638 Реализация прикладных задач в системе «1С:Предприятие 8.2» Результаты расчетов помещаются в табличную часть, и пользователь может их скорректировать. Окончательные записи регистра расчета формируются по табличной части документа при его проведении (рис. 5.64). Рис. 5.64. Схема взаимодействия объектов В процедуре общего модуля, выполняющей расчет записей переданного набора, необходимо предусмотреть выполнение следующих действий (рис. 5.65). Рис. 5.65. Действия в процедуре общего модуля Рассмотрим эти действия подробнее. В данном случае эти действия выполняются в процедуре общего модуля Расчеты, которая называется РассчитатьЗаписиРегистраРасчета(). Глава 5. Реализация сложных периодических расчетов 639 Запись набора с формированием фактического периода действия Перед тем как рассчитывать записи каждого регистра расчета, в котором документ создает движения, необходимо сформировать и записать в регистр набор всех записей документа по этому регистру. Первоначальная запись движений в регистр расчета необходима для формирования правильного фактического периода действия этих записей. В случае последовательного ввода и расчета записей без предварительной записи всего набора результат расчета может оказаться неверным. Рассмотрим влияние этого действия на следующем примере записей документа (рис. 5.66). Рис. 5.66. Пример расчета записей регистра При последовательной записи и расчете этих начислений результат расчета оклада будет неверным, так как в момент расчета оклада записи о командировке еще не будет в регистре, соответственно, фактический период действия оклада будет совпадать с периодом действия, и сотруднику будет начислен полный тариф оклада. В момент записи командировки произойдет вытеснение, и фактический период действия оклада изменится, но на результат его расчета это уже не повлияет, так как запись уже рассчитана. Для формирования правильного фактического периода действия с учетом всех вытеснений в рамках одного набора записей необходимо предварительно записать весь набор в регистр. В момент записи сработает механизм вытеснения, и будет сформирован фактический период действия каждой записи. В этом случае в момент расчета каждая запись будет иметь правильный фактический период действия (рис. 5.67). Для того чтобы запись производилась с расчетом фактического периода действия и формированием записей перерасчетов, о которых будет сказано в следующем разделе, необходимо при вызове метода Записать() набора записей регистра расчета во второй параметр метода (параметр ТолькоЗапись) передать значение Ложь. При установке параметра ТолькоЗапись в значение Истина записи будут помещены в регистр без пересчета фактического периода действия (листинг 5.9). 640 Реализация прикладных задач в системе «1С:Предприятие 8.2» Рис. 5.67. Формирование фактического периода действия Листинг 5.9. Пример расчета записей регистра Процедура РассчитатьЗаписиРегистраРасчета(ИмяРегистра, НаборЗаписей, ТабличнаяЧасть = Неопределено) Экспорт // Первоначальная запись набора с формированием фактического // периода действия НаборЗаписей.Записать(Истина, Ложь); // Расчет записей // ................... КонецПроцедуры Классификация записей по приоритету видов расчета Как уже отмечалось выше, расчет записей одного документа необходимо производить в последовательности, определяемой приоритетом видов расчета, участвующих в этих записях. Поэтому исходный набор записей должен быть разбит на несколько поднаборов, в каждом из которых будут записи одного приоритета. Затем необходимо последовательно рассчитать записи каждого из поднаборов, записав результат расчета в регистр. Запись каждого рассчитанного поднабора необходима для формирования базы расчета следующих по приоритету поднаборов. Ниже приведен пример процедуры, которая классифицирует записи исходного набора по приоритету видов расчета и для каждого уровня приоритета вызывает процедуру расчета поднабора записей. В данном случае из набора записей выгружается массив видов расчета, после чего по этим видам расчета строится запрос с иерархией по приоритету (листинг 5.10). Глава 5. Реализация сложных периодических расчетов 641 Листинг 5.10. Расчет записей по приоритету видов расчета Процедура РассчитатьЗаписиРегистраРасчета(ИмяРегистра, НаборЗаписей, ТабличнаяЧасть = Неопределено) Экспорт НаборЗаписей.Записать(Истина, Ложь); // Определить название плана видов расчета для запроса ИмяПланаВидовРасчета = Метаданные.РегистрыРасчета[ИмяРегистра].ПланВидовРасчета.Имя; // Получить массив видов расчета из набора записей ТаблицаВидовРасчета = НаборЗаписей.Выгрузить(); ТаблицаВидовРасчета.Свернуть("ВидРасчета"); МассивВидовРасчета = ТаблицаВидовРасчета.ВыгрузитьКолонку("ВидРасчета"); // Запрос по приоритетам видов расчета Запрос = Новый Запрос; Запрос.Текст = " |ВЫБРАТЬ РАЗЛИЧНЫЕ | Приоритет |ИЗ | ПланВидовРасчета." + ИмяПланаВидовРасчета + " КАК " + ИмяПланаВидовРасчета + " |ГДЕ | Ссылка В (&МассивВидовРасчета) |УПОРЯДОЧИТЬ ПО | " + ИмяПланаВидовРасчета + ".Приоритет |ИТОГИ ПО | Приоритет"; Запрос.УстановитьПараметр("МассивВидовРасчета", МассивВидовРасчета); ВыборкаПриоритетов = Запрос.Выполнить().Выбрать(ОбходРезультатаЗапроса.ПоГруппировкам); // Для каждого значения приоритета выполнить расчет записей Пока ВыборкаПриоритетов.Следующий() Цикл РассчитатьНаборЗаписей(НаборЗаписей, ВыборкаПриоритетов.Приоритет, ТабличнаяЧасть); // Записать набор в регистр для расчета записей следующего // приоритета, фактический период действия не пересчитывается НаборЗаписей.Записать(Истина, Истина); КонецЦикла; КонецПроцедуры После расчета записей каждого приоритета необходимо перезаписать весь набор в регистр для образования базы расчета для записей следующего приоритета. При этом параметр ТолькоЗапись метода Записать() должен быть установлен в значение Истина, так как пересчитывать фактический период действия уже не нужно, он был рассчитан при первоначальной записи. 642 Реализация прикладных задач в системе «1С:Предприятие 8.2» ПРИМЕЧАНИЕ После расчета записей последнего приоритета набор записей можно не перезаписывать, но только в том случае, если в документе после этого не будет производиться расчет записей другого регистра, который может использовать данные текущего регистра как базу. Например, если после расчета регистра основных начислений в модуле будет сразу производиться расчет дополнительных начислений, то записи регистра основных начислений после расчета последнего приоритета должны быть перезаписаны. Получение данных для расчета Собственно процесс расчета записей каждого поднабора состоит в получении всех необходимых данных для расчета каждой записи и вычислении значений ресурсов этой записи по формуле, определяемой способом расчета данной записи. Например, для расчета записи об окладе нужно будет получить данные графика этой записи, для расчета премии необходимо будет рассчитать базу и так далее. Ниже приведен пример процедуры, осуществляющей расчет набора записей одного приоритета. Для каждой записи при помощи функции ПолучитьДанныеДляРасчета() возвращается структура данных, которая передается в процедуру РассчитатьЗапись() (листинг 5.11). Процедура РассчитатьЗапись() будет описана позже. Листинг 5.11. Расчет набора записей одного приоритета Процедура РассчитатьНаборЗаписей(НаборЗаписей, Приоритет, ТабличнаяЧасть = Неопред