Что такое разделитель в 1с
В случаях, когда нужно разбить строку на части, чаще всего используется один из методов:
- СтрРазделить() - платформенный метод
- РазложитьСтрокуВМассивПодстрок() - функция общего модуля БСП
Всеми рекомендуется использовать СтрРазделить(), так как это платформенный и более оптимизированный метод. Однако, при этом часто забывают, что он не полностью идентичен второму. И в некоторых случаях применить его не получится.
Разберём нагляднее параметры по-порядку:
СтрРазделить(<Строка>, <Разделитель>, <ВключатьПустые>)
РазложитьСтрокуВМассивПодстрок(<Строка>, <Разделитель>, <ПропускатьПустыеСтроки>, <СокращатьНепечатаемыеСимволы>)
- <Строка>
Тут всё понятно. Строка, которую нужно разделить. - <Разделитель>
Вроде тоже ясно. Строка, которая является разделителем.
Однако. Этот параметр оба метода используют по-разному, когда его значение больше, чем один символ.
У СтрРазделить() каждый символ в параметре является отдельным разделителем. В то время как в РазложитьСтрокуВМассивПодстрок() он цельный.
"б1" - цельный разделитель
"б1" - набор из двух несвязанных разделителей. "б" и "1".
Выходит, что когда нам необходимо в качестве разделителя использовать некую строку, то используем метод РазложитьСтрокуВМассивПодстрок(). Ведь платформенный СтрРазделить() сработает иначе.
Так же интересная особенность. Если в этот параметр передать пустую строку, то СтрРазделить() вернёт массив с одним элементов (всей строкой). А РазложитьСтрокуВМассивПодстрок() уйдёт в небытие.
3 . <ВключатьПустые> и <ПропускатьПустыеСтроки>
Параметр хоть и схож, но, снова, не полностью идентичен.
Платформенный метод имеет два положения: Ложь или Истина. Либо результат метода будет содержать пустые строки, либо нет.
В то время, как метод БСП имеет чуть более расширенный функционал, а именно:
Если параметр не задан, то функция работает в режиме совместимости со своей предыдущей версией:
- для разделителя-пробела пустые строки не включаются в результат, для остальных разделителей пустые строки включаются в результат.
- если параметр Строка не содержит значащих символов или не содержит ни одного символа (пустая строка), то в случае разделителя-пробела результатом функции будет массив, содержащий одно значение "" (пустая строка), а при других разделителях результатом функции будет пустой массив.
Получается, если не передать параметр, то БСП сама решит догадаться, нужно ли сохранять пустые элементы или нет. По мне так, если нет необходимости, лучше всегда указывать конкретно логику, чтобы и самому не путаться и не путать других.
4. <СокращатьНепечатаемыеСимволы>
Данный параметр есть только в РазложитьСтрокуВМассивПодстрок().
Всё просто - нужно ли к каждому элементу массива применять СокрЛП (избавлять слева и справа всякие пробелы и переносы строк).
СтрРазделить() этого делать не умеет. Однако, замеры скорости показывают, что быстрее будет обойти циклом результат СтрРазделить(), чем использовать РазложитьСтрокуВМассивПодстрок().
Какие выводы?
В большинстве случаев при помощи СтрРазделить() можно сделать тоже самое, что и РазложитьСтрокуВМассивПодстрок(). В таких случаях нужно применять платформенный метод. Но:
- Когда необходимо использовать разделитель, состоящий из строки, а не одного символа, берёмся за РазложитьСтрокуВМассивПодстрок()
- Когда необходимо, чтобы элементы результата были обработаны СокрЛП(), делаем это сами постобработкой. Так будет быстрее.
Понять особенности методов будет полезно на практике. Но помнить не обязательно. Можно вместо этого использовать обёртку на подобии:
Использование общих реквизитов без разделения данных
Общие реквизиты - это объекты метаданных, позволяющие добавить реквизит сразу для множества прикладных объектов (справочников, документов, регистров).
Общие реквизиты можно разделить на два типа: используемые для разделения данных и не используемые для разделения данных. Это регулируется свойством «Разделение данных».
Назначение общих реквизитов, используемых для разделения данных, вполне очевидно. Они позволяют включить в конфигурации механизм разделения данных (multitenancy), обеспечивающий работу в одной информационной базе нескольких логически независимых или слабо зависимых областей данных.
Для чего предназначены общие реквизиты без разделения данных?
Прежде всего нужно обратить внимание на то, что не только сами общие реквизиты создаются в метаданных отдельно от прикладных объектов, в которых они используются (справочников, документов, регистров, и т.д.), но и описание включения общих реквизитов в прикладные объекты выполняется в самих общих реквизитах. Для этого используется свойство общего реквизита Состав , в котором указывается, в какие прикладные объекты включать общий реквизит. Кроме того, имеется возможность автоматического включения общего реквизита в прикладные объекты (свойство общего реквизита - Автоиспользование ). Это позволяет включать общий реквизит во все новые объекты метаданных без каких-либо действий со стороны разработчика конфигурации.
Таким образом, общие реквизиты, по сути, являются данными, добавляемыми к прикладным объектам со стороны конфигурации, а не со стороны разработки конкретного объекта. Это особенно ярко проявляется, если рассматривать жизненный цикл разработки (обновление конфигурации, доработку конфигурации при внедрении, перенос функционала между конфигурациями, и т.д.).
Соответственно, общие реквизиты без разделения данных предназначены для добавления некоторого функционала, который не является непосредственной частью бизнес-логики прикладных объектов. Общие реквизиты не предназначены для удобства добавления похожих или даже одинаковых реквизитов в прикладные объекты. Они предназначены для реализации функционала, который решает задачи конфигурации в целом, но требует хранения некоторых данных непосредственно в прикладных объектах.
Например, может стоять задача реализации механизма создания сокращенной резервной копии данных, с наиболее критичными данными. Допустим, уже имеется некоторая конфигурация и, разумеется, желательно минимизировать изменения в самой бизнес-логике прикладных объектов конфигурации. Для решения задачи можно создать общий реквизит " ВключатьВРезервнуюКопию " и включить в его состав большинство прикладных объектов. Далее можно реализовать регламентное задание или обработку с пользовательским интерфейсом, которые будут по некоторым правилам проставлять этот признак. Например, признак может быть проставлен документам, введенным за последние 12 месяцев. Соответственно реализуемый механизм выгрузки будет использовать этот реквизит для отбора выгружаемых значений. Разумеется, данную задачу можно решить и другими способами. Здесь она приведена для иллюстрации тех случаев, в которых имеет смысл применять общие реквизиты без разделения данных.
Заметим, что круг таких задач достаточно узок. Важно при принятии решения об использовании общего реквизита оценить правильность применения этого механизма для решения конкретной задачи. Неправильное применение данного механизма может неоправданно усложнить разработку и поддержку конфигурации. В частности, общие реквизиты могут усложнить понимание конфигурации другими разработчиками, так как устройство конкретного прикладного объекта будет менее очевидным и наглядным.
Механизм разделения данных – относительно новая функциональная особенность 1С, отнесенная к облачным технологиям. После появления функционала компанией 1С была доработана БСП. Эти же доработки вошли в состав основанных на БСП типовые конфигурации, например, УНФ и УТ11.
Понадобилось организовать получение общих отчетов из нескольких филиалов с одинаковыми конфигурациями. Решил попробовать наработки из БСП в области разделения данных. Идея заключалась в том, чтобы загрузить данные каждого филиала в свою область данных и сформировать отчеты сразу для всех областей. Сразу скажу, что задачу решить пока не удалось, но сама попытка решения выявила проблемы и сомнительный функционал в БСП.
К статье приложена обработка, выносящая скрытый функционал операций с областями данных на отдельную форму.
В БСП предусмотрены два разделителя учета: ОбластьДанныхОсновныеДанные и ОбластьДанныхВспомогательныеДанные. Загадкой осталось, почему эти 2 разделителя ссылаются на одни и те же параметры сеанса: ОбластьДанныхЗначение, ОбластьДанныхИспользование.
Включение механизма
Если ваша самописная конфигурация основана на БСП, то, скорее всего, перед включением необходимо внедрить загадочную библиотеку "1С:Библиотека технологии сервиса". Странно, что даже Гугл не знает о таком продукте 1С. А в типовых конфигурациях процедуры ПроверитьВозможностьИспользованияКонфигурацииВМоделиСервиса в модуле РаботаВМоделиСервиса не существует. Скорее всего, найти недостающие части из этой библиотеки можно в типовых конфигурациях, выполненных на основе БСП. В частности, одна из подсистем называется СтандартныеПодсистемы > РаботаВМоделиСервиса > ВыгрузкаЗагрузкаДанных.
Механизм разделения данных включается через установку константы ИспользоватьРазделениеПоОбластямДанных. Можно установить через пункт меню Все функции.
Создание пользователей области данных
Этот пункт не обязателен, если используется вход в область данных через форму. В режиме конфигуратора создаются пользователи. Один пользователь с административными правами должен иметь во вкладке Разделение данных все неустановленные разделители данных. Для других пользователей во вкладке Разделение данных должен быть установлен разделитель Область данных основные данные. Этот разделитель должен быть явно указан в командной строке при запуске 1С.
Запуск 1С с параметром командной строки
Этот пункт не обязателен, если используется вход в область данных через форму входа.
1С можно запустить сразу в режиме разделения данных. Предусмотрен параметр командной строки /Z. Например, параметр «/Z-,+1» указывает, что 1С запускается со значением Области данных основные данные равным 1, разделитель Область данных вспомогательные данные не установлен.
Способ очень ненадежный. При запуске возникает ошибка в процедуре РаботаВМоделиСервиса. ПриПроверкеВключенияБезопасногоРежимаРазделенияДанных. Ничего лучшего, чем закомментировать эту процедуру, я не нашел. Процедура проверяет, есть ли у пользователя право менять текущую область данных, ограничены ли его права и влияет на безопасность.
Далее при запуске возникают несколько ошибок среди них: «Разделенным пользователям не может быть назначена роль Администратор системы», «Разделенным пользователям не может быть назначена роль Запуск толстого клиента».
Пользователь не найден в справочнике Пользователи – проблему победить не удалось. В традиционном сценарии Пользователь регистрируется при первом входе. Подозреваю, что при разделении данных Пользователи создаются через другое приложение 1C Fresh.
Заполнить регистр сведений Области данных
Для каждой области нужно заполнить запись в регистре сведений Области Данных, присвоив областям номера и статус «Используется». Обработки могут проверять наличие записей в этом регистре перед началом выполнения.
Выгрузка данных из области
Текущая область выгружается через ОбщаяФорма. ВыгрузкаДанных. До ее использования нужно выполнить вход в нужную область данных. Форма не выведена в интерфейс пользователя в раздел Администрирование.
Данные сериализуются конфигурацией в XML-формат и запаковываются в ZIP. То есть архивирование происходит не средствами 1С-конфигуратора, как традиционная выгрузка.
Загрузить данные в область
Для появления в Администрирование-Сервис нужно через Конфигуратор в составе подсистемы НастройкаИАдминистрирование установить видимость.
Данные загружаются в выбранную область. До этого они должны быть выгружены в XML-формат.
Выводы
Опыты с входами в разные области, выгрузкой и загрузкой областей были удачными. Неудача постигла при попытке выполнить запрос получения всех организаций для всех областей данных. Ошибка: «Нельзя использовать таблицу без указания всех разделителей с независимым использованием разделяемых данных». Отчет работает по одной области, если осуществить вход в какую-нибудь область.
Неясной осталась проблема, как выгрузить данные из базы без разделителей в определенную область данных другой базы.
Интересно было бы узнать о хитрой задумке авторов БСП относительно общих параметров сеансов для двух разделителей, если вызов будет с параметрами: «/Z-,+1», «/Z+1,+1» и «/Z+1,-».
Возникла необходимость организовать учет по двум организациям в одной ИБ. Ситуация не уникальная, но так сложилось, что наша сильно не типовая 250 гигобайтная УППшка работала довольно медленно, поэтому вместо RLS решили попробовать разделение данных. Что это такое, описано, например,
Простые смертные работают только со своей ООО, а главбух иногда смотрит данные по двум юрлицам. В режиме доступа к обеим ООО можно только читать данные, поэтому главбух должен иметь возможность интерактивно переключаться между режимами "все читать"/"писать только по одной организации" и выбирать ООО (т.е. устанавливать значение общего реквизита) для проведения, например, расчета себестоимости.
2. Реализация
Платформа 8.2.19.90, без режима совместимости. СУБД - MSSQL Server 2008 R2 Standart.
Создали общий реквизит ОрганизацияРазделитель типа "число", согласились с предложением создать параметры сеанса, заполнили состав реквизита (включили несколько справочников, все документы, регистры накопления, бухгалтерии и расчета). Разделение данных - "Независимо и совместно". Значение параметра сеанса устанавливается из стандартных настроек пользователя в процедуре УстановкаПараметровСеанса в модуле сеанса:
В интерфейсе главбуха сделали формочку с возможностью переключения между организациями и включения/выключения режима разделения:
При отключенном разделении, когда ПараметрыСеанса.ОрганизацияРазделительИспользование = Ложь, платформа отказывается записывать документы, вываливаясь с ошибками типа "ОшибкаSDBL: ожидается выражение (pos=12)", поэтому давать пользователю записывать документы в таком варианте нельзя. Для надежности, создали подписки на событие "Перед записью" для объектов, входящих в состав общего реквизита:
План действий у нас был такой: готовим конфигурацию-приемник ИБ №1, проставляем значения общего реквизита = 1, загружаем данные из ИБ №2, после загрузки для всех объектов с пустым (равным 0) значением разделителя устанавливаем ОрганизацияРазделитель = 2.
Конфигурацию подготовили, возник вопрос, как установить значение общего реквизита для документов и их движений в закрытых периодах, причем быстро и без риска того, что полетят цифры в балансе? Через объектную модель 1С записывать разделитель отдельно от объекта невозможно, поэтому пришлось нарушить лицензионное соглашение выкручиваться и писать запрос для MS SQL. Поскольку в составе общего реквизита много объектов, а таблиц в скуле по этим объектам еще больше, написали обработку, генерирующую запрос для SQL (для каждого объекта метаданных, входящего в состав разделителя, писали "update " + Имя_БД + ".dbo._" + ИмяТаблицы + " set _" + ПолеОбщийРеквизит + " = 1";)
Значение проставили, перенесли часть данных из ИБ №2, начали тестировать.
Результат разочаровал. Во-первых, проблемы с регистром бухгалтерии. При включенном разделении не видно аналитику:
Хорошо, проставляем значение разделителя через MS SQL, аналитику видим. Теперь не работают отчеты. Оказывается, проблемы с запросами к виртуальным таблицам регистра бухгалтерии "Обороты" и "ОборотыДтКт":
(Fld27033 - это как раз общий реквизит в таблице регистра бухгалтерии)
Разделитель установлен во всех таблицах, это видно на уровне СУБД, в чем может быть ошибка, не понятно. Разворачиваем типовую пустую УПП, делаем описанные выше изменения в конфигурации, вводим пару документов (в этом варианте платформа сама проставляет значение разделителя во всех таблицах регистра бухгалтерии), но ошибки воспроизводятся. Плохо, но исключаем регистры бухгалтерии из состава общего реквизита, продолжаем тестирование.
Далее, выясняется что перестал работать механизм вытеснения у регистров расчета. Планы видов расчета мы не разделяли, пробуем искать проблему в таблицах регистра расчетов и в перерасчетах. Проверяем, проставляем значение основного реквизита, делаем ТиИ - безрезультатно.
Попутно, диагностируем проблему при записи в независимые регистры сведений из формы списка. При этом данные записываются, их можно увидеть после перезапуска. Проблема воспроизводится и на тестовой базе:
Регистры сведений "починить" путем манипуляций с SQL не получилось (значение разделителя во всех таблицах установлено), поэтому просто исключили их из состава общего реквизита. После нескольких дней экспериментов, неудачными оказываются и попытки восстановить работоспособность вытеснения.
На этот момент принимаем решение выключить разделение данных и использовать-таки RLS. При установке разделения в "не использовать" натыкаемся на ошибки "Microsoft OLE DB Provider forSQL Server: CREATE UNIQUE INDEX terminated because a duplicate keywas found for index. ". Т.е., вернуться в состояние до разделения так запросто не получается. Проблема с индексами таблиц перерасчетов, настроек хранения итогов и других. Дело в том, что в таблицах хранятся идентичные строки, отличающиеся только значением общего реквизита. При удалении общего реквизита появляются неуникальные записи. Придется удалить ненужные записи напрямую в MS SQL, примерно так (для таблицы перерасчетов):
И только после чистки нескольких десятков таблиц удается выключить разделение данных. После выключения разделения никаких проблем нет.
Теплилась надежда, что на 8.3 проблемы решены. Не поленились, проверили на 8.3.4.482 (с отключенным режимом совместимости). Смотрели на практически типовой УПП-шке, с изменениями в конфигурации только по общему реквизиту. На этой тестовой базе разделение включили до ввода информации, т.е. платформа должна была корректно записывать значение разделителя во все таблицы, самостоятельно напрямую в MS SQL ничего не писали.
Проблема с запросами к виртуальным таблицам "Обороты" и "ОборотыДтКт" воспроизводится.
Проблема с вытеснением воспроизводится.
Проблема с записью в независимые регистры сведений воспроизводится.
+ проблема с выключением разделения - одним нажатием кнопки от него избавится не получится!
Таким образом, заменить RLS новым механизмом у нас не получилось. Задумывался этот механизм, по всей видимости, для облачных сервисов, и в варианте использования разделяемых данных "независимо", может быть, разделение заработает, но нам нужна общая НСИ. Остается ждать, когда 1С исправит ошибки , а еще лучше, реализует типовой механизм разделения по организациям в типовых конфигурациях.
Читайте также: