Регламентные задания

Версия для печатиPDF-версия

Платформа:

Нужно сделать регламентное задание котрое создает документ контролирующий остатки товара и если нужно то заказывает товар. Помогите, пожалуйста с реализацией. Задание в файле.

Прикреплённые файлы: 

А в чём проблемы?

Создаёте периодический регистр сведений, который будет хранить данные по номенклатуре. Создаёте документ, который будет записывать данные в этот регистр. Создаёте регламентное задание, в котором запросом получаете товары, остаток которых на складе меньше минимума (или меньше точки заказа) и по этим товарам создаёте заказы поставщикам.

Непонятно только зачем в регистре измерение Контрагент (Поставщик). Остатки по нему всё равно не получить. Если контрагент нужен для создания заказа поставщику, то лучше его сделать ресурсом регистра. А лучше добавить у номенклатуры новый реквизит Основной поставщик.

Контрагент для создания документа Заказ поставщику. Документ новый создает записи в новом регистре, регламентной их просматривает каждый день задала расписание и если остатка не хватает создает заказ. Как просмотреть остаток товара, номенкатура склад и организация известны? Сейчас в инете посмотрю еще запросы по товарам.

 

Остатки получать из регистра ТоварыОрганизаций. Нужно настроить аналитику учёта номенклатуры и использовать одноименное измерение регистра

Запрос = Новый Запрос;
Запрос.Текст = 
"ВЫБРАТЬ
| ном.организация,
| ном.склад,
| ном.мин,
| ном.макс,
| ном.среднее,
| ном.номенклатура как номенклатура,
| ном.контрагент
|ИЗ
| РегистрСведений.СреднееНоменклатура.СрезПоследних КАК Ном";
 
Выборка=Запрос.Выполнить();
Выборка2=выборка.Выбрать();
сч=1;
Пока Выборка2.следующий() Цикл
   Выборка1=выборка2.Получить(сч);????????
Запрос1 = Новый Запрос(
   "ВЫБРАТЬ
   |   ТоварыНаСкладеОстатки.Номенклатура КАК Наименование,
   |   ТоварыНаСкладеОстатки.Количество КАК Количество,
   |   ТоварыНаСкладеОстатки.Склад КАК Склад,
 
   |ИЗ
   |   РегистрНакопления.ТоварыНаСкладах.Остатки КАК ТоварыНаСкладеОстатки
   |ГДЕ
   |   ТоварыНаСкладеОстатки.номенклатура = Выборка1.номенклатура"
  );
   Результат = Запрос1.Выполнить();
   ТабЗнач=Результат.Выбрать();
Пока ТабЗнач.Следующий() Цикл
 
  
КонецЦикла;
сч=сч+1;
 КонецЦикла;
не знаю как добраться до строки запроса

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

Используйте временные таблицы в запросе и соединения таблиц.

И как я писал выше, нужно остатки из регистра ТоварыОрганизаций получать, т.к. по регистру ТоварыНаСкладах не получить остатки в разрезе организаций.

Запрос = Новый Запрос;
Запрос.Текст = 
"ВЫБРАТЬ
| ном.организация,
| ном.склад,
| ном.мин,
| ном.макс,
| ном.среднее,
| ном.номенклатура как номенклатура,
| ном.контрагент
|ИЗ
| РегистрСведений.СреднееНоменклатура.СрезПоследних КАК Ном
|ОБЪЕДИНИТЬ
|ВЫБРАТЬ
    |   ТоварыНаСкладеОстатки.организация КАК организация,
    |   ТоварыНаСкладеОстатки.Номенклатура КАК Номенклатура,
    |   ТоварыНаСкладеОстатки.Количество КАК Количество,
    |   ТоварыНаСкладеОстатки.Склад КАК Склад,
 
    |ИЗ
    |   РегистрНакопления.ТоварыОрганизаций.Остатки КАК ТоварыНаСкладеОстатки" ;
 
Выборка=Запрос.Выполнить();
Выборка2=выборка.Выбрать();
сч=1;
Пока Выборка2.следующий() Цикл
   Выборка1=выборка2.Получить(сч);
 
сч=сч+1;
 КонецЦикла;
Как добраться до строки запроса и как для проверки работы вызвать регламентное задание из программы?

1. И что вы получите этим запросом? Надо хотя бы количество с разным знаком получать, чтобы при группировке получить какой-то приемлемый для обработки итог.

Я накидал свой вариант запроса, которым сразу получается номенклатура, которую нужно заказать:

ВЫБРАТЬ
	ТочкиЗаказаСрезПоследних.Организация КАК Организация,
	ТочкиЗаказаСрезПоследних.Склад КАК Склад,
	ТочкиЗаказаСрезПоследних.Номенклатура,
	ТочкиЗаказаСрезПоследних.Поставщик КАК Поставщик,
	ВЫБОР
		КОГДА ТочкиЗаказаСрезПоследних.ТочкаЗаказа = 0
			ТОГДА ВЫБОР
					КОГДА ТочкиЗаказаСрезПоследних.Мин >= ЕСТЬNULL(ТоварыОрганизацийОстатки.КоличествоОстаток, 0)
						ТОГДА ТочкиЗаказаСрезПоследних.Макс - ЕСТЬNULL(ТоварыОрганизацийОстатки.КоличествоОстаток, 0)
					ИНАЧЕ 0
				КОНЕЦ
		ИНАЧЕ ВЫБОР
				КОГДА ТочкиЗаказаСрезПоследних.ТочкаЗаказа >= ЕСТЬNULL(ТоварыОрганизацийОстатки.КоличествоОстаток, 0)
					ТОГДА ТочкиЗаказаСрезПоследних.Макс - ЕСТЬNULL(ТоварыОрганизацийОстатки.КоличествоОстаток, 0)
				ИНАЧЕ 0
			КОНЕЦ
	КОНЕЦ КАК Заказать
ИЗ
	РегистрСведений.ТочкиЗаказа.СрезПоследних КАК ТочкиЗаказаСрезПоследних
		ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.ТоварыОрганизаций.Остатки КАК ТоварыОрганизацийОстатки
		ПО ТочкиЗаказаСрезПоследних.Организация = ТоварыОрганизацийОстатки.Организация
			И ТочкиЗаказаСрезПоследних.Склад = ТоварыОрганизацийОстатки.АналитикаУчетаНоменклатуры.Склад
			И ТочкиЗаказаСрезПоследних.Номенклатура = ТоварыОрганизацийОстатки.АналитикаУчетаНоменклатуры.Номенклатура
ГДЕ
	ВЫБОР
			КОГДА ТочкиЗаказаСрезПоследних.ТочкаЗаказа = 0
				ТОГДА ВЫБОР
						КОГДА ТочкиЗаказаСрезПоследних.Мин >= ЕСТЬNULL(ТоварыОрганизацийОстатки.КоличествоОстаток, 0)
							ТОГДА ТочкиЗаказаСрезПоследних.Макс - ЕСТЬNULL(ТоварыОрганизацийОстатки.КоличествоОстаток, 0)
						ИНАЧЕ 0
					КОНЕЦ
			ИНАЧЕ ВЫБОР
					КОГДА ТочкиЗаказаСрезПоследних.ТочкаЗаказа >= ЕСТЬNULL(ТоварыОрганизацийОстатки.КоличествоОстаток, 0)
						ТОГДА ТочкиЗаказаСрезПоследних.Макс - ЕСТЬNULL(ТоварыОрганизацийОстатки.КоличествоОстаток, 0)
					ИНАЧЕ 0
				КОНЕЦ
		КОНЕЦ > 0
ИТОГИ ПО
	Поставщик,
	Организация,
	Склад

* Поставщик - это ресурс регистра сведений ТочкиЗаказа (НЕ Измерение!).

2. Процедура, вызываемая регламентным заданием, должна располагаться в общем модуле с директивой Экспорт. Для проверки можно создать обработку, из которой вызывать эту процедуру.

работает выводит еще пустые какие-то значения, посмотрю еще. Спасибо!

Для каждого СтрокаТаблицы Из товары Цикл
 
Движение = регистрысведений.среднееноменклатура.СоздатьМенеджерЗаписи();
//Движение=проводка3.Добавить();
 
Движение.Период=Дата;
Движение.Организация=организация;
Движение.Контрагент=Контрагент;
Движение.Склад=Склад;
Движение.Период=ссылка.Дата;
Движение.Номенклатура=строкатаблицы.Номенклатура;
Движение.Мин=строкатаблицы.Мин;
Движение.Макс=строкатаблицы.Макс;
Движение.Среднее=строкатаблицы.Среднее;
Движение.Записать();
КонецЦикла;
ответственный=ПользователиИнформационнойБазы.ТекущийПользователь();
Записать(режимзаписидокумента.Проведение);
 Вызываеться из документа. Пока док не записан при нажатии вызывает ошибку запись не верна! Период не может быть пустым! Дата есть почему ее не пишет?

В каком модуле и обработчике какого события производите запись в регистр?

 

При проведении документа. Как новый документ вывести в меню программы и записать отвественного в поле ввода документа?

1. "При проведении документа" - т.е. в процедуре ОбработкаПроведения() модуля объекта документа?

2. Нужно добавить документ в какую-нибудь подсистему, включенную в командный интерфейс.

3. Ответственного можно заполнять, например, в процедуре ПередЗаписью модуля объекта:

Если ЭтоНовый() Тогда

    Ответственный = Пользователи.ТекущийПользователь();

КонецЕсли; 

1.Да в процедуре проведения.

Процедура ДействияФормыДействиеЗаполнитьИПровести(Кнопка)
Для каждого СтрокаТаблицы Из товары Цикл
 
Движение = регистрысведений.среднееноменклатура.СоздатьМенеджерЗаписи();
Д=Дата;
Движение.Период=(Д);
Движение.Организация=организация;
Движение.Контрагент=Контрагент;
Движение.Склад=Склад;
Движение.Период=ссылка.Дата;лишняя строка была!!!!!!!!!!!СДЕЛАЛА
Движение.Номенклатура=строкатаблицы.товар;
Движение.Мин=строкатаблицы.Мин;
Движение.Макс=строкатаблицы.Макс;
Движение.Среднее=строкатаблицы.Среднее;
попытка
Движение.Записать();
исключение
сообщить("косяк");
конецпопытки;
 
КонецЦикла;
ответственный=ПользователиИнформационнойБазы.ТекущийПользователь();
Записать(режимЗаписиДокумента.Проведение);
 
 
КонецПроцедуры
Если перед нажатием нажмешь кн.Записать, то работает, если новый или скопированный то ошибку дает.
Дату видит.в отладчике движение.период 06.03.2016 0:00:00 Дата

У вас период не заполняется, т.к. зачем-то Период пытаетесь заполнить в 2 строках:

Движение.Период=Дата;
Движение.Период=ссылка.Дата;

Если документ ещё не записан, то у ссылки на него дата не заполнена.

Обработчик команды и обработчик события объекта - это не одно и то же. Нужно все движения заполнять в специальной процедуре модуля объекта документа (не в модуле формы!), которая так и называется ОбработкаПроведения().

Создание процедуры обработки проведения в модуле объекта

Документ внесён в список регистраторов регистра сведений? Если нет, то нужно это сделать. (У регистра сведений должен быть установлен Режим записи = "Подчинение регистратору".) Тогда можно будет создать ОбработкуПроведения с помощью конструктора движений.

Запуск конструктора движений

ПС. У вас точно конфигурация УТ 11.1? По коду больше похоже на обычное приложение.

