Как показать сообщение пользователю? методы: СообщениеПользователю и ПоказатьОповещениеПользователя В 1С предполагается, что СообщениеПользователю выводятся для того, чтобы сообщить пользователю об ошибках.
А для информирования о выполняемом действии рекомендуется использовать метод встроенного языка ПоказатьОповещениеПользователя() .
СообщениеПользователю выводит сообщение пользователю (после окончания обработки) или сохраняет его в очередь, если сообщение невозможно вывести прямо сейчас.
Пример вывода сообщения на клиенте:
Код 1C v 8.3 Если ЗначениеЗаполнено(объект.ИнтернетМагазин) Тогда
// Все заполнено, обрабатываем
Иначе
сбп=Новый СообщениеПользователю;
сбп.Текст = "Укажите интернет-магазин данные которого Вы загружаете!";
сбп.Поле="ИнтернетМагазин";
сбп.ПутьКДанным = "Объект";
сбп.Сообщить();
КонецЕсли; При обработке на сервере:
Необходимо зарегистрировать в системе соответствие объекта и имени реквизита формы. Для этого в глобальном контексте реализована функция УстановитьСоответствиеОбъектаИРеквизитаФормы(). Сделать это можно следующим образом:
Код 1C v 8.3 &НаСервере
Процедура ПроцедураВызываемаяСКлиента(ОбъектДанных)
Документ = ДанныеФормыВЗначение(Объект, Тип("ДокументОбъект.ПоступлениеТМЦ")); // Преобразования данных формы в объект
УстановитьСоответствиеОбъектаИРеквизитаФормы(Документ, "Объект"); // Установка соответствия
ДействиеСОбъектом(Документ); // Действия над объектом, в процессе работы которых может возникнуть необходимость вывода сообщений
КонецПроцедуры В данном фрагменте выполняется преобразование объекта из данных формы в реальный объект и устанавливается его соответствие с реквизитом формы по имени "Объект".
Если в дальнейшем требуется создать сообщение, можно сделать это следующим образом:
Код 1C v 8.3 &НаСервере
Процедура ДействиеСОбъектом(ОбъектДанных)
// Какие либо действия, которые требуют создания сообщения
// Создание сообщения
Сообщение = Новый СообщениеПользователю();
Сообщение.Текст = "В строке 11 табличной части ""Номенклатура"" не хватает " +
НедостающееКоличество + " " + ЕдиницаИзмеренияНоменклатуры;
Сообщение.Поле = "Номенклатура[10].Количество";
// Привязка объекта к реквизиту формы произойдет за счет
// установленного выше по стеку соответствия методом
// УстановитьСоответствиеОбъектаИРеквизитаФормы
Сообщение.УстановитьДанные(ОбъектДанных);
// Теперь у сообщения заполнено поле ПутьКДанным (установлено имя реквизита формы, до этого была пустая строка),
// и свойство КлючДанных (установлена ссылка на документ, до этого было Неопределено)
// Сообщение выводится пользователю
Сообщение.Сообщить();
// в дальнейшем сообщение будет показано в форме и привязано к
// элементу управления связанного с полем Количество
// в 11-й строке табличной части Номенклатура.
КонецПроцедуры; В этом фрагменте создается новый объект СообщениеПользователю, в котором запоминается Текст сообщения и указывается Поле объекта, ошибка в данных которого вызвала необходимость вывода сообщения. Информация о том, как объект расположен в форме берется из предварительно запомненной пары "Объект/ИмяРеквизитаФормы". В дальнейшем сообщение будет выведено в окно сообщений формы и привязано к соответствующему элементу управления.
Примеры заполнения свойства Поле объекта СообщениеПользователю ТипШаблонПример Реквизит ИмяРеквизита Контрагент Табличная часть ИмяТабличнойЧасти Скидки Реквизит табличной части ИмяТабличнойЧасти[ИндексСтроки].ИмяРеквизита Номенклатура[10].Количество Реквизит набора записей [ИндексСтроки].ИмяРеквизита [10].Курс
Еще примеры:
Код 1C v 8.3 &НаКлиенте
Процедура ДействиеСОбъектомНаКлиенте(ОбъектДанных)
// Какие либо действия, которые требуют создания сообщения
// Создание сообщения
Сообщение = Новый СообщениеПользователю();
Сообщение.Текст = "В строке 11 табличной части ""Номенклатура"" не хватает " +
НедостающееКоличество + " " + ЕдиницаИзмеренияНоменклатуры;
Сообщение.Поле = "Номенклатура[10].Количество";
// Привязка объекта к реквизиту формы "вручную"
Сообщение.КлючДанных = ОбъектДанных.Ссылка;
Сообщение.ПутьКДанным = "Объект";
// Сообщение выводится пользователю
Сообщение.Сообщить();
КонецПроцедуры;
&НаСервере
Процедура Сообщить4НаСервере()
Сообщение4 = новый СообщениеПользователю;
Сообщение4.УстановитьДанные(РеквизитФормыВЗначение("Объект"));
Сообщение4.Текст = "4. Сообщение привязанное к реквизиту шапки Организация";
Сообщение4.Поле = "Организация";
Сообщение4.Сообщить();
КонецПроцедуры
// Показываем сообщение из обработки
// КлючДанных и ПутьКДанным - пустые
Сообщение = Новый СообщениеПользователю;
Сообщение.Поле = "Комментарий";
Сообщение.Текст = "Заполните комментарий";
Сообщение.Сообщить();
// Показываем сообщение из документа
// КлючДанных - пустой, ПутьКДанным заполнится автоматически
Сообщение = Новый СообщениеПользователю;
Сообщение.Поле = "Товары[0].Количество";
Сообщение.Текст = "Не заполнено количество товара в первой строке!";
Сообщение.УстановитьДанные(ЭтотОбъект);
Сообщение.Сообщить();
//////////////////// КОД для ТИПОВЫХ конфигураций, БСП:
//в модуле объекта
ОбщегоНазначенияКлиентСервер.СообщитьПользователю(“Текст ошибки”,
ЭтотОбъект,
"Договор",,
Отказ);
//в форме объекта
ОбщегоНазначенияКлиентСервер.СообщитьПользователю(НСтр("ru = 'Дублирование пременной'"), ,
"Запросы["+ИдентификаторСтроки+"].ИмяПеременнойЗапроса",//путь к данным
"Объект", Отказ);
ПоказатьОповещениеПользователя - оповещение возникает в правом нижнем углу приложения и сообщает о совершенном действии. В течение нескольких секунд оно постепенно гаснет и пропадает. При этом, если навести на оповещение курсор мышки, оно не гаснет, и есть возможность внимательно его прочитать:
Код 1C v 8.3 ПоказатьОповещениеПользователя(НСтр("ru = 'Выполнение:'"), ПолучитьНавигационнуюСсылку(Объект), "Выгрузка завершена, все ОК!", БиблиотекаКартинок.ПолнотекстовыйПоискДалее); Код 1C v 8.3 &НаКлиенте
Процедура ПриОткрытии(Отказ)
Если ПолучитьДатуЗапретаРедактирования() >= Объект.Дата Тогда
НавигационнаяСсылка = ПолучитьНавигационнуюСсылку(Объект.Ссылка);
ПоказатьОповещениеПользователя("Только просмотр!",
НавигационнаяСсылка,
"Разрешен только просмотр документа!");
КонецЕсли;
КонецПроцедуры
&НаСервереБезКонтекста
Функция ПолучитьДатуЗапретаРедактирования()
Запрос = Новый Запрос;
Запрос.Текст = "ВЫБРАТЬ
| Константы.ДатаЗапретаРедактирования
|ИЗ
| Константы КАК Константы";
РезультатЗапроса = Запрос.Выполнить();
Возврат РезультатЗапроса.Выгрузить()[0].ДатаЗапретаРедактирования;
КонецФункции Категория:
Работа с Формой (Диалог) и её элементами Событие ПередЗаписью регистра сведений. Как перед записью изменить значение реквизита записи? Событие ПередЗаписью возникает перед выполнением записи набора регистра сведений. Процедура-обработчик вызывается после начала транзакции записи, но до начала записи набора регистра сведений.
Пример проверки на условие и заполнение реквизита Цвет:
Код 1C v 8.х Процедура ПередЗаписью(Отказ, Замещение)
Для Каждого ТекЗапись Из ЭтотОбъект Цикл
Если ТекЗапись.СерияНоменклатуры.Восстановленный Тогда
ТекЗапись.Цвет="2551650";
Иначе
ТекЗапись.Цвет="";
КонецЕсли;
КонецЦикла;
КонецПроцедуры Ниже приведен пример процедуры ПередЗаписью для регистра сведений «Курсы», который содержит курсы валют по периодам. При попытке ввести или изменить курс валюты период которого раньше даты регистрации фирмы будет выведено два сообщения:
Код 1C v 8.2 УП Процедура ПередЗаписью (Отказ, Замещение)
ДатаРегистрации = Константы.ДатаРегистрации.Получить ();
Для Каждого ТекЗапись Из ЭтотОбъект Цикл
Если ТекЗапись.Период < ДатаРегистрации Тогда
// Если период раньше даты регистрации
Отказ = Истина; // отказ от записи
Сообщить(" Запись от " + ТекЗапись.Период +
" с курсом " + ТекЗапись.Курс +
" раньше даты регистрации фирмы!");
КонецЕсли;
КонецЦикла;
Если Отказ Тогда
Сообщить ("Запись не выполнена!");
КонецЕсли;
КонецПроцедуры Категория:
Регистры сведений Управление регистрацией документа в последовательности документов Для управления регистрацией документа в последовательности документов служит набор записей регистрации в последовательности документов.
У документа есть свойство ПринадлежностьПоследовательностям. Значением свойства является коллекция наборов записей регистрации в последовательности документов. Для каждой последовательности, в которой участвует документ, существует свой собственный экземпляр набора записей. Если у документа стоит режим автоматического заполнения последовательностей, то перед записью документа наборы записей регистрации будут автоматически заполнены. Для последовательностей без измерений набор записей будет содержать только одну запись. Для последовательностей с измерениями число записей зависит от содержания документа и настройки соответствия измерений последовательности реквизитам документа.
Набор записей автоматически заполняется до записи документа и записывается после записи документа в одной транзакции с ним. Это позволяет в обработчиках событий документа ПередЗаписью() и ПриЗаписи() переопределить набор записей регистрации. Так, например, если документ входит в последовательность Последовательность1 и у документа стоит признак автоматического заполнения последовательности, то для того что бы отменить его регистрацию в последовательности в зависимости от значения реквизита документа достаточно в модуль документа вставить обработчик события ПередЗаписью() следующего содержания:
Код 1C v 8.х Процедура ПередЗаписью(Отказ, РежимЗаписи, РежимПроведения)
Если Не Регистрировать Тогда
ПринадлежностьПоследовательностям.Последовательность1.Очистить();
КонецЕсли;
КонецПроцедуры В этом случае если реквизит Регистрировать имеет значение "Ложь", то документ не будет зарегистрирован в последовательности Последовательность1. Кроме отмены регистрации документа в последовательности, доступна возможность написания собственного алгоритма регистрации документа в последовательности. Для этого надо очистить набор записей регистрации и заполнить его новыми записями.
Код 1C v 8.х Процедура ПередЗаписью(Отказ, РежимЗаписи, РежимПроведения)
ПринадлежностьПоследовательностям.Последовательность1.Очистить();
Если ВидРегистрации = 1 Тогда
ЗП = ПринадлежностьПоследовательностям.Последовательность1.Добавить();
ЗП.Измерение = Реквизит1;
ИначеЕсли ВидРегистрации = 2 Тогда
ПринадлежностьПоследовательностям.Последовательность1.Добавить();
ЗП.Измерение = Реквизит2;
КонецЕсли;
КонецПроцедуры
Пример
Код 1C v 8.х // Зарегистрируем в последовательности УУ
Если ОтражатьВУправленческомУчете Тогда
ЗаписьРегистрации = ПринадлежностьПоследовательностям.ПартионныйУчет.Добавить();
ЗаписьРегистрации.Период = Дата;
КонецЕсли;
Процедура ПоследовательностьВзаиморачеты(ДокумСсылка) Экспорт
ДокументМоментВремени = Новый МоментВремени(ДокумСсылка.дата, ДокумСсылка);
НаборЗаписей = Последовательности.Взаиморасчеты.СоздатьНаборЗаписей();
НаборЗаписей.Отбор.Регистратор.Установить(ДокумСсылка);
НоваяЗапись = НаборЗаписей.Добавить();
НоваяЗапись.Регистратор = ДокумСсылка;
НоваяЗапись.Период = ДокумСсылка.Дата;
НаборЗаписей.Записать();
//Установим границу последовательности на документ
Последовательности.Взаиморасчеты.УстановитьГраницу(ДокументМоментВремени);
КонецПроцедуры
Функция ПолучитьГраницуПоследовательности(Организация = Неопределено) Экспорт
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| ПартионныйУчетГраницы.МоментВремени
|ИЗ
| Последовательность.ПартионныйУчет.Границы КАК ПартионныйУчетГраницы
|";
Выборка = Запрос.Выполнить().Выбрать();
Если Выборка.Следующий() Тогда
Возврат Выборка.МоментВремени;
Иначе
Возврат Новый МоментВремени('00010101');
КонецЕсли;
КонецФункции
Процедура ОбновитьСписокПоследовательностей()
Для каждого Последовательность Из Обр.СписокПоследовательностей Цикл
ИмяПоследовательности = Последовательность.ИмяПоследовательности;
ГраницаПоследовательности = Последовательности[ИмяПоследовательности].ПолучитьГраницу();
ДатаГраницы = ГраницаПоследовательности.Дата;
Последовательность.Актуальность = "" + ДатаГраницы + " " + ГраницаПоследовательности.Ссылка;
Последовательность.ДатаГраницы = ДатаГраницы;
КонецЦикла;
КонецПроцедуры
// Процедура выполняет поиск и исправление ошибок в последовательности.
//
Процедура КорректировкаРегистрацииВПоследовательности()
Для Каждого ТекПоследовательность Из Метаданные.Последовательности Цикл
ТекстЕстьДвижения = "
| ВЫБОР
| КОГДА СписанныеТоварыСрезПоследних.Регистратор ЕСТЬ NULL";
Для Каждого ДвиженияВлияющиеНаПоследовательность Из ТекПоследовательность.Движения Цикл
ТекстЕстьДвижения = ТекстЕстьДвижения + "
| И РегистрНакопления" + ДвиженияВлияющиеНаПоследовательность.Имя + ".Регистратор ЕСТЬ NULL";
КонецЦикла;
ТекстЕстьДвижения = ТекстЕстьДвижения + "
| ТОГДА ЛОЖЬ
| ИНАЧЕ ИСТИНА
| КОНЕЦ";
ТекстЗапроса = "ВЫБРАТЬ
| Последовательность.Регистратор КАК Регистратор,
| Последовательность.Регистратор.Проведен КАК Проведен,
| Последовательность.Регистратор.Дата КАК Дата,
| Последовательность.Период КАК Период,
|" + ТекстЕстьДвижения + " КАК ЕстьДвижения
|ИЗ
| Последовательность." + ТекПоследовательность.Имя + " КАК Последовательность
| ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.СписанныеТовары КАК СписанныеТоварыСрезПоследних
| ПО Последовательность.Регистратор = СписанныеТоварыСрезПоследних.Регистратор
| И СписанныеТоварыСрезПоследних.НомерСтроки = 1";
Для Каждого ДвиженияВлияющиеНаПоследовательность Из ТекПоследовательность.Движения Цикл
ТекстЗапроса = ТекстЗапроса + "
| ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления." +ДвиженияВлияющиеНаПоследовательность.Имя + ".Обороты(, , Регистратор, ) КАК РегистрНакопления" + ДвиженияВлияющиеНаПоследовательность.Имя + "
| ПО Последовательность.Регистратор = РегистрНакопления" + ДвиженияВлияющиеНаПоследовательность.Имя + ".Регистратор";
КонецЦикла;
ТекстЗапроса = ТекстЗапроса + "
|ГДЕ
| НЕ (Последовательность.Регистратор.Проведен
| И (Последовательность.Регистратор ССЫЛКА Документ.КорректировкаСтоимостиСписанияТоваров
| ИЛИ Последовательность.Регистратор.Дата = Последовательность.Период)
| И " + ТекстЕстьДвижения + ")
|";
Запрос = Новый Запрос(ТекстЗапроса);
Выборка = Запрос.Выполнить().Выбрать();
Пока Выборка.Следующий() Цикл
Если Не Выборка.Проведен Тогда
НаборЗаписей = Последовательности[ТекПоследовательность.Имя].СоздатьНаборЗаписей();
НаборЗаписей.Отбор.Регистратор.Установить(Выборка.Регистратор);
НаборЗаписей.Записать();
ИначеЕсли (Выборка.Дата <> Выборка.Период)
И (ТипЗнч(Выборка.Регистратор) <> Тип("ДокументСсылка.КорректировкаСтоимостиСписанияТоваров")) Тогда
НаборЗаписей = Последовательности[ТекПоследовательность.Имя].СоздатьНаборЗаписей();
НаборЗаписей.Отбор.Регистратор.Установить(Выборка.Регистратор);
НаборЗаписей.Прочитать();
Для Каждого СтрокаНабора Из НаборЗаписей Цикл
СтрокаНабора.Период = Выборка.Дата;
КонецЦикла;
НаборЗаписей.Записать();
КонецЕсли;
Если Не Выборка.ЕстьДвижения Тогда
НаборЗаписей = Последовательности[ТекПоследовательность.Имя].СоздатьНаборЗаписей();
НаборЗаписей.Отбор.Регистратор.Установить(Выборка.Регистратор);
НаборЗаписей.Записать();
КонецЕсли;
КонецЦикла;
КонецЦикла;
КонецПроцедуры
Процедура УдалитьРегистрациюДокументаВПоследовательностях(ДокументОбъект, ПроверятьДвижения = Ложь)Экспорт
// получение списка последовательностей в которых зарегистрирован документ
Если ПроверятьДвижения Тогда
ТаблицаРегистраций = ОпределитьНаличиеРегистрацииДокументаВПоследовательности(ДокументОбъект);
КонецЕсли;
КоллекцияПоследовательностей = ДокументОбъект.ПринадлежностьПоследовательностям;
Для Каждого НаборЗаписейРегистрацииВПоследовательности ИЗ КоллекцияПоследовательностей Цикл
Если (НаборЗаписейРегистрацииВПоследовательности.Количество() > 0)
ИЛИ (ПроверятьДвижения И (НЕ ТаблицаРегистраций.Найти(НаборЗаписейРегистрацииВПоследовательности.Метаданные().Имя,"Имя") = Неопределено)) Тогда
НаборЗаписейРегистрацииВПоследовательности.Очистить();
КонецЕсли;
КонецЦикла;
КонецПроцедуры//УдалитьРегистрациюДокументаВПоследовательностях
Функция ОпределитьНаличиеРегистрацииДокументаВПоследовательности(ДокументОбъект) Экспорт
ТекстЗапроса = "";
Для Каждого Последовательность ИЗ ДокументОбъект.ПринадлежностьПоследовательностям Цикл
// в запросе получаем имена последовательностей, в которых документ зарегистрирован
ТекстЗапроса = ТекстЗапроса + "
|" + ?(ТекстЗапроса = "", "", "ОБЪЕДИНИТЬ ВСЕ ") + "
|ВЫБРАТЬ """ + Последовательность.Метаданные().Имя
+ """ КАК Имя ИЗ " + Последовательность.Метаданные().ПолноеИмя()
+ " ГДЕ Регистратор =Регистратор";
КонецЦикла;
Если ТекстЗапроса = "" Тогда
Возврат Новый ТаблицаЗначений();
Иначе
Запрос = Новый Запрос(ТекстЗапроса);
Запрос.УстановитьПараметр("Регистратор", ДокументОбъект.Ссылка);
ТаблицаЗапроса = Запрос.Выполнить().Выгрузить();
Возврат ТаблицаЗапроса;
КонецЕсли;
КонецФункции Категория:
Документы Как прочитать записи регистра сведений установив отбор и удалить записи? Прочитать записи регистра сведений можно двумя способами: Через Набор Записей или Менеджер
Вот пример через набор записей :
Код 1C v 8.х // Добавление новых данных в существующую запись регистра сведений
НаборЗаписей = РегистрыСведений.ДокументоОборот.СоздатьНаборЗаписей();
НаборЗаписей.Отбор.Доставка.Установить(Доставка);
НаборЗаписей.Отбор.Этап.Установить(Этап);
НаборЗаписей.Прочитать();
Для каждого Запись из НаборЗаписей Цикл
Запись.ДатаВремя = ДатаР;
Запись.Отдел = фио.Подразделение;
Запись.ФИО = ПараметрыСеанса.ТекущийПользователь;
Запись.Документы = Документы;
Запись.Примечание = Примечание;
КонецЦикла;
НаборЗаписей.Записать(); Пример с использованием набора записей и менеджера записи:
Код 1C v 8.х НаборЗаписей = РегистрыСведений.CRM_Напоминания.СоздатьНаборЗаписей();
Отбор = НаборЗаписей.Отбор;
Отбор.Объект.Установить(Объект.Ссылка);
Отбор.Завершено.Установить(Ложь);
НаборЗаписей.Прочитать();
Если НаборЗаписей.Количество() > 0 Тогда
Если ЗадаватьВопрос Тогда
ТекстВопроса = "Завершить все напоминания для " + Строка(Объект.Ссылка) + " ?";
Ответ = Вопрос(ТекстВопроса,РежимДиалогаВопрос.ДаНет, ,КодВозвратаДиалога.Да);
Иначе
Ответ = КодВозвратаДиалога.Да
КонецЕсли;
Если Ответ = КодВозвратаДиалога.Да Тогда
Для каждого Запись Из НаборЗаписей Цикл
РегистрСведенийМенеджерЗаписи = РегистрыСведений.CRM_Напоминания.СоздатьМенеджерЗаписи();
ЗаполнитьЗначенияСвойств(РегистрСведенийМенеджерЗаписи, Запись);
РегистрСведенийМенеджерЗаписи.Прочитать();
Если РегистрСведенийМенеджерЗаписи.Выбран() Тогда //напоминание небыло удалено
Если НЕ РегистрСведенийМенеджерЗаписи.УдалитьПоИстеченииСрока Тогда
РегистрСведенийМенеджерЗаписи.Завершено = Истина;
РегистрСведенийМенеджерЗаписи.Записать();
Иначе
РегистрСведенийМенеджерЗаписи.Удалить();
КонецЕсли;
КонецЕсли;
КонецЦикла;
КонецЕсли;
КонецЕсли;
А вот пример через менеджер записи:
Код 1C v 8.х МенеджерЗаписи = РегистрыСведений.НоменклатураКонтрагентов.СоздатьМенеджерЗаписи();
МенеджерЗаписи.Контрагент = Контрагент;
МенеджерЗаписи.Номенклатура = СтрокаТаблицыТовары.Номенклатура;
МенеджерЗаписи.ХарактеристикаНоменклатуры = СтрокаТаблицыТовары.ХарактеристикаНоменклатуры;
МенеджерЗаписи.Прочитать();
Если МенеджерЗаписи.Выбран() Тогда
Вес = МенеджерЗаписи.ВесНоменклатурыКонтрагента;
КонецЕсли; Категория:
Регистры сведений Как сформировать отчет СКД без проверки прав (в привилегированном режиме)? Что при разработке отчетов требуется чтобы у пользователя с ограниченными правами, отчет формировался полностью без проверки прав!
Особенно если настроен RLS
Есть несколько способов как это сделать: 1. Установить привилегированный режим в модуле отчета
Форма отчета должна быть Управляемой, далее в модуле отчета процедура обработчика «При компоновке результата»:
Код 1C v 8.3 //Перехватываем событие вывода компоновки данных в табличный документ и выводим со своим заголовком
Процедура ПриКомпоновкеРезультата(ДокументРезультат, ДанныеРасшифровки, СтандартнаяОбработка)
СтандартнаяОбработка = Ложь;
УстановитьПривилегированныйРежим(Истина);
//Сформируем отчет
СформироватьОтчет(ДокументРезультат, ДанныеРасшифровки);
УстановитьПривилегированныйРежим(Ложь);
КонецПроцедуры 2. Формирование в п ривилегированном режиме через Общий модуль с галкой Привелигерованный
Создаем общий модуль
так же как в пункте 1 в обработчике «При компоновке результата» пишем:
Код 1C v 8.3 //Перехватываем событие вывода компоновки данных в табличный документ и выводим со своим заголовком
Процедура ПриКомпоновкеРезультата(ДокументРезультат, ДанныеРасшифровки, СтандартнаяОбработка)
СтандартнаяОбработка = Ложь;
МЕ_ДляОтчетаСКД_ПривелРежим.СформироватьОтчетПривРеж(ДокументРезультат, СхемаКомпоновкиДанных, ДанныеРасшифровки, КомпоновщикНастроек);
КонецПроцедуры В общем модуле МЕ_ДляОтчетаСКД_ПривелРежим код:
Код 1C v 8.3 Процедура СформироватьОтчетПривРеж(ТабличныйДокумент, СхемаКомпоновкиДанных, ДанныеРасшифровки, КомпоновщикНастроек) Экспорт
ТабличныйДокумент.Очистить();
КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;
МакетКомпоновкиДанных = КомпоновщикМакета.Выполнить(СхемаКомпоновкиДанных, КомпоновщикНастроек.Настройки, ДанныеРасшифровки,,,Ложь);
ВнешниеНаборыДанных = Новый Структура;
/// можно передать внешние данные ВнешниеНаборыДанных.Вставить("тзПродаж", СформироватьТЗПродаж());
ПроцессорКомпоновкиДанных = Новый ПроцессорКомпоновкиДанных;
ПроцессорКомпоновкиДанных.Инициализировать(МакетКомпоновкиДанных,ВнешниеНаборыДанных,ДанныеРасшифровки);
ПроцессорВывода = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВТабличныйДокумент;
ПроцессорВывода.УстановитьДокумент(ТабличныйДокумент);
ПроцессорВывода.Вывести(ПроцессорКомпоновкиДанных);
КонецПроцедуры 3. Если включен режим Использовать ограничение на уровне прав доступа - RLS
Часто используется в типовых. Тут в модуле для текущего пользователя можно на время формирования отчету установить параметр сеанса ИспользоватьОграниченияПравДоступаНаУровнеЗаписей в Ложь и RLS не сработает.
Код 1C v 8.3 ПараметрыСеанса.ИспользоватьОграниченияПравДоступаНаУровнеЗаписей=Ложь; После завершения формирования, не забудьте включить rls обратно установив = Истина
4. Если в запросе используется конструкция вида регистратор.дата и это поле не отображается в полях отчета СКД
Допустим Вы сделали запрос по регистру накоплений и через регистратор обратились к дате или сумме документа и при формировании отчета СКД, эти поля недоступны !? как же быть?
Проблема в том - что у регистратором может выступать несколько документов и видимо права чтение/просмотр есть не на все - поэтому через скд эта таблица целиком недоступна, решение:
1. открыть доступ на все регистраторы регистра
2. в запросе четко обозначить тип
Код 1C v 8.3 //примеры
ВЫРАЗИТЬ(ДокументыОплаты.Регистратор КАК Документ.ПлатежноеПоручениеВходящее).СуммаДокумента
//или так
ВЫБОР
КОГДА РАЗНОСТЬДАТ(ВЫРАЗИТЬ(ВзаиморасчетыПоДокументам.ДокументРасчетовСКонтрагентом КАК Документ.ПоступлениеТоваровУслуг).Дата,КонецПериода, ДЕНЬ) > ВзаиморасчетыПоДокументам.ДоговорКонтрагента.ДопустимоеЧислоДнейЗадолженности
ТОГДА ДОБАВИТЬКДАТЕ(ВЫРАЗИТЬ(ВзаиморасчетыПоДокументам.ДокументРасчетовСКонтрагентом КАК Документ.ПоступлениеТоваровУслуг).Дата, ДЕНЬ, ВзаиморасчетыПоДокументам.ДоговорКонтрагента.ДопустимоеЧислоДнейЗадолженности)
ИНАЧЕ ДАТАВРЕМЯ(1, 1, 1)
КОНЕЦ КАК ДеньВозникновенияЗадолженности
В дополнении у пункту 1, код процедуры сформировать отчет(). Для вывода отчета я использую шаблон All4CF.ru_Template_SKD_v4.1 в нем уже реализованы почти все необходимые функции и работает в Обычных и УП формах:
Код 1C v 8.3 // Процедура выполняет формирование табличного документа по настройкам СКД
Процедура СформироватьОтчет(ТабличныйДокумент, ДанныеРасшифровки)
УстановитьПривилегированныйРежим(Истина);
// если отчет открывается по расшифровке, отбору, упорядочиванию,
// группировке или условному оформлению - восстановим настройки вывода заголовка,
// т.к., в переданных настройках при этом, вывод заголовка отключен
// для того, чтобы не выводился встроенный заголовок компоновки.
ВосстановитьНастройкиВыводаЗаголовка();
ДанныеРасшифровки = Новый ДанныеРасшифровкиКомпоновкиДанных;
КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;
ПроцессорКомпоновкиДанных = Новый ПроцессорКомпоновкиДанных;
ТабличныйДокумент.Очистить();
// установим обязательные настройки отчета
УстановитьПараметрыОтчета();
// Сделаем копию настроек вывода заголовка
СохранитьНастройкиВыводаЗаголовка();
ВыводитьЗаголовок = ВыводитьЗаголовокОтчета();
Если ВыводитьЗаголовок Тогда
ПрисоединитьЗаголовокОтчетаКТабличномуДокументу(ТабличныйДокумент, ПолучитьТекстЗаголовкаОтчета());
// Отключим в настройках вывод встроенного заголовка
НайденнаяНастройкаВыводаЗаголовка = КомпоновщикНастроек.Настройки.ПараметрыВывода.Элементы.Найти("ВыводитьЗаголовок");
НайденнаяНастройкаВыводаЗаголовка.Значение = ТипВыводаТекстаКомпоновкиДанных.НеВыводить;
НайденнаяНастройкаВыводаЗаголовка.Использование = Истина;
КонецЕсли;
КопияДополнительныхНастроек = УстановитьДополнительныеНастройкиДляРасшифровки();
МакетКомпоновкиДанных = КомпоновщикМакета.Выполнить(СхемаКомпоновкиДанных, КомпоновщикНастроек.Настройки, ДанныеРасшифровки);
// при необходимости вставим внешние наборы данных в СКД
ВнешниеНаборыДанных = Новый Структура;
ТаблицаВнешнегоНабораДанных = ПолучитьТаблицуВнешнегоНабораДанных();
ВнешниеНаборыДанных.Вставить("ТаблицаВнешнегоНабораДанных",ТаблицаВнешнегоНабораДанных);
ПроцессорКомпоновкиДанных.Инициализировать(МакетКомпоновкиДанных,ВнешниеНаборыДанных,ДанныеРасшифровки);
ВывестиРезультатКомпоновкиСАвтофиксациейСтрок(ТабличныйДокумент, ПроцессорКомпоновкиДанных, ДанныеРасшифровки.Элементы,,,КоличествоФиксируемыхСтолбцов);
ДополнительнаяОбработкаРезультатаОтчета(ТабличныйДокумент);
Если ВыводитьЗаголовок Тогда
// вернем настройки вывода заголовка на место
ВосстановитьНастройкиВыводаЗаголовка();
КонецЕсли;
// восстановим дополнительные настройки
Для Каждого ЭлементСтруктуры Из КопияДополнительныхНастроек Цикл
КомпоновщикНастроек.Настройки.ДополнительныеСвойства.Вставить(ЭлементСтруктуры.Ключ, ЭлементСтруктуры.Значение);
КонецЦикла;
// сохраненные настройки нужны только при расшифровке и т.п.
// и не будуть давать изменить вывоз заголовка при обычном формировании.
ОчиститьСохраненныеНастройкиВыводаЗаголовка();
УстановитьВидимостьЗаголовкаОтчета(ТабличныйДокумент);
УстановитьВидимостьПараметровОтчета(ТабличныйДокумент);
УстановитьПривилегированныйРежим(Ложь);
КонецПроцедуры // СформироватьОтчет()
Категория:
Схема Компоновки Данных Обмен данными с сайтом используя формат JSON в 1С Формат JSON в 1С до версии 8.3.6 не реализован, но нижет я приведу примеры функций которые можно использовать для полноценной работы JSON в 1С предыдущий версий.
JSON (JavaScript Object Notation) это текстовый формат обмена данными, широко используемый в веб-приложениях. По сравнению с XML он является более лаконичным и занимает меньше места. Кроме этого все браузеры имеют встроенные средства для работы с JSON.
Необходимость работы с этим форматом на уровне платформы обусловлена не только тем, что это «модный современный» формат, который прикладные решения 1С:Предприятия сами по себе могут использовать для интеграции со сторонними приложениями. Другая причина заключается ещё и в том, что JSON активно используется в HTTP интерфейсах. А в 1С:Предприятии как раз есть такие механизмы, в которых хочется использовать этот формат. Это REST интерфейс приложения, автоматически генерируемый платформой, и HTTP-сервисы, которые вы можете создавать самостоятельно.
В платформе с версии 8.3.6: Потоковое чтение и запись JSON:
Объекты потоковой работы - это общие объекты ЧтениеJSON и ЗаписьJSON. Они последовательно читают JSON из файла или строки, или последовательно записывают JSON в файл или строку. Таким образом, чтение и запись JSON происходят без формирования всего документа в памяти.
В качестве иллюстрации потокового чтения JSON можно привести следующий пример:
Код 1C v 8.3 // Пример чтения JSON.
ЧтениеJSON = Новый ЧтениеJSON;
// Либо открыть файл, из которого будет выполняться чтение, // либо установить строку, из которой будет выполняться чтение.
ЧтениеJSON.ОткрытьФайл("ИмяФайла");
//ЧтениеJSON.УстановитьСтроку("СтрокаJSON");
Пока ЧтениеJSON.Прочитать() Цикл
TипJSON = ЧтениеJSON.ТипТекущегоЗначения;
Если TипJSON = ТипЗначенияJSON.Число ИЛИ TипJSON = ТипЗначенияJSON.Строка ИЛИ TипJSON = ТипЗначенияJSON.Булево ИЛИ TипJSON = ТипЗначенияJSON.Null Тогда
// Обработать значение
Значение = ЧтениеJSON.ТекущееЗначение;
ИначеЕсли ТипJSON = ТипЗначенияJSON.Комментарий Тогда
// Обработать комментарий
Комментарий = ЧтениеJSON.ТекущееЗначение;
ИначеЕсли TипJSON = ТипЗначенияJSON.ИмяСвойства Тогда
// Обработать имя свойства
ИмяСвойства = ЧтениеJSON.ТекущееЗначение;
ИначеЕсли TипJSON = ТипЗначенияJSON.НачалоМассива ИЛИ TипJSON = ТипЗначенияJSON.КонецМассива ИЛИ TипJSON = ТипЗначенияJSON.НачалоОбъекта ИЛИ TипJSON = ТипЗначенияJSON.КонецОбъекта ИЛИ TипJSON = ТипЗначенияJSON.Ничего Тогда
// Обработать начало/коней массива/объекта или отсутствие данных, // ТекущееЗначение читать не нужно.
КонеиЕсли;
КокецЦикла;
ЧтениеJSON.Закрыть();
// При записи JSON вы самостоятельно формируете его структуру. Чтобы «подстраховать» вас от ошибок, объект ЗаписьJSON автоматически проверяет правильность записываемой структуры.
// Для увеличения скорости работы эту проверку можно отключить. В примере ниже это строка:
ЗаписьJSON.ПроверятьСтруктуру = Ложь;
// Также при записи вы можете управлять некоторыми параметрами формируемого текста, например использованием двойных кавычек, переносом строк, символами отступа и экранированием символов.
// В примере ниже для форматирования текста используется символ табуляции:
ПараметрыЗаписиJSON = Новый ПараметрыЗаписиJSON( , Символы.Таб) ;
ЗаписьJSON.ОткрытьФайл("ИмяФайла", , , ПараметрыЗаписиJSON);
// Потоковая запись JSON может выглядеть следующим образом. Записывается массив из четырёх элементов. Три из них примитивного типа, а четвёртый элемент - это объект с двумя свойствами:
// Пример записи JSON. ЗаписьJSON = Новый ЗаписьJSON;
// Для увеличения скорости работы можно отключить автоматическую проверку // правильности структуры записываемого документа JSON. ЗаписьиЗСЖ.ПроверятьСтруктуру = Ложь;
// Для красоты результирующего текста можно увеличить "лесенку".
// Стандартный отступ - 1 пробел.
ПараметрыЗаписиJSON = Новый ПараметрыЗаписиJSON( , Символы.Таб);
// Либо открыть файл, в который будет выполнена запись,
// либо указать, что запись будет выполнена в строку, которую вернет метод Закрыть().
ЗаписьJSON.ОткрытьФайл("ИмяФайла", , , ПараметрыЗаписиJSON);
//ЗаписьJSON.УстановитьСтроку(ПараметрыЗаписиJSON);
// Записать массив.
ЗаписьJSON.ЗаписатьНачалоОбъекта();
ЗаписьJSON.ЗаписатьИмяСвойства("СвойствоТипаМассив");
ЗаписьJSON.ЗаписатьНачалоМассива();
// Первый элемент массива - Строка. ЗаписьJSON.ЗаписатьЗначение("Значение строка");
// Второй элемент массива - Число. ЗаписьJSON.ЗаписатьЗначение(12.345, Истина);
// Третий элемент массива - Булево. ЗаписьJSON-ЗаписатьЗначение(Истина);
// Четвертый элемент массива - объект с двумя свойствами. ЗаписьJSON.ЗаписатьНачалоОбъекта();
// Первое свойство объекта - Строка
ЗаписьJSON.ЗаписатьИмяСвойства("СвойствоТипаСтрока");
ЗаписьJSON.ЗаписатьЗначение("Значение строка");
// Второе свойство объекта - Неопределено
ЗаписьJSON.ЗаписатьИмяСвойства("СвойствоТипаНеопределено");
ЗаписьJSON.ЗаписатьЗначение(Неопределено);
ЗаписьJSON.ЗаписатьКонецОбъекта();
Запись JSON. ЗаписатьКонецМассива () ;
ЗаписьJSON.ЗаписатьКонецОбъекта();
ЗаписьJSON.Закрыть();
//CTpoKaJSON = ЗаписьJSON.Закрыть(); Результат такой записи:
Код 1C v 8.х
{
"СвойствоТипаМассив": [
"Значение строка",
1.2345E1,
true,
{
"СвойствоТипаСтрока": "Значение строка",
"СвойствоТипаНеопределено": null
}
]
} Сериализация примитивных типов и коллекций в JSON
Вторая группа средств работы с JSON хороша тем, что избавляет вас от рутинной работы по чтению/записи каждого отдельного значения или свойства. При чтении документы JSON отображаются в фиксированный набор типов платформы: Строка, Число, Булево, Неопределено, Массив, ФиксированныйМассив, Структура, ФиксированнаяСтруктура, Соответствие, Дата. Соответственно, в обратную сторону, композиция объектов этих типов позволяет сформировать в памяти и быстро записать в файл структуру JSON. Таким образом, чтение и запись небольшого объема JSON заранее известной структуры можно производить немногими строчками кода.
Основное назначение этих средств мы видим в обмене информацией с внешними системами, чтении конфигурационных файлов в формате JSON.
Сериализацию вы можете выполнять с помощью методов глобального контекста ПрочитатьJSON() и ЗаписатьJSON(). Они работают в связке с объектами ЧтениеJSON и ЗаписьJSON.
В качестве примера десериализации JSON можно рассмотреть чтение массива из двух объектов:
Код 1C v 8.3 // В качестве примера десериализации JSON можно рассмотреть чтение массива из двух объектов:
[
{
"имя": "Anton",
"фамилия": "Иванов",
"возраст": 25
},
{
"имя": "Ирина",
"фамилия": "Иванова",
"возраст": 20
}
]
// Код 1С:Предприятия, выполняющий десериализацию, может выглядеть следующим образом:
// Пример чтения JSON.
ЧтениеJSON = Новый ЧтениеJSON();
ЧтениеJSON.ОткрытьФайл("ИмяФайла");
Сотрудники = ПрочитатьJSON(ЧтениеJSON);
ЧтениеJSON.Закрыть();
Для каждого Сотрудник из Сотрудники Цикл
// Обработать данные сотрудника.
ИмяСотрудника = Сотрудник.имя; ФамилияСотрудника = Сотрудник.фамилия; ВозрастСотрудника = Сотрудник.возраст;
КонецЦикла;
// А пример сериализации (записи) в JSON может выглядеть так:
// Пример записи JSON
Структура = Новый Структура;
Вставить("Фамилия","Иванов");
Зставить("Имя", "Иван");
Вставить("Отчество", "Иванович");
Зставить("Возраст", 40) ;
Зставить("Женат", Истина);
Телефоны = Новый Массив;
Телефоны.Добавить("8-999-999-99-90") ;
Телефоны.Добавить("8-999-999-99-91") ;
Структура.Вставить("Телефоны", Телефены);
ЗаписьJSON = Новый ЗаписьJSON;
ЗаписьJSON.ОткрытьФайл("ИмяФайла", , , Новый ПapaмeтpыЗaпиcиJS0N( , Символы.Таб) ) ;
ЗаписатьJSON(ЗаписьJSON, Структура);
ЗаписьJSON.Закрыть();
// Результат записи:
{
"Фамилия": "Иванов",
"Имя": "Иван",
"Отчество": "Иванович",
"Возраст": 40,
"Женат": true,
"Телефоны": [
"8-999-999-99-90",
"8-999-999-99-91"
]
} Подробнее вы можете посмотреть здесь
В платформе с версии 8.3.7: Полностью автоматизировали работу с JSON и реализовали в платформе третью группу средств. Они позволяют сериализовать в JSON прикладные типы 1С:Предприятия: ссылки, объекты, наборы записей и вообще любые типы, для которых поддерживается XDTO сериализация. Конечно же, мы обеспечили и обратную операцию - десериализацию. Зачем это нужно!?
Прежде всего, и в основном, XDTO сериализацию в JSON мы рекомендуем использовать при обмене данными между двумя прикладными решениями 1С:Предприятия. По сравнению с XML формат JSON более компактный, сериализация/десериализация в/из JSON выполняется быстрее. Кроме этого мы предприняли дополнительные меры для того, чтобы сократить объём передаваемых данных.
Кроме обмена между приложениями 1С:Предприятия этот механизм можно использовать и для обмена с внешними системами, готовыми принимать типы данных 1С:Предприятия. Например, XDTO сериализацию в JSON можно использовать для организации собственного HTTP интерфейса прикладного решения. Сервис на платформе 1С:Предприятия будет формировать ответ в памяти в виде строки JSON. А затем передавать её при помощи объекта HTTPСервисОтвет. Реализованный нами механизм сериализации полностью соответствует стандарту JSON. Поэтому внешняя система не должна испытывать каких-либо трудностей с десериализацией.
Использование XDTO сериализации в JSON для других задач видится нам маловероятным. Потому что если внешняя система не готова работать с прикладными типами 1С:Предприятия, то зачем их ей передавать? А если предполагается обмениваться только примитивными типами и коллекциями, то для этой задачи хорошо подходят методы ПрочитатьJSON() и ЗаписатьJSON(). Подробнее здесь
ДО платформы версии 8.3.6, т.е. 8.3.5 и ниже: На HelpF уже есть статья где описан пример: Работа с форматом JSON в 1С но не приведены функции, вот они:
Код 1C v 8.х Функция ПреобразоватьвСистему(Число10,система) Экспорт
Если система > 36 или система < 2 тогда
Сообщить("Выбранная система исчисления не поддерживается");
Возврат -1;
КонецЕсли;
СтрокаЗначений = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
СтрокаСистема = "";
Пока Число10 > 0 цикл
РезДеления = Число10/система;
ЧислоСистема = цел(РезДеления);
остатокОтДеления = Число10 - система*(ЧислоСистема);
СтрокаСистема = сред(СтрокаЗначений,остатокОтДеления+1,1)+ СтрокаСистема;
Число10 = ?(ЧислоСистема=0,0,РезДеления);
КонецЦикла;
Нечётное = стрДлина(СтрокаСистема) - цел(стрДлина(СтрокаСистема)/2)*2;
Если Нечётное тогда
СтрокаСистема = "0"+СтрокаСистема;
КонецЕсли;
Возврат СтрокаСистема;
КонецФункции
Функция URLEncode(стр) Экспорт
Длина=СтрДлина(Стр);
Итог="";
Для Н=1 По Длина Цикл
Знак=Сред(Стр,Н,1);
Код=КодСимвола(Знак);
если ((Знак>="a")и(Знак<="z")) или
((Знак>="A")и(Знак<="Z")) или
((Знак>="0")и(Знак<="9")) тогда
Итог=Итог+Знак;
Иначе
Если (Код>=КодСимвола("А"))И(Код<=КодСимвола("п")) Тогда
Итог=Итог+"%"+ПреобразоватьвСистему(208,16)+"%"+ПреобразоватьвСистему(144+Код-КодСимвола("А"),16);
ИначеЕсли (Код>=КодСимвола("р"))И(Код<=КодСимвола("я")) Тогда
Итог=Итог+"%"+ПреобразоватьвСистему(209,16)+"%"+ПреобразоватьвСистему(128+Код-КодСимвола("р"),16);
ИначеЕсли (Знак="ё") Тогда
Итог=Итог+"%"+ПреобразоватьвСистему(209,16)+"%"+ПреобразоватьвСистему(145,16);
ИначеЕсли (Знак="Ё") Тогда
Итог=Итог+"%"+ПреобразоватьвСистему(208,16)+"%"+ПреобразоватьвСистему(129,16);
Иначе
Итог=Итог+"%"+ПреобразоватьвСистему(Код,16);
КонецЕсли;
КонецЕсли;
КонецЦикла;
Возврат Итог;
КонецФункции
Функция СформироватьСтрокуJSONИзМассива(Объект)
СтрокаJSON = "[";
Для каждого Элемент Из Объект Цикл
Если ТипЗнч(Элемент) = Тип("Строка") Тогда
СтрокаJSON = СтрокаJSON + """" + Элемент + """";
ИначеЕсли ТипЗнч(Элемент) = Тип("Число") Тогда
СтрокаJSON = СтрокаJSON + СтрЗаменить(Строка(Элемент), Символы.НПП, "");
ИначеЕсли ТипЗнч(Элемент) = Тип("Булево") Тогда
СтрокаJSON = СтрокаJSON + Формат(Элемент, "БЛ=false; БИ=true");
ИначеЕсли ТипЗнч(Элемент) = Тип("Дата") Тогда
СтрокаJSON = СтрокаJSON + Формат(Элемент - Дата(1970,1,1,1,0,0), "ЧГ=0");
ИначеЕсли ТипЗнч(Элемент) = Тип("Массив") Тогда
СтрокаJSON = СтрокаJSON + СформироватьСтрокуJSON(Элемент);
ИначеЕсли ТипЗнч(Элемент) = Тип("Структура") Тогда
СтрокаJSON = СтрокаJSON + СформироватьСтрокуJSON(Элемент);
ИначеЕсли ТипЗнч(Элемент) = Тип("ТаблицаЗначений") Тогда
СтрокаJSON = СтрокаJSON + СформироватьСтрокуJSON(Элемент);
Иначе
СтрокаJSON = СтрокаJSON + """" + URLEncode(Строка(Элемент)) + """";
КонецЕсли;
СтрокаJSON = СтрокаJSON + ",";
КонецЦикла;
Если Прав(СтрокаJSON, 1) = "," Тогда
СтрокаJSON = Лев(СтрокаJSON, СтрДлина(СтрокаJSON)-1);
КонецЕсли;
Возврат СтрокаJSON + "]";
КонецФункции
Функция СформироватьСтрокуJSONИзСтруктуры(Объект)
СтрокаJSON = "{";
Для каждого Элемент Из Объект Цикл
Если Элемент.Значение = "" Тогда
Продолжить;
КонецЕсли;
СтрокаJSON = СтрокаJSON + """" + Элемент.Ключ + """" + ":";
Если ТипЗнч(Элемент.Значение) = Тип("Строка") Тогда
СтрокаJSON = СтрокаJSON + """" + Элемент.Значение + """";
ИначеЕсли ТипЗнч(Элемент.Значение) = Тип("Число") Тогда
СтрокаJSON = СтрокаJSON + СтрЗаменить(Строка(Элемент.Значение), Символы.НПП, "");
ИначеЕсли ТипЗнч(Элемент.Значение) = Тип("Булево") Тогда
СтрокаJSON = СтрокаJSON + Формат(Элемент.Значение, "БЛ=false; БИ=true");
ИначеЕсли ТипЗнч(Элемент.Значение) = Тип("Дата") Тогда
СтрокаJSON = СтрокаJSON + Формат(Элемент.Значение - Дата(1970,1,1,1,0,0), "ЧГ=0");
ИначеЕсли ТипЗнч(Элемент.Значение) = Тип("Массив") Тогда
СтрокаJSON = СтрокаJSON + СформироватьСтрокуJSON(Элемент.Значение);
ИначеЕсли ТипЗнч(Элемент.Значение) = Тип("Структура") Тогда
СтрокаJSON = СтрокаJSON + СформироватьСтрокуJSON(Элемент.Значение);
ИначеЕсли ТипЗнч(Элемент.Значение) = Тип("ТаблицаЗначений") Тогда
СтрокаJSON = СтрокаJSON + СформироватьСтрокуJSON(Элемент.Значение);
Иначе
СтрокаJSON = СтрокаJSON + """" + URLEncode(Строка(Элемент.Значение)) + """";
КонецЕсли;
СтрокаJSON = СтрокаJSON + ",";
КонецЦикла;
Если Прав(СтрокаJSON, 1) = "," Тогда
СтрокаJSON = Лев(СтрокаJSON, СтрДлина(СтрокаJSON)-1);
КонецЕсли;
Возврат СтрокаJSON + "}";
КонецФункции
Функция СформироватьСтрокуJSON(Объект) Экспорт
СтрокаJSON = "";
Если ТипЗнч(Объект) = Тип("Массив") Тогда
СтрокаJSON = СформироватьСтрокуJSONИзМассива(Объект);
ИначеЕсли ТипЗнч(Объект) = Тип("Структура") Тогда
СтрокаJSON = СформироватьСтрокуJSONИзСтруктуры(Объект);
ИначеЕсли ТипЗнч(Объект) = Тип("ТаблицаЗначений") Тогда
СоставСтруктуры = "";
Для каждого Колонка Из Объект.Колонки Цикл
СоставСтруктуры = СоставСтруктуры + ?(ЗначениеЗаполнено(СоставСтруктуры), ",", "") + Колонка.Имя;
КонецЦикла;
МассивСтрок = Новый Массив;
Для каждого Строка Из Объект Цикл
СтруктураКолонок = Новый Структура(СоставСтруктуры);
ЗаполнитьЗначенияСвойств(СтруктураКолонок, Строка);
МассивСтрок.Добавить(СтруктураКолонок);
КонецЦикла;
СтрокаJSON = СформироватьСтрокуJSONИзМассива(МассивСтрок);
КонецЕсли;
Возврат СтрокаJSON;
КонецФункции
Процедура ЗаполнитьДанныеИзОтветаJSON(Результат, ТекстJSON, ТипДанных)
ТекстJSON = СокрЛП(Сред(ТекстJSON, 2));
НомерЗначения = 0;
Пока ТекстJSON <> "" Цикл
ПервыйСимвол = Лев(ТекстJSON, 1);
Если ПервыйСимвол = "{" Тогда
Значение = Новый Структура;
ЗаполнитьДанныеИзОтветаJSON(Значение, ТекстJSON, "Структура");
Если ТипДанных = "Структура" Тогда
Результат.Вставить("Значение" + ?(НомерЗначения = 0, "", НомерЗначения), Значение);
НомерЗначения = НомерЗначения + 1;
ИначеЕсли ТипДанных = "Массив" Тогда
Результат.Добавить(Значение);
КонецЕсли;
ИначеЕсли ПервыйСимвол = "[" Тогда
Значение = Новый Массив;
ЗаполнитьДанныеИзОтветаJSON(Значение, ТекстJSON, "Массив");
Если ТипДанных = "Структура" Тогда
Результат.Вставить("Значение" + ?(НомерЗначения = 0, "", НомерЗначения), Значение);
НомерЗначения = НомерЗначения + 1;
Иначе
Результат.Добавить(Значение);
КонецЕсли;
ИначеЕсли ПервыйСимвол = "}" И ТипДанных = "Структура" Тогда
ТекстJSON = СокрЛП(Сред(ТекстJSON, 2));
Если Лев(ТекстJSON, 1) = "," Тогда
ТекстJSON = СокрЛП(Сред(ТекстJSON, 2));
КонецЕсли;
Возврат;
ИначеЕсли ПервыйСимвол = "]" И ТипДанных = "Массив" Тогда
ТекстJSON = СокрЛП(Сред(ТекстJSON, 2));
Если Лев(ТекстJSON, 1) = "," Тогда
ТекстJSON = СокрЛП(Сред(ТекстJSON, 2));
КонецЕсли;
Возврат;
Иначе
Если ТипДанных = "Структура" Тогда
Поз = Найти(ТекстJSON, ":");
Если Поз = 0 Тогда
Прервать;
КонецЕсли;
ИмяЗначения = СокрЛП(Лев(ТекстJSON, Поз-1));
ТекстJSON = СокрЛП(Сред(ТекстJSON, Поз+1));
Если Лев(ТекстJSON, 1) = "{" Тогда
Значение = Новый Структура;
ЗаполнитьДанныеИзОтветаJSON(Значение, ТекстJSON, "Структура");
ИначеЕсли Лев(ТекстJSON, 1) = "[" Тогда
Значение = Новый Массив;
ЗаполнитьДанныеИзОтветаJSON(Значение, ТекстJSON, "Массив");
Иначе
Поз = 0;
Для Сч = 1 По СтрДлина(ТекстJSON) Цикл
Символ = Сред(ТекстJSON, Сч, 1);
Если Символ = "," ИЛИ Символ = "]" ИЛИ Символ = "}" Тогда
Поз = Сч;
Прервать;
КонецЕсли;
КонецЦикла;
Если Поз = 0 Тогда
Значение = ТекстJSON;
ТекстJSON = "";
Иначе
Значение = Лев(ТекстJSON, Поз-1);
ТекстJSON = СокрЛП(Сред(ТекстJSON, Поз + ?(Сред(ТекстJSON, Поз, 1) = ",", 1, 0)));
КонецЕсли;
Значение = СокрЛП(Значение);
КонецЕсли;
Результат.Вставить(ИмяЗначения, Значение);
ИначеЕсли ТипДанных = "Массив" Тогда
Поз = 0;
Для Сч = 1 По СтрДлина(ТекстJSON) Цикл
Символ = Сред(ТекстJSON, Сч, 1);
Если Символ = "," ИЛИ Символ = "]" ИЛИ Символ = "}" Тогда
Поз = Сч;
Прервать;
КонецЕсли;
КонецЦикла;
Если Поз = 0 Тогда
Значение = ТекстJSON;
ТекстJSON = "";
Иначе
Значение = Лев(ТекстJSON, Поз-1);
ТекстJSON = СокрЛП(Сред(ТекстJSON, Поз + ?(Сред(ТекстJSON, Поз, 1) = ",", 1, 0)));
КонецЕсли;
Значение = СокрЛП(Значение);
Результат.Добавить(Значение);
КонецЕсли;
КонецЕсли;
КонецЦикла;
КонецПроцедуры
Функция ЗаполнитьСтруктуруИзОтветаJSON(Знач ТекстJSON) Экспорт
Результат = Новый Структура;
ТекстJSON = СтрЗаменить(ТекстJSON, "\""", """");
ТекстJSON = СтрЗаменить(ТекстJSON, """", "");
Если Лев(ТекстJSON, 1) = "{" Тогда
ЗаполнитьДанныеИзОтветаJSON(Результат, ТекстJSON, "Структура");
ИначеЕсли Лев(ТекстJSON, 1) = "[" Тогда
МассивДанных = Новый Массив;
ЗаполнитьДанныеИзОтветаJSON(МассивДанных, ТекстJSON, "Массив");
Результат.Вставить("Значение", МассивДанных);
КонецЕсли;
Возврат Результат;
КонецФункции Примеры их использования:
Код 1C v 8.х ////////////////////////////////////////////////////////
// преобразование простой структуры
Данные = Новый Структура("server,user,hash",
10234, 3745, "8263ad83ce");
СтрокаJSON = СформироватьСтрокуJSONИзСтруктуры(Данные);
// результатом будет строка
// {"server":"10234","user":"3745","hash":"8263ad83ce"}
////////////////////////////////////////////////////////
// преобразования массива
Данные = Новый Массив;
Данные.Добавить("Nissan");
Данные.Добавить("Ford");
Данные.Добавить("Audi");
СтрокаJSON = СформироватьСтрокуJSONИзСтруктуры(Данные);
// результатом будет строка
// ["Nissan","Ford","Audi"]
////////////////////////////////////////////////////////
// преобразование сложной структуры
Данные = Новый Структура;
Данные.Добавить("server", 10234);
Данные.Добавить("users", Новый Массив);
Данные.Добавить("hash", "8263ad83ce");
Данные.users.Добавить(3745);
Данные.users.Добавить(7462);
Данные.users.Добавить(2374);
СтрокаJSON = СформироватьСтрокуJSONИзСтруктуры(Данные);
// результатом будет строка
// {"server":"10234","users":["3745","7462","2374"],"hash":"8263ad83ce"}
////////////////////////////////////////////////////////
// еще один пример массива
Данные = Новый Структура;
Данные.Вставить("server", 10234);
Данные.Вставить("users", Новый Массив);
Данные.users.Добавить(Новый Структура("id,name", 3745, "Jack"));
Данные.users.Добавить(Новый Структура("id,name", 7246, "Nick"));
СтрокаJSON = СформироватьСтрокуJSONИзСтруктуры(Данные);
// результатом будет строка
// {"server":"10234","users":[{"id":"3745","name":"Jack"},{"id":"7462","name":"Nick"}>
////////////////////////////////////////////////////////
// преобразование таблицы значений
ТаблПользователей = Новый ТаблицаЗначений;
ТаблПользователей.Колонки.Добавить("id");
ТаблПользователей.Колонки.Добавить("name");
НоваяСтрока = ТаблПользователей.Добавить();
НоваяСтрока.id = 3276;
НоваяСтрока.name = "Jack";
НоваяСтрока = ТаблПользователей.Добавить();
НоваяСтрока.id = 3276;
НоваяСтрока.name = "Nick";
СтрокаJSON = СформироватьСтрокуJSONИзСтруктуры(Данные);
// результатом будет строка
// [{"id":"3745","name":"Jack"},{"id":"7462","name":"Nick"}] Пишите комменты
Категория:
Работа с Интернет, Почтой (Mail), FTP СКД Внешний источник данных, грузим из ТЗ и далее получаем остатки на каждый документ Очень часто бывают ситуации, когда необходимо сделать отчет СКД на сложном запросе, который используюет в себе вложенные запросы и объединения внутренние и полные и т.д. - в результате в консоли этот запрос формируется верно, а в скд половина полей пустые! Связано это с особенностью СКД в объединении внутренних данных, а так же не стоит забывать что в СКД наборы данных связываются как левое соединение...
Решения возможны следующие:
Изменить запрос в СКД Сформировать запрос обычным способом и подставить эти данные в СКД как внешние Рассмотрим последний вариант:
Внешний источник данных, грузим из ТЗ Для вывода отчета я использую шаблон All4CF.ru_Template_SKD_v4.1 в нем уже реализованы почти все необходимые функции и работает в Обычных и УП формах.
В модуле объекта уже есть функция
Код 1C v 8.2 УП Функция ПолучитьТаблицуВнешнегоНабораДанных()
Возврат Новый ТаблицаЗначений;
КонецФункции // ПолучитьТаблицуВнешнегоНабораДанных() установим в ней наш запрос, получается примерно так:
Код 1C v 8.2 УП // В данной функции можно сформировать таблицу внешнего набора данных для СКД
//
// Функция должна возвращать таблицу данных (например таблицу значений)
//
Функция ПолучитьТаблицуВнешнегоНабораДанных()
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ РАЗРЕШЕННЫЕ РАЗЛИЧНЫЕ
| ВложенныйЗапрос.Регистратор КАК ДокРеал,
| ВложенныйЗапрос.Регистратор.Доставка КАК ДокДоставка
|ПОМЕСТИТЬ ОплаченнаяРеализация
|ИЗ
| (ВЫБРАТЬ
| ВзаиморасчетыСКонтрагентамиПоДокументамРасчетовОбороты.Регистратор КАК Регистратор
/////// Огромный запрос .......
| СГРУППИРОВАТЬ ПО
| ДоставкаПромежуточнаяНакладная.Ссылка,
| ДоставкаПромежуточнаяНакладная.Ссылка.Счет,
| ДоставкаПромежуточнаяНакладная.Ссылка.ВыставленоКлиенту,
| ИздержкиРаспределенныеНеНаОП.РаспределеннаяИздержка,
| ДоставкаПромежуточнаяНакладная.Ссылка.СтоимостьПрайс + ДоставкаПромежуточнаяНакладная.Ссылка.ЗатратыПриДоставке) КАК ДанныеПоДоставкам
| ПО ДанныеПоРеализации.ДокументПродажи.Доставка = ДанныеПоДоставкам.ДокДоставка";
Запрос.УстановитьПараметр("КонецПериода", НастройкаПериода.ДатаОкончания);
Запрос.УстановитьПараметр("НачалоПериода", НастройкаПериода.ДатаНачала);
Запрос.УстановитьПараметр("НачалоПериодаМинусГод", НастройкаПериода.ДатаНачала-(86400*365));
Результат = Запрос.Выполнить();
Выборка = Результат.Выгрузить();
Возврат Выборка;
КонецФункции // ПолучитьТаблицуВнешнегоНабораДанных() Ниже в коде происходит установка внешних данных из нашей ТЗ с именем ТаблицаВнешнегоНабораДанных
Код 1C v 8.2 УП // при необходимости вставим внешние наборы данных в СКД
ВнешниеНаборыДанных = Новый Структура;
ТаблицаВнешнегоНабораДанных = ПолучитьТаблицуВнешнегоНабораДанных();
ВнешниеНаборыДанных.Вставить("ТаблицаВнешнегоНабораДанных",ТаблицаВнешнегоНабораДанных);
ПроцессорКомпоновкиДанных.Инициализировать(МакетКомпоновкиДанных,ВнешниеНаборыДанных,ДанныеРасшифровки);
ВывестиРезультатКомпоновкиСАвтофиксациейСтрок(ТабличныйДокумент, ПроцессорКомпоновкиДанных, ДанныеРасшифровки.Элементы,,,КоличествоФиксируемыхСтолбцов); В самой компоновке добавляем набор Объект с именем ТаблицаВнешнегоНабораДанных и перечисляем поля, которые будут использоваться в отчете:
Как я уже говорил выше, далее нам необходимо получить остатки взаиморасчетов на дату документа:
Получение остатков на документ в СКД Набор данных Запрос - назвали его Остатки:
Теперь установим связи Запроса и Объекта
Остатки нужно получать на дату документа и по контрагенту
Далее, если нужно, задайте вычисляемые поля, ресурсы, параметры и Настройте Список вывода...
Пример результата отчета:
Категория:
Схема Компоновки Данных Как изменять записи регистра накопления? Основной шаблон такой:
Код 1C v 8.х Набор = РегистрыНакопления.ВашРегистр.СоздатьНаборЗаписей();
Набор.Отбор.<НазваниеОтбора>.Установить(<ЗначениеОтбора>);
Набор.Прочитать();
Для Каждого ТекДвижение Из Набор Цикл
//Делаете с записями регистра то - что вам хочется
КонецЦикла;
Набор.Записать(); Реальный пример:
Код 1C v 8.х Процедура МодификацияЗаписейРегистраНакопления()
ВыбДок = Документы.ПоступлениеТоваровУслуг.Выбрать();
Если ВыбДок.Следующий() Тогда
Набор = РегистрыНакопления.НДСПредъявленный.СоздатьНаборЗаписей();
Набор.Отбор.Регистратор.Установить(ВыбДок.Ссылка);
Набор.Прочитать();
// Изменение существующих записей
Для Каждого Движение Из Набор Цикл
Движение.НДС = 0;
КонецЦикла;
// Добавление новых записей, если вдруг необходимо
Движение = Набор.ДобавитьРасход();
Движение.Сумма = 100;
Движение.Период = ТекущаяДата();
Движение = Набор.Добавить();
Движение.ВидДвижения = ВидДвиженияНакопления.Приход;
Движение.Сумма = 300;
Движение.Период = ТекущаяДата();
// удаление существующих записей если надо
Набор.Удалить(0);
Набор.Записать(Истина);
КонецЕсли;
КонецПроцедуры
Категория:
Регистры накопления Система оповещений Пользователей (универсальная) Для одного проекта пришлось сделать простую систему оповещений!
Она состоит из:
Общая форма
Общий модуль
Регистр Сведений
Общая Форма
На ней поле HTML Документа и Кнопка Ознакомлен (подтверждение что пользователь это видел)
Код 1C v 8.х Перем ТекДата, ТипСсылки, ТекСсылка;
Процедура ПриОткрытии()
ТекДата = Дата;
ЭлементыФормы.ПолеHTMLДокумента.УстановитьТекст(Текст);
КонецПроцедуры
Процедура ОзнакомленНажатие(Элемент)
Если ЗначениеЗаполнено(ТекДата) Тогда
НаборЗаписей = РегистрыСведений.МЕ_Оповещения.СоздатьНаборЗаписей();
НаборЗаписей.Отбор.Получатель.Установить(Пользователь);
НаборЗаписей.Отбор.Период.Установить(ТекДата);
НаборЗаписей.Прочитать();
НовыйНомер = НаборЗаписей[0];
НовыйНомер.ДатаОзнакомления = ТекущаяДата();
НаборЗаписей.Записать();
Если ЗначениеЗаполнено(НовыйНомер.ТипСсылки) Тогда
ТекСсылка = НовыйНомер.Ссылка;
ТипСсылки = НовыйНомер.ТипСсылки;
КонецЕсли;
КонецЕсли;
Парам = Новый Структура;
Парам.Вставить("ТипСсылки", ТипСсылки);
Парам.Вставить("ТекСсылка", ТекСсылка);
ЭтаФорма.Закрыть(Парам);
КонецПроцедуры
Процедура ПолеHTMLДокументаonclick(Элемент, pEvtObj)
// Отказ от стандартной обработки клика.
pEvtObj.returnValue = Ложь;
Если ВРег(pEvtObj.srcElement.tagName) = "A" Тогда
СсылкаТекст = Сред(pEvtObj.srcElement.href, 4);
Ссылка = ЗначениеИзСтрокиВнутр(СсылкаТекст);
Если Ссылка.Пустая()
Или Ссылка.ПолучитьОбъект() = Неопределено Тогда
Предупреждение("Ошибка открытия объекта.",, "Ошибка");
Возврат;
Иначе
ОткрытьЗначение(Ссылка);
КонецЕсли;
КонецЕсли;
КонецПроцедуры
В общем Модуле:
Код 1C v 8.х Процедура СоздатьОповещение(Получатель,ТекстОповещения, ТипСсылки=Неопределено, Ссылка=Неопределено) Экспорт
НаборЗаписей = РегистрыСведений.МЕ_Оповещения.СоздатьНаборЗаписей();
НовЗапись = НаборЗаписей.Добавить();
НовЗапись.Период = ТекущаяДата();
НовЗапись.Получатель = Получатель;
НовЗапись.ТекстОповещения = ТекстОповещения;
Если НЕ ТипСсылки=Неопределено Тогда
НовЗапись.ТипСсылки = ТипСсылки;
КонецЕсли;
Если НЕ Ссылка=Неопределено Тогда
НовЗапись.Ссылка = Ссылка;
КонецЕсли;
НаборЗаписей.Записать(Ложь);
КонецПроцедуры // СоздатьОповещение()
Процедура ПоказатьОповещение(ТекстОповещения)
формОповещ = ПолучитьОбщуюФорму("МЕ_Оповещения");
формОповещ.текст=ТекстОповещения;
Если Не формОповещ.Открыта() Тогда
формОповещ.ОткрытьМодально();
КонецЕсли;
КонецПроцедуры
Регистр сведений (для хранения сообщений):
Думаю что все поля понятны из названия, только ТипСсылки - Строка 35
Проверка непрочитанных сообщений и вызов окна:
Код 1C v 8.х //Проверим Оповещения для пользователя
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| МЕ_Оповещения.Период КАК Период,
| МЕ_Оповещения.Получатель,
| МЕ_Оповещения.ТекстОповещения,
| МЕ_Оповещения.ДатаОзнакомления
|ИЗ
| РегистрСведений.МЕ_Оповещения КАК МЕ_Оповещения
|ГДЕ
| МЕ_Оповещения.ДатаОзнакомления = &ДатаОзнакомления
| И МЕ_Оповещения.Получатель = &Получатель
|
|УПОРЯДОЧИТЬ ПО
| Период";
Запрос.УстановитьПараметр("ДатаОзнакомления", Дата("01.01.0001 0:00:00"));
Запрос.УстановитьПараметр("Получатель", ПараметрыСеанса.ТекущийПользователь);
Результат = Запрос.Выполнить().Выбрать();
Пока Результат.Следующий() Цикл
формОповещ = ПолучитьОбщуюФорму("МЕ_Оповещения");
формОповещ.дата=Результат.период;
формОповещ.пользователь=Результат.Получатель;
формОповещ.текст=Результат.ТекстОповещения;
Если Не формОповещ.Открыта() Тогда
Структ = формОповещ.ОткрытьМодально();
Если Структ = Неопределено Тогда
// Ничего
Иначе
Если СокрЛП(Структ.ТипСсылки) = "ОбработкаЦен" Тогда
Обр = Обработки.ОбработкаЦен.Создать();
Обр.Счет = Структ.ТекСсылка;
Обр.ПолучитьФорму().Открыть();
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецЦикла;
Пример добавления сообщения:
Код 1C v 8.х МЕ_Оповещения.СоздатьОповещение(ТекДоговорКИзменению.Менеджер, "Ваш Договор №"+СокрЛП(ТекДоговорКИзменению.Номер)+
" - Отклонен!!! - "+ИмяПользователя()+"!"+Символы.ПС+" Исправьте его учитывая Комментарии и запустите на Согласование!", "", ТекДоговорКИзменению.Ссылка);
или
//Создадим оповещение с Передачей ссылки
Текст = "" + ПараметрыСеанса.ТекущийПользователь+": Необходимо Доработать цены:<br> <b>"+Счет.Ссылка+"</b>";
МЕ_Оповещения.СоздатьОповещение(СнабженецПоследнееИзменение, Текст, "ОбработкаЦен", Счет.Ссылка); Категория:
Полезные, Универсальные Функции Документ не регистрируется в последовательности, как зарегистрировать программно? Ранее я уже писал:
Что такое Последовательность Документов (в кратце и доступно)
В интернете полно вопросам по созданию новой последовательности документов и регистрации в ней документов, и так по порядку:
1. Создали новую последовательность
2. На закладке Использование указали регистрируемые документы и регистры движений:
3.
Для автоматического регистрирования документов - в свойствах документа должно быть в разделе
Данные , поле
Заполнение последовательности - автоматически
4. Если указано: Не заполнять автоматически
Документы в последовательности не регистрируются сами, для этого в обработку проведения надо добавить код:
Код 1C v 8.х НаборЗаписей = Последовательности.ПартионныйУчет.СоздатьНаборЗаписей();
НаборЗаписей.Отбор.Регистратор.Установить(ДокументСсылка);
НоваяЗапись = НаборЗаписей.Добавить();
НоваяЗапись.Регистратор = ДокументСсылка;
НоваяЗапись.Период = ДокументСсылка.Дата;
НаборЗаписей.Записать();
Если у последовательности есть Измерение, например Организация, то код:
Код 1C v 8.х НаборЗаписей = Последовательности.ПартионныйУчет.СоздатьНаборЗаписей();
НаборЗаписей.Отбор.Регистратор.Установить(ДокументСсылка);
НоваяЗапись = НаборЗаписей.Добавить();
НоваяЗапись.Организация = ДокументСсылка.Организация;
НоваяЗапись.Регистратор = ДокументСсылка;
НоваяЗапись.Период = ДокументСсылка.Дата;
НаборЗаписей.Записать(); Категория:
Документы Срез последних (остатки) на каждую дату Бывают ситуации, когда в запросе требуется получить остатки не на фиксированную дату (параметр - один на весь отчет), а на произвольную, (когда дата остатков в каждой строке своя).
Существует несколько способов получить нужные данные.
1.Непосредственно в запросе (через реальную таблицу регистра)
Способ подходит практически для любой ситуации, и поэтому наиболее универсален. Единственный, пожалуй, минус этого способа - если в отчете пользователю не требуется курс, то запрос быдет выбирать избыточные данные.
Вызов СрезПоследних() можно использовать только с передачей в него заранее готового значения даты, на которую требуется получить значения. Поэтому сабж делается через стыковку нескольких запросов - основной, к нему стыкуется запрос по регистру сведений с условием по дате и поиском записи с максимальной датой (периодом).
Код 1C v 8.х ВЫБРАТЬ
Таб1.СсылкаДок,
Таб1.ДатаДок,
Таб1.ВалютаДок,
Таб2.Курс
ИЗ
(ВЫБРАТЬ
ЗаказПокупателя.Ссылка КАК СсылкаДок,
ЗаказПокупателя.Дата КАК ДатаДок,
ЗаказПокупателя.ВалютаДокумента КАК ВалютаДок,
МАКСИМУМ(Валюты.Период) КАК ПериодДок
ИЗ
Документ.ЗаказПокупателя КАК ЗаказПокупателя
ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.КурсыВалют КАК Валюты
ПО Валюты.Период <= ЗаказПокупателя.Дата И
Валюты.Валюта = ЗаказПокупателя.ВалютаДокумента
СГРУППИРОВАТЬ ПО
ЗаказПокупателя.Ссылка) КАК Таб1
ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.КурсыВалют КАК Таб2
ПО Таб1.ПериодДок = Таб2.Период И Таб1.ВалютаДок = Таб2.Валюта
Для общего развития:
Что есть срез последних в платформе?
Код 1C v 8.х ВЫБРАТЬ
Рег.Период,
Рег.Измерение,
Рег.Ресурс
ИЗ
РегситрСведений.ПериодическийРегистр.СрезПоследних(&Дата) КАК Рег
В зависимости от периодичности регистра (по времени, по позизии регистратора) ВТ разворачивается в следующий запрос:
1. По времени (год, месяц, ... секунда)
Код 1C v 8.х ВЫБРАТЬ
Таблица3.Ресурс,
Таблица3.Измерение,
Таблица3.Период
ИЗ
(ВЫБРАТЬ
Таблица1.Измерение КАК Измерение,
МАКСИМУМ(Таблица1.Период) КАК Период
ИЗ
РегистрСведений.ПериодическийРегистр КАК Таблица1
ГДЕ
Таблица1.Период <= &Дата
СГРУППИРОВАТЬ ПО
Таблица1.Измерение) КАК Таблица2
ВНУТРЕННЕЕ СОЕДИНЕНИЕ РегистрСведений.ПериодическийРегистр КАК Таблица3
ПО Таблица2.Измерение= Таблица3.Измерение
И Таблица2.Период = Таблица3.Период
2. По позиции регистратора
В данном случае нужно еще раз обернуть выборку
Код 1C v 8.х ВЫБРАТЬ
Таблица5.Ресурс,
Таблица5.Измерение,
Таблица5.Период,
Таблица5.Регистратор
ИЗ
(ВЫБРАТЬ
МАКСИМУМ(Таблица3.Регистратор) КАК Регистратор,
Таблица3.Измерение
ИЗ
(ВЫБРАТЬ
Таблица1.Измерение КАК Измерение,
МАКСИМУМ(Таблица1.Период) КАК Период
ИЗ
РегистрСведений.ПериодическийРегистр КАК Таблица1
ГДЕ
Таблица1.Период <= &Дата
СГРУППИРОВАТЬ ПО
Таблица1.Измерение) КАК Таблица2
ВНУТРЕННЕЕ СОЕДИНЕНИЕ РегистрСведений.ПериодическийРегистр КАК Таблица3
ПО Таблица2.Измерение= Таблица3.Измерение
И Таблица2.Период = Таблица3.Период
СГРУППИРОВАТЬ ПО
Таблица3.Измерение) КАК Таблица4
ВНУТРЕННЕЕ СОЕДИНЕНИЕ РегистрСведений.ПериодическийРегистр КАК Таблица5
ПО Таблица4.Измерение = Таблица5.Измерение
И Таблица4.Регистратор = Таблица5.Регистратор
Все это можно увидеть посмотрев технологический журнал с включенным режимом протоколирования запросов
2.Система компоновки данных (передача набора значений одной таблицы в параметр виртуальной таблицы)
Данный способ подходит для отчетов. Из очевидных плюсов - если курс (или другие данные) не нужны для построения отчета, то СКД не будет их получать. Однако быстродействие такого отчета может оказаться и несколько ниже, чем в первом способе.
Для примера сделаем отчет - список заказов покупателей.
Для этого создадим набор данных "Документы" - запрос:
Код 1C v 8.х ВЫБРАТЬ
ЗаказПокупателя.Ссылка КАК ЗаказПокупателя,
ЗаказПокупателя.Дата КАК Дата,
ЗаказПокупателя.ВалютаДокумента КАК ВалютаДокумента,
ЗаказПокупателя.СуммаДокумента КАК СуммаДокумента
{ВЫБРАТЬ
ЗаказПокупателя.*,
Дата,
ВалютаДокумента.*,
СуммаДокумента}
ИЗ
Документ.ЗаказПокупателя КАК ЗаказПокупателя
{ГДЕ
ЗаказПокупателя.Ссылка.* КАК ЗаказПокупателя,
ЗаказПокупателя.СуммаДокумента}
Для того, чтобы потом успешно свзать наборы данных, в запрос необходимо включить поля "Дата" и "ВалютаДокумента". Чтобы они не появлялись в списке доступных полей, если это необходимо, их можно убрать, установив флажки ограничений в таблице "Поля" схемы компоновки. В остальном запрос вряд ли требует комментариев.
Для того, чтобы получить информацию о курсах валют, добавим второй набор данных-запрос, "Курсы валют":
Код 1C v 8.х ВЫБРАТЬ
&Дата КАК Дата,
КурсыВалютСрезПоследних.Валюта КАК Валюта,
КурсыВалютСрезПоследних.Курс КАК Курс,
КурсыВалютСрезПоследних.Кратность КАК Кратность
{ВЫБРАТЬ
Дата,
Валюта.*,
Курс,
Кратность}
ИЗ
РегистрСведений.КурсыВалют.СрезПоследних(&Дата, Валюта = &Валюта) КАК КурсыВалютСрезПоследних
{ГДЕ
КурсыВалютСрезПоследних.Курс,
КурсыВалютСрезПоследних.Кратность}
В этом запросе имеются 2 параметра: "Дата" и "Валюта". Эти параметры будут установлены СКД при соединении наборов. Кроме того, параметр "Дата" указан в выбранных полях - это нужно для соединения таблиц.
Для ненужный полей "Дата" и "Валюта" также устанавливаем флажки ограничений, чтобы они не появлялись в доступных полях.
Перейдем к соединению наборов. На странице "Связи наборов данных" добавим 2 связи:
1. Источник связи - набор "Документы", приемник - набор "Курсы валют". Выражение источник - "Дата", выражение приемник - "Дата", Параметр - "Дата"
2. Источник связи - набор "Документы", приемник - набор "Курсы валют". Выражение источник - "ВалютаДокумента", выражение приемник - "Валюта", Параметр - "Валюта"
Главное здесь - параметры связи. При соединении наборов данных, если указан параметр, СКД передает в подчиненный набор (в нашем случае - запрос "Курсы валют") параметры, указанные в соединении. Значениями параметров будут значения соответствующих полей набора-источника.
Перейдем к вычисляемым полям. Добавим вычисляемое поле "СуммаВВалютеУпрУчета". Выражение поля - "СуммаДокумента * Курс / Кратность".
Также укажем поля "СуммаДокумента" и "СуммаВВалютеУпрУчета" как ресурсы
Настроим отчет.
Добавим одну группировку "Детальные записи", в выбранных полях укажем "ЗаказПолкупателя", "Курс" и "Кратность". Добавим ресурсы "СуммаДокумента" и "СуммаВВалютеУпрУчета"
Можно формировать отчет
Категория:
Регистры накопления Получение данных для расчета и Расчет Собственно процесс расчета записей каждого поднабора состоит в получении всех необходимых данных для расчета каждой записи и вычислении значений ресурсов этой записи по формуле, определяемой способом расчета данной записи. Например, для расчета записи об окладе нужно будет получить данные графика этой записи, для расчета премии необходимо будет рассчитать базу и так далее.
Ниже приведен пример процедуры, осуществляющей расчет набора записей одного приоритета. Для каждой записи при помощи функции
ПолучитьДанныеДляРасчета() возвращается структура данных, которая передается в процедуру РассчитатьЗапись().
Расчет набора записей одного приоритета
Код 1C v 8.х Процедура РассчитатьНаборЗаписей(НаборЗаписей, Приоритет, ТабличнаяЧасть = Неопределено)
Иначе
СтруктураДанных.Вставить("ОтработаноВремени", 0); СтруктураДанных.Вставить("НормаВремени", 0);
Для каждого Запись из НаборЗаписей Цикл
Если Запись.ВидРасчета.Приоритет = Приоритет Тогда
// Получить данные для расчета записи.
ДанныеДляРасчета = ПолучитьДанныеДляРасчета(Запись);
// Вызвать процедуру расчета записи. РассчитатьЗапись(Запись, ДанныеДляРасчета);
// Возвратить результат расчета в табличную часть документа. Если Не ТабличнаяЧасть = Неопределено Тогда
СтрокаТабличнойЧасти = ТабличнаяЧасть.Получить(Запись.НомерСтроки-1); СтрокаТабличнойЧасти.Результат = Запись.Результат;
КонецЕсли; КонецЕсли;
КонецЦикла;
КонецПроцедуры
В функции ПолучитьДанныеДляРасчета() должны быть прописаны алгоритмы, при помощи которых можно получить данные для расчета записи с любым способом расчета, существующим в конфигурации. Ниже приведен пример функции, которая получает данные для трех способов расчета:
Получение данных для трех видов расчета
Код 1C v 8.х Функция ПолучитьДанныеДляРасчета(Запись)
СпособРасчета = Запись.ВидРасчета.СпособРасчета; СтруктураДанных = Новый Структура;
Если СпособРасчета = Перечисления.СпособыРасчета.ПоМесячнойСтавке Тогда
// Получить данные графика.
Запрос = Новый Запрос("
|ВЫБРАТЬ
| ДанныеГрафика.ЗначениеФактическийПериодДействия КАК ГрафикФакт,
| ДанныеГрафика.ЗначениеПериодДействия КАК ГрафикНорма
|ИЗ
| РегистрРасчета.ОсновныеНачисленияРегл.ДанныеГрафика(
| Регистратор = &Регистратор
| И НомерСтроки = &НомерСтроки)
КАК ДанныеГрафика");
Запрос.УстановитьПараметр("Регистратор", Запись.Регистратор); Запрос.УстановитьПараметр("НомерСтроки", Запись.НомерСтроки);
Выборка = Запрос.Выполнить().Выбрать();
Если Выборка.Следующий() Тогда
СтруктураДанных.Вставить("ОтработаноВремени", Выборка.ГрафикФакт);
СтруктураДанных.Вставить("НормаВремени", Выборка.ГрафикНорма);
КонецЕсли;
ИначеЕсли
СпособРасчета = Перечисления.СпособыРасчета.ПроцентомОтБазы Тогда
Запрос = Новый Запрос("
|ВЫБРАТЬ
| База.РезультатБаза
|ИЗ
| РегистрРасчета.ОсновныеНачисленияРегл.БазаОсновныеНачисленияРегл(
| &Измерения, &Измерения, ,
| Регистратор = &Регистратор
| И НомерСтроки = &НомерСтроки) КАК База");
Измерения = Новый Массив(2); Измерения[0] = "ФизЛицо"; Измерения[1] = "Организация";
Запрос.УстановитьПараметр("Регистратор", Запись.Регистратор);
Запрос.УстановитьПараметр("НомерСтроки", Запись.НомерСтроки);
Запрос.УстановитьПараметр("Измерения", Измерения);
Выборка = Запрос.Выполнить().Выбрать();
Если Выборка.Следующий() Тогда
СтруктураДанных.Вставить("База", Выборка.РезультатБаза);
Иначе
СтруктураДанных.Вставить("База", 0);
КонецЕсли;
ИначеЕсли СпособРасчета = Перечисления.СпособыРасчета.ПоСдельнойВыработке Тогда
// Получить данные регистра накопления
// фактическая выработка за период действия записи.
Запрос = Новый Запрос("
|ВЫБРАТЬ
| СУММА(СдельнаяВыработкаОбороты.ВыработкаОборот) КАК ВыработкаОборот
|ИЗ
| РегистрНакопления.СдельнаяВыработка.Обороты(
| &ДатаНачало, &ДатаКонец, ,
| Организация = &Организация И ФизЛицо = &ФизЛицо)
| КАК СдельнаяВыработкаОбороты");
Запрос.УстановитьПараметр("ДатаНачало", НачалоДня(Запись.ПериодДействияНачало));
Запрос.УстановитьПараметр("ДатаКонец", КонецДня(Запись.ПериодДействияКонец));
Запрос.УстановитьПараметр("ФизЛицо", Запись.ФизЛицо); Запрос.УстановитьПараметр("Организация", Запись.Организация);
Выборка = Запрос.Выполнить().Выбрать(); Если Выборка.Следующий() Тогда
СтруктураДанных.Вставить("Выработка", Выборка.ВыработкаОборот);
Иначе
СтруктураДанных.Вставить("Выработка", 0); КонецЕсли;
КонецЕсли;
Возврат СтруктураДанных;
КонецФункции // ПолучитьДанныеДляРасчета
В данном случае для расчета записей со способом ПоМесячнойСтавке система получит данные графика за период действия и фактический период действия, для способа ПроцентомОтБазы будет получена расчетная база записи, а для способа ПоСдельнойВыработке будут рассчитаны обороты по соответствующему регистру накопления за интервал периода действия записи. Способ расчета ФиксированнойСуммой не требует получения данных.
Функция ПолучитьДанныеДляРасчета() возвращает структуру, содер- жащую различные поля в зависимости от способа расчета, применяемого в данной записи
Расчет значений ресурсов записи
После того как данные для расчета получены, необходимо прописать в модуле формулу для заполнения реквизитов каждой записи в соответствии со способом расчета. В данном случае эту функцию выполняет процедура РассчитатьЗапись(). В процедуре РассчитатьЗапись() для каждого возмож- ного способа расчета описывается формула, позволяющая из реквизитов записи и полученных данных рассчитать значения ресурсов этой записи.
Процедура расчета записей
Код 1C v 8.х Процедура РассчитатьЗапись(Запись, ДанныеДляРасчета) СпособРасчета = Запись.ВидРасчета.СпособРасчета;
Если СпособРасчета = Перечисления.СпособыРасчета.ПоМесячнойСтавке Тогда
Если Не ДанныеДляРасчета.НормаВремени = 0 Тогда
Результат = Запись.Размер * ДанныеДляРасчета.ОтработаноВремени / ДанныеДляРасчета.НормаВремени;
Иначе
Результат = 0; КонецЕсли;
ИначеЕсли
СпособРасчета = Перечисления.СпособыРасчета.ПроцентомОтБазы Тогда
Результат = Запись.Размер * ДанныеДляРасчета.База / 100;
ИначеЕсли
СпособРасчета = Перечисления.СпособыРасчета.ФиксированнойСуммой Тогда
Результат = Запись.Размер;
ИначеЕсли
СпособРасчета = Перечисления.СпособыРасчета.ПоСдельнойВыработке Тогда
Результат = ДанныеДляРасчета.Выработка; КонецЕсли;
Запись.Результат = Результат * ?(Запись.Сторно, -1, 1);
КонецПроцедуры // Рассчитать запись
При расчете записей следует учитывать, что сторно-записи рассчитываются в общем порядке. Поэтому в ресурсы сторно-записи должно попадать отрицательное значение результата расчета. Например, сторно- запись отменяет начисленный оклад за период 5 дней. При расчете такой записи по формуле система получит сумму оклада за 5 дней, например, 1200 руб. В ресурс сторно-записи в этом случае должно быть записано значение -1200.
Категория:
Регистры расчета Добавление в набор сторно-записей Если в рассчитываемом регистре установлено свойство Период действия, в сформированном наборе могут присутствовать записи, у которых период действия принадлежит более раннему периоду, чем период регистрации. В этом случае они могут вступать в конкуренцию на этом периоде действия с записями более раннего периода регистрации. Чтобы такие записи могли иметь непустой фактический период действия, необходимо допол- нить сформированный набор соответствующими сторно-записями.
Добавление сторно-записей происходит с использованием метода
ПолучитьДополнение() набора записей регистра. Ниже приведен текст модуля, позволяющий добавить в набор сторно-записи. Добавление записи происходит при помощи вызова процедуры
ДобавитьСтрокуСторноОсновныхНачислений() , которая должна быть описана в процедуре
РассчитатьОсновныеНачисления() . При этом для каждой сторно- записи необходимо добавить новую строку в табличную часть документа, чтобы при проведении эта запись попала в регистр
Код 1C v 8.х // Добавить сторно-записи в набор и в табличную часть.
Процедура ДобавитьСтрокуСторноОсновныхНачислений(ДанныеСтроки,
НаборЗаписей, ТабличнаяЧасть = Неопределено)
Движение = НаборЗаписей.Добавить();
// Предопределенные поля.
Движение.ПериодРегистрации = ДанныеСтроки.ПериодРегистрацииСторно;
Движение.ПериодДействияНачало = ДанныеСтроки.ПериодДействияНачалоСторно;
Движение.ПериодДействияКонец = ДанныеСтроки.ПериодДействияКонецСторно;
Движение.ВидРасчета = ДанныеСтроки.ВидРасчета;
Движение.Сторно = Истина;
// Измерения.
Движение.ФизЛицо = ДанныеСтроки.ФизЛицо;
Движение.Организация = ДанныеСтроки.Организация;
// Реквизиты.
Движение.ГрафикРаботы = ДанныеСтроки.ГрафикРаботы;
Движение.Размер = ДанныеСтроки.Размер;
Движение.ВидУчетаВремени = ДанныеСтроки.ВидУчетаВремени;
Движение.Подразделение = ДанныеСтроки.Подразделение;
Движение.СтатьяЗатрат = ДанныеСтроки.СтатьяЗатрат;
Если Не ТабличнаяЧасть = Неопределено Тогда
НоваяСтрока = ТабличнаяЧасть.Добавить();
НоваяСтрока.ФизЛицо = ДанныеСтроки.ФизЛицо;
НоваяСтрока.ВидРасчета = ДанныеСтроки.ВидРасчета;
НоваяСтрока.ДатаНачало = ДанныеСтроки.ПериодДействияНачалоСторно;
НоваяСтрока.ДатаКонец = ДанныеСтроки.ПериодДействияКонецСторно;
НоваяСтрока.Размер = ДанныеСтроки.Размер;
НоваяСтрока.Подразделение = ДанныеСтроки.Подразделение;
НоваяСтрока.Сторно = Истина;
КонецЕсли;
КонецПроцедуры // ДобавитьСтрокуСторноОсновныхНачислений
// Процедура расчета основных начислений.
Процедура РассчитатьОсновныеНачисления() Экспорт
НачатьТранзакцию();
// Сформировать набор записей.
// …
// Сформировать таблицу сторно-записей.
ТаблицаСторно = НаборОсновныеНачисления.ПолучитьДополнение();
// Добавить сторно-записи в набор.
Для Каждого СтрокаСторно из ТаблицаСторно Цикл
ДобавитьСтрокуСторноОсновныхНачислений(СтрокаСторно,
НаборОсновныеНачисления,
ОсновныеНачисления);
КонецЦикла;
// …
ЗафиксироватьТранзакцию();
КонецПроцедуры // РассчитатьОсновныеНачисления
При формировании сторно-записей данные всех измерений и реквизитов записи указаны в строке дополнения. Также в этой строке содержатся данные о периоде регистрации и периоде действия сторно-записи. Ресурсы сторно-записи не заполняются, так как запись будет рассчитана в общем порядке
Категория:
Регистры расчета Формирование записей регистра расчета Для формирования записей регистра расчета используется метод Добавить() объекта
РегистрРасчетаНаборЗаписей
Код 1C v 8.2 УП //Формирование записей регистра расчета
// Процедура добавляет запись в регистр основных начислений.
Процедура ДобавитьСтрокуОсновныхНачислений(ДанныеСтроки, НаборЗаписей)
Движение = НаборЗаписей.Добавить();
// Предопределенные поля.
Движение.ПериодРегистрации = ПериодРегистрации;
Движение.ПериодДействияНачало = ДанныеСтроки.ДатаНачало;
Движение.ПериодДействияКонец = ДанныеСтроки.ДатаКонец;
Движение.ВидРасчета = ДанныеСтроки.ВидРасчета;
Движение.Сторно = ДанныеСтроки.Сторно;
// Измерения.
Движение.ФизЛицо = ДанныеСтроки.ФизЛицо; Движение.Организация= Организация;
// Ресурсы.
Движение.Результат = ДанныеСтроки.Результат;
// Реквизиты.
Движение.ГрафикРаботы = ДанныеСтроки.ФизЛицо.ГрафикРаботы;
Движение.Размер = ДанныеСтроки.Размер;
Движение.ВидУчетаВремени = ДанныеСтроки.ВидРасчета.ВидУчетаВремени;
Движение.Подразделение = ДанныеСтроки.Подразделение;
Движение.СтатьяЗатрат = ДанныеСтроки.ВидРасчета.СтатьяЗатрат;
КонецПроцедуры // ДобавитьСтрокуОсновныхНачислений
// Обработка проведения.
Процедура ОбработкаПроведения(Отказ)
Движения.ОсновныеНачисленияРегл.Записывать = Истина; Движения.ДополнительныеНачисленияРегл.Записывать = Истина;
// Сформировать запрос по табличной части при помощи функции общего модуля. ВыборкаОсновныеНачисления = ОбщегоНазначения.
СформироватьЗапросПоТабличнойЧасти(ЭтотОбъект, "ОсновныеНачисления").Выбрать();
// По каждой строке табличной части сформировать запись в регистр. Пока ВыборкаОсновныеНачисления.Следующий() Цикл
ДобавитьСтрокуОсновныхНачислений(ВыборкаОсновныеНачисления, Движения.ОсновныеНачисленияРегл);
настройка алгоритмов расчета
КонецЦикла;
// Запись дополнительных начислений в регистр.
ВыборкаДополнительныеНачисления = ОбщегоНазначения.
СформироватьЗапросПоТабличнойЧасти(ЭтотОбъект, "ДополнительныеНачисления").Выбрать();
Пока ВыборкаДополнительныеНачисления.Следующий() Цикл
ДобавитьСтрокуДополнительныхНачислений(ВыборкаДополнительныеНачисления, Движения.ДополнительныеНачисленияРегл);
КонецЦикла;
КонецПроцедуры // ОбработкаПроведения Категория:
Регистры расчета Как изменить запись регистра сведений? Код 1C v 8.х НаборЗаписей = РегистрыСведений.НумерацияДоговоров.СоздатьНаборЗаписей();
НаборЗаписей.Отбор.Период.Установить(НачалоГода(Дата));
НаборЗаписей.Отбор.Организация.Установить(Организация);
НаборЗаписей.Прочитать();
Если НаборЗаписей.Количество() = 0 Тогда
НовыйНомер = НаборЗаписей.Добавить();
НовыйНомер.Организация = Организация;
НовыйНомер.Период = НачалоГода(Дата);
НовыйНомер.Номер = 2; ном=1;
ИначеЕсли НаборЗаписей.Количество() = 1 Тогда
НовыйНомер = НаборЗаписей[0];
ном = НовыйНомер.Номер;
НовыйНомер.Номер = ном+1;
КонецЕсли;
НаборЗаписей.Записать();
Номер = Организация.Префикс + "-" + Ном + "/" + Строка(Прав(Год(ТекущаяДата()),2));
Код 1C v 8.х //Установить курс Валюты USD
КурсыВалют = РегистрыСведений.КурсыВалют;
НаборКурсов = КурсыВалют.СоздатьНаборЗаписей();
Доллар = Справочники.Валюты.НайтиПоНаименованию("USD");
НаборКурсов.Отбор.Валюта.Установить(Доллар);
НаборКурсов.Отбор.Период.Установить(НачалоДня(ТекущаяДата()));
НаборКурсов.Прочитать();
Если НаборКурсов.Количество() = 0 Тогда
НовыйКурс = НаборКурсов.Добавить();
НовыйКурс.Валюта = Доллар;
НовыйКурс.Период = ТекущаяДата();
ИначеЕсли НаборКурсов.Количество() = 1 Тогда
НовыйКурс = НаборКурсов[0];
Иначе
Предупреждение("Курс валюты задается один раз в день.", 60);
Возврат;
КонецЕсли;
НовыйКурс.Курс = 31.44;
НовыйКурс.Кратность = 1;
НаборКурсов.Записать();
Код 1C v 8.х //В регистр были ошибочно записаны штрихкоды.
// Нужно по заданным Номенклатуре (Товар) и Характеристике (ХарактеристикаТовара) найти эту запись и заменить там штрихкод.
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| ШтрихкодыНоменклатуры.Штрихкод КАК Штрихкод
|ИЗ
| РегистрСведений.ШтрихкодыНоменклатуры КАК ШтрихкодыНоменклатуры
|ГДЕ
| ШтрихкодыНоменклатуры.Номенклатура = &Номенклатура И
| ШтрихкодыНоменклатуры.Характеристика = &Характеристика";
Запрос.УстановитьПараметр("Номенклатура", Товар);
Запрос.УстановитьПараметр("Характеристика", ХарактеристикаТовара);
Выборка = Запрос.Выполнить().Выбрать();
Если НЕ Выборка.Следующий() Тогда
ТекЗапись = РегистрыСведений.ШтрихкодыНоменклатуры.СоздатьМенеджерЗаписи();
ТекЗапись.Номенклатура = Товар;
Если ЗначениеЗаполнено(ХарактеристикаТовара) Тогда
ТекЗапись.Характеристика = ХарактеристикаТовара;
Иначе
ТекЗапись.Характеристика = Справочники.ХарактеристикиНоменклатуры.ПустаяСсылка();
КонецЕсли;
ТекЗапись.Штрихкод = ?(ПустаяСтрока(ШтрихКод),РегистрыСведений.ШтрихкодыНоменклатуры.СформироватьШтрихкодEAN13(), Штрихкод);
Попытка
ТекЗапись.Записать();
Исключение
КонецПопытки;
Иначе
НайденныйШтрихкод = Выборка.Штрихкод;
ТекЗапись = РегистрыСведений.ШтрихкодыНоменклатуры.СоздатьМенеджерЗаписи();
ТекЗапись.Штрихкод = НайденныйШтрихкод;
ТекЗапись.Прочитать();
ТекЗапись.Штрихкод = Штрихкод;
Попытка
ТекЗапись.Записать();
Исключение
КонецПопытки;
КонецЕсли; Категория:
Регистры сведений