gifts2017

Программисту на заметку: автозаполнение реквизитов документов и справочников

Опубликовал Дмитрий Романовский (vdscom) в раздел Обработки - Обработка документов

Часто бывает необходимым, чтобы при создании документа, элемента справочника автоматически заполнялись заданным значением определенные его реквизиты. Ниже предлагается вариант реализации механизма автозаполнения реквизитов документов по заданным условиям.

Часто бывает необходимым, чтобы при создании документа, элемента справочника автоматически заполнялись заданным значением определенные его реквизиты. Можно, конечно, прописать заполнение реквизитов в коде программы, но заменяемое значение со временем может понадобиться изменить либо вообще задать его в зависимости от каких то условий, и при этом постоянно дорабатывать программу считаю не очень правильным.

Ниже предлагается вариант реализации механизма автозаполнения реквизитов документов по заданным условиям.

 

1. Создаем подписку на событие "ПередЗаписьюДокумента_АвтозаполнениеРеквизитов". Источник - "ДокументОбъект", событие - "Перед записью", обработчик "ОбщегоНазначения.ПередЗаписьюДокумента_АвтозаполнениеРеквизитов"

2. Текст процедуры общего модуля "ПередЗаписьюДокумента_АвтозаполнениеРеквизитов" и вспомогательных процедур:

 

Процедура ПередЗаписьюДокумента_АвтозаполнениеРеквизитов(Источник, Отказ, РежимЗаписи, РежимПроведения) Экспорт

ИмяДокумента = Источник.Метаданные().Имя;
ТипДокумента = Источник.Метаданные().Синоним;
Если Источник.Метаданные().Реквизиты.Найти("ВидОперации") <> Неопределено Тогда
ВидОперации = Строка(Источник.ВидОперации);
Иначе
ВидОперации = "";
КонецЕсли;

// предварительная проверка наличия настроек автозамены для данного типа документа и вида операции
Запрос = Новый Запрос;
Запрос.УстановитьПараметр("ТипДокумента",ТипДокумента);
Запрос.УстановитьПараметр("ВидОперации",ВидОперации);

Запрос.Текст = "ВЫБРАТЬ
| ПараметрыАвтозаполненияДокументов.Ссылка
|ИЗ
| Справочник.ПараметрыАвтозаполненияДокументов КАК ПараметрыАвтозаполненияДокументов
|ГДЕ
| ПараметрыАвтозаполненияДокументов.ТипДокумента = &ТипДокумента
| И ПараметрыАвтозаполненияДокументов.ВидОперации = &ВидОперации
| И НЕ ПараметрыАвтозаполненияДокументов.Отключено
| И НЕ ПараметрыАвтозаполненияДокументов.ПометкаУдаления";
Выборка = Запрос.Выполнить().Выбрать();

Если Выборка.Количество() = 0 Тогда
Возврат;
КонецЕсли;

// окончательная проверка наличия настроек автозамены для данного типа документа и вида операции
ПараметрыАвтозаполнения = Неопределено;

Пока Выборка.Следующий() Цикл
УсловияВыполнены = Истина;
УсловияАвтозаполнения = Выборка.Ссылка.Условия;

Для каждого стр из УсловияАвтозаполнения Цикл
Если Источник[ПолучитьИмяРеквизитаПоСинониму(,стр.Реквизит,ИмяДокумента)] <> стр.Значение Тогда
УсловияВыполнены = Ложь;
Прервать;
КонецЕсли;
КонецЦикла;

Если УсловияВыполнены Тогда
ПараметрыАвтозаполнения = Выборка.Ссылка.Настройки;
Прервать;
КонецЕсли;
КонецЦикла;

Если Не ЗначениеЗаполнено(ПараметрыАвтозаполнения) Тогда
Возврат;
КонецЕсли;

ПредставлениеДокумента = ТипДокумента+" № "+Источник.Номер+" от "+Формат(Источник.Дата,"ДФ=dd.MM.yyyy");