Спасибо огромное! Все сделала это задание как Вы посоветовали, работает.Конфигурация  1.1.36.2, я еще путаюсь, работаю стажером во франчайзи со многими конфигурациями. Учусь еще. На восьмерке только 2 мес. работаю, опыта мало. Но ничего потихоньку со временем научусь!

 
Запрос = Новый Запрос;
Запрос.Текст = 
"ВЫБРАТЬ
|ТочкиЗаказаСрезПоследних.Организация КАК Организация,
|ТочкиЗаказаСрезПоследних.Склад КАК Склад,
|ТочкиЗаказаСрезПоследних.Номенклатура,
|ТочкиЗаказаСрезПоследних.контрагент КАК Поставщик,
|ВЫБОР
| КОГДА ТочкиЗаказаСрезПоследних.среднее = 0
| ТОГДА ВЫБОР
| КОГДА ТочкиЗаказаСрезПоследних.Мин >= ЕСТЬNULL(ТоварыОрганизацийОстатки.КоличествоОстаток, 0)
| ТОГДА ТочкиЗаказаСрезПоследних.Макс - ЕСТЬNULL(ТоварыОрганизацийОстатки.КоличествоОстаток, 0)
| ИНАЧЕ 0
| КОНЕЦ
| ИНАЧЕ ВЫБОР
| КОГДА ТочкиЗаказаСрезПоследних.среднее >= ЕСТЬNULL(ТоварыОрганизацийОстатки.КоличествоОстаток, 0)
| ТОГДА ТочкиЗаказаСрезПоследних.Макс - ЕСТЬNULL(ТоварыОрганизацийОстатки.КоличествоОстаток, 0)
| ИНАЧЕ 0
| КОНЕЦ
| КОНЕЦ КАК Заказать
|ИЗ
| РегистрСведений.среднееноменклатура.СрезПоследних КАК ТочкиЗаказаСрезПоследних
| ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.ТоварыОрганизаций.Остатки КАК ТоварыОрганизацийОстатки
| ПО ТочкиЗаказаСрезПоследних.Организация = ТоварыОрганизацийОстатки.Организация
| И ТочкиЗаказаСрезПоследних.Склад = ТоварыОрганизацийОстатки.Склад
| И ТочкиЗаказаСрезПоследних.Номенклатура = ТоварыОрганизацийОстатки.Номенклатура
|ГДЕ
| ВЫБОР
| КОГДА ТочкиЗаказаСрезПоследних.среднее = 0
| ТОГДА ВЫБОР
| КОГДА ТочкиЗаказаСрезПоследних.Мин >= ЕСТЬNULL(ТоварыОрганизацийОстатки.КоличествоОстаток, 0)
| ТОГДА ТочкиЗаказаСрезПоследних.Макс - ЕСТЬNULL(ТоварыОрганизацийОстатки.КоличествоОстаток, 0)
| ИНАЧЕ 0
| КОНЕЦ
| ИНАЧЕ ВЫБОР
| КОГДА ТочкиЗаказаСрезПоследних.среднее >= ЕСТЬNULL(ТоварыОрганизацийОстатки.КоличествоОстаток, 0)
| ТОГДА ТочкиЗаказаСрезПоследних.Макс - ЕСТЬNULL(ТоварыОрганизацийОстатки.КоличествоОстаток, 0)
| ИНАЧЕ 0
| КОНЕЦ
| КОНЕЦ > 0
|Сгруппировать по точкизаказасрезпоследних.организация,точкизаказасрезпоследних.склад,точкизаказасрезпоследних.номенклатура,точкизаказасрезпоследних.контрагент упорядочить по ТочкиЗаказаСрезПоследних.контрагент
Ругаеться. Как добавить группировку правильно?
";
 
    Выборка=Запрос.Выполнить();
ТЗ=новый таблицаЗначений;
ТЗ=Выборка.Выгрузить();
ТЗ.Свернуть("организация,склад,номенклатура,поставщик","Заказать");
ТЗ.Сортировать("Поставщик");
сч=0;
пост="";
орг="";
склад="";
Для каждого строкатаблицы из тз Цикл
Попытка
выборка2=тз.Получить(сч);
 
Если (выборка2.заказать)<>0 тогда
сообщить(строка(орг)+строка(пост)+строка(склад));
 
Док1=Документы.ЗаказПоставщику;
Если НЕ((пост=выборка2.поставщик)и(орг=выборка2.организация)и(склад=выборка2.склад))или
((пост="")и(орг="")и(склад="")) тогда
Док=Док1.СоздатьДокумент();
пост=Выборка2.поставщик;
орг=выборка2.организация;
склад=выборка2.склад ;
 
