Неверный тип параметра измерения основного регистра 1с
В платформе 1С:Предприятие 8.х реализовано два механизма обмена данными: универсальный механизм обмена данными и механизм распределенной информационной базы. Оба эти механизма базируются на одних тех же технологиях. Одной из этих технологий является служба регистрации изменений данных.
Изменения данных могут регистрироваться в автоматическом режиме. Для этого необходимо при включении объекта метаданных в состав плана обмена разрешить автоматическую регистрацию: установить признак Авторегистрация в значение Разрешить.
Однако часто требуется регистрация не каждого изменения данных, или регистрация изменений смежных объектов, или зависящих от изменяемых данных. Это можно выполнить различными способами.
Для регистрации изменений всех данных для конкретного узла плана обмена необходимо вызвать метод ЗарегистрироватьИзменения() менеджера планов обмена, передав ему в качестве параметра Данные значение Неопределено.
Для регистрации изменений данных одного типа необходимо вызвать метод ЗарегистрироватьИзменения() менеджера планов обмена, передав ему в качестве параметра Данные объект описания метаданных, соответствующий данным.
Пример: регистрация изменения всех элементов справочника Номенклатура для узла Узел:
Код 1C v 8.х
Для регистрации конкретных данных различных типов необходимо вызвать метод ЗарегистрироватьИзменения() менеджера планов обмена, передав ему в качестве параметра Данные либо сами данные, либо ссылку на них.
К объектным типам относятся справочники, документы, планы счетов, планы видов характеристик, планы расчета, бизнес-процессы, задачи. Для их регистрации необходимо вызвать метод ЗарегистрироватьИзменения() менеджера планов обмена, передав ему в качестве параметра Данные либо сам объект, либо ссылку на него.
К таким регистрам относятся регистры накопления, регистры бухгалтерии, регистры расчета и регистры сведений со свойством РежимЗаписи, установленным в значение ПодчинениеРегистратору. Для регистрации изменений наборов записей указанных регистров необходимо вызвать метод ЗарегистрироватьИзменения() менеджера планов обмена, передав ему в качестве параметра Данные набор записей с установленным отбором, в котором в элемент отбора Регистратор установлено значение регистратора данного набора записей. При этом чтение данных набора записей перед его регистрацией не обязательно.
К таким регистрам относятся регистры сведений со свойством РежимЗаписи, установленным в значение Независимый. Для регистрации изменений наборов записей данного регистра необходимо вызвать метод ЗарегистрироватьИзменения() менеджера планов обмена, передав ему в качестве параметра Данные набор записей. Состав элементов отбора, при этом, должен строго соответствовать основному отбору регистра. Выбирать поля, входящие в основной отбор регистра необходимо в соответствии с логикой работы конфигурации (см. Подготовка конфигурации к работе в распределенной информационной базе).
Для регистрации данных регистра сведений, отбираемых по некоторому критерию, необходимо:
выбрать уникальные значения измерений регистра, входящих в основной отбор (если регистр сведений является периодическим и Период включен в основной отбор, то Период также должен участвовать в отборе)
выполнить регистрацию наборов записей с установленными значениями отбора, соответствующими каждой выбранной комбинации значений измерений (входящих в основной отбор).
Свойство Базовое измерения регистра расчета
Одна из задач, решаемых при помощи регистров расчета - получение оборотов регистра при помощи запросов к виртуальной таблице базовых данных или метода ПолучитьБазу() . Обороты регистра получаются на основании большого числа разных исходных данных, в том числе настроек и содержимого плана видов расчета, настроек регистра расчета, параметров виртуальной таблицы базовых данных и т.п. Но одну из существенных ролей при получении базовых данных играют измерения регистра расчета.
Роль измерений при параметризации виртуальной таблицы базовых данных
Один из важных параметров виртуальной таблицы базовых данных - список измерений, по которым выполняется сопоставление записей регистра при суммировании данных. Для решения разных задач, возможно, придется выполнять суммирование ресурсов регистра по разным наборам измерений. Рассмотрим на примере регистра, предназначенного для расчета зарплаты и имеющего три измерения:
- Организация,
- Физлицо,
- Подразделение.
Представим, что необходимо решить следующие задачи:
- Получение для тех или иных записей регистра оборотов регистра по всем записям с таким же подразделением, как и у исходной записи. Это может быть, например, расчет надбавки, зависящий от начислений всего подразделения.
- Получение оборотов по записям с таким же Физлицом и Подразделением. Т.е. получение суммы начислений работника, которые ему же начислены в том же подразделении (исключаются начисления по этому же работнику, которые он получил по другим подразделениям).
- Получение оборотов по записям с таким же Физлицом и такой же Организацией (все начисления Физлицу в рамках той же организации).
Все перечисленные задачи решаются при помощи запросов к виртуальной таблице базовых данных. При этом параметры "Измерения основного регистра" и "Измерения базового регистра" будут для всех трех задач разными. В первом случае измерение одно - "Подразделение"; во втором - "Физлицо" и "Подразделение"; в третьем - "Организация" и "Физлицо".
Оптимизация получения базовых данных
Для перечисленных выше случаев при формировании запроса к виртуальной таблице базовых данных система будет, в терминах языка запросов, выполнять "левое соединение" таблицы регистра расчета с той же таблицей. При этом одно из условий соединения - равенство значений в полях, заданных как измерения основного и базового регистра. Разумеется, помимо этого условия есть сравнение периода действия или периода регистрации с началом и окончанием базового периода, сравнение видов расчета и т.п., но самым "жестким" ограничением, как правило, бывает ограничение по значениям измерений.
Таким образом, для эффективной работы результирующего запроса важно иметь индекс таблицы регистра расчета, который в качестве первых полей содержал бы поля сопоставляемых измерений.
Возможность индексирования измерений регистра расчета позволяет решить такую задачу, но только для случая, когда сопоставляется одно измерение (в нашем примере - задача получения данных по подразделению). В том случае, когда сопоставляемых измерений два и более требуется построить индекс по нескольким измерениям сразу.
Именно эту задачу и позволяет решить свойство Базовое измерения регистра расчета. Устанавливая это свойство нескольким измерениям, разработчик конфигурации тем самым создает индекс по всем отмеченным как "базовые" измерениям (более подробно - см. раздел "Индексы таблиц базы данных").
Из сказанного ясно, что для регистра расчета можно создать только один такой индекс для оптимизации получения базовых данных, выбрав те или иные измерения. Таким образом, при разработке важно правильно оценить, какие именно виртуальные таблицы будут чаще использоваться, и оптимизация работы которых наиболее важна.
Вернемся к нашему примеру. Представим себе, что начисления, которые требуют получения данных по физлицу и подразделению будут при эксплуатации конфигурации встречаться реже, чем начисления, которые требуют получения данных по физлицу и организации. Тогда следует в качестве базовых измерений отметить измерения "Организация" и "Физлицо". Нам при этом придется мириться с тем, что получение базовых данных по физлицу и подразделению будет выполняться относительно медленно.
При выборе базовых измерений следует также оценивать их "селективность", т.е. представлять насколько много значений будет в том или ином измерении при эксплуатации конфигурации. Представим себе, что в нашем примере у одного физлица может встречаться очень мало (одна-две) организаций и относительно много подразделений. Т.е. физлицу почти всегда начисляется зарплата по одной организации и при этом часто начисляется зарплата по разным подразделениям. При таких обстоятельствах разумнее в качестве базовых выбрать измерения "Физлицо" и "Подразделение".
Но при этом важно помнить о порядке измерений регистра расчета.
О порядке измерений в регистре расчета
Дело в том, что при создании индекса, который облегчит получение базовых данных, система включает в него измерения в той последовательности, в которой они расположены в дереве конфигурации. Это значит, что просто "переставив местами" измерения "Физлицо" и "Подразделение" мы поменяем порядок полей в индексе.
В нашем примере, если в качестве базовых выбраны измерения "Физлицо" и "Подразделения", то, переставив их местами, мы не изменим скорость получения базовых данных по физлицу и подразделению, но радикально ухудшим ситуацию с получением данных по физлицу и организации. При сравнении значений в полях "Организация" и "Физлицо" система не сможет использовать индекс Подразделение+Физлицо, так как поле "Физлицо" в нем не является первым, а на подразделение условие не налагается. А в случае индекса Физлицо+Подразделение выиграют и получение базовых данных по подразделению и физлицу, и получение базовых данных по организации и физлицу, так как поле "Физлицо" будет в индексе первым, то система сможет его использовать "частично" (по одному полю). Вместе с тем поле "Физлицо" обладает гораздо большей "селективностью", чем поле "Организация" и на отработку условия по организации не потребуется много времени.
Если базовое измерение одно
Не забудем и про задачу нашего примера, предполагающую получение базовых данных только по подразделению. Казалось бы, создание индекса Физлицо+Подразделение для решения двух остальных задач исключает эффективную работу виртуальной таблицы базовых данных по одному измерению "Подразделение". Но здесь нужно вспомнить о возможности индексирования измерений регистра (свойство Индексирование ). Возможность индексировать измерение позволяет эффективно решить задачу получения базы по одному базовому измерению.
Таким образом, в рассмотренном нами примере необходимо выставить свойство Базовое измерениям "Физлицо" и "Подразделение", свойство Индексирование измерению "Подразделение", а также убедится в том, что измерение "Физлицо" "выше" измерения "Подразделение" (порядок измерения "Организация" при этом не важен).
Получение базовых данных в регистрах расчета
При работе с регистрами расчета есть возможность получения базовых данных. Это своеобразный способ расчета оборотов регистра, при котором функция расчета оборотов не является простой функцией суммирования ресурсов регистра по измерениям за определенный период, а представляет собой более сложную функцию. Эта функция зависит от состояния плана видов расчета, назначенного регистру расчета и, таким образом, управляется пользователем.
В данном разделе мы рассмотрим два существующих в системе способа получения базовых данных - при помощи языка запросов и при помощи функциональной записи, методом ПолучитьБазу() . При этом будет называть "основным" регистром расчета тот регистр, для которого необходимо получить базовые данные, а "базовыми" регистрами (которых в общем случае может быть несколько) будем называть те регистры, для которых выполняется суммирование ресурсов.
Мы не будем рассматривать эти способы подробно, рассмотрим только их отличия и область применения.
Метод ПолучитьБазу()
Метод ПолучитьБазу() определен для объектов РегистрРасчетаМенеджер.<Имя регистра расчета> и РегистрРасчетаЗапись.<Имя регистра расчета> . Метод позволяет задать ресурсы базовых регистров, по которым необходимо получить обороты, задать поля, в разрезе которых нужно получить обороты и задать правила сопоставления измерений основного и базовых регистров расчета.
Правила сопоставления записей регистров расчета задаются структурой, каждый элемент которой задает для того или иного измерения основного регистра список измерений базовых регистров расчета. Имена элементов структуры должны совпадать с именами измерений основного регистра, а значения элементов структуры - строки, со списком измерений базовых регистров через запятую. Если элемент структуры с именем того или иного измерения не задан, то это значит, что на соответствующее измерение не налагается условие.
Имена измерений и ресурсов базовых регистров задаются в формате <ИмяРегистраРасчета>.<ИмяПоля>.
Пример использования метода:
В приведенном выше примере измерение "Физлицо" основного регистра при получении оборотов будет сопоставляться с измерением "Физлицо" базового регистра "ОсновныеНачисления" и измерением "Работник" базового регистра "ДополнительныеНачисления".
Таблица языка запросов для получения базовых данных
Для получения базовых данных в языке запросов определены виртуальные таблицы "РегистрРасчета.<Имя регистра расчета>.База<Имя базового регистра расчета>". В качестве параметров виртуальной таблицы задаются измерения основного регистра, измерения базового регистра и поля, в разрезе которых нужно получить базовые данные. Измерения и разрезы задаются как массив (или список значений) строк с именами измерений.
Пример написания запроса с использованием виртуальных таблиц базовых данных:
Приведенный пример предполагает ту же структуру данных и ту же решаемую задачу, что и пример для метода ПолучитьБазу() . При этом мы видим заметное увеличение исходного кода и кажущуюся его сложность.
Сравнение
Заметным отличием функционального метода получения базовых данных и получения при помощи запроса является то, что в функциональном методе одним вызовом метода можно получить базовые данные по всем базовым регистрам, а при использовании запросов получение базовых данных делается запросом к нескольким таблицам - по числу базовых регистров. Тем не менее, рекомендуемым способом получения данных является получение данных запросом. Это позволит, например, получить не только данные базовых видов расчета, но и дополнительную информацию, необходимую для расчета.
Отметим, что производительность получения данных при помощи функционального метода и при помощи запроса одинакова несмотря на кажущееся усложнение исполняемого кода в случае с запросами.
Краткая функциональная запись с использованием метода ПолучитьБазу() допустима только в том случае, если нет необходимости в иных данных помимо базовых, и при этом хочется "сэкономить" на строках кода. Совершенно не допустимо из соображений производительности кода, применение метода ПолучитьБазу() в том случае, если после его использование все равно придется при помощи запроса получать дополнительные данные для расчета.
Еще одно соображение касается условий отбора базовых данных. Для метода ПолучитьБазу() , фактически, нет возможности получить базовые данные иначе, чем по одной записи или по конкретному регистратору (с отбором по тем или иным измерениям). В случае же запроса в распоряжении у разработчика все возможности языка запросов по отбору записей.
При работе с регистрами расчета есть возможность получения базовых данных. Это своеобразный способ расчета оборотов регистра, при котором функция расчета оборотов не является простой функцией суммирования ресурсов регистра по измерениям за определенный период, а представляет собой более сложную функцию. Эта функция зависит от состояния плана видов расчета, назначенного регистру расчета и, таким образом, управляется пользователем.
В данном разделе мы рассмотрим два существующих в системе способа получения базовых данных - при помощи языка запросов и при помощи функциональной записи, методом ПолучитьБазу(). При этом будет называть "основным" регистром расчета тот регистр, для которого необходимо получить базовые данные, а "базовыми" регистрами (которых в общем случае может быть несколько) будем называть те регистры, для которых выполняется суммирование ресурсов.
Мы не будем рассматривать эти способы подробно, рассмотрим только их отличия и область применения.
Метод ПолучитьБазу()
Метод ПолучитьБазу() определен для объектов РегистрРасчетаМенеджер.<Имя регистра расчета> и РегистрРасчетаЗапись.<Имя регистра расчета>. Метод позволяет задать ресурсы базовых регистров, по которым необходимо получить обороты, задать поля, в разрезе которых нужно получить обороты и задать правила сопоставления измерений основного и базовых регистров расчета.
Правила сопоставления записей регистров расчета задаются структурой, каждый элемент которой задает для того или иного измерения основного регистра список измерений базовых регистров расчета. Имена элементов структуры должны совпадать с именами измерений основного регистра, а значения элементов структуры - строки, со списком измерений базовых регистров через запятую. Если элемент структуры с именем того или иного измерения не задан, то это значит, что на соответствующее измерение не налагается условие.
Имена измерений и ресурсов базовых регистров задаются в формате <ИмяРегистраРасчета>.<ИмяПоля>.
Пример использования метода:
Код 1C v 8.х
В приведенном выше примере измерение "Физлицо" основного регистра при получении оборотов будет сопоставляться с измерением "Физлицо" базового регистра "ОсновныеНачисления" и измерением "Работник" базового регистра "ДополнительныеНачисления".
Таблица языка запросов для получения базовых данных
Для получения базовых данных в языке запросов определены виртуальные таблицы "РегистрРасчета.<Имя регистра расчета>.База<Имя базового регистра расчета>". В качестве параметров виртуальной таблицы задаются измерения основного регистра, измерения базового регистра и поля, в разрезе которых нужно получить базовые данные. Измерения и разрезы задаются как массив (или список значений) строк с именами измерений.
Пример написания запроса с использованием виртуальных таблиц базовых данных:
Код 1C v 8.х
Приведенный пример предполагает ту же структуру данных и ту же решаемую задачу, что и пример для метода ПолучитьБазу(). При этом мы видим заметное увеличение исходного кода и кажущуюся его сложность.
Сравнение
Заметным отличием функционального метода получения базовых данных и получения при помощи запроса является то, что в функциональном методе одним вызовом метода можно получить базовые данные по всем базовым регистрам, а при использовании запросов получение базовых данных делается запросом к нескольким таблицам - по числу базовых регистров. Тем не менее, рекомендуемым способом получения данных является получение данных запросом. Это позволит, например, получить не только данные базовых видов расчета, но и дополнительную информацию, необходимую для расчета.
Отметим, что производительность получения данных при помощи функционального метода и при помощи запроса одинакова несмотря на кажущееся усложнение исполняемого кода в случае с запросами.
Краткая функциональная запись с использованием метода ПолучитьБазу() допустима только в том случае, если нет необходимости в иных данных помимо базовых, и при этом хочется "сэкономить" на строках кода. Совершенно не допустимо из соображений производительности кода, применение метода ПолучитьБазу() в том случае, если после его использование все равно придется при помощи запроса получать дополнительные данные для расчета.
Еще одно соображение касается условий отбора базовых данных. Для метода ПолучитьБазу(), фактически, нет возможности получить базовые данные иначе, чем по одной записи или по конкретному регистратору (с отбором по тем или иным измерениям). В случае же запроса в распоряжении у разработчика все возможности языка запросов по отбору записей.
В платформе 1С:Предприятие 8.х реализовано два механизма обмена данными: универсальный механизм обмена данными и механизм распределенной информационной базы. Оба эти механизма базируются на одних тех же технологиях. Одной из этих технологий является служба регистрации изменений данных.
Изменения данных могут регистрироваться в автоматическом режиме. Для этого необходимо при включении объекта метаданных в состав плана обмена разрешить автоматическую регистрацию: установить признак Авторегистрация в значение Разрешить.
Однако часто требуется регистрация не каждого изменения данных, или регистрация изменений смежных объектов, или зависящих от изменяемых данных. Это можно выполнить различными способами.
Для регистрации изменений всех данных для конкретного узла плана обмена необходимо вызвать метод ЗарегистрироватьИзменения() менеджера планов обмена, передав ему в качестве параметра Данные значение Неопределено.
Для регистрации изменений данных одного типа необходимо вызвать метод ЗарегистрироватьИзменения() менеджера планов обмена, передав ему в качестве параметра Данные объект описания метаданных, соответствующий данным.
Пример: регистрация изменения всех элементов справочника Номенклатура для узла Узел:
Код 1C v 8.х
Для регистрации конкретных данных различных типов необходимо вызвать метод ЗарегистрироватьИзменения() менеджера планов обмена, передав ему в качестве параметра Данные либо сами данные, либо ссылку на них.
К объектным типам относятся справочники, документы, планы счетов, планы видов характеристик, планы расчета, бизнес-процессы, задачи. Для их регистрации необходимо вызвать метод ЗарегистрироватьИзменения() менеджера планов обмена, передав ему в качестве параметра Данные либо сам объект, либо ссылку на него.
К таким регистрам относятся регистры накопления, регистры бухгалтерии, регистры расчета и регистры сведений со свойством РежимЗаписи, установленным в значение ПодчинениеРегистратору. Для регистрации изменений наборов записей указанных регистров необходимо вызвать метод ЗарегистрироватьИзменения() менеджера планов обмена, передав ему в качестве параметра Данные набор записей с установленным отбором, в котором в элемент отбора Регистратор установлено значение регистратора данного набора записей. При этом чтение данных набора записей перед его регистрацией не обязательно.
К таким регистрам относятся регистры сведений со свойством РежимЗаписи, установленным в значение Независимый. Для регистрации изменений наборов записей данного регистра необходимо вызвать метод ЗарегистрироватьИзменения() менеджера планов обмена, передав ему в качестве параметра Данные набор записей. Состав элементов отбора, при этом, должен строго соответствовать основному отбору регистра. Выбирать поля, входящие в основной отбор регистра необходимо в соответствии с логикой работы конфигурации (см. Подготовка конфигурации к работе в распределенной информационной базе).
Для регистрации данных регистра сведений, отбираемых по некоторому критерию, необходимо:
выбрать уникальные значения измерений регистра, входящих в основной отбор (если регистр сведений является периодическим и Период включен в основной отбор, то Период также должен участвовать в отборе)
выполнить регистрацию наборов записей с установленными значениями отбора, соответствующими каждой выбранной комбинации значений измерений (входящих в основной отбор).
Читайте также: