Как удалить движения документа программно? Потребовалось в УТ быстро удалить все движения по банку, дело вроде легкое - отменить проведение всех поступлений и списаний безналичных денежных средств, но не тут то было...
При попытке отмены проведения выполнялись проверки на условия оплаты по заказу и документ ни как не отменял проведения
Ну не может типовым способом, заставим не типовым: Через запрос делаем выбору необходимых нам документов и в обработке результата пишем:
Код 1C v 8.3 Для Каждого СтрокаРезультата Из РезультатТаблица Цикл
//алгоритм обработки строки результата - начало
ДокОбъект = СтрокаРезультата.Ссылка.ПолучитьОбъект();
Для Каждого Движение ИЗ ДокОбъект.Движения Цикл
Если Движение.Количество() > 0 Тогда
Точка = Найти(Строка(Движение), ".");
ВидРегистра = Лев(Строка(Движение), Точка - 13);
РегистрИмя = СокрП(Сред(Строка(Движение), Точка + 1));
Если ВидРегистра = "РегистрНакопления" Тогда
НаборЗаписей = РегистрыНакопления[РегистрИмя].СоздатьНаборЗаписей();
ИначеЕсли ВидРегистра = "РегистрБухгалтерии" Тогда
НаборЗаписей = РегистрыБухгалтерии[РегистрИмя].СоздатьНаборЗаписей();
ИначеЕсли ВидРегистра = "РегистрСведений" Тогда
НаборЗаписей = РегистрыСведений[РегистрИмя].СоздатьНаборЗаписей();
ИначеЕсли ВидРегистра = "РегистрРасчета" Тогда
НаборЗаписей = РегистрыРасчета[РегистрИмя].СоздатьНаборЗаписей();
КонецЕсли;
НаборЗаписей.Отбор.Регистратор.Установить(ДокОбъект.Ссылка);
Иначе
НаборЗаписей = Движение;
КонецЕсли;
Попытка
НаборЗаписей.Записать();
Исключение
Сообщить(ОписаниеОшибки());
КонецПопытки;
КонецЦикла;
ДокОбъект.Проведен = Ложь;
//ДокОбъект.ОбменДанными.Загрузка = Истина;
ДокОбъект.Записать(режимзаписидокумента.запись);
//алгоритм обработки строки результата - конец
КонецЦикла;
Готовая функция для использования в своих обработках или общем модуле:
Код 1C v 8.3 Процедура УдалитьДвиженияДокумента(Документ)
ДокОбъект = Документ.ПолучитьОбъект();
Для Каждого Движение ИЗ ДокОбъект.Движения Цикл
Если Движение.Количество() > 0 Тогда
Точка = Найти(Строка(Движение), ".");
ВидРегистра = Лев(Строка(Движение), Точка - 13);
РегистрИмя = СокрП(Сред(Строка(Движение), Точка + 1));
Если ВидРегистра = "РегистрНакопления" Тогда
НаборЗаписей = РегистрыНакопления[РегистрИмя].СоздатьНаборЗаписей();
ИначеЕсли ВидРегистра = "РегистрБухгалтерии" Тогда
НаборЗаписей = РегистрыБухгалтерии[РегистрИмя].СоздатьНаборЗаписей();
ИначеЕсли ВидРегистра = "РегистрСведений" Тогда
НаборЗаписей = РегистрыСведений[РегистрИмя].СоздатьНаборЗаписей();
ИначеЕсли ВидРегистра = "РегистрРасчета" Тогда
НаборЗаписей = РегистрыРасчета[РегистрИмя].СоздатьНаборЗаписей();
КонецЕсли;
НаборЗаписей.Отбор.Регистратор.Установить(ДокОбъект.Ссылка);
Иначе
НаборЗаписей = Движение;
КонецЕсли;
Попытка
НаборЗаписей.Записать();
Исключение
Сообщить(ОписаниеОшибки());
КонецПопытки;
КонецЦикла;
КонецПроцедуры
Категория:
Документы Ошибка: Неверная дата ранее 01.01.1991 или позднее текущей даты как исправить? Большая часть контрагентов в справочнике покраснели с ошибкой "Неверная дата ранее 01.01.1991 или позднее текущей даты"
Решение:
1. Удалить Состояния контрагентов в регистре сведений. Открываем в программе обработку: Удаление и изменение записей регистра сведений
Выбираем регистр "Состояние сотрудников" и жмем Удалить записи
2. Потом в поддержке и обслуживании в фоновых заданиях (регламентированные), нашел проверка контрагентов нажал выполнить
Все проверилось и статусы в списках контрагентов стали актуальными
Категория:
Системные Ошибки Событие ПередЗаписью регистра сведений. Как перед записью изменить значение реквизита записи? Событие ПередЗаписью возникает перед выполнением записи набора регистра сведений. Процедура-обработчик вызывается после начала транзакции записи, но до начала записи набора регистра сведений.
Пример проверки на условие и заполнение реквизита Цвет:
Код 1C v 8.х Процедура ПередЗаписью(Отказ, Замещение)
Для Каждого ТекЗапись Из ЭтотОбъект Цикл
Если ТекЗапись.СерияНоменклатуры.Восстановленный Тогда
ТекЗапись.Цвет="2551650";
Иначе
ТекЗапись.Цвет="";
КонецЕсли;
КонецЦикла;
КонецПроцедуры
Ниже приведен пример процедуры ПередЗаписью для регистра сведений «Курсы», который содержит курсы валют по периодам. При попытке ввести или изменить курс валюты период которого раньше даты регистрации фирмы будет выведено два сообщения:
Код 1C v 8.2 УП Процедура ПередЗаписью (Отказ, Замещение)
ДатаРегистрации = Константы.ДатаРегистрации.Получить ();
Для Каждого ТекЗапись Из ЭтотОбъект Цикл
Если ТекЗапись.Период < ДатаРегистрации Тогда
// Если период раньше даты регистрации
Отказ = Истина; // отказ от записи
Сообщить(" Запись от " + ТекЗапись.Период +
" с курсом " + ТекЗапись.Курс +
" раньше даты регистрации фирмы!");
КонецЕсли;
КонецЦикла;
Если Отказ Тогда
Сообщить ("Запись не выполнена!");
КонецЕсли;
КонецПроцедуры
Категория:
Регистры сведений Как выбрать запросом записи регистра сведений и удалить их? В регистре сведений штрих кодов появились ошибочные записи, которые надо было быстро удалить... можно конечно и ручками выбирать и жать Delete, но это не наш метод!
Код 1C v 8.3 Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Штрихкоды.Штрихкод,
| Штрихкоды.Владелец,
| Штрихкоды.ТипШтрихкода,
| Штрихкоды.ЕдиницаИзмерения,
| Штрихкоды.ХарактеристикаНоменклатуры,
| Штрихкоды.СерияНоменклатуры,
| Штрихкоды.Качество
|ИЗ
| РегистрСведений.Штрихкоды КАК Штрихкоды
|ГДЕ
| Штрихкоды.СерияНоменклатуры.ПометкаУдаления";
Результат = Запрос.Выполнить();
РезультатТаблица = Результат.Выгрузить();
ТекПозиция = 0;
Для каждого СтрокаЗапроса из РезультатТаблица Цикл
ОбработкаПрерыванияПользователя();
ТекПозиция = ТекПозиция + 1;
Состояние("Выполнено " + Окр(ТекПозиция / РезультатТаблица.Количество() * 100) + "%");
НаборЗаписей = РегистрыСведений.Штрихкоды.СоздатьНаборЗаписей();
НаборЗаписей.Отбор.Штрихкод.Установить(СтрокаЗапроса.Штрихкод);
НаборЗаписей.Отбор.Владелец.Установить(СтрокаЗапроса.Владелец);
НаборЗаписей.Отбор.ТипШтрихкода.Установить(СтрокаЗапроса.ТипШтрихкода);
НаборЗаписей.Отбор.ЕдиницаИзмерения.Установить(СтрокаЗапроса.ЕдиницаИзмерения);
НаборЗаписей.Отбор.ХарактеристикаНоменклатуры.Установить(СтрокаЗапроса.ХарактеристикаНоменклатуры);
НаборЗаписей.Отбор.СерияНоменклатуры.Установить(СтрокаЗапроса.СерияНоменклатуры);
// Удаляем записи
НаборЗаписей.Записать(Истина);
КонецЦикла;
Предупреждение("Обработка закончена.");
Категория:
Регистры сведений Функции получения всех плановых Начислений и Удержаний сотрудника При доработке ЗУПа потребовалось во фронте расчетчика информативно выводить все плановые начисления и удержания по сотруднику на текущий момент. В результате 2 удобные функции, результат возвращают в виде таблицы значений:
Код 1C v 8.3 Функция ПолучитьСписокПлановыхНачислений(Организация, Сотрудник, ДатаО) Экспорт
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| ПлановыеНачисленияСрезПоследних.Период,
| ПлановыеНачисленияСрезПоследних.ВидРасчета,
| ПлановыеНачисленияСрезПоследних.Показатель1,
| ПлановыеНачисленияСрезПоследних.Валюта1,
| ПлановыеНачисленияСрезПоследних.ТарифныйРазряд1,
| ПлановыеНачисленияСрезПоследних.Показатель2,
| ПлановыеНачисленияСрезПоследних.Валюта2,
| ПлановыеНачисленияСрезПоследних.ТарифныйРазряд2,
| ПлановыеНачисленияСрезПоследних.Показатель3,
| ПлановыеНачисленияСрезПоследних.Валюта3,
| ПлановыеНачисленияСрезПоследних.ТарифныйРазряд3,
| ПлановыеНачисленияСрезПоследних.Показатель4,
| ПлановыеНачисленияСрезПоследних.Валюта4,
| ПлановыеНачисленияСрезПоследних.ТарифныйРазряд4,
| ПлановыеНачисленияСрезПоследних.Показатель5,
| ПлановыеНачисленияСрезПоследних.Валюта5,
| ПлановыеНачисленияСрезПоследних.ТарифныйРазряд5,
| ПлановыеНачисленияСрезПоследних.Показатель6,
| ПлановыеНачисленияСрезПоследних.Валюта6,
| ПлановыеНачисленияСрезПоследних.ТарифныйРазряд6,
| ПлановыеНачисленияСрезПоследних.Действие,
| ПлановыеНачисленияСрезПоследних.ПериодЗавершения,
| ПлановыеНачисленияСрезПоследних.ВидРасчетаЗавершения,
| ПлановыеНачисленияСрезПоследних.ДействиеЗавершения,
| ПлановыеНачисленияСрезПоследних.Показатель1Завершения,
| ПлановыеНачисленияСрезПоследних.Показатель2Завершения,
| ПлановыеНачисленияСрезПоследних.Показатель3Завершения,
| ПлановыеНачисленияСрезПоследних.Показатель4Завершения,
| ПлановыеНачисленияСрезПоследних.Показатель5Завершения,
| ПлановыеНачисленияСрезПоследних.Показатель6Завершения,
| ПлановыеНачисленияСрезПоследних.Валюта1Завершения,
| ПлановыеНачисленияСрезПоследних.Валюта2Завершения,
| ПлановыеНачисленияСрезПоследних.Валюта3Завершения,
| ПлановыеНачисленияСрезПоследних.Валюта4Завершения,
| ПлановыеНачисленияСрезПоследних.Валюта5Завершения,
| ПлановыеНачисленияСрезПоследних.Валюта6Завершения,
| ПлановыеНачисленияСрезПоследних.ТарифныйРазряд1Завершения,
| ПлановыеНачисленияСрезПоследних.ТарифныйРазряд2Завершения,
| ПлановыеНачисленияСрезПоследних.ТарифныйРазряд3Завершения,
| ПлановыеНачисленияСрезПоследних.ТарифныйРазряд4Завершения,
| ПлановыеНачисленияСрезПоследних.ТарифныйРазряд5Завершения,
| ПлановыеНачисленияСрезПоследних.ТарифныйРазряд6Завершения,
| ПлановыеНачисленияСрезПоследних.Регистратор
|ИЗ
| РегистрСведений.ПлановыеНачисленияРаботниковОрганизаций.СрезПоследних(
| &ДатаСреза,
| Организация =ГоловнаяОрганизация
| И Сотрудник =Ссылка) КАК ПлановыеНачисленияСрезПоследних
|ГДЕ
| ВЫБОР
| КОГДА ПлановыеНачисленияСрезПоследних.Действие = ЗНАЧЕНИЕ(Перечисление.ВидыДействияСНачислением.Прекратить)
| И ПлановыеНачисленияСрезПоследних.ДействиеЗавершения = ЗНАЧЕНИЕ(Перечисление.ВидыДействияСНачислением.ПустаяСсылка)
| ТОГДА ЛОЖЬ
| КОГДА ПлановыеНачисленияСрезПоследних.Действие = ЗНАЧЕНИЕ(Перечисление.ВидыДействияСНачислением.Прекратить)
| И ПлановыеНачисленияСрезПоследних.ДействиеЗавершения <> ЗНАЧЕНИЕ(Перечисление.ВидыДействияСНачислением.ПустаяСсылка)
| ИДатаСреза < ПлановыеНачисленияСрезПоследних.ПериодЗавершения
| ТОГДА ЛОЖЬ
| КОГДА ПлановыеНачисленияСрезПоследних.ДействиеЗавершения = ЗНАЧЕНИЕ(Перечисление.ВидыДействияСНачислением.Прекратить)
| ИДатаСреза >= ПлановыеНачисленияСрезПоследних.ПериодЗавершения
| ТОГДА ЛОЖЬ
| ИНАЧЕ ИСТИНА
| КОНЕЦ";
Запрос.УстановитьПараметр("ГоловнаяОрганизация", Организация);
Запрос.УстановитьПараметр("ДатаСреза", ДатаО);
Запрос.УстановитьПараметр("Ссылка", Сотрудник);
Возврат Запрос.Выполнить().Выгрузить();
КонецФункции
Функция ПолучитьСписокПлановыхУдержаний(Организация, Сотрудник, ДатаО) Экспорт
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| ПлановыеУдержанияСрезПоследних.Период,
| ПлановыеУдержанияСрезПоследних.ВидРасчета,
| ПлановыеУдержанияСрезПоследних.Показатель1,
| ПлановыеУдержанияСрезПоследних.Валюта1,
| ПлановыеУдержанияСрезПоследних.Показатель2,
| ПлановыеУдержанияСрезПоследних.Валюта2,
| ПлановыеУдержанияСрезПоследних.Показатель3,
| ПлановыеУдержанияСрезПоследних.Валюта3,
| ПлановыеУдержанияСрезПоследних.Показатель4,
| ПлановыеУдержанияСрезПоследних.Валюта4,
| ПлановыеУдержанияСрезПоследних.Показатель5,
| ПлановыеУдержанияСрезПоследних.Валюта5,
| ПлановыеУдержанияСрезПоследних.Показатель6,
| ПлановыеУдержанияСрезПоследних.Валюта6,
| ПлановыеУдержанияСрезПоследних.Действие,
| ПлановыеУдержанияСрезПоследних.ПериодЗавершения,
| ПлановыеУдержанияСрезПоследних.ДействиеЗавершения,
| ПлановыеУдержанияСрезПоследних.Показатель1Завершения,
| ПлановыеУдержанияСрезПоследних.Показатель2Завершения,
| ПлановыеУдержанияСрезПоследних.Показатель3Завершения,
| ПлановыеУдержанияСрезПоследних.Показатель4Завершения,
| ПлановыеУдержанияСрезПоследних.Показатель5Завершения,
| ПлановыеУдержанияСрезПоследних.Показатель6Завершения,
| ПлановыеУдержанияСрезПоследних.Валюта1Завершения,
| ПлановыеУдержанияСрезПоследних.Валюта2Завершения,
| ПлановыеУдержанияСрезПоследних.Валюта3Завершения,
| ПлановыеУдержанияСрезПоследних.Валюта4Завершения,
| ПлановыеУдержанияСрезПоследних.Валюта5Завершения,
| ПлановыеУдержанияСрезПоследних.Валюта6Завершения,
| ПлановыеУдержанияСрезПоследних.Регистратор
|ИЗ
| РегистрСведений.ПлановыеУдержанияРаботниковОрганизаций.СрезПоследних(
| &ДатаСреза,
| Организация =ГоловнаяОрганизация
| И Физлицо =Ссылка) КАК ПлановыеУдержанияСрезПоследних
|ГДЕ
| ВЫБОР
| КОГДА ПлановыеУдержанияСрезПоследних.Действие = ЗНАЧЕНИЕ(Перечисление.ВидыДействияСНачислением.Прекратить)
| И ПлановыеУдержанияСрезПоследних.ДействиеЗавершения = ЗНАЧЕНИЕ(Перечисление.ВидыДействияСНачислением.ПустаяСсылка)
| ТОГДА ЛОЖЬ
| КОГДА ПлановыеУдержанияСрезПоследних.Действие = ЗНАЧЕНИЕ(Перечисление.ВидыДействияСНачислением.Прекратить)
| И ПлановыеУдержанияСрезПоследних.ДействиеЗавершения <> ЗНАЧЕНИЕ(Перечисление.ВидыДействияСНачислением.ПустаяСсылка)
| ИДатаСреза < ПлановыеУдержанияСрезПоследних.ПериодЗавершения
| ТОГДА ЛОЖЬ
| КОГДА ПлановыеУдержанияСрезПоследних.ДействиеЗавершения = ЗНАЧЕНИЕ(Перечисление.ВидыДействияСНачислением.Прекратить)
| ИДатаСреза >= ПлановыеУдержанияСрезПоследних.ПериодЗавершения
| ТОГДА ЛОЖЬ
| ИНАЧЕ ИСТИНА
| КОНЕЦ";
Запрос.УстановитьПараметр("ГоловнаяОрганизация", Организация);
Запрос.УстановитьПараметр("ДатаСреза", ДатаО);
Запрос.УстановитьПараметр("Ссылка", Сотрудник.Физлицо);
Возврат Запрос.Выполнить().Выгрузить();
КонецФункции
Категория:
1С Зарплата и Управление Персоналом 2.5 Управление регистрацией документа в последовательности документов Для управления регистрацией документа в последовательности документов служит набор записей регистрации в последовательности документов.
У документа есть свойство ПринадлежностьПоследовательностям. Значением свойства является коллекция наборов записей регистрации в последовательности документов. Для каждой последовательности, в которой участвует документ, существует свой собственный экземпляр набора записей. Если у документа стоит режим автоматического заполнения последовательностей, то перед записью документа наборы записей регистрации будут автоматически заполнены. Для последовательностей без измерений набор записей будет содержать только одну запись. Для последовательностей с измерениями число записей зависит от содержания документа и настройки соответствия измерений последовательности реквизитам документа.
Набор записей автоматически заполняется до записи документа и записывается после записи документа в одной транзакции с ним. Это позволяет в обработчиках событий документа ПередЗаписью() и ПриЗаписи() переопределить набор записей регистрации. Так, например, если документ входит в последовательность Последовательность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.х // Добавление новых данных в существующую запись регистра сведений
НаборЗаписей = РегистрыСведений.ДокументоОборот.СоздатьНаборЗаписей();
НаборЗаписей.Отбор.Доставка.Установить(Доставка);
НаборЗаписей.Отбор.Этап.Установить(Этап);
НаборЗаписей.Прочитать();
Для каждого Запись из НаборЗаписей Цикл
Запись.ДатаВремя = ДатаР;
Запись.Отдел = фио.Подразделение;
Запись.ФИО = ПараметрыСеанса.ТекущийПользователь;
Запись.Документы = Документы;
Запись.Примечание = Примечание;
КонецЦикла;
НаборЗаписей.Записать();
Пример с использованием набора записей и менеджера записи:
Код 1C v 8.х НаборЗаписей = РегистрыСведений.CRM_Напоминания.СоздатьНаборЗаписей();
Отбор = НаборЗаписей.Отбор;
Отбор.Объект.Установить(Объект.Ссылка);
Отбор.Завершено.Установить(Ложь);
НаборЗаписей.Прочитать();
Если НаборЗаписей.Количество() > 0 Тогда
Если ЗадаватьВопрос Тогда
ТекстВопроса = "Завершить все напоминания для " + Строка(Объект.Ссылка) + " ?";
Ответ = Вопрос(ТекстВопроса,РежимДиалогаВопрос.ДаНет, ,КодВозвратаДиалога.Да);
Иначе
Ответ = КодВозвратаДиалога.Да
КонецЕсли;
Если Ответ = КодВозвратаДиалога.Да Тогда
Для каждого Запись Из НаборЗаписей Цикл
РегистрСведенийМенеджерЗаписи = РегистрыСведений.CRM_Напоминания.СоздатьМенеджерЗаписи();
ЗаполнитьЗначенияСвойств(РегистрСведенийМенеджерЗаписи, Запись);
РегистрСведенийМенеджерЗаписи.Прочитать();
Если РегистрСведенийМенеджерЗаписи.Выбран() Тогда //напоминание небыло удалено
Если НЕ РегистрСведенийМенеджерЗаписи.УдалитьПоИстеченииСрока Тогда
РегистрСведенийМенеджерЗаписи.Завершено = Истина;
РегистрСведенийМенеджерЗаписи.Записать();
Иначе
РегистрСведенийМенеджерЗаписи.Удалить();
КонецЕсли;
КонецЕсли;
КонецЦикла;
КонецЕсли;
КонецЕсли;
А вот пример через менеджер записи:
Код 1C v 8.х МенеджерЗаписи = РегистрыСведений.НоменклатураКонтрагентов.СоздатьМенеджерЗаписи();
МенеджерЗаписи.Контрагент = Контрагент;
МенеджерЗаписи.Номенклатура = СтрокаТаблицыТовары.Номенклатура;
МенеджерЗаписи.ХарактеристикаНоменклатуры = СтрокаТаблицыТовары.ХарактеристикаНоменклатуры;
МенеджерЗаписи.Прочитать();
Если МенеджерЗаписи.Выбран() Тогда
Вес = МенеджерЗаписи.ВесНоменклатурыКонтрагента;
КонецЕсли;
Категория:
Регистры сведений Как установить цену из РегистраСведений на дату создания документа Код 1C v 8.3
&НаКлиенте
Процедура ТоварНоменклатураПриИзменении(Элемент)
СтрокаТабличнойЧасти = ЭтаФорма.ТекущийЭлемент.ТекущиеДанные;
Номенклатура = СтрокаТабличнойЧасти.Номенклатура;
ТипЦен = ЭтаФорма.ТипЦен;
ТекДата = Объект.Дата;
СтрокаТабличнойЧасти.Цена = ПолучитьЦену(Номенклатура, ТипЦен, ТекДата);
КонецПроцедуры
&НаСервере
Функция ПолучитьЦену(Номенклатура, ТипЦен, ТекДата) Экспорт
Отбор = Новый Структура;
Отбор.Вставить("Номенклатура",Номенклатура);
Отбор.Вставить("ТипЦены",ТипЦен);
ЦенаТовара = РегистрыСведений.ЦеныНоменклатуры.ПолучитьПоследнее(ТекДата,Отбор);
Возврат ЦенаТовара.Цена;
КонецФункции
Категория:
Регистры сведений Блокировка записей, невозможно изменить или удалить из регистра. Конфликт блокировок MS SQL + 1C При попытке удалить запись из регистра сведений - получаю ошибку: она заблокирована, ошибка блокировок и т.д.
Отключил всех пользователей, перезапустил сервер, пробую удалить - опять ошибка блокировки
Путем тестов было вяснено, что проблема не в коде, а происходит это на этапе обращения платформы к SQL серверу... после долгих поисков решений, в интернете была найдена статья, которая помогла в решении данной проблемы:
Кто что блокирует, MS SQL + 1C
В повседневной работе достаточно задействовать только первый блок "/*кто кого*/". Открываем MS SQL Server Management Studio, правой на корень - "new query" - вставляем код запроса (только верхнюю часть до "Кто что блокирует", остальное - для детального анализа), выполняем запрос (вверху есть кнопочка выполнения запроса).
Выполнив запрос, запоминаем "ID виновника", быстренько идем в консоль сервера 1С, заходим в ветку "Сеансы" нашей базы. Видим все соединения с 1С-сервером, ищем там колонку "Соединение с СУБД", чтобы увидеть соединения 1С-сервера с MSSQL-сервером. В колонке будет всего несколько заполненных значений, среди них и будет "ID виновника".
Что делать если его там нет, тут 3 варианта:
1. Вернитесь в MSSQL и сделайте запрос еще несколько раз подряд, если значения меняются или таблица вообще пуста - постоянной блокировки нет, у вас (уже) все в порядке.
2. Сеанс который блокирует MSSQL находится в другой базе т.е. блокировка не в той базе (можно попробовать задействовать ветку всех сеансов в консоли 1С-сервера) - вернитесь в MSSQL и внимательно посмотрите в колонку DB в ней находится название базы.
3. Бывает что ID процесса в 1С-консоли вообще отсутствует, такое тоже бывает если у вас есть какие-то внешние программы подключенные напрямую в базу 1С, если пускаете кого-то в MSSQL напрямую, то вариант не исключен.
Код SQL-запроса:
Код SQL SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
DECLARE @dbid AS smallint;
use [ВАШАБАЗА];
SET @dbid=DB_ID();
/*кто кого*/
SELECT DB_NAME(pr1.dbid) AS 'DB'
,pr1.spid AS 'ID жертвы'
,RTRIM(pr1.loginame) AS 'Login жертвы'
,pr2.spid AS 'ID виновника'
,RTRIM(pr2.loginame) AS 'Login виновника'
,pr1.program_name AS 'программа жертвы'
,pr2.program_name AS 'программа виновника'
,txt.[text] AS 'Запрос виновника'
FROM MASTER.dbo.sysprocesses pr1(NOLOCK)
JOIN MASTER.dbo.sysprocesses pr2(NOLOCK)
ON (pr2.spid = pr1.blocked)
OUTER APPLY sys.[dm_exec_sql_text](pr2.[sql_handle]) AS txt
WHERE pr1.blocked <> 0
/* Кто что блокирует */
SELECT s.[nt_username]
,request_session_id
,tran_locks.[request_status]
,rd.[Description] + ' (' + tran_locks.resource_type + ' ' + tran_locks.request_mode + ')' [Object]
,txt_blocked.[text]
,COUNT(*) [COUNT]
FROM sys.dm_tran_locks AS tran_locks WITH (NOLOCK)
JOIN sys.sysprocesses AS s WITH (NOLOCK)
ON tran_locks.request_session_id = s.[spid]
JOIN (
SELECT 'KEY' AS sResource_type
,p.[hobt_id] AS [id]
,QUOTENAME(o.name) + '.' + QUOTENAME(i.name) AS [Description]
FROM sys.partitions p
JOIN sys.objects o
ON p.object_id = o.object_id
JOIN sys.indexes i
ON p.object_id = i.object_id
AND p.index_id = i.index_id
UNION ALL
SELECT 'RID' AS sResource_type
,p.[hobt_id] AS [id]
,QUOTENAME(o.name) + '.' + QUOTENAME(i.name) AS [Description]
FROM sys.partitions p
JOIN sys.objects o
ON p.object_id = o.object_id
JOIN sys.indexes i
ON p.object_id = i.object_id
AND p.index_id = i.index_id
UNION ALL
SELECT 'PAGE'
,p.[hobt_id]
,QUOTENAME(o.name) + '.' + QUOTENAME(i.name)
FROM sys.partitions p
JOIN sys.objects o
ON p.object_id = o.object_id
JOIN sys.indexes i
ON p.object_id = i.object_id
AND p.index_id = i.index_id
UNION ALL
SELECT 'OBJECT'
,o.[object_id]
,QUOTENAME(o.name)
FROM sys.objects o
) AS RD
ON RD.[sResource_type] = tran_locks.resource_type
AND RD.[id] = tran_locks.resource_associated_entity_id
OUTER APPLY sys.[dm_exec_sql_text](s.[sql_handle]) AS txt_Blocked
WHERE (
tran_locks.request_mode = 'X'
AND tran_locks.resource_type = 'OBJECT'
)
OR tran_locks.[request_status] = 'WAIT'
GROUP BY
s.[nt_username]
,request_session_id
,tran_locks.[request_status]
,rd.[Description] + ' (' + tran_locks.resource_type + ' ' + tran_locks.request_mode + ')'
,txt_blocked.[text]
ORDER BY
6 DESC
IF EXISTS ( SELECT Name
FROM tempdb..sysobjects
WHERE name LIKE '#LOCK_01_01%' )
DROP TABLE #LOCK_01_01
CREATE TABLE #LOCK_01_01
(
spid INT,
dbid INT,
ObjId INT,
IndId SMALLINT,
Type VARCHAR(20),
Resource VARCHAR(50),
Mode VARCHAR(20),
Status VARCHAR(20)
)
INSERT INTO #LOCK_01_01
EXEC sp_lock
select OBJECT_NAME(ObjId) as [Имя объекта], Mode [Тип блокировки (код)],
CASE
WHEN Mode='Sch-S' THEN 'Блокировка стабильности схемы. Гарантирует, что элемент схемы, такой как таблица или индекс, не будет удален до тех пор, пока сеанс связи удерживает блокировку стабильности схемы на данный элемент схемы;'
WHEN Mode='Sch-М' THEN '= Блокировка изменения схемы. Должен поддерживаться любым сеансом связи, во время которого предполагается изменить схему данного ресурса. Гарантирует, что другие сеансы не имеют ссылок на обозначенный объект;'
WHEN Mode='S' THEN 'S = Коллективная блокировка. Удерживающему сеансу предоставлен коллективный доступ к ресурсу;'
WHEN Mode='U' THEN 'U = Блокировка обновления. Указывает блокировку обновления, полученную на ресурсы, которые со временем могут быть обновлены. Используется для предотвращения общей формы взаимоблокировки, которая возникает, когда множество сеансов блокируют ресурсы для потенциального обновления в последующее время;'
WHEN Mode='X' THEN 'X = Монопольная блокировка. Удерживающему сеансу предоставлен исключительный доступ к ресурсу;'
WHEN Mode='IS' THEN 'IS = Блокировка с намерением коллективного доступа. Указывает намерение поместить S блокировки на некоторые подчиненные ресурсы в иерархии блокировок;'
WHEN Mode='IU' THEN 'IU = Блокировка с намерением обновления. Указывает намерение поместить U блокировки на некоторые подчиненные ресурсы в иерархии блокировок;'
WHEN Mode='IX' THEN 'IX = Блокировка с намерением монопольного доступа. Указывает намерение поместить X блокировки на некоторые подчиненные ресурсы в иерархии блокировок;'
WHEN Mode='SIU' THEN 'SIU = Коллективная блокировка с намерением обновления. Указывает коллективный доступ к ресурсу с намерением получения блокировок обновления на подчиненные ресурсы в иерархии блокировок;'
WHEN Mode='SIX' THEN 'SIX = Коллективная блокировка с намерением монопольного доступа. Указывает коллективный доступ к ресурсу с намерением получения монопольных блокировок на подчиненные ресурсы в иерархии блокировок;'
WHEN Mode='UIX' THEN 'UIX = Блокировка обновления с намерением монопольного доступа. Указывает блокировку обновления ресурса с намерением получения монопольных блокировок на подчиненные ресурсы в иерархии блокировок;'
WHEN Mode='BU' THEN 'BU = Блокировка массового обновления. Используется для массовых операций;'
--[ ELSE else_result_expression ]
END as [Тип блокировки]
,syspr.spid, syspr.dbid, syspr.open_tran, syspr.status, syspr.hostprocess, syspr.loginame, syspr.hostname
From
#LOCK_01_01
inner join master.dbo.sysprocesses as syspr
on syspr.spid = #LOCK_01_01.spid and syspr.dbid = #LOCK_01_01.dbid
where
#LOCK_01_01.Type = 'TAB'
and
#LOCK_01_01.dbid = @dbid
/* Чем занят сервер*/
SELECT s.[spid]
,s.[loginame]
,s.[open_tran]
,s.[blocked]
,s.[waittime]
,s.[cpu]
,s.[physical_io]
,s.[memusage]
INTO #sysprocesses
FROM sys.[sysprocesses] s
WAITFOR DELAY '00:00:01'
SELECT txt.[text]
,s.[spid]
,s.[loginame]
,s.[hostname]
,DB_NAME(s.[dbid]) [db_name]
,SUM(s.[waittime] -ts.[waittime]) [waittime]
,SUM(s.[cpu] -ts.[cpu]) [cpu]
,SUM(s.[physical_io] -ts.[physical_io]) [physical_io]
,s.[program_name]
FROM sys.[sysprocesses] s
JOIN #sysprocesses ts
ON s.[spid] = ts.[spid]
AND s.[loginame] = ts.[loginame]
OUTER APPLY sys.[dm_exec_sql_text](s.[sql_handle]) AS txt
WHERE s.[cpu] -ts.[cpu]
+ s.[physical_io] -ts.[physical_io]
> 500
OR (s.[waittime] -ts.[waittime]) > 3000
GROUP BY
txt.[text]
,s.[spid]
,s.[loginame]
,s.[hostname]
,DB_NAME(s.[dbid])
,s.[program_name]
ORDER BY
[physical_io] DESC
DROP TABLE #sysprocesses
Категория:
Администрирование Как установить параметр динамического списка? Когда используете для вывода данных динамический список и произвольный запрос, то бывают ситуации когда надо указать параметр используемый в этом запросе. Ниже пример вывода данных регистра сведений в карточке клиента
Для вывода используется используется запрос:
Код 1C v 8.3 ВЫБРАТЬ
РегистрСведенийFinans.Период,
РегистрСведенийFinans.Клиент,
РегистрСведенийFinans.Движение,
РегистрСведенийFinans.Расшифровка,
РегистрСведенийFinans.СуммаОбщая,
РегистрСведенийFinans.РасходыСервиса,
РегистрСведенийFinans.W1C
ИЗ
РегистрСведений.Finans КАК РегистрСведенийFinans
ГДЕ
РегистрСведенийFinans.Клиент =Клиент
Чтобы при открытии не отображалась информацию по другим клиентам, необходимо установить параметр динамического списка , сделаем это так:
Код 1C v 8.3 &НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
Финансы.Параметры.УстановитьЗначениеПараметра("Клиент", Объект.Ссылка);
КонецПроцедуры
Можно и просто настроить отбор через настройки, используя ЭлементОтбораКомпоновкиДанных
Подробнее об этом: Динамический список ~ Как на управляемой форме разместить список регистра сведений с отбором?
Категория:
Работа с Формой (Диалог) и её элементами Объектная модель схемы запроса Периодически во встроенном языке возникает необходимость изменения текста запроса в зависимости от разных алгоритмических условий. Раньше подобная задача решалась путём непосредственного формирования нужного текста запроса в виде строки. А это не всегда удобно и зачастую очень громоздко.
Теперь во встроенном языке мы реализовали объектную модель схемы запроса. Вы можете создать пустую схему запроса конструктором и загрузить в неё имеющийся текст запроса. После этого отдельные элементы текста запроса будут доступны вам как свойства объектной модели.
На рисунке ниже стрелки показывают, в каких объектах встроенного языка будут доступны те или иные элементы простого запроса, загруженного в схему:
Редактирование текста запроса с помощью объектной модели позволяет вам проще и понятнее модифицировать имеющиеся запросы. Или даже создавать их во встроенном языке «с нуля». А затем просто получать готовый текст запроса из схемы методом ПолучитьТекстЗапроса() .
Пример использования Схемы запроса Код 1C v 8.3 //Создание схемы запроса
СхемаЗапроса = Новый СхемаЗапроса;
ЗапросВыбораИзИБ = СхемаЗапроса.ПакетЗапросов[0];
//Установка свойств запроса
ЗапросВыбораИзИБ.ТаблицаДляПомещения = "ТаблицаОбороты";
ЗапросВыбораИзИБ.ВыбиратьРазрешенные = Истина;
//Добавляем операторы выбора первого запроса пакета
ОператорВыбораЗакупок = ЗапросВыбораИзИБ.Операторы[0];
ИсточникНоменклатура = ОператорВыбораЗакупок.Источники.Добавить("Справочник.Номенклатура","Товары");
//Добавляем запрос выбора из регистра закупок
ИсточникЗакупки = ОператорВыбораЗакупок.Источники.Добавить("РегистрНакопления.Закупки.Обороты","Закупки");
ИсточникЗакупки.Источник.Параметры[0].Выражение = Новый ВыражениеСхемыЗапроса("&Начало") ;
ИсточникЗакупки.Источник.Параметры[1].Выражение = Новый ВыражениеСхемыЗапроса("&Окончание") ;
ИсточникЗакупки.Источник.Параметры[2].Выражение = Новый ВыражениеСхемыЗапроса("Месяц") ;
//Меняем тип соединения
ИсточникЗакупки.Соединения[0].ТипСоединения = ТипСоединенияСхемыЗапроса.ПравоеВнешнее;
//Указываем выбираемые поля
ОператорВыбораЗакупок.ВыбираемыеПоля.Добавить("Товары.Ссылка");
ОператорВыбораЗакупок.ВыбираемыеПоля.Добавить("Закупки.Период");
ОператорВыбораЗакупок.ВыбираемыеПоля.Добавить("ЕСТЬNULL(Закупки.СуммаОборот, 0)");
ОператорВыбораЗакупок.ВыбираемыеПоля.Добавить("0");
//Указываем спевдонимы для выбранных полей
ЗапросВыбораИзИБ.Колонки[0].Псевдоним = "Номенклатура";
ЗапросВыбораИзИБ.Колонки[1].Псевдоним = "Период";
ЗапросВыбораИзИБ.Колонки[2].Псевдоним = "СуммаЗакупок";
ЗапросВыбораИзИБ.Колонки[3].Псевдоним = "СуммаПродаж";
//Добавляем отбор
ОператорВыбораЗакупок.Отбор.Добавить("НЕ Товары.ЭтоГруппа");
///////////////////////
//Выбираем данные о продажах
ОператорВыбораПродаж = ЗапросВыбораИзИБ.Операторы.Добавить();
ИсточникНоменклатура = ОператорВыбораПродаж.Источники.Добавить("Справочник.Номенклатура","Товары");
ОператорВыбораПродаж.ВыбираемыеПоля.Добавить("Товары.Ссылка");
//Добавляем источник РН и устанавливаем параметры
ИсточникПродажи =ОператорВыбораПродаж.Источники.Добавить("РегистрНакопления.Продажи.Обороты","Продажи");
ИсточникПродажи.Источник.Параметры[0].Выражение = Новый ВыражениеСхемыЗапроса("&Начало") ;
ИсточникПродажи.Источник.Параметры[1].Выражение = Новый ВыражениеСхемыЗапроса("&Окончание") ;
ИсточникПродажи.Источник.Параметры[2].Выражение = Новый ВыражениеСхемыЗапроса("Месяц") ;
ИсточникПродажи.Соединения[0].ТипСоединения = ТипСоединенияСхемыЗапроса.ПравоеВнешнее;
//Указываем отбираемые поля и устанавливаем для числовых полей соответствие с полями первого запроса
ОператорВыбораПродаж.ВыбираемыеПоля.Добавить("Продажи.Период");
ВыражениеЗакупки = ОператорВыбораПродаж.ВыбираемыеПоля.Добавить("0");
ВыражениеПродажи = ОператорВыбораПродаж.ВыбираемыеПоля.Добавить("ЕСТЬNULL(Продажи.СуммаОборот, 0)");
ЗапросВыбораИзИБ.Колонки[2].Поля.Установить(1,ВыражениеЗакупки);
ЗапросВыбораИзИБ.Колонки[3].Поля.Установить(1,ВыражениеПродажи);
//Добавляем отбор
ОператорВыбораПродаж.Отбор.Добавить("НЕ Товары.ЭтоГруппа");
//Индексируем данные
ЗапросВыбораИзИБ.Индекс.Добавить(ЗапросВыбораИзИБ.Колонки[0]);
ЗапросВыбораИзИБ.Индекс.Добавить(ЗапросВыбораИзИБ.Колонки[1]);
//Устанавливаем параметры выбора данных
ОператорВыбораПродаж.ВыбиратьРазличные = Истина;
ОператорВыбораПродаж.КоличествоПолучаемыхЗаписей = 100;
////////////////
//Второй пакет запроса
ЗапросВыбораИзВТ = СхемаЗапроса.ПакетЗапросов.Добавить();
ОператорВыбрать = ЗапросВыбораИзВТ.Операторы[0];
//Устанавливаем сформированную в прошлом запросе временную таблицу как источник
Источник = ОператорВыбрать.Источники.Добавить("ТаблицаОбороты","ТаблицаОбороты");
ОператорВыбрать.ВыбираемыеПоля.Добавить("ТаблицаОбороты.Номенклатура");
ОператорВыбрать.ВыбираемыеПоля.Добавить("ТаблицаОбороты.Период");
ОператорВыбрать.ВыбираемыеПоля.Добавить("СУММА(ТаблицаОбороты.СуммаЗакупок)");
ОператорВыбрать.ВыбираемыеПоля.Добавить("СУММА(ТаблицаОбороты.СуммаПродаж)");
//Условие отбора
ОператорВыбрать.Отбор.Добавить("СУММА(ТаблицаОбороты.СуммаЗакупок) > 0");
//Устанавливаем псевдонимы колонок
ЗапросВыбораИзВТ.Колонки[0].Псевдоним = "Номенклатура";
ЗапросВыбораИзВТ.Колонки[1].Псевдоним = "Период";
ЗапросВыбораИзВТ.Колонки[2].Псевдоним = "СуммаЗакупок";
ЗапросВыбораИзВТ.Колонки[3].Псевдоним = "СуммаПродаж";
//Порядок сортировки данных
ЗапросВыбораИзВТ.Порядок.Добавить(ЗапросВыбораИзВТ.Операторы[0].Источники[0].Источник.ДоступныеПоля[0].Поля[6]);
ЗапросВыбораИзВТ.Порядок.Добавить(ЗапросВыбораИзВТ.Колонки[1]);
//Итоги запроса
ИтогНоменклатура = ЗапросВыбораИзВТ.КонтрольныеТочкиИтогов.Добавить(ЗапросВыбораИзВТ.Колонки[0]);
ИтогНоменклатура.ТипКонтрольнойТочки = ТипКонтрольнойТочкиСхемыЗапроса.ТолькоИерархия;
ЗапросВыбораИзВТ.ОбщиеИтоги =Истина;
ЗапросВыбораИзВТ.ВыраженияИтогов.Добавить(ЗапросВыбораИзВТ.Колонки[2]);
ЗапросВыбораИзВТ.ВыраженияИтогов.Добавить(ЗапросВыбораИзВТ.Колонки[3]);
////////////////
//Последний запрос пакета - удаление временной таблицы
ЗапросУничтоженияВТ = СхемаЗапроса.ПакетЗапросов.Добавить(Тип("ЗапросУничтоженияТаблицыСхемыЗапроса"));
ЗапросУничтоженияВТ.ИмяТаблицы = "ТаблицаОбороты";
// ДАЛЕЕ ЕСЛИнам необходимо этот запрос модифицировать дальше в зависимости от настроек.
// Рассмотрим несколько примеров модификация нашего пакета из 3х запросов:
// Пример 1. Допустим, у нас есть переменные "Организация" и "Склад". И в случае, если они заполнены, нам необходимо добавить в отбор данных условия на эти переменные.
Если ЗначениеЗаполнено(Организация) Тогда
ОператорВыбораЗакупок.Отбор.Добавить("Закупки.Организация = &Организация");
ОператорВыбораПродаж.Отбор.Добавить("Продажи.Организация = &Организация");
КонецЕсли;
Если ЗначениеЗаполнено(Склад) Тогда
ОператорВыбораЗакупок.Отбор.Добавить("Закупки.Склад = &Склад");
ОператорВыбораПродаж.Отбор.Добавить("Продажи.Склад = &Склад");
КонецЕсли;
// Пример 2. Нам нужно отобрать товары, для которых последняя цена выше 1000руб. Т.е. необходимо
// 1. Добавить в текст запроса выбор во временную таблицу из регистра цен номенклатуры, по которой цены выше 1000руб.
// 2. Добавить при выборе данных условия по этой временной таблице в оба запроса выбора данных (закупки и продажи).
// Как вклиниваться в текстовый запрос для выполнения этих действий, вы пожете представить самостоятельно.
// Программно мы просто добавляем строки кода:
//Добавляем временную таблицу
ЗапросИзРегистраЦен = СхемаЗапроса.ПакетЗапросов.Добавить();
//Настраиваем временную таблицу
ЗапросИзРегистраЦен.ТаблицаДляПомещения = "ВТ_ЦеныНоменклатуры";
ОператорВыбрать = ЗапросИзРегистраЦен.Операторы[0];
Источник = ОператорВыбрать.Источники.Добавить("РегистрСведений.ЦеныНоменклатуры.СрезПоследних","ЦеныНоменклатурыСрезПоследних");
ОператорВыбрать.ВыбираемыеПоля.Добавить("ЦеныНоменклатурыСрезПоследних.Номенклатура");
ОператорВыбрать.Отбор.Добавить("ЦеныНоменклатурыСрезПоследних.Цена > &Цена");
//Сдвигаем новую табличку перед запросами выбора данных
СхемаЗапроса.ПакетЗапросов.Сдвинуть(СхемаЗапроса.ПакетЗапросов.Индекс(ЗапросИзРегистраЦен),0);
//Добавляем условия в исходные запросы
ОператорВыбораЗакупок.Отбор.Добавить("Закупки.Номенклатура В (ВЫБРАТЬ ВТ_ЦеныНоменклатуры.Номенклатура ИЗ ВТ_ЦеныНоменклатуры КАК ВТ_ЦеныНоменклатуры)");
ОператорВыбораПродаж.Отбор.Добавить("Продажи.Номенклатура В (ВЫБРАТЬ ВТ_ЦеныНоменклатуры.Номенклатура ИЗ ВТ_ЦеныНоменклатуры КАК ВТ_ЦеныНоменклатуры)");
// Еще один небольшой пример использования схемы запроса. Формирование запроса, выполняющего поиск задвоенных значений предопределенных данных.
// Без обращения к метаданным формирует один общий запрос ко всем справочникам, планам счетов, ПВХ, ПВР вцелом по конфигурации.
СхемаЗапроса = Новый СхемаЗапроса;
КоллекцияОператоры = СхемаЗапроса.ПакетЗапросов[0].Операторы;
Для каждого ГруппаТаблиц Из СхемаЗапроса.ПакетЗапросов[0].ДоступныеТаблицы Цикл
Если ГруппаТаблиц.Представление = "Справочники"
ИЛИ ГруппаТаблиц.Представление = "ПланыСчетов"
ИЛИ ГруппаТаблиц.Представление = "ПланыВидовРасчета"
ИЛИ ГруппаТаблиц.Представление = "ПланыВидовХарактеристик" Тогда
Для каждого Таблица Из ГруппаТаблиц.Состав Цикл
Для каждого ПолеТаблицы Из Таблица.Поля Цикл
Если ПолеТаблицы.Имя = "ИмяПредопределенныхДанных" Тогда
НовыйОператор = КоллекцияОператоры.Добавить();
НовыйИсточник = НовыйОператор.Источники.Добавить(Таблица,"СправочникИмя");
НовыйОператор.ВыбираемыеПоля.Добавить(""""+Таблица.Имя+"""");
НовыйОператор.ВыбираемыеПоля.Добавить("КОЛИЧЕСТВО(РАЗЛИЧНЫЕ СправочникИмя.ИмяПредопределенныхДанных)" );
НовыйОператор.Группировка.Добавить("СправочникИмя.ИмяПредопределенныхДанных");
НовыйОператор.Отбор.Добавить("СправочникИмя.Предопределенный");
НовыйОператор.Отбор.Добавить("КОЛИЧЕСТВО(РАЗЛИЧНЫЕ СправочникИмя.Ссылка) > 1");
Продолжить;
КонецЕсли;
КонецЦикла;
КонецЦикла;
КонецЕсли;
КонецЦикла;
Категория:
Запросы Как включить режим редактирования записей в списке? В 8.1 для многих объектов (справочники, регистры сведений и т.п.) в свойствах можно было настроить способ редактирования записей/элементов: в диалоге или в списке или обоими способами
В 8.2 эту возможность убрали из целей производительности, Максим Радченко пишет в своей книге:
В версии 8.2 не поддерживается режим редактирования ссылочных данных информационной базы в списке. Данные можно редактировать только в форме.
При работе в режиме управляемого приложения свойство объекта конфигурации Способ редактирования игнорируется, и данные редактируются всегда в отдельной форме.
Это относится ко всем таблицам, источником данных которых является динамический список.
Если же таблица имеет другой источник данных (табличная часть, дерево значений и т.д.), то ее данные редактируются непосредственно в списке
В обычных формах, программно можно установить режим редактирования в списке
Код 1C v 8.х ЭлементыФормы.СписокДоговорыПайщиков.СпособРедактирования = СпособРедактированияСписка.ВСписке;
// или
ЭлементыФормы.ДанныеФизЛиц.СпособРедактирования = СпособРедактированияСписка.ВСписке;
Для Регистра Сведений или Справочника - открыть палитру Свойства - закладка - представление - установить способ редактирования В Списке
Категория:
Список Справочника, Документов, Регистров Программное создание динамического списка для регистра сведений Код 1C v 8.х &НаСервере
Процедура ИзменитьНаСервере(ИмяРеквизита)
// проверяем нужно ли создавать новый реквизит
Если Элементы.Найти(ИмяРеквизита) = Неопределено Тогда
МассивРеквизитов = Новый Массив;
// добавляем реквизиты
МассивРеквизитов.Добавить(Новый РеквизитФормы(ИмяРеквизита, Новый ОписаниеТипов("ДинамическийСписок"),,"Поле таблицы"));
// изменяем реквизиты формы
ЭтаФорма.ИзменитьРеквизиты(МассивРеквизитов);
// устанавлиеваем основную таблицу
ЭтаФорма[ИмяРеквизита].ОсновнаяТаблица = "РегистрСведений." + ИмяРеквизита;
// добавляем динамический список на форму
Элемент = Элементы.Добавить(ИмяРеквизита, Тип("ТаблицаФормы"), ЭтаФорма);
Элемент.ПутьКДанным = ИмяРеквизита;
Элемент.Видимость = Истина;
//добавляем колонки динамического списка
КолонкаКод = Элементы.Добавить("Код" + ИмяРеквизита, Тип("ПолеФормы"), Элементы[ИмяРеквизита]);
КолонкаКод.Вид = ВидПоляФормы.ПолеВвода;
КолонкаКод.ПутьКДанным = ИмяРеквизита + ".Код";
КолонкаНаименование = Элементы.Добавить("Наименование" + ИмяРеквизита, Тип("ПолеФормы"), Элементы[ИмяРеквизита]);
КолонкаНаименование.Вид = ВидПоляФормы.ПолеВвода;
КолонкаНаименование.ПутьКДанным = ИмяРеквизита + ".Наименование";
КонецЕсли;
// если реквизит создан ранее меняем его видимость на форме
Если ТекущийСписок <> ИмяРеквизита Тогда
// при первом выполнении, реквизита нет
Если НЕ ПустаяСтрока(ТекущийСписок) Тогда
Элементы[ТекущийСписок].Видимость = Ложь;
конецЕсли;
Элементы[ИмяРеквизита].Видимость = Истина;
// промежуточная переменная, для определения текущего списка
ТекущийСписок = ИмяРеквизита;
КонецЕсли;
КонецПроцедуры
&НаКлиенте
Процедура АдресныеСокращения(Команда)
ИзменитьНаСервере("АдресныеСокращения");
КонецПроцедуры
&НаКлиенте
Процедура АдресныйКлассификатор(Команда)
ИзменитьНаСервере("АдресныйКлассификатор");
КонецПроцедуры
Пример
Категория:
1С Бухгалтерия 2.0 Работа с контактной информацией в типовых конфигурациях Код 1C v 8.х // Исправляем значения Контактной Информации контрагента в Регистре сведений
Функция ОчиститьEmail(
Контрагент,
ТипКонтактнойИнформации,
ВидКонтактнойИнформации,
Представление
)
// #1 Создаем набор записей
НаборЗаписей = РегистрыСведений.КонтактнаяИнформация.СоздатьНаборЗаписей();
// #2 Отбираем (по измерениям)
НаборЗаписей.Отбор.Объект.Установить(Контрагент);
НаборЗаписей.Отбор.Тип.Установить(ТипКонтактнойИнформации);
НаборЗаписей.Отбор.Вид.Установить(ВидКонтактнойИнформации);
// #3 Читаем набор записей
НаборЗаписей.Прочитать();
// #4 редактируем в цикле каждую запись из набора
Для каждого СтрНабЗап Из НаборЗаписей Цикл
СтрНабЗап.Представление = "";
сообщить("" + Контрагент + " | "
+ ТипКонтактнойИнформации + " | "
+ ВидКонтактнойИнформации + " | "
+ Представление + " -> " + СтрНабЗап.Представление + " [Ok!]");
КонецЦикла;
// #5 Сохраняем набор записей
НаборЗаписей.Записать();
КонецФункции
// Получить таблицу значений
// Записи из Регистра Сведений КонтактнаяИнформация с некорректными Email
функция ПолучитьТЗ()
Запрос = Новый Запрос;
Запрос.Текст = "ВЫБРАТЬ ПЕРВЫЕ 1000000
| КонтактнаяИнформация.Объект,
| КонтактнаяИнформация.Тип,
| КонтактнаяИнформация.Вид,
| КонтактнаяИнформация.Представление,
| (ВЫРАЗИТЬ(КонтактнаяИнформация.Представление КАК СТРОКА(1000))) как стрПредставление
|ИЗ
| РегистрСведений.КонтактнаяИнформация КАК КонтактнаяИнформация
|ГДЕ
| КонтактнаяИнформация.Тип = &Тип
| //И КонтактнаяИнформация.Вид = &Вид
| И (ВЫРАЗИТЬ(КонтактнаяИнформация.Представление КАК СТРОКА(1000))) <> &ПустоеЗначение
| И НЕ КонтактнаяИнформация.Представление ПОДОБНО &ШаблонEmail";
//Параметры запроса:
// Типы контактной информации
Запрос.УстановитьПараметр("Тип",Перечисления.ТипыКонтактнойИнформации.АдресЭлектроннойПочты);
// пустая строка
Запрос.УстановитьПараметр("ПустоеЗначение","");// Строка
// критерий отбора для примера простой - строка содержит символ "@" - значит это почта
Запрос.УстановитьПараметр("ШаблонEmail","%@%");// Строка
Результат = Запрос.Выполнить();
//Выборка = Результат.Выбрать();
// результат запроса выгрузить в
// таблицу значений
ПлохиеEmailТЗ = Результат.Выгрузить();
Возврат ПлохиеEmailТЗ;
КонецФункции
Категория:
1С Общие вопросы - Обычные формы