Files
SSL/SSL/src/CommonModules/ПодключаемыеКоманды/Module.bsl
T
2020-09-30 23:05:00 +03:00

1461 lines
111 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
///////////////////////////////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2020, ООО 1С-Софт
// Все права защищены. Эта программа и сопроводительные материалы предоставляются
// в соответствии с условиями лицензии Attribution 4.0 International (CC BY 4.0)
// Текст лицензии доступен по ссылке:
// https://creativecommons.org/licenses/by/4.0/legalcode
///////////////////////////////////////////////////////////////////////////////////////////////////////
#Область ПрограммныйИнтерфейс
// Выводит подключенные команды в форме.
// Для вызова из обработчика формы ПриСозданииНаСервере.
//
// Если в форме несколько списков, то в обработчике формы ПриСозданииНаСервере
// следует разместить несколько вызовов этой процедуры с указанием параметра ПараметрыРазмещения.
// Параметр ПараметрыРазмещения также применяется, когда типы источников зависят от параметров открытия формы.
//
// Параметры:
// Форма - ФормаКлиентскогоПриложения - форма, в которой необходимо разместить команды.
// ПараметрыРазмещения - см. ПодключаемыеКоманды.ПараметрыРазмещения
// - Неопределено
//
Процедура ПриСозданииНаСервере(Форма, ПараметрыРазмещения = Неопределено) Экспорт
ИмяФормы = Форма.ИмяФормы;
ИсточникиЧерезЗапятую = "";
Если ПараметрыРазмещения = Неопределено Тогда
ПараметрыРазмещения = ПараметрыРазмещения();
Иначе
Если ТипЗнч(ПараметрыРазмещения.Источники) = Тип("ОписаниеТипов") Тогда
Типы = ПараметрыРазмещения.Источники.Типы();
Для Каждого Тип Из Типы Цикл
ОбъектМетаданных = Метаданные.НайтиПоТипу(Тип);
Если ОбъектМетаданных <> Неопределено Тогда
ИсточникиЧерезЗапятую = ИсточникиЧерезЗапятую + ?(ИсточникиЧерезЗапятую = "", "", ",") + ОбъектМетаданных.ПолноеИмя();
КонецЕсли;
КонецЦикла;
ИначеЕсли ТипЗнч(ПараметрыРазмещения.Источники) = Тип("Массив") Тогда
Для Каждого ОбъектМетаданных Из ПараметрыРазмещения.Источники Цикл
Если ТипЗнч(ОбъектМетаданных) = Тип("ОбъектМетаданных") Тогда
ИсточникиЧерезЗапятую = ИсточникиЧерезЗапятую + ?(ИсточникиЧерезЗапятую = "", "", ",") + ОбъектМетаданных.ПолноеИмя();
ИначеЕсли ОбъектМетаданных <> Неопределено Тогда
ОбщегоНазначенияКлиентСервер.ПроверитьПараметр(
"ПодключаемыеКоманды.ПриСозданииНаСервере",
"ПараметрыРазмещения.Источники[...]",
ОбъектМетаданных,
Новый ОписаниеТипов("ОбъектМетаданных"));
КонецЕсли;
КонецЦикла;
ИначеЕсли ПараметрыРазмещения.Источники <> Неопределено Тогда
ОбщегоНазначенияКлиентСервер.ПроверитьПараметр(
"ПодключаемыеКоманды.ПриСозданииНаСервере",
"ПараметрыРазмещения.Источники",
ПараметрыРазмещения.Источники,
Новый ОписаниеТипов("ОписаниеТипов, Массив"));
КонецЕсли;
КонецЕсли;
ЭтоФормаОбъекта = Неопределено;
Параметры = Форма.Параметры;
ЕстьПараметрыСписка = Параметры.Свойство("Отбор") И Параметры.Свойство("ТекущаяСтрока");
ЕстьПараметрыОбъекта = Параметры.Свойство("Ключ") И Параметры.Свойство("Основание");
Если ЕстьПараметрыСписка <> ЕстьПараметрыОбъекта Тогда
ЭтоФормаОбъекта = ЕстьПараметрыОбъекта;
КонецЕсли;
// Для форм внешних отчетов и обработок невозможно получить метаданные имея только имя формы,
// поэтому определение источников команд выполняется до вызова ПовтИсп.
Если ИсточникиЧерезЗапятую = "" И ТребуетсяУказаниеИсточниковКоманд(ИмяФормы) Тогда
Если ЕстьПараметрыОбъекта Тогда
ОбъектМетаданных = Метаданные.НайтиПоТипу(ТипЗнч(Параметры.Ключ));
Если ОбъектМетаданных <> Неопределено Тогда
ИсточникиЧерезЗапятую = ОбъектМетаданных.ПолноеИмя();
КонецЕсли;
КонецЕсли;
Если ИсточникиЧерезЗапятую = "" Тогда
ВызватьИсключение СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
НСтр("ru = 'В формах отчетов, обработок и в общих формах
|при вызове процедуры ""%1""
|требуется явно указывать параметр ""%2""'"),
"ПодключаемыеКоманды.ПриСозданииНаСервере",
"ПараметрыРазмещения.Источники");
КонецЕсли;
КонецЕсли;
КэшФормы = ПодключаемыеКомандыПовтИсп.КэшФормы(ИмяФормы, ИсточникиЧерезЗапятую, ЭтоФормаОбъекта);
ПараметрыРазмещения.Вставить("ЕстьУсловияВидимости", КэшФормы.ЕстьУсловияВидимости);
ПараметрыРазмещения.Вставить("ЭтоФормаОбъекта", КэшФормы.ЭтоФормаОбъекта);
ПараметрыРазмещения.Вставить("ВводНаОснованииЧерезПодключаемыеКоманды", КэшФормы.ВводНаОснованииЧерезПодключаемыеКоманды);
Если КэшФормы.ФункциональныеОпции.Количество() > 0 Тогда
Форма.УстановитьПараметрыФункциональныхОпцийФормы(КэшФормы.ФункциональныеОпции);
КонецЕсли;
Команды = КэшФормы.Команды.Скопировать();
ВывестиКоманды(Форма, Команды, ПараметрыРазмещения);
КонецПроцедуры
// Конструктор одноименного параметра процедуры ПодключаемыеКоманды.ПриСозданииНаСервере.
//
// Возвращаемое значение:
// Структура - параметры размещения подключаемых команд:
// * Источники - ОписаниеТипов
// - Массив - источники команд.
// Используется для второстепенных списков, а также в формах объектов, не являющихся поставщиками
// команд (обработки, общие формы). В массиве ожидаются элементы типа "ОбъектМетаданных".
// * КоманднаяПанель - ГруппаФормы - командная панель или группа команд, в которой выводятся подменю.
// Используется как родитель для создания подменю в случае их отсутствия.
// Если не указан то в первую очередь ищется группа "ПодключаемыеКоманды".
// * ПрефиксГрупп - Строка - добавка к именам подменю и имени командной панели.
// Используется при необходимости префиксации групп с командами (в частности, когда в форме несколько таблиц).
// В качестве префикса рекомендуется использовать имя таблицы формы, для которой выводятся команды.
// Например, если ПрефиксГрупп = "СкладскиеДокументы" (имя второстепенной таблицы формы),
// то используются подменю с именами "СкладскиеДокументыПодменюПечать", "СкладскиеДокументыПодменюОтчеты" и т.д.
//
Функция ПараметрыРазмещения() Экспорт
Результат = Новый Структура("Источники, КоманднаяПанель, ПрефиксГрупп");
Результат.ПрефиксГрупп = "";
Возврат Результат;
КонецФункции
// Обработчик команды формы, требующей контекстного вызова сервера.
//
// Параметры:
// Форма - ФормаКлиентскогоПриложения - форма, из которой выполняется команда.
// ПараметрыВызова - Структура
// Источник - ТаблицаФормы
// - ДанныеФормыСтруктура - объект или список формы с полем "Ссылка".
// Результат - Структура - результат выполнения команды.
//
Процедура ВыполнитьКоманду(Знач Форма, Знач ПараметрыВызова, Знач Источник, Результат = Неопределено) Экспорт
Если ТипЗнч(ПараметрыВызова) <> Тип("Структура")
Или ПараметрыВызова.Количество() <> 3
Или ТипЗнч(Форма) <> Тип("ФормаКлиентскогоПриложения") Тогда
Возврат;
КонецЕсли;
АдресНастроек = Форма.ПараметрыПодключаемыхКоманд.АдресТаблицыКоманд;
ОписаниеКоманды = ОписаниеКоманды(ПараметрыВызова.ИмяКомандыВФорме, АдресНастроек);
ПараметрыВыполнения = ПараметрыВыполненияКоманды();
ПараметрыВыполнения.ОписаниеКоманды = Новый Структура(ОписаниеКоманды);
ПараметрыВыполнения.Форма = Форма;
ПараметрыВыполнения.ЭтоФормаОбъекта = ТипЗнч(Источник) = Тип("ДанныеФормыСтруктура");
ПараметрыВыполнения.Источник = Источник;
ПараметрыЭкспортнойПроцедуры = Новый Массив;
ПараметрыЭкспортнойПроцедуры.Добавить(ПараметрыВызова.ПараметрКоманды);
ПараметрыЭкспортнойПроцедуры.Добавить(ПараметрыВыполнения);
Обработчик = ОписаниеКоманды.Обработчик;
ПрефиксОбщегоМодуля = НРег("ОбщийМодуль.");
Если СтрНачинаетсяС(НРег(Обработчик), ПрефиксОбщегоМодуля) Тогда
Обработчик = Сред(Обработчик, СтрДлина(ПрефиксОбщегоМодуля) + 1);
КонецЕсли;
ОбщегоНазначения.ВыполнитьМетодКонфигурации(Обработчик, ПараметрыЭкспортнойПроцедуры);
Результат = ПараметрыВыполнения.Результат;
ПараметрыВызова.Результат = ПараметрыВыполнения.Результат;
КонецПроцедуры
// Задает условия видимости команды на форме в зависимости от контекста.
//
// Параметры:
// Команда - СтрокаТаблицыЗначений - команда, для которой добавляется условие видимости.
// Реквизит - Строка - имя реквизита объекта.
// Значение - Произвольный - значение реквизита объекта. Параметр обязательный для всех видов
// сравнения кроме Заполнено и НеЗаполнено.
// ВидСравнения - ВидСравненияКомпоновкиДанных - вид сравнения значений.
// Допустимо использовать следующие виды сравнения:
// ВидСравненияКомпоновкиДанных.Равно,
// ВидСравненияКомпоновкиДанных.НеРавно,
// ВидСравненияКомпоновкиДанных.Заполнено,
// ВидСравненияКомпоновкиДанных.НеЗаполнено,
// ВидСравненияКомпоновкиДанных.ВСписке,
// ВидСравненияКомпоновкиДанных.НеВСписке,
// ВидСравненияКомпоновкиДанных.Больше,
// ВидСравненияКомпоновкиДанных.Меньше,
// ВидСравненияКомпоновкиДанных.БольшеИлиРавно,
// ВидСравненияКомпоновкиДанных.МеньшеИлиРавно.
// Значение по умолчанию - ВидСравненияКомпоновкиДанных.Равно.
//
Процедура ДобавитьУсловиеВидимостиКоманды(Команда, Реквизит, Значение = Неопределено, Знач ВидСравнения = Неопределено) Экспорт
Если ВидСравнения = Неопределено Тогда
ВидСравнения = ВидСравненияКомпоновкиДанных.Равно;
КонецЕсли;
УсловиеВидимости = Новый Структура;
УсловиеВидимости.Вставить("Реквизит", Реквизит);
УсловиеВидимости.Вставить("ВидСравнения", ВидСравнения);
УсловиеВидимости.Вставить("Значение", Значение);
Команда.УсловияВидимости.Добавить(УсловиеВидимости);
КонецПроцедуры
// Свойства второго параметра обработчика подключаемой команды, выполняемой на сервере.
//
// Возвращаемое значение:
// Структура:
// * ОписаниеКоманды - Структура - состав свойств совпадает с колонками таблицы значений параметра Команды процедуры
/// ПодключаемыеКомандыПереопределяемый.ПриОпределенииКомандПодключенныхКОбъекту.
// Ключевые свойства:
// ** Идентификатор - Строка - идентификатор команды.
// ** Представление - Строка - представление команды в форме.
// ** Имя - Строка - имя команды в форме.
// ** ДополнительныеПараметры - Структура - дополнительные свойства, состав которых определяется видом
// конкретной команды.
// * Форма - ФормаКлиентскогоПриложения - форма, из которой вызвана команда.
// * ЭтоФормаОбъекта - Булево - Истина, если команда вызвана из формы объекта.
// * Источник - ТаблицаФормы
// - ДанныеФормыСтруктура - объект или список формы с полем "Ссылка".
//
Функция ПараметрыВыполненияКоманды() Экспорт
ПараметрыВыполнения = ПодключаемыеКомандыКлиентСервер.ПараметрыВыполненияКоманды();
// Служебные параметры.
Результат = Новый Структура;
Результат.Вставить("Текст", "");
Результат.Вставить("Подробно", "");
ПараметрыВыполнения.Вставить("Результат", Результат);
Возврат ПараметрыВыполнения;
КонецФункции
#КонецОбласти
#Область СлужебныйПрограммныйИнтерфейс
////////////////////////////////////////////////////////////////////////////////
// Обработчики событий.
// Формирует таблицу общих настроек всех расширений, подключенных к объекту метаданных.
Функция ПодключенныеОбъекты(ОписаниеИсточника, ПодключенныеОбъекты = Неопределено, НастройкиПрограммногоИнтерфейса = Неопределено) Экспорт
Источники = ДеревоИсточниковКоманд();
Если ТипЗнч(ОписаниеИсточника) = Тип("СправочникСсылка.ИдентификаторыОбъектовМетаданных") Тогда
Источник = Источники.Строки.Добавить();
Источник.СсылкаМетаданных = ОписаниеИсточника;
Источник.ТипСсылкиДанных = ОбщегоНазначения.ЗначениеРеквизитаОбъекта(ОписаниеИсточника, "ЗначениеПустойСсылки");
Иначе
Источник = ОписаниеИсточника;
КонецЕсли;
Если ПодключенныеОбъекты = Неопределено Тогда
ПодключенныеОбъекты = ТаблицаПодключаемыхОбъектов(НастройкиПрограммногоИнтерфейса);
КонецЕсли;
Если Источник.СсылкаМетаданных = Неопределено Тогда
Возврат ПодключенныеОбъекты;
КонецЕсли;
ПолныеИменаПодключенныхОбъектов = ПодключаемыеКомандыПовтИсп.Параметры().ПодключенныеОбъекты[Источник.СсылкаМетаданных];
Если ПолныеИменаПодключенныхОбъектов = Неопределено Тогда
Возврат ПодключенныеОбъекты;
КонецЕсли;
Для Каждого ПолноеИмя Из ПолныеИменаПодключенныхОбъектов Цикл
ПодключенныйОбъект = ПодключенныеОбъекты.Найти(ПолноеИмя, "ПолноеИмя");
Если ПодключенныйОбъект = Неопределено Тогда
НастройкиПодключаемогоОбъекта = НастройкиПодключаемогоОбъекта(ПолноеИмя, НастройкиПрограммногоИнтерфейса);
Если НастройкиПодключаемогоОбъекта = Неопределено Тогда
Продолжить;
КонецЕсли;
ПодключенныйОбъект = ПодключенныеОбъекты.Добавить();
ЗаполнитьЗначенияСвойств(ПодключенныйОбъект, НастройкиПодключаемогоОбъекта);
ПодключенныйОбъект.ТипСсылкиДанных = Источник.ТипСсылкиДанных;
ПодключенныйОбъект.Метаданные = Метаданные.НайтиПоПолномуИмени(ПолноеИмя);
Иначе
ПодключенныйОбъект.ТипСсылкиДанных = ОбъединитьТипы(ПодключенныйОбъект.ТипСсылкиДанных, Источник.ТипСсылкиДанных);
КонецЕсли;
КонецЦикла;
Возврат ПодключенныеОбъекты;
КонецФункции
// Получает настройки интеграции объекта метаданных - поставщика команд (отчета или обработки).
//
// Параметры:
// ПолноеИмя - Строка - полное имя объекта метаданных.
// НастройкиПрограммногоИнтерфейса - Произвольный - результат выполнения функции
// НастройкиПрограммногоИнтерфейсаПодключаемыхОбъектов().
//
// Возвращаемое значение:
// Структура - настройки интеграции этого объекта.
// Состав полей см. в блоке "Параметры процедуры ПриОпределенииНастроек"
// процедуры ПодключаемыеКомандыПереопределяемый.ПриОпределенииСоставаНастроекПодключаемыхОбъектов().
// Дополнительно содержит следующие поля:
// * Вид - Строка - вид имя объекта метаданных в верхнем регистре.
// * ПолноеИмя - Строка - полное имя объекта метаданных.
// * Менеджер - ОбработкаМенеджер
// - ОтчетМенеджер - менеджер объекта метаданных.
//
Функция НастройкиПодключаемогоОбъекта(ПолноеИмя, НастройкиПрограммногоИнтерфейса = Неопределено) Экспорт
ЧастиИмени = СтрРазделить(ПолноеИмя, ".");
Если ЧастиИмени.Количество() <> 2 Тогда
Возврат Неопределено;
КонецЕсли;
ВидВРег = ВРег(ЧастиИмени[0]);
Имя = ЧастиИмени[1];
Если ВидВРег = "ОТЧЕТ" Тогда
Узел = Отчеты;
ИначеЕсли ВидВРег = "ОБРАБОТКА" Тогда
Узел = Обработки;
Иначе
Возврат Неопределено;
КонецЕсли;
Если НастройкиПрограммногоИнтерфейса = Неопределено Тогда
НастройкиПрограммногоИнтерфейса = НастройкиПрограммногоИнтерфейсаПодключаемыхОбъектов();
КонецЕсли;
Настройки = Новый Структура;
Для Каждого Настройка Из НастройкиПрограммногоИнтерфейса Цикл
Если Настройка.ВидыПодключаемыхОбъектов = ""
Или СтрНайти(ВРег(Настройка.ВидыПодключаемыхОбъектов), ВидВРег) > 0 Тогда
Настройки.Вставить(Настройка.Ключ, Настройка.ОписаниеТипов.ПривестиЗначение());
КонецЕсли;
КонецЦикла;
Менеджер = Узел[Имя];
Попытка
Менеджер.ПриОпределенииНастроек(Настройки);
Исключение
ТекстОшибки = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
НСтр("ru = 'Не удалось прочитать настройки объекта %1 из модуля менеджера:'"), ПолноеИмя);
ТекстОшибки = ТекстОшибки + Символы.ПС + ПодробноеПредставлениеОшибки(ИнформацияОбОшибке());
ЗаписьЖурналаРегистрации(
НСтр("ru = 'Подключаемые команды'", ОбщегоНазначения.КодОсновногоЯзыка()),
УровеньЖурналаРегистрации.Ошибка,
Метаданные.НайтиПоПолномуИмени(ПолноеИмя),
ПолноеИмя,
ТекстОшибки);
Возврат Неопределено;
КонецПопытки;
Настройки.Вставить("Вид", ВидВРег);
Настройки.Вставить("ПолноеИмя", ПолноеИмя);
Настройки.Вставить("Менеджер", Менеджер);
Возврат Настройки;
КонецФункции
// Добавляет типы в массив.
//
// Параметры:
// Массив - Массив - массив типов.
// ТипИлиОписаниеТипов - Тип
// - ОписаниеТипов - добавляемые типы.
//
Процедура ДополнитьМассивТипов(Массив, ТипИлиОписаниеТипов) Экспорт
Если ТипЗнч(ТипИлиОписаниеТипов) = Тип("ОписаниеТипов") Тогда
ОбщегоНазначенияКлиентСервер.ДополнитьМассив(Массив, ТипИлиОписаниеТипов.Типы(), Истина);
ИначеЕсли ТипЗнч(ТипИлиОписаниеТипов) = Тип("Тип") И Массив.Найти(ТипИлиОписаниеТипов) = Неопределено Тогда
Массив.Добавить(ТипИлиОписаниеТипов);
КонецЕсли;
КонецПроцедуры
// Регистрирует в дереве источников команд объект метаданных, а также вспомогательные объекты метаданных,
// подключенных к указанному объекту метаданных.
//
// Параметры:
// ОбъектМетаданных - ОбъектМетаданных - объект метаданных, к которому подключены источники команд.
// Источники - ДеревоЗначений - см. описание одноименного параметра
// процедуры ПодключаемыеКомандыПереопределяемый.ПриОпределенииКомандПодключенныхКОбъекту().
// ПодключенныеОбъекты - см. ПодключаемыеКоманды.ТаблицаПодключаемыхОбъектов
// НастройкиПрограммногоИнтерфейса - см. ПодключаемыеКоманды.НастройкиПрограммногоИнтерфейсаПодключаемыхОбъектов
//
// Возвращаемое значение:
// СтрокаДереваЗначений - настройки объекта метаданных. См. описание 2 параметра
// процедуры ПодключаемыеКомандыПереопределяемый.ПриОпределенииКомандПодключенныхКОбъекту().
//
Функция ЗарегистрироватьИсточник(ОбъектМетаданных, Источники, ПодключенныеОбъекты, НастройкиПрограммногоИнтерфейса) Экспорт
Если ОбъектМетаданных = Неопределено Тогда
Возврат Неопределено;
КонецЕсли;
ПолноеИмя = ОбъектМетаданных.ПолноеИмя();
Менеджер = ОбщегоНазначения.МенеджерОбъектаПоПолномуИмени(ПолноеИмя);
Если Менеджер = Неопределено Тогда
Возврат Неопределено; // Объект не может быть источником команд.
КонецЕсли;
Источник = Источники.Строки.Добавить();
Источник.Метаданные = ОбъектМетаданных;
Источник.ПолноеИмя = ПолноеИмя;
Источник.Менеджер = Менеджер;
Источник.СсылкаМетаданных = ОбщегоНазначения.ИдентификаторОбъектаМетаданных(ПолноеИмя);
Источник.Вид = ВРег(СтрРазделить(ПолноеИмя, ".")[0]);
Источник.ЭтоЖурналДокументов = (Источник.Вид = "ЖУРНАЛДОКУМЕНТОВ");
Если Источник.ЭтоЖурналДокументов Тогда
МассивТипов = Новый Массив;
Для Каждого МетаданныеДокумента Из ОбъектМетаданных.РегистрируемыеДокументы Цикл
Документ = ЗарегистрироватьИсточник(МетаданныеДокумента, Источник, ПодключенныеОбъекты, НастройкиПрограммногоИнтерфейса);
Если Документ <> Неопределено Тогда
МассивТипов.Добавить(Документ.ТипСсылкиДанных);
КонецЕсли;
КонецЦикла;
Источник.ТипСсылкиДанных = Новый ОписаниеТипов(МассивТипов);
ИначеЕсли Не Метаданные.Обработки.Содержит(ОбъектМетаданных) И Не Метаданные.Отчеты.Содержит(ОбъектМетаданных) Тогда
Источник.ТипСсылкиДанных = Тип(Источник.Вид + "Ссылка." + ОбъектМетаданных.Имя);
КонецЕсли;
ПодключенныеОбъекты(Источник, ПодключенныеОбъекты, НастройкиПрограммногоИнтерфейса);
Возврат Источник;
КонецФункции
////////////////////////////////////////////////////////////////////////////////
// Шаблоны.
// Шаблон сведений об объектах метаданных - источников команд.
//
// Возвращаемое значение:
// См. описание 2 параметра процедуры ПодключаемыеКомандыПереопределяемый.ПриОпределенииКомандПодключенныхКОбъекту().
//
Функция ДеревоИсточниковКоманд() Экспорт
Результат = Новый ДеревоЗначений;
Результат.Колонки.Добавить("Метаданные");
Результат.Колонки.Добавить("ПолноеИмя", Новый ОписаниеТипов("Строка"));
Результат.Колонки.Добавить("Менеджер");
Результат.Колонки.Добавить("СсылкаМетаданных");
Результат.Колонки.Добавить("ТипСсылкиДанных");
Результат.Колонки.Добавить("Вид", Новый ОписаниеТипов("Строка"));
Результат.Колонки.Добавить("ЭтоЖурналДокументов", Новый ОписаниеТипов("Булево"));
Возврат Результат;
КонецФункции
// Шаблон сведений об отчетах и обработках, подключенных к источникам команд.
//
// Возвращаемое значение:
// ТаблицаЗначений - вспомогательные параметры:
// * ПолноеИмя - Строка - полное имя объекта. Например: "Документ.ИмяДокумента".
// * Менеджер - Произвольный - модуль менеджера объекта.
// * Размещение - Массив - список объектов, к которым подключен отчет или обработка.
// * ТипСсылкиДанных - Тип
// - ОписаниеТипов - тип объектов, к которым подключен отчет или обработка..
//
Функция ТаблицаПодключаемыхОбъектов(НастройкиПрограммногоИнтерфейса = Неопределено) Экспорт
Если НастройкиПрограммногоИнтерфейса = Неопределено Тогда
НастройкиПрограммногоИнтерфейса = НастройкиПрограммногоИнтерфейсаПодключаемыхОбъектов();
КонецЕсли;
Таблица = Новый ТаблицаЗначений;
Таблица.Колонки.Добавить("ПолноеИмя", Новый ОписаниеТипов("Строка"));
Таблица.Колонки.Добавить("Менеджер");
Таблица.Колонки.Добавить("Метаданные");
Таблица.Колонки.Добавить("ТипСсылкиДанных");
Для Каждого Настройка Из НастройкиПрограммногоИнтерфейса Цикл
Попытка
Таблица.Колонки.Добавить(Настройка.Ключ, Настройка.ОписаниеТипов);
Исключение
ТекстОшибки = НСтр("ru = 'Не удалось зарегистрировать настройку программного интерфейса подключаемых объектов.
|Ключ: ""%1"", описание типов: ""%2"", описание ошибки: ""%3"".'");
ТекстОшибки = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
ТекстОшибки,
Настройка.Ключ,
Строка(Настройка.ОписаниеТипов),
КраткоеПредставлениеОшибки(ИнформацияОбОшибке()));
ВызватьИсключение ТекстОшибки;
КонецПопытки;
КонецЦикла;
Таблица.Индексы.Добавить("ПолноеИмя");
Возврат Таблица;
КонецФункции
// Шаблон сведений об отчетах и обработках, подключенных к источникам команд.
//
// Возвращаемое значение:
// ТаблицаЗначений - описание параметра Настройки процедуры ПриОпределенииНастроек объектов,
// включенных в состав подсистемы ПодключаемыеОтчетыИОбработки:
// * Ключ - Строка - имя настройки.
// * ОписаниеТипов - ОписаниеТипов - тип настройки.
// * ВидыПодключаемыхОбъектов - Строка - вид объекта метаданных в верхнем регистре.
// Например: "ОТЧЕТ" или "ОБРАБОТКА".
//
Функция НастройкиПрограммногоИнтерфейсаПодключаемыхОбъектов() Экспорт
Таблица = Новый ТаблицаЗначений;
Таблица.Колонки.Добавить("Ключ", Новый ОписаниеТипов("Строка"));
Таблица.Колонки.Добавить("ОписаниеТипов", Новый ОписаниеТипов("ОписаниеТипов"));
Таблица.Колонки.Добавить("ВидыПодключаемыхОбъектов", Новый ОписаниеТипов("Строка"));
Настройка = Таблица.Добавить();
Настройка.Ключ = "Размещение";
Настройка.ОписаниеТипов = Новый ОписаниеТипов("Массив");
Настройка.ВидыПодключаемыхОбъектов = "Отчет, Обработка";
ЗаполнениеОбъектов.ПриОпределенииСоставаНастроекПодключаемыхОбъектов(Таблица);
СозданиеНаОсновании.ПриОпределенииСоставаНастроекПодключаемыхОбъектов(Таблица);
ИнтеграцияПодсистемБСП.ПриОпределенииСоставаНастроекПодключаемыхОбъектов(Таблица);
ПодключаемыеКомандыПереопределяемый.ПриОпределенииСоставаНастроекПодключаемыхОбъектов(Таблица);
Возврат Таблица;
КонецФункции
////////////////////////////////////////////////////////////////////////////////
// Обработчики событий подсистем конфигурации.
// См. ОбновлениеИнформационнойБазыБСП.ПриДобавленииОбработчиковОбновления.
Процедура ПриДобавленииОбработчиковОбновления(Обработчики) Экспорт
Обработчик = Обработчики.Добавить();
Обработчик.ВыполнятьВГруппеОбязательных = Ложь;
Обработчик.ОбщиеДанные = Истина;
Обработчик.УправлениеОбработчиками = Ложь;
Обработчик.РежимВыполнения = "Оперативно";
Обработчик.Версия = "*";
Обработчик.Процедура = "ПодключаемыеКоманды.ОперативноеОбновлениеОбщихДанныхКонфигурации";
Обработчик.Приоритет = 90;
КонецПроцедуры
// Обработчик обновления кэшей, связанных с расширениями.
Функция ПриЗаполненииВсехПараметровРаботыРасширений() Экспорт
Возврат ОперативноеОбновлениеОбщихДанных(Тип("СправочникСсылка.ИдентификаторыОбъектовРасширений"));
КонецФункции
#КонецОбласти
#Область СлужебныеПроцедурыИФункции
////////////////////////////////////////////////////////////////////////////////
// Кэш формы ПриСозданииНаСервере.
// Кэш формы, в которой будут выводиться подключаемые команды.
Функция КэшФормы(ИмяФормы, ИсточникиЧерезЗапятую, ЭтоФормаОбъекта) Экспорт
Команды = ТаблицаКоманд();
Источники = ДеревоИсточниковКоманд();
НастройкиПрограммногоИнтерфейса = НастройкиПрограммногоИнтерфейсаПодключаемыхОбъектов();
ПодключенныеОбъекты = ТаблицаПодключаемыхОбъектов(НастройкиПрограммногоИнтерфейса);
КэшФормы = Новый Структура;
КэшФормы.Вставить("Команды", Команды);
КэшФормы.Вставить("ЕстьУсловияВидимости", Ложь);
КэшФормы.Вставить("ФункциональныеОпции", Новый Структура);
МетаданныеФормы = Метаданные.НайтиПоПолномуИмени(ИмяФормы);
МетаданныеРодителя = ?(МетаданныеФормы = Неопределено, Неопределено, МетаданныеФормы.Родитель());
ВидВРег = ВРег(СтрРазделить(ИмяФормы, ".")[0]);
ТипыИсточников = Новый Массив;
Если ИсточникиЧерезЗапятую = "" Тогда
Источник = ЗарегистрироватьИсточник(МетаданныеРодителя, Источники, ПодключенныеОбъекты, НастройкиПрограммногоИнтерфейса);
ДополнитьМассивТипов(ТипыИсточников, Источник.ТипСсылкиДанных);
Иначе
ПолныеИменаИсточников = СтроковыеФункцииКлиентСервер.РазложитьСтрокуВМассивПодстрок(ИсточникиЧерезЗапятую, ",", Истина, Истина);
Для Каждого ПолноеИмя Из ПолныеИменаИсточников Цикл
ОбъектМетаданных = Метаданные.НайтиПоПолномуИмени(ПолноеИмя);
Источник = ЗарегистрироватьИсточник(ОбъектМетаданных, Источники, ПодключенныеОбъекты, НастройкиПрограммногоИнтерфейса);
ДополнитьМассивТипов(ТипыИсточников, Источник.ТипСсылкиДанных);
КонецЦикла;
КонецЕсли;
Если ЭтоФормаОбъекта = Истина И ТипыИсточников.Количество() = 1 И МетаданныеРодителя <> Метаданные.НайтиПоТипу(ТипыИсточников[0]) Тогда
ЭтоФормаОбъекта = Ложь; // В форме объекта размещен список от другого типа объекта.
КонецЕсли;
Если ЭтоФормаОбъекта = Неопределено Тогда
Если ТипыИсточников.Количество() > 1 Тогда
ЭтоФормаОбъекта = Ложь;
ИначеЕсли МетаданныеРодителя <> Неопределено Тогда
Коллекция = Новый Структура("ОсновнаяФормаСписка, ОсновнаяФормаОбъекта");
ЗаполнитьЗначенияСвойств(Коллекция, МетаданныеРодителя);
Если МетаданныеФормы = Коллекция.ОсновнаяФормаСписка Тогда
ЭтоФормаОбъекта = Ложь;
ИначеЕсли МетаданныеФормы = Коллекция.ОсновнаяФормаОбъекта И МетаданныеРодителя <> Метаданные.НайтиПоТипу(ТипыИсточников[0]) Тогда
ЭтоФормаОбъекта = Истина;
Иначе
Если ВидВРег = ВРег("ЖурналДокументов") Тогда
ЭтоФормаОбъекта = Ложь;
ИначеЕсли ВидВРег = ВРег("Обработка") Тогда
ЭтоФормаОбъекта = Ложь;
Иначе
ЭтоФормаОбъекта = Истина;
КонецЕсли;
КонецЕсли;
Иначе
ЭтоФормаОбъекта = Ложь;
КонецЕсли;
КонецЕсли;
КэшФормы.Вставить("ЭтоФормаОбъекта", ЭтоФормаОбъекта);
Контекст = Новый Структура;
Контекст.Вставить("ВидВРег", ВидВРег);
Контекст.Вставить("ИмяФормы", ИмяФормы);
Контекст.Вставить("МетаданныеФормы", МетаданныеФормы);
Контекст.Вставить("ТипыИсточников", ТипыИсточников);
Контекст.Вставить("ЭтоФормаОбъекта", ЭтоФормаОбъекта);
Контекст.Вставить("ФункциональныеОпции", КэшФормы.ФункциональныеОпции);
КэшФормы.Вставить("ВводНаОснованииЧерезПодключаемыеКоманды", СозданиеНаОсновании.ОбъектыПодключеныКПодсистеме(ТипыИсточников));
Если КэшФормы.ВводНаОснованииЧерезПодключаемыеКоманды Тогда
СозданиеНаОсновании.ПриОпределенииКомандПодключенныхКОбъекту(Контекст, Источники, ПодключенныеОбъекты, Команды);
КонецЕсли;
ЗаполнениеОбъектов.ПриОпределенииКомандПодключенныхКОбъекту(Контекст, Источники, ПодключенныеОбъекты, Команды);
ИнтеграцияПодсистемБСП.ПриОпределенииКомандПодключенныхКОбъекту(Контекст, Источники, ПодключенныеОбъекты, Команды);
ПодключаемыеКомандыПереопределяемый.ПриОпределенииКомандПодключенныхКОбъекту(Контекст, Источники, ПодключенныеОбъекты, Команды);
// Фильтр команд по именам форм и функциональным опциям.
ЧастиИмени = СтрРазделить(ИмяФормы, ".");
КраткоеИмяФормы = ЧастиИмени[ЧастиИмени.ВГраница()];
Количество = Команды.Количество();
Для Номер = 1 По Количество Цикл
Команда = Команды[Количество - Номер];
// Значения по умолчанию.
Если Команда.ИзменяетВыбранныеОбъекты = Неопределено Тогда
Команда.ИзменяетВыбранныеОбъекты = Ложь;
КонецЕсли;
// Фильтр по назначению.
Если Команда.Назначение = "ДляСписка" И Контекст.ЭтоФормаОбъекта Или Команда.Назначение = "ДляОбъекта" И Не Контекст.ЭтоФормаОбъекта Тогда
Команды.Удалить(Команда);
Продолжить;
КонецЕсли;
// Фильтр по именам форм.
ВидимостьВФормах = СтроковыеФункцииКлиентСервер.РазложитьСтрокуВМассивПодстрок(ВРег(Команда.ВидимостьВФормах), ",", Истина, Истина);
Если ВидимостьВФормах.Количество() > 0
И ВидимостьВФормах.Найти(ВРег(КраткоеИмяФормы)) = Неопределено
И ВидимостьВФормах.Найти(ВРег(ИмяФормы)) = Неопределено Тогда
Команды.Удалить(Команда);
Продолжить;
КонецЕсли;
// Фильтр по функциональным опциям.
ФункциональныеОпции = СтроковыеФункцииКлиентСервер.РазложитьСтрокуВМассивПодстрок(Команда.ФункциональныеОпции, ",", Истина, Истина);
ВидимостьКоманды = ФункциональныеОпции.Количество() = 0;
Для Каждого ИмяОпции Из ФункциональныеОпции Цикл
Если ПолучитьФункциональнуюОпцию(СокрЛП(ИмяОпции)) Тогда
ВидимостьКоманды = Истина;
Прервать;
КонецЕсли;
КонецЦикла;
Если Не ВидимостьКоманды Тогда
Команды.Удалить(Команда);
Продолжить;
КонецЕсли;
// Динамические применяемые условия видимости.
Если ТипЗнч(Команда.ТипПараметра) = Тип("Тип") Тогда
МассивТипов = Новый Массив;
МассивТипов.Добавить(Команда.ТипПараметра);
Команда.ТипПараметра = Новый ОписаниеТипов(МассивТипов);
КонецЕсли;
Если ТипЗнч(Команда.ТипПараметра) = Тип("ОписаниеТипов") И ЗначениеЗаполнено(Команда.ТипПараметра) Тогда
СодержитХотьОдинТип = Ложь;
Для Каждого Тип Из ТипыИсточников Цикл
Если Команда.ТипПараметра.СодержитТип(Тип) Тогда
СодержитХотьОдинТип = Истина;
Иначе
Команда.ЕстьУсловияВидимости = Истина;
КонецЕсли;
КонецЦикла;
Если Не СодержитХотьОдинТип Тогда
Команды.Удалить(Команда);
Продолжить;
КонецЕсли;
КонецЕсли;
Если ТипЗнч(Команда.УсловияВидимости) = Тип("Массив") И Команда.УсловияВидимости.Количество() > 0 Тогда
Команда.ЕстьУсловияВидимости = Истина;
КонецЕсли;
Если Команда.МножественныйВыбор = Неопределено Тогда
Команда.МножественныйВыбор = Истина;
КонецЕсли;
Команда.ПорядокВажности = ?(Команда.Важность = "Важное", 1, ?(Команда.Важность = "СмТакже", 3, 2));
КэшФормы.ЕстьУсловияВидимости = КэшФормы.ЕстьУсловияВидимости Или Команда.ЕстьУсловияВидимости;
Если ПустаяСтрока(Команда.Идентификатор) Тогда
Команда.Идентификатор = "Авто_" + ОбщегоНазначения.КонтрольнаяСуммаСтрокой(Команда.Менеджер + "/" + Команда.ИмяФормы + "/" + Команда.Обработчик);
КонецЕсли;
КонецЦикла;
Возврат КэшФормы;
КонецФункции
Функция ВидыКоманд()
Виды = Новый ТаблицаЗначений;
Виды.Колонки.Добавить("Имя", Новый ОписаниеТипов("Строка"));
Виды.Колонки.Добавить("ИмяПодменю", Новый ОписаниеТипов("Строка"));
Виды.Колонки.Добавить("Заголовок", Новый ОписаниеТипов("Строка"));
Виды.Колонки.Добавить("Порядок", Новый ОписаниеТипов("Число"));
Виды.Колонки.Добавить("Картинка"); // Картинка, Неопределено.
Виды.Колонки.Добавить("Отображение"); // ОтображениеКнопки, Неопределено.
Виды.Колонки.Добавить("ВидГруппыФормы");
// Вид с пустой группой для команд, которые следует размещать в командной панели.
Вид = Виды.Добавить();
Вид.Имя = "КоманднаяПанель";
Вид.ИмяПодменю = "";
Вид.Порядок = 90;
ЗаполнениеОбъектов.ПриОпределенииВидовПодключаемыхКоманд(Виды);
СозданиеНаОсновании.ПриОпределенииВидовПодключаемыхКоманд(Виды);
ИнтеграцияПодсистемБСП.ПриОпределенииВидовПодключаемыхКоманд(Виды);
ПодключаемыеКомандыПереопределяемый.ПриОпределенииВидовПодключаемыхКоманд(Виды);
Виды.Сортировать("Порядок Возр");
Возврат Виды;
КонецФункции
Процедура ПроверитьИмяВидаКоманд(ИмяВида)
Структура = Новый Структура;
Попытка
Структура.Вставить(ИмяВида, Неопределено);
Исключение
ТекстОшибки = НСтр("ru = 'Имя вида команд ""%1"" не удовлетворяет требованиям именования переменных.'");
ВызватьИсключение СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(ТекстОшибки, ИмяВида);
КонецПопытки;
КонецПроцедуры
////////////////////////////////////////////////////////////////////////////////
// Вывод.
// Размещает подключенные команды в форме.
//
// Параметры:
// Форма - ФормаКлиентскогоПриложения - форма, в которой необходимо разместить команды.
// Команды - см. ТаблицаКоманд
// ПараметрыРазмещения - см. ПараметрыРазмещения
//
Процедура ВывестиКоманды(Форма, Команды, ПараметрыРазмещения)
ПодключенныеКоманды = ПодключенныеКоманды(Форма);
КлючПараметровРазмещения = КлючПараметровРазмещения(ПараметрыРазмещения);
РанееДобавленныеКоманды = Неопределено;
Если ПодключенныеКоманды.АдресТаблицыКоманд <> Неопределено И ЭтоАдресВременногоХранилища(ПодключенныеКоманды.АдресТаблицыКоманд) Тогда
РанееДобавленныеКоманды = ПолучитьИзВременногоХранилища(ПодключенныеКоманды.АдресТаблицыКоманд);
УдаляемыеКоманды = РанееДобавленныеКоманды.НайтиСтроки(Новый Структура("КлючПараметровРазмещения", КлючПараметровРазмещения));
УдалитьКоманды(Форма, УдаляемыеКоманды);
Для Каждого Команда Из УдаляемыеКоманды Цикл
РанееДобавленныеКоманды.Удалить(Команда);
КонецЦикла;
КонецЕсли;
ПодключенныеКоманды.ЕстьУсловияВидимости = ПодключенныеКоманды.ЕстьУсловияВидимости Или ПараметрыРазмещения.ЕстьУсловияВидимости;
Элементы = Форма.Элементы;
ПрефиксГрупп = ?(ЗначениеЗаполнено(ПараметрыРазмещения.ПрефиксГрупп), ПараметрыРазмещения.ПрефиксГрупп, "");
КоманднаяПанель = ПараметрыРазмещения.КоманднаяПанель;
Если КоманднаяПанель = Неопределено Тогда
КоманднаяПанель = КоманднаяПанельФормы(Форма, ПрефиксГрупп, ПараметрыРазмещения.ЭтоФормаОбъекта);
КонецЕсли;
СведенияОВсехПодменю = Новый ТаблицаЗначений;
СведенияОВсехПодменю.Колонки.Добавить("Подменю");
СведенияОВсехПодменю.Колонки.Добавить("ВыведеноКоманд", Новый ОписаниеТипов("Число"));
СведенияОВсехПодменю.Колонки.Добавить("ЕстьКомандыСУсловиямиВидимости", Новый ОписаниеТипов("Булево"));
СведенияОВсехПодменю.Колонки.Добавить("ЕстьКомандыБезУсловийВидимости", Новый ОписаниеТипов("Булево"));
СведенияОВсехПодменю.Колонки.Добавить("Группы", Новый ОписаниеТипов("Структура"));
СведенияОВсехПодменю.Колонки.Добавить("ГруппаПоУмолчанию");
СведенияОВсехПодменю.Колонки.Добавить("ПоследняяКоманда");
СведенияОВсехПодменю.Колонки.Добавить("КомандыСУсловиямиВидимости", Новый ОписаниеТипов("Массив"));
БыстрыйПоискСведенийОПодменю = Новый Соответствие;
КорневыеПодменюИКоманды = ПодключенныеКоманды.КорневыеПодменюИКоманды;
// Вывод команд.
Команды.Сортировать("Вид, ПорядокВажности Возр, Порядок Возр, Представление Возр");
СчетчикКомандСАвтогенерируемымИменем = 0;
ВидыКоманд = ВидыКоманд();
Для Каждого ВидКоманд Из ВидыКоманд Цикл
ПроверитьИмяВидаКоманд(ВидКоманд.Имя);
КомандыВида = Команды.НайтиСтроки(Новый Структура("Вид", ВидКоманд.Имя));
Если КомандыВида.Количество() = 0 И ВидКоманд.Имя <> "СозданиеНаОсновании" Тогда
Продолжить;
КонецЕсли;
ИмяПодменюПоУмолчанию = "";
Если Не ПустаяСтрока(ВидКоманд.ИмяПодменю) Тогда
ИмяПодменюПоУмолчанию = ПрефиксГрупп + ВидКоманд.ИмяПодменю;
КонецЕсли;
СведенияОПодменюПоУмолчанию = БыстрыйПоискСведенийОПодменю.Получить(НРег(ИмяПодменюПоУмолчанию));
Если СведенияОПодменюПоУмолчанию = Неопределено Тогда
СведенияОПодменюПоУмолчанию = ЗарегистрироватьПодменю(Элементы, СведенияОВсехПодменю, ИмяПодменюПоУмолчанию, ВидКоманд, КоманднаяПанель);
БыстрыйПоискСведенийОПодменю.Вставить(НРег(ИмяПодменюПоУмолчанию), СведенияОПодменюПоУмолчанию);
КонецЕсли;
Для Каждого Команда Из КомандыВида Цикл
Если ПустаяСтрока(Команда.Подменю) Тогда
СведенияОПодменюКоманды = СведенияОПодменюПоУмолчанию;
Иначе
ИмяПодменю = ПрефиксГрупп + Команда.Подменю;
СведенияОПодменюКоманды = БыстрыйПоискСведенийОПодменю.Получить(НРег(ИмяПодменю));
Если СведенияОПодменюКоманды = Неопределено Тогда
СведенияОПодменюКоманды = ЗарегистрироватьПодменю(Элементы, СведенияОВсехПодменю, ИмяПодменю, , , СведенияОПодменюПоУмолчанию);
БыстрыйПоискСведенийОПодменю.Вставить(НРег(ИмяПодменю), СведенияОПодменюКоманды);
КонецЕсли;
КонецЕсли;
ГруппаФормы = Неопределено; // ГруппаФормы
Если Не ЗначениеЗаполнено(Команда.Важность)
Или Не СведенияОПодменюКоманды.Группы.Свойство(Команда.Важность, ГруппаФормы) Тогда
ГруппаФормы = СведенияОПодменюКоманды.ГруппаПоУмолчанию;
КонецЕсли;
Команда.ИмяВФорме = ОпределитьИмяКоманды(Форма, ГруппаФормы.Имя, Команда.Идентификатор, СчетчикКомандСАвтогенерируемымИменем);
Команда.КлючПараметровРазмещения = КлючПараметровРазмещения;
Подменю = СведенияОПодменюКоманды.Подменю; // ГруппаФормы
ИмяКорневогоЭлемента = ?(ВидКоманд.Имя = "КоманднаяПанель", Команда.ИмяВФорме, Подменю.Имя);
Если КорневыеПодменюИКоманды.Найти(ИмяКорневогоЭлемента) = Неопределено Тогда
КорневыеПодменюИКоманды.Добавить(ИмяКорневогоЭлемента);
КонецЕсли;
КомандаФормы = Форма.Команды.Добавить(Команда.ИмяВФорме);
КомандаФормы.Действие = "Подключаемый_ВыполнитьКоманду";
КомандаФормы.Заголовок = Команда.Представление;
КомандаФормы.Подсказка = КомандаФормы.Заголовок;
КомандаФормы.Отображение = ?(ЗначениеЗаполнено(Команда.ОтображениеКнопки),
Команда.ОтображениеКнопки, ОтображениеКнопки.КартинкаИТекст);
Если ТипЗнч(Команда.Картинка) = Тип("Картинка") Тогда
КомандаФормы.Картинка = Команда.Картинка;
КонецЕсли;
Если ТипЗнч(Команда.СочетаниеКлавиш) = Тип("СочетаниеКлавиш") Тогда
КомандаФормы.СочетаниеКлавиш = Команда.СочетаниеКлавиш;
КонецЕсли;
Если СведенияОПодменюКоманды.Подменю = КоманднаяПанель
И СтрДлина(Команда.Представление) > 35
И ЗначениеЗаполнено(КомандаФормы.Картинка) Тогда
КомандаФормы.Отображение = ОтображениеКнопки.Картинка;
КонецЕсли;
КнопкаФормы = Элементы.Добавить(Команда.ИмяВФорме, Тип("КнопкаФормы"), ГруппаФормы);
КнопкаФормы.Вид = ВидКнопкиФормы.КнопкаКоманднойПанели;
КнопкаФормы.ИмяКоманды = Команда.ИмяВФорме;
КнопкаФормы.ТолькоВоВсехДействиях = Команда.ТолькоВоВсехДействиях;
Если Команда.ИзменяетВыбранныеОбъекты И Форма.ТолькоПросмотр Тогда
КнопкаФормы.Доступность = Ложь;
КонецЕсли;
Если ЗначениеЗаполнено(Команда.ЗначениеПометки) И ЭтоПутьДоРеквизита(Команда.ЗначениеПометки) Тогда
Команда.ЗначениеПометки = ВыражениеВычислениеПометки(Команда.ЗначениеПометки);
ПодключенныеКоманды.КомандыСПометкой.Добавить(ОписаниеКомандыНаКлиенте(Команда, КнопкаФормы));
КонецЕсли;
СведенияОПодменюКоманды.ВыведеноКоманд = СведенияОПодменюКоманды.ВыведеноКоманд + 1;
СведенияОПодменюКоманды.ПоследняяКоманда = КомандаФормы;
Если Команда.ЕстьУсловияВидимости Тогда
СведенияОПодменюКоманды.ЕстьКомандыСУсловиямиВидимости = Истина;
СведенияОКоманде = Новый Структура("ИмяВФорме, ТипПараметра, УсловияВидимости");
ЗаполнитьЗначенияСвойств(СведенияОКоманде, Команда);
СведенияОПодменюКоманды.КомандыСУсловиямиВидимости.Добавить(СведенияОКоманде);
Иначе
СведенияОПодменюКоманды.ЕстьКомандыБезУсловийВидимости = Истина;
КонецЕсли;
КонецЦикла;
СозданиеНаОсновании.ПриВыводеКоманд(Форма, ВидКоманд, СведенияОПодменюПоУмолчанию, ПараметрыРазмещения);
КонецЦикла;
// Команда-заглушка нужна всегда.
КомандаЗаглушка = Форма.Команды.Найти("КомандаДляВыводаВПустоеПодменю");
Если КомандаЗаглушка = Неопределено Тогда
КомандаЗаглушка = Форма.Команды.Добавить("КомандаДляВыводаВПустоеПодменю");
КомандаЗаглушка.Заголовок = НСтр("ru = '(нет)'");
КонецЕсли;
// Постобработка задействованных подменю.
Для Каждого СведенияОПодменю Из СведенияОВсехПодменю Цикл
Если СведенияОПодменю.ВыведеноКоманд = 0 Тогда
Продолжить;
КонецЕсли;
ЭтоКоманднаяПанель = (СведенияОПодменю.Подменю = КоманднаяПанель);
КомандаФормы = СведенияОПодменю.ПоследняяКоманда;
Подменю = СведенияОПодменю.Подменю;
Если Не ЭтоКоманднаяПанель Тогда
Если СведенияОПодменю.ВыведеноКоманд = 1 И КомандаФормы <> Неопределено Тогда
// Превращение подменю в кнопку когда выведена 1 команда с коротким заголовком.
Если Не ЗначениеЗаполнено(КомандаФормы.Картинка) И Подменю.Вид = ВидГруппыФормы.Подменю Тогда
КомандаФормы.Картинка = Подменю.Картинка;
КонецЕсли;
Если СтрДлина(КомандаФормы.Заголовок) <= 35 И Подменю.Отображение <> ОтображениеКнопки.Картинка Тогда
КомандаФормы.Отображение = ОтображениеКнопки.КартинкаИТекст;
Иначе
КомандаФормы.Отображение = ОтображениеКнопки.Картинка;
КонецЕсли;
Подменю.Вид = ВидГруппыФормы.ГруппаКнопок;
КомандаФормы.Подсказка = КомандаФормы.Заголовок;
Иначе
// Добавление кнопок-заглушек, которые показываются когда в подменю скрыты все команды.
ИмяКомандыЗаглушки = Подменю.Имя + "Заглушка";
Если Элементы.Найти(ИмяКомандыЗаглушки) = Неопределено Тогда
КнопкаФормы = Элементы.Добавить(ИмяКомандыЗаглушки, Тип("КнопкаФормы"), Подменю);
КнопкаФормы.Вид = ВидКнопкиФормы.КнопкаКоманднойПанели;
КнопкаФормы.ИмяКоманды = "КомандаДляВыводаВПустоеПодменю";
КнопкаФормы.Видимость = Ложь;
КнопкаФормы.Доступность = Ложь;
КонецЕсли;
КонецЕсли;
КонецЕсли;
Если СведенияОПодменю.ЕстьКомандыСУсловиямиВидимости Тогда
КраткиеСведенияОПодменю = Новый Структура("Имя, КомандыСУсловиямиВидимости, ЕстьКомандыБезУсловийВидимости");
ЗаполнитьЗначенияСвойств(КраткиеСведенияОПодменю, СведенияОПодменю);
КраткиеСведенияОПодменю.Имя = СведенияОПодменю.Подменю.Имя;
ПодключенныеКоманды.ПодменюСУсловиямиВидимости.Добавить(КраткиеСведенияОПодменю);
КонецЕсли;
КонецЦикла;
Если РанееДобавленныеКоманды <> Неопределено Тогда
РанееДобавленныеКоманды = ПолучитьИзВременногоХранилища(ПодключенныеКоманды.АдресТаблицыКоманд);
Если ТипЗнч(РанееДобавленныеКоманды) = Тип("ТаблицаЗначений") Тогда
Индекс = -1;
Для Каждого СтрокаТаблицы Из РанееДобавленныеКоманды Цикл
Индекс = Индекс + 1;
ЗаполнитьЗначенияСвойств(Команды.Вставить(Индекс), СтрокаТаблицы);
КонецЦикла;
КонецЕсли;
УдалитьИзВременногоХранилища(ПодключенныеКоманды.АдресТаблицыКоманд);
КонецЕсли;
Команды.Колонки.Удалить("СочетаниеКлавиш");
ПодключенныеКоманды.АдресТаблицыКоманд = ПоместитьВоВременноеХранилище(Команды, Форма.УникальныйИдентификатор);
КонецПроцедуры
Функция КлючПараметровРазмещения(Знач ПараметрыРазмещения)
ПараметрыРазмещения = ОбщегоНазначения.СкопироватьРекурсивно(ПараметрыРазмещения);
ГруппаФормы = ПараметрыРазмещения.КоманднаяПанель;
Если ТипЗнч(ГруппаФормы) = Тип("ГруппаФормы") Тогда
ПараметрыРазмещения.КоманднаяПанель = ГруппаФормы.Имя;
КонецЕсли;
Источники = Новый Массив;
Если ТипЗнч(ПараметрыРазмещения.Источники) = Тип("Массив") Тогда
Для Каждого ОбъектМетаданных Из ПараметрыРазмещения.Источники Цикл
Источники.Добавить(ОбъектМетаданных.ПолноеИмя());
КонецЦикла;
ПараметрыРазмещения.Источники = Источники;
КонецЕсли;
Возврат ОбщегоНазначения.КонтрольнаяСуммаСтрокой(ОбщегоНазначения.ЗначениеВСтрокуXML(ПараметрыРазмещения));
КонецФункции
Процедура УдалитьКоманды(Форма, УдаляемыеКоманды)
Для Каждого ОписаниеКоманды Из УдаляемыеКоманды Цикл
Команда = Форма.Команды[ОписаниеКоманды.ИмяВФорме];
Форма.Команды.Удалить(Команда);
Форма.Элементы.Удалить(Форма.Элементы[ОписаниеКоманды.ИмяВФорме]);
КонецЦикла;
КонецПроцедуры
Функция КоманднаяПанельФормы(Форма, ПрефиксГрупп, ЭтоФормаОбъекта)
Элементы = Форма.Элементы;
Результат = Элементы.Найти(ПрефиксГрупп + "ПодключаемыеКоманды");
Если Результат = Неопределено Тогда
Результат = Элементы.Найти(ПрефиксГрупп + "КоманднаяПанель");
Если Результат = Неопределено Тогда
Результат = Элементы.Найти(ПрефиксГрупп + "ОсновнаяКоманднаяПанель");
Если Результат = Неопределено И ЗначениеЗаполнено(ПрефиксГрупп) Тогда
ТаблицаФормы = Элементы.Найти(ПрефиксГрупп);
Если ТипЗнч(ТаблицаФормы) = Тип("ТаблицаФормы") Тогда
Результат = ТаблицаФормы.КоманднаяПанель;
КонецЕсли;
КонецЕсли;
Если Не ЭтоФормаОбъекта
И Результат = Неопределено
И Не ЗначениеЗаполнено(ПрефиксГрупп) Тогда
ТаблицаФормы = Элементы.Найти("Список");
Если ТипЗнч(ТаблицаФормы) = Тип("ТаблицаФормы")
И ТаблицаФормы.ПоложениеКоманднойПанели <> ПоложениеКоманднойПанелиЭлементаФормы.Нет Тогда
Результат = ТаблицаФормы.КоманднаяПанель;
КонецЕсли;
КонецЕсли;
Если Результат = Неопределено Тогда
Результат = Форма.КоманднаяПанель;
КонецЕсли;
КонецЕсли;
КонецЕсли;
Возврат Результат;
КонецФункции
Функция ПодключенныеКоманды(Форма)
ЗначенияСвойств = Новый Структура("ПараметрыПодключаемыхКоманд", Null);
ЗаполнитьЗначенияСвойств(ЗначенияСвойств, Форма);
Результат = ЗначенияСвойств.ПараметрыПодключаемыхКоманд;
Если ТипЗнч(Результат) <> Тип("Структура") Тогда
Если Результат = Null Тогда
ДобавляемыеРеквизиты = Новый Массив;
ДобавляемыеРеквизиты.Добавить(Новый РеквизитФормы("ПараметрыПодключаемыхКоманд", Новый ОписаниеТипов));
Форма.ИзменитьРеквизиты(ДобавляемыеРеквизиты);
КонецЕсли;
Результат = Новый Структура;
Результат.Вставить("ЕстьУсловияВидимости", Ложь);
Результат.Вставить("ПодменюСУсловиямиВидимости", Новый Массив);
Результат.Вставить("КомандыСПометкой", Новый Массив);
Результат.Вставить("КорневыеПодменюИКоманды", Новый Массив);
Результат.Вставить("ДоступностьКоманд", Истина);
Результат.Вставить("АдресТаблицыКоманд", Неопределено);
Форма.ПараметрыПодключаемыхКоманд = Результат;
КонецЕсли;
Возврат Результат;
КонецФункции
Функция ЭтоПутьДоРеквизита(Знач ПутьДоРеквизита)
Результат = Истина;
ПутьДоРеквизита = ВРег(ПутьДоРеквизита);
ПутьДоРеквизита = СтрЗаменить(ПутьДоРеквизита, "НЕ ", "");
Идентификаторы = СтрРазделить(СтрЗаменить(ПутьДоРеквизита, "%ИСТОЧНИК%",""), ".");
Для Каждого Элемент Из Идентификаторы Цикл
Попытка
Пустышка = Новый Структура(Элемент);
Исключение
Результат = Ложь;
Прервать;
КонецПопытки;
КонецЦикла;
Возврат Результат;
КонецФункции
Функция ОписаниеКомандыНаКлиенте(Команда, КнопкаФормы)
ОписаниеКоманды = Новый Структура;
ОписаниеКоманды.Вставить("ИмяВФорме", КнопкаФормы.Имя);
ОписаниеКоманды.Вставить("Вид", Команда.Вид);
ОписаниеКоманды.Вставить("Идентификатор", Команда.Идентификатор);
ОписаниеКоманды.Вставить("ЗначениеПометки", Команда.ЗначениеПометки);
Возврат ОписаниеКоманды;
КонецФункции
Функция ЗарегистрироватьПодменю(Элементы, СведенияОВсехПодменю, ИмяПодменю, ШаблонНового = Неопределено, КоманднаяПанель = Неопределено, ПодменюПоУмолчанию = Неопределено)
ВыведеноКоманд = 0;
Группы = Новый Структура;
Если ЗначениеЗаполнено(ИмяПодменю) Тогда
Подменю = Элементы.Найти(ИмяПодменю);
Если Подменю = Неопределено Тогда
Если ШаблонНового = Неопределено Тогда
Возврат ПодменюПоУмолчанию;
КонецЕсли;
Подменю = Элементы.Добавить(ИмяПодменю, Тип("ГруппаФормы"), КоманднаяПанель);
Подменю.Вид = ?(ЗначениеЗаполнено(ШаблонНового.ВидГруппыФормы), ШаблонНового.ВидГруппыФормы, ВидГруппыФормы.Подменю);
Подменю.Заголовок = ШаблонНового.Заголовок;
Если Подменю.Вид = ВидГруппыФормы.Подменю Тогда
Подменю.Картинка = ШаблонНового.Картинка;
Подменю.Отображение = ШаблонНового.Отображение;
КонецЕсли;
Иначе
ГруппаПоУмолчанию = Подменю;
ВыведеноКоманд = КоличествоКомандВГруппе(ГруппаПоУмолчанию);
Для Каждого Группа Из Подменю.ПодчиненныеЭлементы Цикл
Если ТипЗнч(Группа) <> Тип("ГруппаФормы") Тогда
Продолжить;
КонецЕсли;
КраткоеИмя = Группа.Имя;
Если СтрНачинаетсяС(НРег(КраткоеИмя), НРег(ИмяПодменю)) Тогда
КраткоеИмя = Сред(КраткоеИмя, СтрДлина(ИмяПодменю) + 1);
Если НРег(КраткоеИмя) = НРег("Обычное") Тогда
ГруппаПоУмолчанию = Группа;
КонецЕсли;
КонецЕсли;
Группы.Вставить(КраткоеИмя, Группа);
КонецЦикла;
КонецЕсли;
Если Подменю.Отображение = ОтображениеКнопки.Картинка И Не ЗначениеЗаполнено(Подменю.Подсказка) Тогда
Подменю.Подсказка = Подменю.Заголовок;
КонецЕсли;
Если Не Группы.Свойство("Важное") Тогда
ГруппаВажное = Элементы.Добавить(ИмяПодменю + "Важное", Тип("ГруппаФормы"), Подменю);
ГруппаВажное.Вид = ВидГруппыФормы.ГруппаКнопок;
ГруппаВажное.Заголовок = Подменю.Заголовок + " (" + НСтр("ru = 'Важное'") + ")";
Группы.Вставить("Важное", ГруппаВажное);
КонецЕсли;
Если Не Группы.Свойство("Обычное") Тогда
ГруппаПоУмолчанию = Элементы.Добавить(ИмяПодменю + "Обычное", Тип("ГруппаФормы"), Подменю);
ГруппаПоУмолчанию.Вид = ВидГруппыФормы.ГруппаКнопок;
ГруппаПоУмолчанию.Заголовок = Подменю.Заголовок + " (" + НСтр("ru = 'Обычное'") + ")";
Группы.Вставить("Обычное", ГруппаПоУмолчанию);
КонецЕсли;
Если Не Группы.Свойство("СмТакже") Тогда
ГруппаСмТакже = Элементы.Добавить(ИмяПодменю + "СмТакже", Тип("ГруппаФормы"), Подменю);
ГруппаСмТакже.Вид = ВидГруппыФормы.ГруппаКнопок;
ГруппаСмТакже.Заголовок = Подменю.Заголовок + " (" + НСтр("ru = 'См. также'") + ")";
Группы.Вставить("СмТакже", ГруппаСмТакже);
КонецЕсли;
Иначе
Если ШаблонНового = Неопределено Тогда
Возврат ПодменюПоУмолчанию;
КонецЕсли;
Подменю = КоманднаяПанель;
ГруппаПоУмолчанию = КоманднаяПанель;
КонецЕсли;
Результат = СведенияОВсехПодменю.Добавить();
Результат.Подменю = Подменю;
Результат.ГруппаПоУмолчанию = ГруппаПоУмолчанию;
Результат.Группы = Группы;
Результат.ВыведеноКоманд = ВыведеноКоманд;
Возврат Результат;
КонецФункции
Функция КоличествоКомандВГруппе(Группа)
Результат = 0;
Для Каждого Элемент Из Группа.ПодчиненныеЭлементы Цикл
Если ТипЗнч(Элемент) = Тип("ГруппаФормы") Тогда
Результат = Результат + КоличествоКомандВГруппе(Элемент);
ИначеЕсли ТипЗнч(Элемент) = Тип("КнопкаФормы") Тогда
Результат = Результат + 1;
КонецЕсли;
КонецЦикла;
Возврат Результат;
КонецФункции
Функция ОпределитьИмяКоманды(Форма, ИмяГруппы, ИдентификаторКоманды, СчетчикКомандСАвтогенерируемымИменем)
Если ИмяСоответствуетТребованиямИменованияСвойств(ИдентификаторКоманды) Тогда
ИмяКоманды = ИмяГруппы + "_" + ИдентификаторКоманды;
Иначе
СчетчикКомандСАвтогенерируемымИменем = СчетчикКомандСАвтогенерируемымИменем + 1;
ИмяКоманды = ИмяГруппы + "_" + Формат(СчетчикКомандСАвтогенерируемымИменем, "ЧН=; ЧГ=");
КонецЕсли;
Пока Форма.Элементы.Найти(ИмяКоманды) <> Неопределено
Или Форма.Команды.Найти(ИмяКоманды) <> Неопределено Цикл
СчетчикКомандСАвтогенерируемымИменем = СчетчикКомандСАвтогенерируемымИменем + 1;
ИмяКоманды = ИмяГруппы + "_" + Формат(СчетчикКомандСАвтогенерируемымИменем, "ЧН=; ЧГ=");
КонецЦикла;
Возврат ИмяКоманды;
КонецФункции
Функция ИмяСоответствуетТребованиямИменованияСвойств(Имя)
Буквы = "АБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯABCDEFGHIJKLMNOPQRSTUVWXYZ";
Цифры = "1234567890";
Если Имя = "" Или СтрНайти(Буквы + "_", ВРег(Лев(Имя, 1))) = 0 Тогда
Возврат Ложь;
КонецЕсли;
Возврат СтрРазделить(ВРег(Имя), Буквы + Цифры + "_", Ложь).Количество() = 0;
КонецФункции
////////////////////////////////////////////////////////////////////////////////
// Обновление информационной базы.
Функция ОперативноеОбновлениеОбщихДанныхКонфигурации() Экспорт
Возврат ОперативноеОбновлениеОбщихДанных(Тип("СправочникСсылка.ИдентификаторыОбъектовМетаданных"));
КонецФункции
// Обновляет кэш объектов метаданных указанного типа.
//
// Параметры:
// ФильтрПоТипуИдентификаторов - * - тип объектов метаданных.
// - СправочникСсылка.ИдентификаторыОбъектовМетаданных - обновлять кэш конфигурации.
// Структура с ключом "ПодключенныеОбъекты" записывается в константу ПараметрыПодключаемыхКоманд.
// - СправочникСсылка.ИдентификаторыОбъектовРасширений - обновлять кэш расширений.
// Структура с ключом "ПодключенныеОбъекты" записывается в регистр ПараметрыРаботыВерсийРасширений.
//
// Возвращаемое значение:
// Структура:
// * ЕстьИзменения - Булево - Истина когда обновление прошло не "в холостую".
// * ПодключенныеОбъекты - Соответствие - кэш для быстрого определения списка объектов,
// подключенных к объектам конфигурации.
// Ключами и значениям являются ссылки объектов метаданных конфигурации и расширений.
//
Функция ОперативноеОбновлениеОбщихДанных(ФильтрПоТипуИдентификаторов)
Результат = Новый Структура;
Результат.Вставить("ЕстьИзменения", Ложь);
Если ФильтрПоТипуИдентификаторов = Тип("СправочникСсылка.ИдентификаторыОбъектовРасширений")
И Не ЗначениеЗаполнено(ПараметрыСеанса.ВерсияРасширений) Тогда
Возврат Результат;
КонецЕсли;
ПодключенныеОбъекты = Новый Соответствие;
НастройкиПрограммногоИнтерфейса = НастройкиПрограммногоИнтерфейсаПодключаемыхОбъектов();
Состав = Метаданные.Подсистемы.ПодключаемыеОтчетыИОбработки.Состав;
Для Каждого ОбъектМетаданныхПоставщика Из Состав Цикл
Если Не ОбщегоНазначения.ДоступноИспользованиеРазделенныхДанных() И ОбъектМетаданныхПоставщика.РасширениеКонфигурации() <> Неопределено Тогда
Продолжить;
КонецЕсли;
СсылкаПодключенногоОМ = ОбщегоНазначения.ИдентификаторОбъектаМетаданных(ОбъектМетаданныхПоставщика);
Если ТипЗнч(СсылкаПодключенногоОМ) <> ФильтрПоТипуИдентификаторов Тогда
Продолжить;
КонецЕсли;
ПолноеИмя = ОбъектМетаданныхПоставщика.ПолноеИмя();
Настройки = НастройкиПодключаемогоОбъекта(ПолноеИмя, НастройкиПрограммногоИнтерфейса);
Если Настройки = Неопределено Тогда
Продолжить;
КонецЕсли;
Для Каждого ОбъектМетаданных Из Настройки.Размещение Цикл
СсылкаОМ = ОбщегоНазначения.ИдентификаторОбъектаМетаданных(ОбъектМетаданных);
МассивПриемник = ПодключенныеОбъекты[СсылкаОМ];
Если МассивПриемник = Неопределено Тогда
МассивПриемник = Новый Массив;
ПодключенныеОбъекты.Вставить(СсылкаОМ, МассивПриемник);
КонецЕсли;
Если МассивПриемник.Найти(ПолноеИмя) = Неопределено Тогда
МассивПриемник.Добавить(ПолноеИмя);
КонецЕсли;
КонецЦикла;
КонецЦикла;
Если ФильтрПоТипуИдентификаторов = Тип("СправочникСсылка.ИдентификаторыОбъектовМетаданных") Тогда
СтароеЗначение = СтандартныеПодсистемыСервер.ПараметрРаботыПрограммы(ПолноеИмяПодсистемы());
ИначеЕсли ФильтрПоТипуИдентификаторов = Тип("СправочникСсылка.ИдентификаторыОбъектовРасширений") Тогда
СтароеЗначение = СтандартныеПодсистемыСервер.ПараметрРаботыРасширения(ПолноеИмяПодсистемы());
Иначе
Возврат Результат;
КонецЕсли;
НовоеЗначение = Новый Структура("ПодключенныеОбъекты", ПодключенныеОбъекты);
Если Не ОбщегоНазначения.ДанныеСовпадают(СтароеЗначение, НовоеЗначение) Тогда
Результат.ЕстьИзменения = Истина;
Если ФильтрПоТипуИдентификаторов = Тип("СправочникСсылка.ИдентификаторыОбъектовМетаданных") Тогда
СтандартныеПодсистемыСервер.УстановитьПараметрРаботыПрограммы(ПолноеИмяПодсистемы(), НовоеЗначение);
ИначеЕсли ФильтрПоТипуИдентификаторов = Тип("СправочникСсылка.ИдентификаторыОбъектовРасширений") Тогда
СтандартныеПодсистемыСервер.УстановитьПараметрРаботыРасширения(ПолноеИмяПодсистемы(), НовоеЗначение);
КонецЕсли;
КонецЕсли;
Результат.Вставить("ПодключенныеОбъекты", ПодключенныеОбъекты);
Возврат Результат;
КонецФункции
////////////////////////////////////////////////////////////////////////////////
// Вызовы из модулей ВызовСервера.
// Возвращает описание команды по имени элемента формы.
Функция ОписаниеКоманды(ИмяКомандыВФорме, АдресНастроек) Экспорт
Команды = ПолучитьИзВременногоХранилища(АдресНастроек);
Команда = Команды.Найти(ИмяКомандыВФорме, "ИмяВФорме");
Если Команда = Неопределено Тогда
ВызватьИсключение СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
НСтр("ru = 'Сведения о команде ""%1"" не существуют.'"),
ИмяКомандыВФорме);
КонецЕсли;
ОписаниеКоманды = ОбщегоНазначения.СтрокаТаблицыЗначенийВСтруктуру(Команда);
Если ЗначениеЗаполнено(ОписаниеКоманды.ИмяФормы) Тогда
ОписаниеКоманды.Вставить("Серверная", Ложь);
МассивПодстрок = СтроковыеФункцииКлиентСервер.РазложитьСтрокуВМассивПодстрок(ОписаниеКоманды.ИмяФормы, ".", Истина, Истина);
КоличествоПодстрок = МассивПодстрок.Количество();
Если КоличествоПодстрок = 1
Или (КоличествоПодстрок = 2 И ВРег(МассивПодстрок[0]) <> "ОБЩАЯФОРМА") Тогда
ОписаниеКоманды.ИмяФормы = ОписаниеКоманды.Менеджер + "." + ОписаниеКоманды.ИмяФормы;
КонецЕсли;
Иначе
ОписаниеКоманды.Вставить("Серверная", Истина);
Если ЗначениеЗаполнено(ОписаниеКоманды.Обработчик) Тогда
Если Не ПустаяСтрока(ОписаниеКоманды.Менеджер) И СтрНайти(ОписаниеКоманды.Обработчик, ".") = 0 Тогда
ОписаниеКоманды.Обработчик = ОписаниеКоманды.Менеджер + "." + ОписаниеКоманды.Обработчик;
КонецЕсли;
Если СтрНачинаетсяС(ВРег(ОписаниеКоманды.Обработчик), ВРег("ОбщийМодуль.")) Тогда
ПозицияТочки = СтрНайти(ОписаниеКоманды.Обработчик, ".");
ОписаниеКоманды.Обработчик = Сред(ОписаниеКоманды.Обработчик, ПозицияТочки + 1);
КонецЕсли;
МассивПодстрок = СтроковыеФункцииКлиентСервер.РазложитьСтрокуВМассивПодстрок(ОписаниеКоманды.Обработчик, ".", Истина, Истина);
КоличествоПодстрок = МассивПодстрок.Количество();
Если КоличествоПодстрок = 2 Тогда
ИмяМодуля = МассивПодстрок[0];
ОбъектМетаданныхОбщийМодуль = Метаданные.ОбщиеМодули.Найти(ИмяМодуля);
Если ОбъектМетаданныхОбщийМодуль = Неопределено Тогда
ВызватьИсключение СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
НСтр("ru = 'Общий модуль ""%1"" не существует.'"),
ИмяМодуля);
КонецЕсли;
Если ОбъектМетаданныхОбщийМодуль.КлиентУправляемоеПриложение Тогда
ОписаниеКоманды.Серверная = Ложь;
КонецЕсли;
Иначе
Вид = ВРег(МассивПодстрок[0]);
ВидВоМножественномЧисле = ВидОбъектаМетаданныхВоМножественномЧисле(Вид);
Если ВидВоМножественномЧисле <> Неопределено Тогда
МассивПодстрок.Установить(0, ВидВоМножественномЧисле);
ОписаниеКоманды.Обработчик = СтрСоединить(МассивПодстрок, ".");
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецЕсли;
ОписаниеКоманды.Удалить("Менеджер");
Возврат Новый ФиксированнаяСтруктура(ОписаниеКоманды);
КонецФункции
////////////////////////////////////////////////////////////////////////////////
// Работа с объектами метаданных.
// Возвращает вид объекта во множественном числе.
Функция ВидОбъектаМетаданныхВоМножественномЧисле(Знач Вид)
Вид = ВРег(СокрЛП(Вид));
Если Вид = "ПЛАНОБМЕНА" Тогда
Возврат "ПланыОбмена";
ИначеЕсли Вид = "СПРАВОЧНИК" Тогда
Возврат "Справочники";
ИначеЕсли Вид = "ДОКУМЕНТ" Тогда
Возврат "Документы";
ИначеЕсли Вид = "ЖУРНАЛДОКУМЕНТОВ" Тогда
Возврат "ЖурналыДокументов";
ИначеЕсли Вид = "ПЕРЕЧИСЛЕНИЕ" Тогда
Возврат "Перечисления";
ИначеЕсли Вид = "ОТЧЕТ" Тогда
Возврат "Отчеты";
ИначеЕсли Вид = "ОБРАБОТКА" Тогда
Возврат "Обработки";
ИначеЕсли Вид = "ПЛАНВИДОВХАРАКТЕРИСТИК" Тогда
Возврат "ПланыВидовХарактеристик";
ИначеЕсли Вид = "ПЛАНСЧЕТОВ" Тогда
Возврат "ПланыСчетов";
ИначеЕсли Вид = "ПЛАНВИДОВРАСЧЕТА" Тогда
Возврат "ПланыВидовРасчета";
ИначеЕсли Вид = "РЕГИСТРСВЕДЕНИЙ" Тогда
Возврат "РегистрыСведений";
ИначеЕсли Вид = "РЕГИСТРНАКОПЛЕНИЯ" Тогда
Возврат "РегистрыНакопления";
ИначеЕсли Вид = "РЕГИСТРБУХГАЛТЕРИИ" Тогда
Возврат "РегистрыБухгалтерии";
ИначеЕсли Вид = "РЕГИСТРРАСЧЕТА" Тогда
Возврат "РегистрыРасчета";
ИначеЕсли Вид = "ПЕРЕРАСЧЕТ" Тогда
Возврат "Перерасчеты";
ИначеЕсли Вид = "БИЗНЕСПРОЦЕСС" Тогда
Возврат "БизнесПроцессы";
ИначеЕсли Вид = "ЗАДАЧА" Тогда
Возврат "Задачи";
ИначеЕсли Вид = "КОНСТАНТА" Тогда
Возврат "Константы";
ИначеЕсли Вид = "ПОСЛЕДОВАТЕЛЬНОСТЬ" Тогда
Возврат "Последовательности";
Иначе
Возврат Неопределено;
КонецЕсли;
КонецФункции
////////////////////////////////////////////////////////////////////////////////
// Шаблоны.
// Шаблон таблицы подключаемых команд.
//
// Возвращаемое значение:
// см. ПодключаемыеКомандыПереопределяемый.ПриОпределенииКомандПодключенныхКОбъекту.Команды
//
Функция ТаблицаКоманд()
Таблица = Новый ТаблицаЗначений;
Таблица.Колонки.Добавить("Вид", Новый ОписаниеТипов("Строка"));
Таблица.Колонки.Добавить("Идентификатор", Новый ОписаниеТипов("Строка"));
// Настройки внешнего вида:
Таблица.Колонки.Добавить("Представление", Новый ОписаниеТипов("Строка"));
Таблица.Колонки.Добавить("Подменю", Новый ОписаниеТипов("Строка"));
Таблица.Колонки.Добавить("Важность", Новый ОписаниеТипов("Строка"));
Таблица.Колонки.Добавить("Порядок", Новый ОписаниеТипов("Число"));
Таблица.Колонки.Добавить("Картинка"); // Картинка.
Таблица.Колонки.Добавить("СочетаниеКлавиш"); // СочетаниеКлавиш.
Таблица.Колонки.Добавить("ОтображениеКнопки");
Таблица.Колонки.Добавить("ТолькоВоВсехДействиях", Новый ОписаниеТипов("Булево"));
Таблица.Колонки.Добавить("ЗначениеПометки", Новый ОписаниеТипов("Строка"));
// Настройки видимости и доступность:
Таблица.Колонки.Добавить("ТипПараметра"); // ОписаниеТипов.
Таблица.Колонки.Добавить("ВидимостьВФормах", Новый ОписаниеТипов("Строка"));
Таблица.Колонки.Добавить("Назначение", Новый ОписаниеТипов("Строка"));
Таблица.Колонки.Добавить("ФункциональныеОпции", Новый ОписаниеТипов("Строка"));
Таблица.Колонки.Добавить("УсловияВидимости", Новый ОписаниеТипов("Массив"));
Таблица.Колонки.Добавить("ИзменяетВыбранныеОбъекты"); // Булево или Неопределено.
// Настройки процесса выполнения:
Таблица.Колонки.Добавить("МножественныйВыбор"); // Булево или Неопределено.
Таблица.Колонки.Добавить("РежимЗаписи", Новый ОписаниеТипов("Строка"));
Таблица.Колонки.Добавить("ТребуетсяРаботаСФайлами", Новый ОписаниеТипов("Булево"));
// Настройки обработчика:
Таблица.Колонки.Добавить("Менеджер", Новый ОписаниеТипов("Строка"));
Таблица.Колонки.Добавить("Обработчик", Новый ОписаниеТипов("Строка"));
Таблица.Колонки.Добавить("ДополнительныеПараметры", Новый ОписаниеТипов("Структура"));
Таблица.Колонки.Добавить("ИмяФормы", Новый ОписаниеТипов("Строка"));
Таблица.Колонки.Добавить("ПараметрыФормы"); // Структура или Неопределено.
Таблица.Колонки.Добавить("ИмяПараметраФормы", Новый ОписаниеТипов("Строка"));
// Служебные:
Таблица.Колонки.Добавить("ПорядокВажности", Новый ОписаниеТипов("Число"));
Таблица.Колонки.Добавить("ИмяВФорме", Новый ОписаниеТипов("Строка"));
Таблица.Колонки.Добавить("ЕстьУсловияВидимости", Новый ОписаниеТипов("Булево"));
Таблица.Колонки.Добавить("КлючПараметровРазмещения", Новый ОписаниеТипов("Строка"));
Возврат Таблица;
КонецФункции
////////////////////////////////////////////////////////////////////////////////
// Прочее.
// Возвращает полное имя подсистемы.
Функция ПолноеИмяПодсистемы() Экспорт
Возврат "СтандартныеПодсистемы.ПодключаемыеКоманды";
КонецФункции
Функция ОбъединитьТипы(Тип1, Тип2)
Тип1ЭтоОписаниеТипов = ТипЗнч(Тип1) = Тип("ОписаниеТипов");
Тип2ЭтоОписаниеТипов = ТипЗнч(Тип2) = Тип("ОписаниеТипов");
Если Тип1ЭтоОписаниеТипов И Тип1.Типы().Количество() > 0 Тогда
ИсходноеОписаниеТипов = Тип1;
ДобавляемыеТипы = ?(Тип2ЭтоОписаниеТипов, Тип2.Типы(), ЗначениеВМассив(Тип2));
ИначеЕсли Тип2ЭтоОписаниеТипов И Тип2.Типы().Количество() > 0 Тогда
ИсходноеОписаниеТипов = Тип2;
ДобавляемыеТипы = ЗначениеВМассив(Тип1);
ИначеЕсли ТипЗнч(Тип1) <> Тип("Тип") Тогда
Возврат Тип2;
ИначеЕсли ТипЗнч(Тип2) <> Тип("Тип") Тогда
Возврат Тип1;
Иначе
Типы = Новый Массив;
Типы.Добавить(Тип1);
Типы.Добавить(Тип2);
Возврат Новый ОписаниеТипов(Типы);
КонецЕсли;
Если ДобавляемыеТипы.Количество() = 0 Тогда
Возврат ИсходноеОписаниеТипов;
Иначе
Возврат Новый ОписаниеТипов(ИсходноеОписаниеТипов, ДобавляемыеТипы);
КонецЕсли;
КонецФункции
Функция ЗначениеВМассив(Значение)
Результат = Новый Массив;
Результат.Добавить(Значение);
Возврат Результат;
КонецФункции
Функция ТребуетсяУказаниеИсточниковКоманд(ПолноеИмяОбъектаМетаданных)
ВидОбъектаМетаданных = НРег(СтрРазделить(ПолноеИмяОбъектаМетаданных, ".")[0]);
Возврат ВидОбъектаМетаданных = НРег("ВнешняяОбработка")
Или ВидОбъектаМетаданных = НРег("ВнешнийОтчет")
Или ВидОбъектаМетаданных = НРег("Обработка")
Или ВидОбъектаМетаданных = НРег("Отчет")
Или ВидОбъектаМетаданных = НРег("ОбщаяФорма");
КонецФункции
Функция ВыражениеВычислениеПометки(Знач ВыражениеПометки)
Результат = "";
ВыражениеПометки = ВРег(ВыражениеПометки);
ПутьДоРеквизита = СтрЗаменить(ВыражениеПометки, "НЕ ", "");
Если СтрНачинаетсяС(ВыражениеПометки, "НЕ ") Тогда
Результат = "НЕ "
КонецЕсли;
ЧастиПутиЗначениеПометки = СтрРазделить(ПутьДоРеквизита, ".");
Для Сч = 0 По ЧастиПутиЗначениеПометки.Количество() - 1 Цикл
ЧастиПутиЗначениеПометки[Сч] = "["""+ЧастиПутиЗначениеПометки[Сч]+"""]";
КонецЦикла;
Результат = Результат + "Форма"+СтрСоединить(ЧастиПутиЗначениеПометки, "");
Возврат Результат;
КонецФункции // ()
#КонецОбласти