Для каждого стр из ПараметрыАвтозаполнения Цикл
Если Не ЗначениеЗаполнено(стр.ТабличнаяЧасть) Тогда
// заполняем значения реквизита в шапке документа
ИмяРеквизита = ПолучитьИмяРеквизитаПоСинониму(,стр.Реквизит,ИмяДокумента);
Если стр.Принудительно или Не ЗначениеЗаполнено(Источник[ИмяРеквизита]) Тогда
Сообщить(" "+ПредставлениеДокумента+": выполнено "+?(ЗначениеЗаполнено(Источник[ИмяРеквизита]),"изменение","автозаполнение")+" реквизита """+стр.Реквизит+"""");
Источник[ИмяРеквизита] = стр.Значение;
КонецЕсли;
Иначе
// заполняем значения реквизита в табличной части
ИмяТабличнойЧасти = ПолучитьИмяОбъектаПоСинониму("ТабличнаяЧасть",стр.ТабличнаяЧасть,ИмяДокумента);
ИмяРеквизита = ПолучитьИмяРеквизитаПоСинониму(ИмяТабличнойЧасти,стр.Реквизит,ИмяДокумента);
Для каждого стрТЧ из Источник[ИмяТабличнойЧасти] Цикл
Если стр.Принудительно или Не ЗначениеЗаполнено(стрТЧ[ИмяРеквизита]) Тогда
Сообщить(" "+ПредставлениеДокумента+": выполнено "+?(ЗначениеЗаполнено(стрТЧ[ИмяРеквизита]),"изменение","автозаполнение")+" реквизита """+стр.Реквизит+""" табличной части """+стр.ТабличнаяЧасть+"""");
стрТЧ[ИмяРеквизита] = стр.Значение;
КонецЕсли;
КонецЦикла;
КонецЕсли;
КонецЦикла;

КонецПроцедуры

 

Функция ПолучитьИмяРеквизитаПоСинониму(ИмяТабличнойЧасти="",СинонимОбъекта,ИмяДокумента) Экспорт

Если Не ЗначениеЗаполнено(ИмяТабличнойЧасти) Тогда
// по синониму реквизита шапки документа находим его имя
Для каждого Реквизит из Метаданные.Документы[ИмяДокумента].Реквизиты Цикл
Если Реквизит.Синоним = СинонимОбъекта Тогда
Возврат Реквизит.Имя;
КонецЕсли;
КонецЦикла;
Иначе
// по синониму реквизита табличной части документа находим его имя
Для каждого Реквизит из Метаданные.Документы[ИмяДокумента].ТабличныеЧасти[ИмяТабличнойЧасти].Реквизиты Цикл
Если Реквизит.Синоним = СинонимОбъекта Тогда
Возврат Реквизит.Имя;
КонецЕсли;
КонецЦикла;
КонецЕсли;

КонецФункции

 

3. Создаем справочник "Параметры автозаполнения документов"


Типы значений реквизитов:

ТипДокумента - Строка(100)

ВидОперации - Строка(100)

Отключено - Булево

Реквизит - Строка(100)

Значение - ЛюбаяСсылка, Булево, Строка, Дата, Число

ТабличнаяЧасть - Строка(100)

Реквизит - Строка(100)

Значение - ЛюбаяСсылка, Булево, Строка, Дата, Число

Принудительно - Булево


Форма списка справочника:

 

Форма элемента справочника:

 

Модуль формы элемента справочника:

 

Перем ИмяДокумента;

Процедура ПриОткрытии()

ИмяДокумента = _ОбщегоНазначения.ПолучитьИмяОбъектаПоСинониму("Документ",ТипДокумента);
ЗаполнитьСписокТиповДокументов();

КонецПроцедуры

Процедура ТипДокументаПриИзменении(Элемент)

ВидОперации = "";
Условия.Очистить();
Настройки.Очистить();
ИмяДокумента = _ОбщегоНазначения.ПолучитьИмяОбъектаПоСинониму("Документ",ТипДокумента);

ЗаполнитьСписокВидовОперацийДокумента();

КонецПроцедуры

Процедура ВидОперацииНачалоВыбораИзСписка(Элемент, СтандартнаяОбработка)

Если ЭлементыФормы.ВидОперации.СписокВыбора.Количество() = 0 Тогда
ЗаполнитьСписокВидовОперацийДокумента();
КонецЕсли;

КонецПроцедуры


Процедура УсловияПередНачаломДобавления(Элемент, Отказ, Копирование)

Если Не ЗначениеЗаполнено(ИмяДокумента) Тогда
Отказ = Истина;
КонецЕсли;

КонецПроцедуры

Процедура НастройкиПередНачаломДобавления(Элемент, Отказ, Копирование)

Если Не ЗначениеЗаполнено(ИмяДокумента) Тогда
Отказ = Истина;
КонецЕсли;

КонецПроцедуры


Процедура НастройкиТабличнаяЧастьНачалоВыбораИзСписка(Элемент, СтандартнаяОбработка)

ЗаполнитьСписокТабличныхЧастейДокумента();

КонецПроцедуры

 

Процедура НастройкиТабличнаяЧастьПриИзменении(Элемент)

стр = ЭлементыФормы.Настройки.ТекущаяСтрока;
стр.Реквизит = "";
стр.Значение = "";

КонецПроцедуры


Процедура УсловияРеквизитНачалоВыбораИзСписка(Элемент, СтандартнаяОбработка)

ЗаполнитьСписокРеквизитовДокумента_Условия();

КонецПроцедуры

 

Процедура НастройкиРеквизитНачалоВыбораИзСписка(Элемент, СтандартнаяОбработка)

стр = ЭлементыФормы.Настройки.ТекущаяСтрока;
ЗаполнитьСписокРеквизитовДокумента_Настройки(_ОбщегоНазначения.ПолучитьИмяОбъектаПоСинониму("ТабличнаяЧасть",стр.ТабличнаяЧасть,ИмяДокумента));

КонецПроцедуры


Процедура УсловияРеквизитПриИзменении(Элемент)

стр = ЭлементыФормы.Условия.ТекущаяСтрока;
стр.Значение = "";

КонецПроцедуры

 

Процедура НастройкиРеквизитПриИзменении(Элемент)

стр = ЭлементыФормы.Настройки.ТекущаяСтрока;
стр.Значение = "";

КонецПроцедуры


Процедура УсловияПриАктивизацииЯчейки(Элемент)

Если Элемент.ТекущаяКолонка.Имя = "Значение" Тогда
стр = ЭлементыФормы.Условия.ТекущаяСтрока;
Если стр = Неопределено Тогда
Возврат;
КонецЕсли;

Если ЗначениеЗаполнено(стр.Реквизит) Тогда
ЗадатьТипЗначенияРеквизита_Условия(стр);
КонецЕсли;
КонецЕсли;

КонецПроцедуры

 

Процедура НастройкиПриАктивизацииЯчейки(Элемент)

Если Элемент.ТекущаяКолонка.Имя = "Значение" Тогда
стр = ЭлементыФормы.Настройки.ТекущаяСтрока;
Если стр = Неопределено Тогда
Возврат;
КонецЕсли;

Если ЗначениеЗаполнено(стр.Реквизит) Тогда
ЗадатьТипЗначенияРеквизита_Настройки(стр);
КонецЕсли;
КонецЕсли;

КонецПроцедуры


Процедура ПередЗаписью(Отказ)

// удаляем пустые строки табличной части УСЛОВИЯ
ном = Условия.Количество()-1;
Пока ном >= 0 Цикл
Если Не ЗначениеЗаполнено(Условия[ном].Реквизит) Тогда
Условия.Удалить(ном);
КонецЕсли;
ном = ном - 1;
КонецЦикла;

// сортируем строки табличной части УСЛОВИЯ
Условия.Сортировать("Реквизит");

// проверяем наличие дублей строк табличной части УСЛОВИЯ
табУсловия = Условия.Выгрузить();
табУсловия.Колонки.Добавить("Счетчик");
табУсловия.ЗаполнитьЗначения(1,"Счетчик");

табУсловия.Свернуть("Реквизит","Счетчик");

Для каждого стр из табУсловия Цикл
Если стр.Счетчик > 1 Тогда
Сообщить("Обнаружены дубли строк в табличной части ""Условия отбора"" !");
Отказ = Истина;
КонецЕсли;
КонецЦикла;

// удаляем пустые строки табличной части НАСТРОЙКИ
ном = Настройки.Количество()-1;
Пока ном >= 0 Цикл
Если Не ЗначениеЗаполнено(Настройки[ном].Реквизит) Тогда
Настройки.Удалить(ном);
КонецЕсли;
ном = ном - 1;
КонецЦикла;

// сортируем строки табличной части НАСТРОЙКИ
Настройки.Сортировать("ТабличнаяЧасть,Реквизит");

// проверяем наличие дублей строк табличной части НАСТРОЙКИ
табНастройки = Настройки.Выгрузить();
табНастройки.Колонки.Добавить("Счетчик");
табНастройки.ЗаполнитьЗначения(1,"Счетчик");

табНастройки.Свернуть("ТабличнаяЧасть,Реквизит","Счетчик");

Для каждого стр из табНастройки Цикл
Если стр.Счетчик > 1 Тогда
Сообщить("Обнаружены дубли строк в табличной части ""Настройки заполнения"" !");
Отказ = Истина;
КонецЕсли;
КонецЦикла;

Если Отказ Тогда
Возврат;
КонецЕсли;

// проверяем наличие дублей в справочнике
Запрос = Новый Запрос;
Запрос.УстановитьПараметр("ТипДокумента",ТипДокумента);
Запрос.УстановитьПараметр("ВидОперации",ВидОперации);
Запрос.УстановитьПараметр("Ссылка",Ссылка);

Запрос.Текст = "ВЫБРАТЬ
| ПараметрыАвтозаполненияДокументов.Ссылка
|ИЗ
| Справочник.ПараметрыАвтозаполненияДокументов КАК ПараметрыАвтозаполненияДокументов
|ГДЕ
| ПараметрыАвтозаполненияДокументов.ТипДокумента = &ТипДокумента
| И ПараметрыАвтозаполненияДокументов.ВидОперации = &ВидОперации
| И ПараметрыАвтозаполненияДокументов.Ссылка <> &Ссылка";
Выборка = Запрос.Выполнить().Выбрать();

ЕстьСовпадения = Ложь;
Пока Выборка.Следующий() Цикл
УсловияОтбора = Выборка.Ссылка.Условия;

Если Условия.Количество() <> УсловияОтбора.Количество() Тогда
Продолжить;
Иначе
Если Условия.Количество() = 0 Тогда
ЕстьСовпадения = Истина;
КонецЕсли;
КонецЕсли;

Для ном = 0 по Условия.Количество()-1 Цикл
Если Условия[ном].Реквизит <> УсловияОтбора[ном].Реквизит или Условия[ном].Значение <> УсловияОтбора[ном].Значение Тогда
Прервать;
Иначе
ЕстьСовпадения = Истина;
КонецЕсли;
КонецЦикла;

Если ЕстьСовпадения Тогда
Сообщить("В справочнике ""Параметры автозаполнения документов"" уже есть настройки для данного типа документа и вида операции с аналогичными условиями отбора !");
Отказ = Истина;
Прервать;
КонецЕсли;
КонецЦикла;

КонецПроцедуры


Процедура ЗаполнитьСписокТиповДокументов()


СписокТиповДокументов = Новый СписокЗначений;

// заполним список доступных типов документов
Для каждого эл из Метаданные.Документы Цикл
СписокТиповДокументов.Добавить(эл.Синоним,эл.Синоним);
КонецЦикла;

ЭлементыФормы.ТипДокумента.СписокВыбора = СписокТиповДокументов;

КонецПроцедуры

 

Процедура ЗаполнитьСписокВидовОперацийДокумента()

СписокВидовОперацийДокумента = Новый СписокЗначений;

РеквизитВидОперации = Метаданные.Документы[ИмяДокумента].Реквизиты.Найти("ВидОперации");
Если РеквизитВидОперации <> Неопределено Тогда
Реквизит = РеквизитВидОперации.Тип.ПривестиЗначение();

// заполним список возможных видов операций документа
Для каждого эл из Реквизит.Метаданные().ЗначенияПеречисления Цикл
СписокВидовОперацийДокумента.Добавить(эл.Синоним,эл.Синоним);
КонецЦикла;
КонецЕсли;

ЭлементыФормы.ВидОперации.СписокВыбора = СписокВидовОперацийДокумента;

Если СписокВидовОперацийДокумента.Количество() > 0 Тогда
ЭлементыФормы.НадписьВидОперации.Доступность = Истина;
ЭлементыФормы.ВидОперации.Доступность = Истина;
Иначе
ВидОперации = "";
ЭлементыФормы.НадписьВидОперации.Доступность = Ложь;
ЭлементыФормы.ВидОперации.Доступность = Ложь;
КонецЕсли;

КонецПроцедуры


Процедура ЗаполнитьСписокТабличныхЧастейДокумента()

СписокТабличныхЧастейДокумента = Новый СписокЗначений;

Для каждого тч из Метаданные.Документы[ИмяДокумента].ТабличныеЧасти Цикл
СписокТабличныхЧастейДокумента.Добавить(тч.Синоним,тч.Синоним);
КонецЦикла;

ЭлементыФормы.Настройки.Колонки.ТабличнаяЧасть.ЭлементУправления.СписокВыбора = СписокТабличныхЧастейДокумента;

КонецПроцедуры


Процедура ЗаполнитьСписокРеквизитовДокумента_Условия()

РеквизитВидОперации = Метаданные.Документы[ИмяДокумента].Реквизиты.Найти("ВидОперации");
СписокРеквизитовДокумента = Новый СписокЗначений;

Для каждого эл из Метаданные.Документы[ИмяДокумента].Реквизиты Цикл
Если эл = РеквизитВидОперации Тогда
Продолжить;
КонецЕсли;
СписокРеквизитовДокумента.Добавить(эл.Синоним,эл.Синоним);
КонецЦикла;

ЭлементыФормы.Условия.Колонки.Реквизит.ЭлементУправления.СписокВыбора = СписокРеквизитовДокумента;

КонецПроцедуры

 

Процедура ЗаполнитьСписокРеквизитовДокумента_Настройки(ИмяТабличнойЧасти)

РеквизитВидОперации = Метаданные.Документы[ИмяДокумента].Реквизиты.Найти("ВидОперации");
СписокРеквизитовДокумента = Новый СписокЗначений;

Если Не ЗначениеЗаполнено(ИмяТабличнойЧасти) Тогда
Для каждого эл из Метаданные.Документы[ИмяДокумента].Реквизиты Цикл
Если эл = РеквизитВидОперации Тогда
Продолжить;
КонецЕсли;
СписокРеквизитовДокумента.Добавить(эл.Синоним,эл.Синоним);
КонецЦикла;
Иначе
Для каждого эл из Метаданные.Документы[ИмяДокумента].ТабличныеЧасти[ИмяТабличнойЧасти].Реквизиты Цикл
СписокРеквизитовДокумента.Добавить(эл.Синоним,эл.Синоним);
КонецЦикла;
КонецЕсли;

ЭлементыФормы.Настройки.Колонки.Реквизит.ЭлементУправления.СписокВыбора = СписокРеквизитовДокумента;

КонецПроцедуры


Процедура ЗадатьТипЗначенияРеквизита_Условия(стр)

ИмяРеквизита = _ОбщегоНазначения.ПолучитьИмяРеквизитаПоСинониму(,стр.Реквизит,ИмяДокумента);
ТипРеквизита = _ОбщегоНазначения.ПолучитьТипРеквизитаПоИмени(,ИмяРеквизита,ИмяДокумента);

Если ТипЗнч(стр.Значение) <> ТипЗнч(ТипРеквизита.ПривестиЗначение()) Тогда
стр.Значение = ТипРеквизита.ПривестиЗначение();
ЭлементыФормы.Условия.Колонки.Значение.ЭлементУправления.ОграничениеТипа = ТипРеквизита;
ЭлементыФормы.Условия.Колонки.Значение.ЭлементУправления.Значение = ТипРеквизита.ПривестиЗначение();
КонецЕсли;

КонецПроцедуры

 

Процедура ЗадатьТипЗначенияРеквизита_Настройки(стр)

ИмяТабличнойЧасти = _ОбщегоНазначения.ПолучитьИмяОбъектаПоСинониму("ТабличнаяЧасть",стр.ТабличнаяЧасть,ИмяДокумента);
ИмяРеквизита = _ОбщегоНазначения.ПолучитьИмяРеквизитаПоСинониму(ИмяТабличнойЧасти,стр.Реквизит,ИмяДокумента);
ТипРеквизита = _ОбщегоНазначения.ПолучитьТипРеквизитаПоИмени(ИмяТабличнойЧасти,ИмяРеквизита,ИмяДокумента);

Если ТипЗнч(стр.Значение) <> ТипЗнч(ТипРеквизита.ПривестиЗначение()) Тогда
стр.Значение = ТипРеквизита.ПривестиЗначение();
ЭлементыФормы.Настройки.Колонки.Значение.ЭлементУправления.ОграничениеТипа = ТипРеквизита;
ЭлементыФормы.Настройки.Колонки.Значение.ЭлементУправления.Значение = ТипРеквизита.ПривестиЗначение();
КонецЕсли;

КонецПроцедуры

 

Как это работает

При срабатывании события "ПередЗаписью" документа выполняется проверка, есть ли элементы справочника с подходящим типом документа и видом операции, если есть, выполняется проверка дополнительных условий, и затем указанные в справочнике реквизиты шапки либо табличной части документа заполняются заданным в справочнике значением.

Замечания

1. Для табличной части реквизит заполняется одновременно для всех строк

2. Предполагается, что синонимы реквизитов объектов метаданных - уникальны в пределах этого объекта

См. также

Contragent+ 5.0 от 2 500
Подписаться Добавить вознаграждение

Комментарии

1. Сергей Ожерельев (Поручик) 23.09.13 16:18
(0) Лучше сделайте в виде отдельной подсистемы и продавайте за деньги.
2. Дмитрий Романовский (vdscom) 23.09.13 16:34
(1) Поручик,
спасибо, подумаю :)
возможно, объединю с другими механизмами, пока не опубликованными на сайте
3. Василий Казьмин (awk) 23.09.13 18:23
(1) Поручик, Кто это купит?

1. Ошибки проектирования:

Ошибка №1. Поиск по синониму. Если делать, так делать по полному имени Метаданные().ПолноеИмя();
Ошибка №2. Работа при записи, а не перед записью.
Ошибка (сильно субъективная) №3. Использование справочника. По моему гораздо лучше подойдет объект регистр сведений. Тем более там контроль уникальности по измерениям и периодичность.

Регистр (периодический независимый):
  Измерения:
    ПолноеИмя: Полное имя объекта метаданных
  Ресурсы:
    Условие: Строка - функция дополнительной проверки Если Не ПустаяСтрока(Условие) И Вычислить(Условие) <> Истина Тогда Возврат; КонецЕсли;
    ЗначениеПоУмолчанию: Составной - значение для подстановки.
    ЗаменятьТолькоЕслиНеЗаполнено: Булево - Если Истина, тогда проверяем на заполненность иначе не проверяем.
    Обработчик: Строка - Обработчик перед записью конкретного объекта.
...Показать Скрыть


2. Способы применения? Почему нельзя использовать Перед записью в объекте или подписке на событие? Что мешает работать в конфигураторе?

3. Безопасность. Где гарантия, что сторонняя установка не понаставит того, чего не надо?
4. Дмитрий Романовский (vdscom) 23.09.13 18:43
(3) awk,
я не считаю это ошибками

1. поиск по синониму делал сознательно, в конце статьи указал, что синонимы в пределах объекта метаданных должны быть уникальны
2. чем вам не нравится событие "ПриЗаписи" ?
3. а мне справочник больше нравится. интуитивнее, что ли. контроль уникальности реализован программно
4. насчет конфигуратора не совсем понял вашу мысль. у нас настройки автозамены выполняют сами бухгалтера, кому как нужно
5. не понаставит. если не поставить галочку "принудительно", то заполняются только незаполненные значения
5. Василий Казьмин (awk) 23.09.13 19:13
(4) vdscom,
1. Считаешь ты поиск по синониму ошибкой или нет. Пишешь или нет, что он должен быть уникальным. Это остается ошибкой. То есть действием нарушающим правило. А правило гласит: "Идентификатор должен быть уникальным". Второе правило гласит: "Если что-то может пойти не так и ты об этом знаешь, то оно обязательно пойдет не так".
2. Тем что При записи выполняется после записи объекта в БД, но до окончания транзакции. Это серьезная ошибка.
3. А я и написал, что субъективно. То есть спорно и не факт, что правильно.
4. Что-то неправильное в этом. Если одному надо одно, другому - другое, то вроде реализовано это пользовательскими настройками, зачем огород городить?
5. А если оно должно оставаться пустым?
6. Дмитрий Романовский (vdscom) 23.09.13 20:34
(5) awk,
1. вся жизнь у нас построена на допущениях. в контексте поставленной передо мной задачи поиск по синонимам меня вполне устраивает. считаете вы это ошибкой или нет. появится необходимость - переделаю, а пока - есть такое выражение - "Лучшее враг хорошего".
2. насчет "ПриЗаписи" - почти согласен
3. тут мы поняли друг друга
4,5. пользовательскими настройками реализовано далеко не все, а только заполнение некоторых стандартных параметров, типа ОсновнаяОрганизация или Ответственный. предложенный механизм - универсальный, заполняй любой параметр любым значением, в зависимости от заданных условий. "а если оно должно оставаться пустым" - ну так не создавайте для этого реквизита правило или наоборот, создайте правило, при определенных условиях записывающее в этот реквизит пустое значение. а если совсем уж везде враги народа мерещатся - настройте права доступа к этому справочнику
7. Василий Казьмин (awk) 23.09.13 23:38
1. Зачем делать допущение, что два плюс два равно пять? Всем известно, что два плюс два равно четыре. Так и тут. Зачем делать допущение что синоним неизменен и уникален? Есть имя - оно хоть и изменяемо, но уникально в пределах типа. А полное имя уникально в пределах конфигурации.
2. Что означает почти? Что событие при записи возникает до помещения в базу данных? Или что оно происходит вне транзакции? Или что на ИТС нет рекомендаций? :D
3...
45. Ну хорошо. Допустим. Но посмотреть реализацию на всякий случай можно было? Там реализовано автозаполнение форм при открытии. Почему? Да потому, что пользователь перед записью видит что делает и может повлиять на записываемый реквизит. А если при записи это делать, то может получится следующее:

* Открываем выписку по кредиту
* Смотрим и видим, что в ней сумма нашего долга равна нулю
* Закрываем с записью

И о чудо мы должны 100 тысяч рублей.

А как должно бы было быть:

* Открываем выписку по кредиту
* Смотрим и видим, что в ней сумма нашего долга равна нулю
* Закрываем с записью

И видим сообщение, что надо либо указать сумму кредита, либо закрыть без сохранения.
ikekoval; teflon; Makushimo; baton_pk; the1; +5 Ответить 1
8. Дмитрий Романовский (vdscom) 24.09.13 13:00
(7) awk,
1. еще раз повторюсь, я сознательно сделал это допущение. в контексте моей задачи меня это вполне устраивает. абсолютно и полностью.
2. посмотрел в конфигураторе рабочих баз - в подписке на событие задан обработчик "ПередЗаписью". получается, что в моей статье опечатка и мы спорили ни о чем :)
4,5. опять же, я делаю допущение, что пользователи, когда настраивают параметры автозамены, понимают, что и с какой целью они делают. то есть, в этом вопросе я пользователям доверяю. всесторонней защиты от дурака не было цели создавать. заполнение документа при открытии не устраивает по той простой причине, что для этого нужно дорабатывать каждый документ, пусть и всего одной строчкой кода.

надеюсь, мы друг друга услышали
9. Василий Казьмин (awk) 24.09.13 14:06
10. mikhail burlakov (burlakov) 24.09.13 16:43
не сочтите за рекламу, но моя разработка в чем-то лучше вашей. посмотрите сами http://infostart.ru/public/197108/

единственное неудобство, что надо втыкать код в сами модули, но подписки приоткрытии и присоздании пока к сожалению не придумали. на счет продавать вряд ли получится - моя бесплатна :)
11. Дмитрий Романовский (vdscom) 24.09.13 17:00
(10) burlakov,
ну, мне моя больше нравится :)
и денег за нее я тоже не прошу
12. Гульнара Р (Эсти) 19.08.14 11:25
Для написания сообщения необходимо авторизоваться
Прикрепить файл
Дополнительные параметры ответа