конецесли;
док.Дата=ТекущаяДата();
док.Склад=выборка2.склад;
док.Организация=выборка2.организация;
док.ВалютаДокумента= Константы.ВалютаРегламентированногоУчета;
док.Контрагент=выборка2.поставщик;
док.ДоговорКонтрагента=Выборка2.поставщик.ОсновнойДоговорконтрагента;
Док.ДатаОплаты=Док.Дата+Док.ДоговорКонтрагента.ДопустимоеЧислоДнейЗадолженности*84600;
Док.ДатаПоступления=Док.Дата+Док.ДоговорКонтрагента.ДопустимоеЧислоДнейЗадолженности*84600;
стр=док.Товары.Добавить();
стр.ЕдиницаИзмерения=выборка2.номенклатура.ССЫЛКА.базоваяединицаизмерения;
сообщить(стр.ЕдиницаИзмерения);
стр.Количество=выборка2.заказать;
стр.Номенклатура=выборка2.номенклатура;
Док.Записать();
КонецЕсли;
 
исключение
Конецпопытки;
 
сч=сч+1;
 
 КонецЦикла;
 
Как избавиться от таблицы значений методом группировать и упорядочить по в запросе?

В моём примере запроса это уже присутствовало.
Нужно убрать из запроса секцию СГРУППИРОВАТЬ и добавить секцию ИТОГИ:

ИТОГИ ПО
	Поставщик,
	Организация,
	Склад

Далее сразу получаете выборки по группировкам и создаёте документы:

РезультатЗапроса = Запрос.Выполнить();
ВыборкаПоставщик = РезультатЗапроса.Выбрать(ОбходРезультатаЗапроса.ПоГруппировкам);
Пока ВыборкаПоставщик.Следующий() Цикл
	ВыборкаОрганизация = ВыборкаПоставщик.Выбрать(ОбходРезультатаЗапроса.ПоГруппировкам);
	Пока ВыборкаОрганизация.Следующий() Цикл
		ВыборкаСклад = ВыборкаОрганизация.Выбрать(ОбходРезультатаЗапроса.ПоГруппировкам);
		Пока ВыборкаСклад.Следующий() Цикл
			// Создание документа Заказ поставщику
			НовДок = Документы.ЗаказПоставщику.СоздатьДокумент();
			// Заполнение шапки документа
			НовДок.Дата = ТекущаяДата();
			НовДок.Контрагент = ВыборкаСклад.Поставщик;
			ЗаполнитьЗначенияСвойств(НовДок, ВыборкаСклад);
			// Заполнение табличной части Товары
			ВыборкаДетальныеЗаписи = ВыборкаСклад.Выбрать();
			Пока ВыборкаДетальныеЗаписи.Следующий() Цикл
				НовСтрока = НовДок.Товары.Добавить();
				ЗаполнитьЗначенияСвойств(НовСтрока, ВыборкаДетальныеЗаписи);
			КонецЦикла;
			Попытка
				НовДок.Записать();
			Исключение
			КонецПопытки;
		КонецЦикла;
	КонецЦикла;
КонецЦикла;

Использование таблицы значений здесь необоснованно.

Еще сейчас посмотрела при отмене проведения документа не удаляються записи регистра. Как сделать?

Новый документ сделали регистратором для регистра сведений? Если да, то нужно установить Удаление движений = "Удалять автоматически при отмене проведения". Если нет, то надо самому прописывать удаление записей регистра в процедуре ОбработкаУдаленияПроведения() в модуле объекта.

Я советую сделать документ регистратором. Так будет проще и правильней.

Установила в регистре подчинен регистратору, котрый выбрала док. среднее номенлатура.
обработка проведения пишу

//Движение = регистрысведений.среднееноменклатура.СоздатьНаборЗаписей();
Движение.Отбор.Регистратор.Установить(ссылка); 
движение.Прочитать();
Для каждого СтрокаТаблицы Из товары Цикл
 
 
стр=Движение.Добавить();
стр.Регистратор=ссылка;
Д=Дата;
стр.Период=конецдня(Д+200);
стр.Организация=организация;
стр.Контрагент=Контрагент;
стр.Склад=Склад;
стр.Номенклатура=строкатаблицы.товар;
стр.Мин=строкатаблицы.Мин;
стр.Макс=строкатаблицы.Макс;
стр.Среднее=строкатаблицы.Среднее;
   
