#Область ОбработчикиСобытийФормы
&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
Формула = Параметры.Формула;
ИсходнаяФормула = Параметры.Формула;
ИспользуетсяДеревоОперандов = Параметры.ИспользуетсяДеревоОперандов;
Элементы.ГруппаОперандыСтраницы.ТекущаяСтраница = Элементы.СтраницаЧисловыхОперандов;
Операнды.Загрузить(ПолучитьИзВременногоХранилища(Параметры.Операнды));
Для Каждого ТекСтрока Из Операнды Цикл
Если ТекСтрока.ПометкаУдаления Тогда
ТекСтрока.ИндексКартинки = 3;
Иначе
ТекСтрока.ИндексКартинки = 2;
КонецЕсли;
КонецЦикла;
ДеревоОператоров = ПолучитьСтандартноеДеревоОператоров();
ЗначениеВРеквизитФормы(ДеревоОператоров, "Операторы");
Если ЗначениеЗаполнено(Параметры.ОперандыЗаголовок) Тогда
Элементы.ГруппаОперанды.Заголовок = Параметры.ОперандыЗаголовок;
Элементы.ГруппаОперанды.Подсказка = Параметры.ОперандыЗаголовок;
КонецЕсли;
КонецПроцедуры
&НаКлиенте
Процедура ПередЗакрытием(Отказ, ЗавершениеРаботы, ТекстПредупреждения, СтандартнаяОбработка)
СтандартнаяОбработка = Ложь;
Если Не Модифицированность Или Не ЗначениеЗаполнено(ИсходнаяФормула) Или ИсходнаяФормула = Формула Тогда
Возврат;
КонецЕсли;
Отказ = Истина;
Если ЗавершениеРаботы Тогда
Возврат;
КонецЕсли;
ПоказатьВопрос(Новый ОписаниеОповещения("ПередЗакрытиемЗавершение", ЭтотОбъект), НСтр("ru = 'Данные были изменены. Сохранить изменения?'"), РежимДиалогаВопрос.ДаНетОтмена);
КонецПроцедуры
&НаКлиенте
Процедура ПередЗакрытиемЗавершение(РезультатВопроса, ДополнительныеПараметры) Экспорт
Ответ = РезультатВопроса;
Если Ответ = КодВозвратаДиалога.Да Тогда
Если ПроверитьФормулу(Формула, Операнды()) Тогда
Модифицированность = Ложь;
Закрыть(Формула);
КонецЕсли;
ИначеЕсли Ответ = КодВозвратаДиалога.Нет Тогда
Модифицированность = Ложь;
Закрыть(Неопределено);
КонецЕсли;
КонецПроцедуры
#КонецОбласти
#Область ОбработчикиСобытийЭлементовШапкиФормы
&НаКлиенте
Процедура КомпоновщикНастроекНастройкиВыборДоступныеПоляВыбораВыбор(Элемент, ВыбраннаяСтрока, Поле, СтандартнаяОбработка)
ТекстСтроки = Строка(КомпоновщикНастроек.Настройки.ДоступныеПоляПорядка.ПолучитьОбъектПоИдентификатору(ВыбраннаяСтрока).Поле);
Операнд = ОбработатьТекстОперанда(ТекстСтроки);
ВставитьТекстВФормулу(Операнд);
КонецПроцедуры
&НаКлиенте
Процедура КомпоновщикНастроекНачалоПеретаскивания(Элемент, ПараметрыПеретаскивания, Выполнение)
ТекстЭлемента = Строка(КомпоновщикНастроек.Настройки.ДоступныеПоляПорядка.ПолучитьОбъектПоИдентификатору(Элементы.КомпоновщикНастроек.ТекущаяСтрока).Поле);
ПараметрыПеретаскивания.Значение = ОбработатьТекстОперанда(ТекстЭлемента);
КонецПроцедуры
#КонецОбласти
#Область ОбработчикиСобытийЭлементовТаблицыФормыОперанды
&НаКлиенте
Процедура ОперандыВыбор(Элемент, ВыбраннаяСтрока, Поле, СтандартнаяОбработка)
Если Поле.Имя = "ОперандыЗначение" Тогда
Возврат;
КонецЕсли;
Если Элемент.ТекущиеДанные.ПометкаУдаления Тогда
СтандартнаяОбработка = Ложь;
ПоказатьВопрос(
Новый ОписаниеОповещения("ОперандыВыборЗавершение", ЭтотОбъект),
НСтр("ru = 'Выбранный элемент помечен на удаление.
|Продолжить?'"),
РежимДиалогаВопрос.ДаНет);
Возврат;
КонецЕсли;
СтандартнаяОбработка = Ложь;
ВставитьОперандВФормулу();
КонецПроцедуры
&НаКлиенте
Процедура ОперандыВыборЗавершение(РезультатВопроса, ДополнительныеПараметры) Экспорт
Если РезультатВопроса = КодВозвратаДиалога.Да Тогда
ВставитьОперандВФормулу();
КонецЕсли;
КонецПроцедуры
&НаКлиенте
Процедура ОперандыНачалоПеретаскивания(Элемент, ПараметрыПеретаскивания, СтандартнаяОбработка)
ПараметрыПеретаскивания.Значение = ПолучитьТекстОперандаДляВставки(Элемент.ТекущиеДанные.Идентификатор);
КонецПроцедуры
&НаКлиенте
Процедура ОперандыОкончаниеПеретаскивания(Элемент, ПараметрыПеретаскивания, СтандартнаяОбработка)
Если Элемент.ТекущиеДанные.ПометкаУдаления Тогда
ПоказатьВопрос(Новый ОписаниеОповещения("ОперандыОкончаниеПеретаскиванияЗавершение", ЭтотОбъект),
НСтр("ru = 'Выбранный элемент помечен на удаление.
|Продолжить?'"), РежимДиалогаВопрос.ДаНет);
КонецЕсли;
КонецПроцедуры
&НаКлиенте
Процедура ОперандыОкончаниеПеретаскиванияЗавершение(РезультатВопроса, ДополнительныеПараметры) Экспорт
Ответ = РезультатВопроса;
Если Ответ = КодВозвратаДиалога.Нет Тогда
НачалоСтроки = 0;
НачалоКолонки = 0;
КонецСтроки = 0;
КонецКолонки = 0;
Элементы.Формула.ПолучитьГраницыВыделения(НачалоСтроки, НачалоКолонки, КонецСтроки, КонецКолонки);
Элементы.Формула.ВыделенныйТекст = "";
Элементы.Формула.УстановитьГраницыВыделения(НачалоСтроки, НачалоКолонки, НачалоСтроки, НачалоКолонки);
КонецЕсли;
КонецПроцедуры
&НаКлиенте
Процедура ДеревоОперандовВыбор(Элемент, ВыбраннаяСтрока, Поле, СтандартнаяОбработка)
ТекущиеДанные = Элементы.ДеревоОперандов.ТекущиеДанные;
Если ТекущиеДанные = Неопределено Тогда
Возврат;
КонецЕсли;
СтрокаРодитель = ТекущиеДанные.ПолучитьРодителя();
Если СтрокаРодитель = Неопределено Тогда
Возврат;
КонецЕсли;
ВставитьТекстВФормулу(ПолучитьТекстОперандаДляВставки(
СтрокаРодитель.Идентификатор + "." + ТекущиеДанные.Идентификатор));
КонецПроцедуры
#КонецОбласти
#Область ОбработчикиСобытийЭлементовТаблицыФормыДеревоОперандов
&НаКлиенте
Процедура ДеревоОперандовНачалоПеретаскивания(Элемент, ПараметрыПеретаскивания, Выполнение)
Если ПараметрыПеретаскивания.Значение = Неопределено Тогда
Возврат;
КонецЕсли;
СтрокаДерева = ДеревоОперандов.НайтиПоИдентификатору(ПараметрыПеретаскивания.Значение);
СтрокаРодитель = СтрокаДерева.ПолучитьРодителя();
Если СтрокаРодитель = Неопределено Тогда
Выполнение = Ложь;
Возврат;
Иначе
ПараметрыПеретаскивания.Значение =
ПолучитьТекстОперандаДляВставки(СтрокаРодитель.Идентификатор +"." + СтрокаДерева.Идентификатор);
КонецЕсли;
КонецПроцедуры
#КонецОбласти
#Область ОбработчикиСобытийЭлементовТаблицыФормыОператоры
&НаКлиенте
Процедура ОператорыВыбор(Элемент, ВыбраннаяСтрока, Поле, СтандартнаяОбработка)
СтандартнаяОбработка = Ложь;
ВставитьОператорВФормулу();
КонецПроцедуры
&НаКлиенте
Процедура ОператорыНачалоПеретаскивания(Элемент, ПараметрыПеретаскивания, СтандартнаяОбработка)
Если ЗначениеЗаполнено(Элемент.ТекущиеДанные.Оператор) Тогда
ПараметрыПеретаскивания.Значение = Элемент.ТекущиеДанные.Оператор;
Иначе
СтандартнаяОбработка = Ложь;
КонецЕсли;
КонецПроцедуры
&НаКлиенте
Процедура ОператорыОкончаниеПеретаскивания(Элемент, ПараметрыПеретаскивания, СтандартнаяОбработка)
Если Элемент.ТекущиеДанные.Оператор = "Формат(,)" Тогда
ФорматСтроки = Новый КонструкторФорматнойСтроки;
ФорматСтроки.Показать(Новый ОписаниеОповещения("ОператорыОкончаниеПеретаскиванияЗавершение", ЭтотОбъект, Новый Структура("ФорматСтроки", ФорматСтроки)));
КонецЕсли;
КонецПроцедуры
&НаКлиенте
Процедура ОператорыОкончаниеПеретаскиванияЗавершение(Текст, ДополнительныеПараметры) Экспорт
ФорматСтроки = ДополнительныеПараметры.ФорматСтроки;
Если ЗначениеЗаполнено(ФорматСтроки.Текст) Тогда
ТекстДляВставки = "Формат( , """ + ФорматСтроки.Текст + """)";
Элементы.Формула.ВыделенныйТекст = ТекстДляВставки;
КонецЕсли;
КонецПроцедуры
#КонецОбласти
#Область ОбработчикиКомандФормы
&НаКлиенте
Процедура ОК(Команда)
ОчиститьСообщения();
Если ПроверитьФормулу(Формула, Операнды()) Тогда
Закрыть(Формула);
КонецЕсли;
КонецПроцедуры
&НаКлиенте
Процедура Проверить(Команда)
ОчиститьСообщения();
ПроверитьФормулуИнтерактивно(Формула, Операнды());
КонецПроцедуры
#КонецОбласти
#Область СлужебныеПроцедурыИФункции
&НаКлиенте
Процедура ВставитьТекстВФормулу(ТекстДляВставки, Сдвиг = 0)
СтрокаНач = 0;
СтрокаКон = 0;
КолонкаНач = 0;
КолонкаКон = 0;
Элементы.Формула.ПолучитьГраницыВыделения(СтрокаНач, КолонкаНач, СтрокаКон, КолонкаКон);
Если (КолонкаКон = КолонкаНач) И (КолонкаКон + СтрДлина(ТекстДляВставки)) > Элементы.Формула.Ширина / 8 Тогда
Элементы.Формула.ВыделенныйТекст = "";
КонецЕсли;
Элементы.Формула.ВыделенныйТекст = ТекстДляВставки;
Если Не Сдвиг = 0 Тогда
Элементы.Формула.ПолучитьГраницыВыделения(СтрокаНач, КолонкаНач, СтрокаКон, КолонкаКон);
Элементы.Формула.УстановитьГраницыВыделения(СтрокаНач, КолонкаНач - Сдвиг, СтрокаКон, КолонкаКон - Сдвиг);
КонецЕсли;
ТекущийЭлемент = Элементы.Формула;
КонецПроцедуры
&НаКлиенте
Процедура ВставитьОперандВФормулу()
ВставитьТекстВФормулу(ПолучитьТекстОперандаДляВставки(Элементы.Операнды.ТекущиеДанные.Идентификатор));
КонецПроцедуры
&НаКлиенте
Функция Операнды()
Результат = Новый Массив();
Для Каждого Операнд Из Операнды Цикл
Результат.Добавить(Операнд.Идентификатор);
КонецЦикла;
Возврат Результат;
КонецФункции
&НаКлиенте
Процедура ВставитьОператорВФормулу()
Если Элементы.Операторы.ТекущиеДанные.Наименование = "Формат" Тогда
ФорматСтроки = Новый КонструкторФорматнойСтроки;
ФорматСтроки.Показать(Новый ОписаниеОповещения("ВставитьОператорВФормулуЗавершение", ЭтотОбъект, Новый Структура("ФорматСтроки", ФорматСтроки)));
Возврат;
Иначе
ВставитьТекстВФормулу(Элементы.Операторы.ТекущиеДанные.Оператор, Элементы.Операторы.ТекущиеДанные.Сдвиг);
КонецЕсли;
КонецПроцедуры
&НаКлиенте
Процедура ВставитьОператорВФормулуЗавершение(Текст, ДополнительныеПараметры) Экспорт
ФорматСтроки = ДополнительныеПараметры.ФорматСтроки;
Если ЗначениеЗаполнено(ФорматСтроки.Текст) Тогда
ТекстДляВставки = "Формат( , """ + ФорматСтроки.Текст + """)";
ВставитьТекстВФормулу(ТекстДляВставки, Элементы.Операторы.ТекущиеДанные.Сдвиг);
Иначе
ВставитьТекстВФормулу(Элементы.Операторы.ТекущиеДанные.Оператор, Элементы.Операторы.ТекущиеДанные.Сдвиг);
КонецЕсли;
КонецПроцедуры
&НаКлиенте
Функция ОбработатьТекстОперанда(ТекстОперанда)
ТекстСтроки = ТекстОперанда;
ТекстСтроки = СтрЗаменить(ТекстСтроки, "[", "");
ТекстСтроки = СтрЗаменить(ТекстСтроки, "]", "");
Операнд = "[" + СтрЗаменить(ТекстСтроки,
?(НаборСвойств.НаборСвойствНоменклатуры, "Номенклатура.",
?(НЕ НаборСвойств.Свойство("НаборСвойствХарактеристик") ИЛИ НаборСвойств.НаборСвойствХарактеристик, "ХарактеристикаНоменклатуры.", "СерияНоменклатуры.")), "") + "]";
Возврат Операнд
КонецФункции
&НаСервере
Функция ПолучитьПустоеДеревоОператоров()
Дерево = Новый ДеревоЗначений();
Дерево.Колонки.Добавить("Наименование");
Дерево.Колонки.Добавить("Оператор");
Дерево.Колонки.Добавить("Сдвиг", Новый ОписаниеТипов("Число"));
Возврат Дерево;
КонецФункции
&НаСервере
Функция ДобавитьГруппуОператоров(Дерево, Наименование)
НоваяГруппа = Дерево.Строки.Добавить();
НоваяГруппа.Наименование = Наименование;
Возврат НоваяГруппа;
КонецФункции
&НаСервере
Функция ДобавитьОператор(Дерево, Родитель, Наименование, Оператор = Неопределено, Сдвиг = 0)
НоваяСтрока = ?(Родитель <> Неопределено, Родитель.Строки.Добавить(), Дерево.Строки.Добавить());
НоваяСтрока.Наименование = Наименование;
НоваяСтрока.Оператор = ?(ЗначениеЗаполнено(Оператор), Оператор, Наименование);
НоваяСтрока.Сдвиг = Сдвиг;
Возврат НоваяСтрока;
КонецФункции
&НаСервере
Функция ПолучитьСтандартноеДеревоОператоров()
Дерево = ПолучитьПустоеДеревоОператоров();
ГруппаОператоров = ДобавитьГруппуОператоров(Дерево, НСтр("ru = 'Разделители'"));
ДобавитьОператор(Дерево, ГруппаОператоров, "/", " + ""/"" + ");
ДобавитьОператор(Дерево, ГруппаОператоров, "\", " + ""\"" + ");
ДобавитьОператор(Дерево, ГруппаОператоров, "|", " + ""|"" + ");
ДобавитьОператор(Дерево, ГруппаОператоров, "_", " + ""_"" + ");
ДобавитьОператор(Дерево, ГруппаОператоров, ",", " + "", "" + ");
ДобавитьОператор(Дерево, ГруппаОператоров, ".", " + "". "" + ");
ДобавитьОператор(Дерево, ГруппаОператоров, НСтр("ru = 'Пробел'"), " + "" "" + ");
ДобавитьОператор(Дерево, ГруппаОператоров, "(", " + "" ("" + ");
ДобавитьОператор(Дерево, ГруппаОператоров, ")", " + "") "" + ");
ДобавитьОператор(Дерево, ГруппаОператоров, """", " + """""""" + ");
ГруппаОператоров = ДобавитьГруппуОператоров(Дерево, НСтр("ru = 'Операторы'"));
ДобавитьОператор(Дерево, ГруппаОператоров, "+", " + ");
ДобавитьОператор(Дерево, ГруппаОператоров, "-", " - ");
ДобавитьОператор(Дерево, ГруппаОператоров, "*", " * ");
ДобавитьОператор(Дерево, ГруппаОператоров, "/", " / ");
ГруппаОператоров = ДобавитьГруппуОператоров(Дерево, НСтр("ru = 'Логические операторы и константы'"));
ДобавитьОператор(Дерево, ГруппаОператоров, "<", " < ");
ДобавитьОператор(Дерево, ГруппаОператоров, ">", " > ");
ДобавитьОператор(Дерево, ГруппаОператоров, "<=", " <= ");
ДобавитьОператор(Дерево, ГруппаОператоров, ">=", " >= ");
ДобавитьОператор(Дерево, ГруппаОператоров, "=", " = ");
ДобавитьОператор(Дерево, ГруппаОператоров, "<>", " <> ");
ДобавитьОператор(Дерево, ГруппаОператоров, "И", " " + "И" + " ");
ДобавитьОператор(Дерево, ГруппаОператоров, "Или", " " + "Или" + " ");
ДобавитьОператор(Дерево, ГруппаОператоров, "Не", " " + "Не" + " ");
ДобавитьОператор(Дерево, ГруппаОператоров, "ИСТИНА", " " + "ИСТИНА" + " ");
ДобавитьОператор(Дерево, ГруппаОператоров, "ЛОЖЬ", " " + "ЛОЖЬ" + " ");
ГруппаОператоров = ДобавитьГруппуОператоров(Дерево, НСтр("ru = 'Числовые функции'"));
ДобавитьОператор(Дерево, ГруппаОператоров, "Макс", "Макс(,)", 2);
ДобавитьОператор(Дерево, ГруппаОператоров, "Мин", "Мин(,)", 2);
ДобавитьОператор(Дерево, ГруппаОператоров, "Окр", "Окр(,)", 2);
ДобавитьОператор(Дерево, ГруппаОператоров, "Цел", "Цел()", 1);
ГруппаОператоров = ДобавитьГруппуОператоров(Дерево, НСтр("ru = 'Строковые функции'"));
ДобавитьОператор(Дерево, ГруппаОператоров, "Строка", "Строка()");
ДобавитьОператор(Дерево, ГруппаОператоров, "ВРег", "ВРег()");
ДобавитьОператор(Дерево, ГруппаОператоров, "Лев", "Лев()");
ДобавитьОператор(Дерево, ГруппаОператоров, "НРег", "НРег()");
ДобавитьОператор(Дерево, ГруппаОператоров, "Прав", "Прав()");
ДобавитьОператор(Дерево, ГруппаОператоров, "СокрЛ", "СокрЛ()");
ДобавитьОператор(Дерево, ГруппаОператоров, "СокрЛП", "СокрЛП()");
ДобавитьОператор(Дерево, ГруппаОператоров, "СокрП", "СокрП()");
ДобавитьОператор(Дерево, ГруппаОператоров, "ТРег", "ТРег()");
ДобавитьОператор(Дерево, ГруппаОператоров, "СтрЗаменить", "СтрЗаменить(,,)");
ДобавитьОператор(Дерево, ГруппаОператоров, "СтрДлина", "СтрДлина()");
ГруппаОператоров = ДобавитьГруппуОператоров(Дерево, НСтр("ru = 'Прочие функции'"));
ДобавитьОператор(Дерево, ГруппаОператоров, НСтр("ru = 'Условие'"), "?(,,)", 3);
ДобавитьОператор(Дерево, ГруппаОператоров, "ПредопределенноеЗначение", "ПредопределенноеЗначение()");
ДобавитьОператор(Дерево, ГруппаОператоров, "ЗначениеЗаполнено", "ЗначениеЗаполнено()");
ДобавитьОператор(Дерево, ГруппаОператоров, "Формат", "Формат(,)");
Возврат Дерево;
КонецФункции
&НаКлиентеНаСервереБезКонтекста
Функция ПолучитьТекстОперандаДляВставки(Операнд)
Возврат "[" + Операнд + "]";
КонецФункции
&НаКлиенте
Функция ПроверитьФормулу(Формула, Операнды)
Если Не ЗначениеЗаполнено(Формула) Тогда
Возврат Истина;
КонецЕсли;
ЗначениеЗамены = """1""";
ТекстРасчета = Формула;
Для Каждого Операнд Из Операнды Цикл
ТекстРасчета = СтрЗаменить(ТекстРасчета, ПолучитьТекстОперандаДляВставки(Операнд), ЗначениеЗамены);
КонецЦикла;
Если СтрНачинаетсяС(СокрЛ(ТекстРасчета), "=") Тогда
ТекстРасчета = Сред(СокрЛ(ТекстРасчета), 2);
КонецЕсли;
Попытка
РезультатРасчета = Вычислить(ТекстРасчета);
Исключение
ТекстОшибки = НСтр("ru = 'В формуле обнаружены ошибки. Проверьте формулу.
|Формулы должны составляться по правилам написания выражений на встроенном языке 1С:Предприятия.'");
ОбщегоНазначенияКлиент.СообщитьПользователю(ТекстОшибки, , "Формула");
Возврат Ложь;
КонецПопытки;
Возврат Истина;
КонецФункции
&НаКлиенте
Процедура ПроверитьФормулуИнтерактивно(Формула, Операнды)
Если ЗначениеЗаполнено(Формула) Тогда
Если ПроверитьФормулу(Формула, Операнды) Тогда
ПоказатьОповещениеПользователя(
НСтр("ru = 'В формуле ошибок не обнаружено'"),
,
,
БиблиотекаКартинок.Информация32);
КонецЕсли;
КонецЕсли;
КонецПроцедуры
#КонецОбласти