Конеццикла;
Попытка
Движение.Записать();
исключение
сообщить("Запись существует! Снимите с проведения и обновите запись.");
Конецпопытки;
При перепроведении уже проведенного дока взывает ошибку запись уже существует. Как то избавиться можно?
 

Конструктором движений не пробовали воспользоваться?

Текст процедуры примерно следующий:

// регистр ТочкиЗаказа
Движения.ТочкиЗаказа.Записывать = Истина;
Для Каждого ТекСтрокаТовары Из Товары Цикл
	Движение = Движения.ТочкиЗаказа.Добавить();
	Движение.Период = Дата;
	Движение.Организация = Организация;
	Движение.Склад = Склад;
	Движение.Номенклатура = ТекСтрокаТовары.Номенклатура;
	Движение.ТочкаЗаказа = ТекСтрокаТовары.ТочкаЗаказа;
КонецЦикла;

Да, сделала конструктором движений.  Надо сделать чтобы задавался вопрос если документ изменялся " сохранить документ" если нет то не создавать документы. Это просто метод записать использовать?

Добавьте проверку в обработчике ПередЗаписью() модуля формы документа.

Сказали сделать обращение к результату запроса без цикла. Это как?

Выборка=Запрос.Выполнить();
ТЗ=Выборка.Выбрать();
пост="";
орг="";
склад="";
//Для каждого строкатаблицы из тз Цикл
Пока ТЗ.Следующий() Цикл
//сообщить(строка(тз.Получить(сч)));
Попытка
//выборка2=тз.Получить(сч);
Если (тз.заказать)<>0 тогда
 
Док1=Документы.ЗаказПоставщику;
Если НЕ((пост=тз.поставщик)и(орг=тз.организация)и(склад=тз.склад))или
((пост="")и(орг="")и(склад="")) тогда
Док=Док1.СоздатьДокумент();
пост=тз.поставщик;
орг=тз.организация;
склад=тз.склад ;
 
конецесли;
док.Дата=ТекущаяДата();
док.Склад=тз.склад;
док.Организация=тз.организация;
док.ВалютаДокумента= Константы.ВалютаРегламентированногоУчета;
док.Контрагент=тз.поставщик;
док.ДоговорКонтрагента=тз.поставщик.ОсновнойДоговорконтрагента;
Док.ДатаОплаты=Док.Дата+Док.ДоговорКонтрагента.ДопустимоеЧислоДнейЗадолженности*84600;
Док.ДатаПоступления=Док.Дата+Док.ДоговорКонтрагента.ДопустимоеЧислоДнейЗадолженности*84600;
стр=док.Товары.Добавить();
стр.ЕдиницаИзмерения=тз.номенклатура.базоваяединицаизмерения;
стр.Количество=тз.заказать;
стр.Номенклатура=тз.номенклатура;
Док.Записать();
КонецЕсли;
 
исключение
Конецпопытки;
 
 
 КонецЦикла;
 
 

 

ТЗ=Выборка.Выбрать();
пост="";
орг="";
склад="";
Для каждого строкатаблицы из тз Цикл
Так тоже перебор?

Лучше уточните, что они имеют в виду. От цикла тут никуда не деться. Даже если использовать выгрузку в таблицу/дерево значений. Как я уже писал, выгрузка в таблицу значений здесь необоснованна. Работа с выборкой оптимальней по производительности и требованиям к ресурсам, чем работа с таблицей значений.

Уточнила ответили, "все параметры надо делать в запросе" на мое недоумение по поводу как без цикла обойтись если запрос дает возврат таблицу с энным колвом строк. Это как?

Можно, конечно, в запросе сразу получать договор контрагента, валюту, единицу измерения и пр. Может это имеется в виду?

нет говорит что перебор после запроса отправит базу в небытие.

???
Человек, наверное, с 8кой никогда не работал.

Страницы