Адресная система хранения на складе

Публикация № 556329

Разработка - Практика программирования

Склад Адресная система хранения Тестовое задание

Решение тестового задания. Разбор ошибок.

Дано:

Есть склад, на котором реализована адресная система хранения.

Каждое место хранения маркируется 3-х значным индексом вида:

<SS><NN><LL>

Где, SS номер ряда стеллажей, NN – номер стойки в ряду стеллажей, LL уровень стеллажа.

На складе ведется только количественный учет, без суммового.

Хранение товаров на складе определяется следующим правилам:

* На каждом месте хранения одновременно может находиться только товар одного вида.

* Каждому товару присуще свойство – коэффициент палетирования, указывающий сколько единиц хранения товара составляет палетту.

* На одном месте хранения может храниться не более одной полной палетты.

Задание:

Реализовать процессы склада, отвечающие следующим критериям:
Процесс Критерий
Прием товара Занять как можно меньше свободных мест хранения, соответственно оставить как можно больше свободных мест хранения
Отпуск товара Отпуск товара производится с минимальный перемещением персонала склада. Нужно отсортировать позиции в накладной в соответствии с порядком обхода склада.
Уплотнение склада Освободить как можно больше мест хранения.
Инвентаризация Частичная инвентаризация по товарным позициям или по местам хранения (ряд, стойка, уровень).
Создать следующие отчеты:
Отчет Описание
Остатки товара Остатки товара на складе по местам хранения
Материальная ведомость Все движения выбранных товарных позиций по складу за выбранный период
Загруженность склада Временная диаграмма загруженности склада за выбранный период

Решение.

Создаем:

1. Справочник "Номенклатура", реквизит КП(Коэффициент палетирования)

2. Регистр сведений "МестаХранения", измерения: SS, NN, LL; ресурс: ПорядокОбхода

Будет хранить перечень всех мест хранения на складе

3. Регистр накопления "ПозицииТовара", измерения: Номенклатура, SS, NN, LL; ресурс: Количество

Будет хранить складские остатки в разрезе номенклатур и адресов

Прием товара

Создаем документ "ПриемТовара", табличные части: 

- "Товары" (колонки: Номенклатура, Количество);

- "МестаХранения" (колонки: Номенклатура, SS, NN, LL, Количество)

Создаем форму, размещаем на ней элементы управления.

Документ будет позволять ручное размещение товара, поэтому необходима функция проверки правильности заполнения позиций (может запускаться перед записью документа и после редактирования строки):

// Проверить строки
//
&НаСервере
Функция МестаХраненияПроверитьСтроки(ПроверкаРаспределения = Истина, ВыводитьСообщения = Истина)
	
	// Получить места по складу
	тзМеста = СкладСервер.ПолучитьМеста(Объект.Дата);	
	
	тзМестаХранения = Объект.МестаХранения.Выгрузить();
	тзМестаХранения.Свернуть("Номенклатура, SS, NN, LL", "Количество");
	
	тзТовары = Объект.Товары.Выгрузить();
	тзТовары.Свернуть("Номенклатура", "Количество");
	
	// Проверка доступности мест хранения
	
	Для каждого СтрокаМестаХранения Из тзМестаХранения Цикл
		
		Отбор = Новый Структура();
		Отбор.Вставить("SS", СтрокаМестаХранения.SS);
		Отбор.Вставить("NN", СтрокаМестаХранения.NN);
		Отбор.Вставить("LL", СтрокаМестаХранения.LL);
		Строки = тзМеста.НайтиСтроки(Отбор);
		Если Строки.Количество() = 0 Тогда
			СообщениеПользователю("Место хранения SS: Парам1 NN: Парам2 LL: Парам3 не найдено!", Новый Структура("Парам1, Парам2, Парам3",  СтрокаМестаХранения.SS, СтрокаМестаХранения.NN, СтрокаМестаХранения.LL), ВыводитьСообщения);
			Возврат Ложь;
		ИначеЕсли Строки.Количество() > 1 ИЛИ НЕ (Строки[0].Номенклатура = СтрокаМестаХранения.Номенклатура ИЛИ Строки[0].Номенклатура = NULL) Тогда
			СообщениеПользователю("Место хранения SS: Парам1 NN: Парам2 LL: Парам3 содержит различные номенклатуры!", Новый Структура("Парам1, Парам2, Парам3",  СтрокаМестаХранения.SS, СтрокаМестаХранения.NN, СтрокаМестаХранения.LL), ВыводитьСообщения);
			Возврат Ложь;
		ИначеЕсли ?(Строки[0].Номенклатура = NULL,0,Строки[0].Количество) + СтрокаМестаХранения.Количество > СтрокаМестаХранения.Номенклатура.КП Тогда
			СообщениеПользователю("Место хранения SS: Парам1 NN: Парам2 LL: Парам3 переполнено! Доступно: Парам4", Новый Структура("Парам1, Парам2, Парам3, Парам4",  СтрокаМестаХранения.SS, СтрокаМестаХранения.NN, СтрокаМестаХранения.LL, (?(Строки[0].Номенклатура = NULL, СтрокаМестаХранения.Номенклатура.КП,Строки[0].НоменклатураКП) - ?(Строки[0].Номенклатура = NULL,0,Строки[0].Количество))), ВыводитьСообщения);
			Возврат Ложь;
		КонецЕсли;
		
		СтрокаПроверки = тзТовары.Добавить();
		СтрокаПроверки.Номенклатура = СтрокаМестаХранения.Номенклатура;
		СтрокаПроверки.Количество = - СтрокаМестаХранения.Количество;
		
	КонецЦикла; 
	
	// Проверить все ли позиции номенклатуры распределены
	
	Если ПроверкаРаспределения Тогда
	
		тзТовары.Свернуть("Номенклатура", "Количество");

		Для каждого СтрокаПроверки Из тзТовары Цикл
			Если НЕ СтрокаПроверки.Количество = 0 Тогда
				СообщениеПользователю("Не размещено Парам1 в количестве: Парам2", Новый Структура("Парам1, Парам2",  СтрокаПроверки.Номенклатура, СтрокаПроверки.Количество), ВыводитьСообщения);
				Возврат Ложь
			КонецЕсли;
		КонецЦикла;
	
	КонецЕсли;
	
	Возврат Истина;
	
КонецФункции

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

// Получить места по складу
//
Функция ПолучитьМеста(Период) Экспорт

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

КонецФункции // ПолучитьМеста()

Процедура "СообщениеПользователю" из глобального модуля:

Процедура СообщениеПользователю(Знач Шаблон, Параметры = Неопределено, ВыводитьСообщение = Истина) Экспорт

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

КонецПроцедуры // СообщениеПользователю()

Для автоматического распределения поступивших товаров создаем команду "Заполнить" и прописываем обработчик:

&НаСервере
Процедура ЗаполнитьНаСервере()
	
	Объект.МестаХранения.Очистить();
	
	тзТовары = Объект.Товары.Выгрузить();
	тзТовары.Свернуть("Номенклатура", "Количество");
	
	// Получить места по складу в порядке увеличения места
	тзОстатки = СкладСервер.ПолучитьМеста(Объект.Дата);	
	
	Для каждого СтрокаТовары Из тзТовары Цикл
		Если НЕ СтрокаТовары.Количество = 0 Тогда
			ОсталосьРаспределить = СтрокаТовары.Количество;
			
			// Смотрим где осталось место
			Для каждого МестоХранения Из тзОстатки Цикл
				Если НЕ МестоХранения.Номенклатура = СтрокаТовары.Номенклатура Тогда
					Продолжить;
				КонецЕсли;
				Если НЕ МестоХранения.Места > 0 Тогда
					Продолжить;
				КонецЕсли;
				НоваяСтрока = Объект.МестаХранения.Добавить();
				ЗаполнитьЗначенияСвойств(НоваяСтрока, МестоХранения);
				Если ОсталосьРаспределить > МестоХранения.Места Тогда
					НоваяСтрока.Количество = МестоХранения.Места;	
				Иначе
					НоваяСтрока.Количество = ОсталосьРаспределить;	
				КонецЕсли;
				ОсталосьРаспределить = ОсталосьРаспределить - НоваяСтрока.Количество;
				МестоХранения.Места = МестоХранения.Места - НоваяСтрока.Количество;
				Если ОсталосьРаспределить = 0 Тогда
					Прервать;
				КонецЕсли;
			КонецЦикла; 			
			
			Если НЕ ОсталосьРаспределить = 0 Тогда
				// Нужно искать целые места
				// Условия задачи не требуют размещения номенклатуры рядом с одноименной
				// Берем любое целое место
				
				Для каждого МестоХранения Из тзОстатки Цикл
					Если НЕ МестоХранения.Номенклатура = NULL Тогда
						Продолжить;
					КонецЕсли;
					НоваяСтрока = Объект.МестаХранения.Добавить();
					ЗаполнитьЗначенияСвойств(НоваяСтрока, МестоХранения);
					НоваяСтрока.Номенклатура = СтрокаТовары.Номенклатура;
					Если ОсталосьРаспределить > СтрокаТовары.Номенклатура.КП Тогда
						НоваяСтрока.Количество = СтрокаТовары.Номенклатура.КП;	
					Иначе
						НоваяСтрока.Количество = ОсталосьРаспределить;	
					КонецЕсли;
					ОсталосьРаспределить = ОсталосьРаспределить - НоваяСтрока.Количество;
					МестоХранения.Номенклатура = НоваяСтрока.Номенклатура;
					МестоХранения.Места = СтрокаТовары.Номенклатура.КП - НоваяСтрока.Количество;
					Если ОсталосьРаспределить = 0 Тогда
						Прервать;
					КонецЕсли;
				КонецЦикла; 			
			
			КонецЕсли;
		КонецЕсли;
	КонецЦикла;
	
КонецПроцедуры

Строки из табличной части "Товары" выгружаем в таблицу значений и сворачиваем по Номенклатуре.

В таблицу значений тзОстатки помещаем перчень свободных мест, отсортированных в порядке увеличения места.

Далее для каждой номенклатуры подбираем свободное место. Если не удается заполнить существующие недозаполненные места, берем любое свободное место (можно и не любое, но тогда нужно подыскивать место рядом с одноименной номенклатурой, что не требовалось условиями задачи). В результате заполняется табличная часть "МестаХранения" документа. После выполнения процедуры заполнения, нужно выполнить функцию контроля корректности размещения товаров (приведена выше).

Обработка проведения документа:

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

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

Отпуск товара

Далее создаем документ "ОтпускТовара". Можно скопировать предыдущий документ, потому как структура табличных частей идентична.

Функция контроля распределения товаров сходна с аналогичной из документа "ПриемТовара" с тем отличием, что необходимо проверить не наличие свободных мест, а наличие достаточного количества товара на выбранных местах:

// Проверить строки
//
&НаСервере
Функция МестаХраненияПроверитьСтроки(ПроверкаРаспределения = Истина, ВыводитьСообщения = Истина)
	
	// Получить остатки по складу
	тзОстатки = СкладСервер.ПолучитьОстатки(Объект.Дата);	
	
	тзМестаХранения = Объект.МестаХранения.Выгрузить();
	тзМестаХранения.Свернуть("Номенклатура, SS, NN, LL", "Количество");
	
	тзТовары = Объект.Товары.Выгрузить();
	тзТовары.Свернуть("Номенклатура", "Количество");
	
	// Проверка наличия остатков
	
	Для каждого СтрокаМестаХранения Из тзМестаХранения Цикл
		
		Отбор = Новый Структура();
		Отбор.Вставить("SS", СтрокаМестаХранения.SS);
		Отбор.Вставить("NN", СтрокаМестаХранения.NN);
		Отбор.Вставить("LL", СтрокаМестаХранения.LL);
		Строки = тзОстатки.НайтиСтроки(Отбор);
		Если Строки.Количество() = 0 Тогда
			СообщениеПользователю("Место хранения SS: Парам1 NN: Парам2 LL: Парам3 не найдено!", Новый Структура("Парам1, Парам2, Парам3",  СтрокаМестаХранения.SS, СтрокаМестаХранения.NN, СтрокаМестаХранения.LL), ВыводитьСообщения);
			Возврат Ложь;
		ИначеЕсли Строки.Количество() > 1 ИЛИ НЕ (Строки[0].Номенклатура = СтрокаМестаХранения.Номенклатура) Тогда
			СообщениеПользователю("Место хранения SS: Парам1 NN: Парам2 LL: Парам3 не содержит нужную номенклатуру!", Новый Структура("Парам1, Парам2, Парам3",  СтрокаМестаХранения.SS, СтрокаМестаХранения.NN, СтрокаМестаХранения.LL), ВыводитьСообщения);
			Возврат Ложь;
		ИначеЕсли ?(Строки[0].Номенклатура = NULL,0,Строки[0].Количество) < СтрокаМестаХранения.Количество Тогда
			СообщениеПользователю("Место хранения SS: Парам1 NN: Парам2 LL: Парам3 не достаточно количества! Доступно: Парам4", Новый Структура("Парам1, Парам2, Парам3, Парам4",  СтрокаМестаХранения.SS, СтрокаМестаХранения.NN, СтрокаМестаХранения.LL, Строки[0].Количество), ВыводитьСообщения);
			Возврат Ложь;
		КонецЕсли;
		
		СтрокаПроверки = тзТовары.Добавить();
		СтрокаПроверки.Номенклатура = СтрокаМестаХранения.Номенклатура;
		СтрокаПроверки.Количество = - СтрокаМестаХранения.Количество;
		
	КонецЦикла; 
	
	// Проверить все ли позиции номенклатуры найдены
	
	Если ПроверкаРаспределения Тогда
	
		тзТовары.Свернуть("Номенклатура", "Количество");

		Для каждого СтрокаПроверки Из тзТовары Цикл
			Если НЕ СтрокаПроверки.Количество = 0 Тогда
				СообщениеПользователю("Не найдено Парам1 в количестве: Парам2", Новый Структура("Парам1, Парам2",  СтрокаПроверки.Номенклатура, СтрокаПроверки.Количество), ВыводитьСообщения);
				Возврат Ложь
			КонецЕсли;
		КонецЦикла;
	
	КонецЕсли;
	
	Возврат Истина;
	
КонецФункции

Функция "ПолучитьОстатки" из общего модуля "СкладСервер" возвращает таблицу значений, содержащую данные о размещении остатков на складе:

// Получить остатки по складу
//
Функция ПолучитьОстатки(Период) Экспорт

	Запрос = Новый Запрос;
	Запрос.Текст = 
	"ВЫБРАТЬ
	|	ПозицииТовараОстатки.Номенклатура КАК Номенклатура,
	|	ПозицииТовараОстатки.SS КАК SS,
	|	ПозицииТовараОстатки.NN КАК NN,
	|	ПозицииТовараОстатки.LL КАК LL,
	|	ПозицииТовараОстатки.КоличествоОстаток КАК Количество
	|ИЗ
	|	РегистрНакопления.ПозицииТовара.Остатки(&Период, ) КАК ПозицииТовараОстатки
	|ГДЕ
	|	ПозицииТовараОстатки.КоличествоОстаток > 0
	|
	|УПОРЯДОЧИТЬ ПО
	|	Количество";
				   
	Запрос.Параметры.Вставить("Период", Период);
				   
	Возврат Запрос.Выполнить().Выгрузить();

КонецФункции // ПолучитьОстатки()

Обработчик автоматического подбора позиций товаров выглядит так:

&НаСервере
Процедура ЗаполнитьНаСервере()
	
	Объект.МестаХранения.Очистить();
	
	тзТовары = Объект.Товары.Выгрузить();
	тзТовары.Свернуть("Номенклатура", "Количество");
	
	// Получить остатки по складу в порядке увеличения количества
	тзОстатки = СкладСервер.ПолучитьОстатки(Объект.Дата);	
	
	Для каждого СтрокаТовары Из тзТовары Цикл
		Если НЕ СтрокаТовары.Количество = 0 Тогда
			ОсталосьРаспределить = СтрокаТовары.Количество;
			
			// Смотрим где чего можно взять
			Для каждого МестоХранения Из тзОстатки Цикл
				Если НЕ МестоХранения.Номенклатура = СтрокаТовары.Номенклатура Тогда
					Продолжить;
				КонецЕсли;
				НоваяСтрока = Объект.МестаХранения.Добавить();
				ЗаполнитьЗначенияСвойств(НоваяСтрока, МестоХранения);
				Если ОсталосьРаспределить > МестоХранения.Количество Тогда
					НоваяСтрока.Количество = МестоХранения.Количество;	
				Иначе
					НоваяСтрока.Количество = ОсталосьРаспределить;	
				КонецЕсли;
				ОсталосьРаспределить = ОсталосьРаспределить - НоваяСтрока.Количество;
				Если ОсталосьРаспределить = 0 Тогда
					Прервать;
				КонецЕсли;
			КонецЦикла; 			
			
		КонецЕсли;
	КонецЦикла;
	
КонецПроцедуры

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

Обработка проведения документа:

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

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

В условии задачи требуется сформировать печатную форму документа с сортировкой по порядку обхода склада. Для этого можно воспользоваться конструктором печати, а для сортировки использовать реквизит "ПорядокОбхода" регистра сведений "МестаХранения".

Инвентаризация

Далее создаем документ "Инвентаризация". Для этого также можно скопировать документ поступления товара. Табличная часть здесь одна: "МестаХранения". Инвентаризация сводится к списанию остатков с указанных мест хранения и размещению других позиций товаров. Хотя, возможно, правильней не списывать остатки, а оставлять их как "потерянные" на одном измерении по номенклатуре. Алгоритм проверки корректности заполнения табличной части немного отличается от аналогичной в "Поступлении товара" и выглядит так:

// Проверить строки
//
&НаСервере
Функция МестаХраненияПроверитьСтроки(ПроверкаРаспределения = Истина, ВыводитьСообщения = Истина)
	
	// Получить места по складу
	тзМеста = СкладСервер.ПолучитьВсеМеста();	
	
	тзМестаХранения = Объект.МестаХранения.Выгрузить();
	тзМестаХранения.Свернуть("Номенклатура, SS, NN, LL", "Количество");
	
	// Проверка доступности мест хранения
	
	Для каждого СтрокаМестаХранения Из тзМестаХранения Цикл
		
		Отбор = Новый Структура();
		Отбор.Вставить("SS", СтрокаМестаХранения.SS);
		Отбор.Вставить("NN", СтрокаМестаХранения.NN);
		Отбор.Вставить("LL", СтрокаМестаХранения.LL);
		Строки = тзМеста.НайтиСтроки(Отбор);
		Если Строки.Количество() = 0 Тогда
			СообщениеПользователю("Место хранения SS: Парам1 NN: Парам2 LL: Парам3 не найдено!", Новый Структура("Парам1, Парам2, Парам3",  СтрокаМестаХранения.SS, СтрокаМестаХранения.NN, СтрокаМестаХранения.LL), ВыводитьСообщения);
			Возврат Ложь;
		ИначеЕсли НЕ (Строки[0].Номенклатура = СтрокаМестаХранения.Номенклатура ИЛИ Строки[0].Номенклатура = Справочники.Номенклатура.ПустаяСсылка()) Тогда
			СообщениеПользователю("Место хранения SS: Парам1 NN: Парам2 LL: Парам3 содержит различные номенклатуры!", Новый Структура("Парам1, Парам2, Парам3",  СтрокаМестаХранения.SS, СтрокаМестаХранения.NN, СтрокаМестаХранения.LL), ВыводитьСообщения);
			Возврат Ложь;
		ИначеЕсли СтрокаМестаХранения.Количество > СтрокаМестаХранения.Номенклатура.КП Тогда
			СообщениеПользователю("Место хранения SS: Парам1 NN: Парам2 LL: Парам3 переполнено! Доступно: Парам4", Новый Структура("Парам1, Парам2, Парам3, Парам4",  СтрокаМестаХранения.SS, СтрокаМестаХранения.NN, СтрокаМестаХранения.LL, (?(Строки[0].Номенклатура = Справочники.Номенклатура.ПустаяСсылка(), СтрокаМестаХранения.Номенклатура.КП,Строки[0].НоменклатураКП))), ВыводитьСообщения);
			Возврат Ложь;
		КонецЕсли;
		
		Строки[0].Номенклатура = СтрокаМестаХранения.Номенклатура;
		
	КонецЦикла; 
	
	Возврат Истина;
	
КонецФункции

В обработке проведения сначала списываются существующие остатки, затем размещаются другие:

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

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

Перемещение товара

По условиям задачи требуется реализовать процесс "Уплотнения склада", что является по сути перемещением товара с целью более оптимального его хранения. Создаем документ "ПеремещениеТовара".  Табличные части у документа две: "Откуда" и "Куда" (колонки: Номенклатура, SS, NN, LL, Количество).

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

// Проверить строки
//
&НаСервере
Функция МестаХраненияПроверитьСтроки(ПроверкаРаспределения = Истина, ВыводитьСообщения = Истина)
	
	// Получить остатки по складу
	тзОстатки = СкладСервер.ПолучитьОстатки(Объект.Дата);	
	
	тзОткуда = Объект.Откуда.Выгрузить();
	тзОткуда.Свернуть("Номенклатура, SS, NN, LL", "Количество");
	
	тзТовары = Объект.Откуда.Выгрузить();
	тзТовары.Свернуть("Номенклатура", "Количество");
	
	// Проверка наличия остатков
	
	Для каждого СтрокаОткуда Из тзОткуда Цикл
		
		Отбор = Новый Структура();
		Отбор.Вставить("SS", СтрокаОткуда.SS);
		Отбор.Вставить("NN", СтрокаОткуда.NN);
		Отбор.Вставить("LL", СтрокаОткуда.LL);
		Строки = тзОстатки.НайтиСтроки(Отбор);
		Если Строки.Количество() = 0 Тогда
			СообщениеПользователю("Место хранения SS: Парам1 NN: Парам2 LL: Парам3 не найдено!", Новый Структура("Парам1, Парам2, Парам3",  СтрокаОткуда.SS, СтрокаОткуда.NN, СтрокаОткуда.LL), ВыводитьСообщения);
			Возврат Ложь;
		ИначеЕсли Строки.Количество() > 1 ИЛИ НЕ (Строки[0].Номенклатура = СтрокаОткуда.Номенклатура) Тогда
			СообщениеПользователю("Место хранения SS: Парам1 NN: Парам2 LL: Парам3 не содержит нужную номенклатуру!", Новый Структура("Парам1, Парам2, Парам3",  СтрокаОткуда.SS, СтрокаОткуда.NN, СтрокаОткуда.LL), ВыводитьСообщения);
			Возврат Ложь;
		ИначеЕсли ?(Строки[0].Номенклатура = NULL,0,Строки[0].Количество) < СтрокаОткуда.Количество Тогда
			СообщениеПользователю("Место хранения SS: Парам1 NN: Парам2 LL: Парам3 не достаточно количества! Доступно: Парам4", Новый Структура("Парам1, Парам2, Парам3, Парам4",  СтрокаОткуда.SS, СтрокаОткуда.NN, СтрокаОткуда.LL, Строки[0].Количество), ВыводитьСообщения);
			Возврат Ложь;
		КонецЕсли;
		
	КонецЦикла; 
	
	// Получить места по складу
	тзМеста = СкладСервер.ПолучитьМеста(Объект.Дата);	
	
	тзКуда = Объект.Куда.Выгрузить();
	тзКуда.Свернуть("Номенклатура, SS, NN, LL", "Количество");
	
	// Проверка доступности мест хранения
	
	Для каждого СтрокаКуда Из тзКуда Цикл
		
		Отбор = Новый Структура();
		Отбор.Вставить("SS", СтрокаКуда.SS);
		Отбор.Вставить("NN", СтрокаКуда.NN);
		Отбор.Вставить("LL", СтрокаКуда.LL);
		Строки = тзМеста.НайтиСтроки(Отбор);
		Если Строки.Количество() = 0 Тогда
			СообщениеПользователю("Место хранения SS: Парам1 NN: Парам2 LL: Парам3 не найдено!", Новый Структура("Парам1, Парам2, Парам3",  СтрокаКуда.SS, СтрокаКуда.NN, СтрокаКуда.LL), ВыводитьСообщения);
			Возврат Ложь;
		ИначеЕсли Строки.Количество() > 1 ИЛИ НЕ (Строки[0].Номенклатура = СтрокаКуда.Номенклатура ИЛИ Строки[0].Номенклатура = NULL) Тогда
			СообщениеПользователю("Место хранения SS: Парам1 NN: Парам2 LL: Парам3 содержит различные номенклатуры!", Новый Структура("Парам1, Парам2, Парам3",  СтрокаКуда.SS, СтрокаКуда.NN, СтрокаКуда.LL), ВыводитьСообщения);
			Возврат Ложь;
		ИначеЕсли ?(Строки[0].Номенклатура = NULL,0,Строки[0].Количество) + СтрокаКуда.Количество > СтрокаКуда.Номенклатура.КП Тогда
			СообщениеПользователю("Место хранения SS: Парам1 NN: Парам2 LL: Парам3 переполнено! Доступно: Парам4", Новый Структура("Парам1, Парам2, Парам3, Парам4",  СтрокаКуда.SS, СтрокаКуда.NN, СтрокаКуда.LL, (?(Строки[0].Номенклатура = NULL, СтрокаКуда.Номенклатура.КП,Строки[0].НоменклатураКП) - ?(Строки[0].Номенклатура = NULL,0,Строки[0].Количество))), ВыводитьСообщения);
			Возврат Ложь;
		КонецЕсли;
		
		СтрокаПроверки = тзТовары.Добавить();
		СтрокаПроверки.Номенклатура = СтрокаКуда.Номенклатура;
		СтрокаПроверки.Количество = - СтрокаКуда.Количество;
		
	КонецЦикла; 
	
	// Проверить все ли позиции номенклатуры распределены
	
	Если ПроверкаРаспределения Тогда
	
		тзТовары.Свернуть("Номенклатура", "Количество");

		Для каждого СтрокаПроверки Из тзТовары Цикл
			Если НЕ СтрокаПроверки.Количество = 0 Тогда
				СообщениеПользователю("Не размещено Парам1 в количестве: Парам2", Новый Структура("Парам1, Парам2",  СтрокаПроверки.Номенклатура, СтрокаПроверки.Количество), ВыводитьСообщения);
				Возврат Ложь
			КонецЕсли;
		КонецЦикла;
	
	КонецЕсли;
	
	Возврат Истина;
	
КонецФункции

Процедура уплотнения склада выглядит так:

&НаСервере
Процедура ЗаполнитьНаСервере()
	
	Объект.Куда.Очистить();
	
	ПеремещатьТоЧтоВыбрано = НЕ Объект.Откуда.Количество() = 0;
	Если ПеремещатьТоЧтоВыбрано Тогда
		тзОстатки = Объект.Откуда.Выгрузить();
	Иначе	
		// Получить остатки по складу в порядке увеличения количества
		тзОстатки = СкладСервер.ПолучитьОстатки(Объект.Дата);	
	КонецЕсли; 
	
	// Получить места по складу в порядке увеличения места
	тзМеста = СкладСервер.ПолучитьМеста(Объект.Дата);	
	
	СвободныхМестДо = тзМеста.НайтиСтроки(Новый Структура("Количество", NULL)).Количество();
	
	// Выбираем что можно переместить
	Для каждого СтрокаОткуда Из тзОстатки Цикл
		Если (СтрокаОткуда.Количество > 0  И СтрокаОткуда.Количество < СтрокаОткуда.Номенклатура.КП) ИЛИ ПеремещатьТоЧтоВыбрано Тогда
			ОсталосьРаспределить = СтрокаОткуда.Количество;
			
			// Смотрим куда можно переместить
			Для каждого СтрокаКуда Из тзМеста Цикл
				Если НЕ СтрокаКуда.Номенклатура = СтрокаОткуда.Номенклатура Тогда
					Продолжить;
				КонецЕсли;
				Если НЕ СтрокаКуда.Места > 0 Тогда
					Продолжить;
				КонецЕсли;
				Если СтрокаКуда.NN = СтрокаОткуда.NN И СтрокаКуда.SS = СтрокаОткуда.SS И СтрокаКуда.LL = СтрокаОткуда.LL Тогда
					Продолжить;
				КонецЕсли; 
				НоваяСтрокаКуда = Объект.Куда.Добавить();
				ЗаполнитьЗначенияСвойств(НоваяСтрокаКуда, СтрокаКуда);
				Если ОсталосьРаспределить > СтрокаКуда.Места Тогда
					НоваяСтрокаКуда.Количество = СтрокаКуда.Места;	
				Иначе
					НоваяСтрокаКуда.Количество = ОсталосьРаспределить;	
				КонецЕсли;
				ОсталосьРаспределить = ОсталосьРаспределить - НоваяСтрокаКуда.Количество;
				
				// Обновить строку свободных мест
				СтрокаКуда.Места = СтрокаКуда.Места - НоваяСтрокаКуда.Количество;
				
				Если НЕ ПеремещатьТоЧтоВыбрано Тогда
					// Обновить строку остатков
					СтрокаКудаОстатки = тзОстатки.НайтиСтроки(Новый Структура("SS, NN, LL", СтрокаКуда.SS, СтрокаКуда.NN, СтрокаКуда.LL))[0];				
					СтрокаКудаОстатки.Количество = СтрокаКудаОстатки.Количество - НоваяСтрокаКуда.Количество;
				КонецЕсли; 
				
				// Обновить строку мест
				СтрокаОткудаМеста = тзМеста.НайтиСтроки(Новый Структура("SS, NN, LL", СтрокаОткуда.SS, СтрокаОткуда.NN, СтрокаОткуда.LL))[0];				
				СтрокаОткудаМеста.Места = СтрокаОткудаМеста.Места + НоваяСтрокаКуда.Количество;
				Если СтрокаОткудаМеста.Места = СтрокаОткудаМеста.Номенклатура.КП Тогда
					СтрокаОткудаМеста.Места = NULL;
					СтрокаОткудаМеста.Количество = NULL;
					СтрокаОткудаМеста.Номенклатура = NULL;
				КонецЕсли;
				
				Если ОсталосьРаспределить = 0 Тогда
					Прервать;
				КонецЕсли;
			КонецЦикла;
			
			Если НЕ ПеремещатьТоЧтоВыбрано Тогда
				// Заполнить ТЧ откуда
				Если ОсталосьРаспределить < СтрокаОткуда.Количество Тогда
					НоваяСтрокаОткуда = Объект.Откуда.Добавить();
					ЗаполнитьЗначенияСвойств(НоваяСтрокаОткуда, СтрокаОткуда);
					НоваяСтрокаОткуда.Количество = СтрокаОткуда.Количество - ОсталосьРаспределить;
				КонецЕсли;
			КонецЕсли;
			
		КонецЕсли;
	КонецЦикла;
	
	СвободныхМестПосле = тзМеста.НайтиСтроки(Новый Структура("Количество", NULL)).Количество();
	
	ЭтаФорма.Информация = "Свободных мест до: " + СвободныхМестДо + " после перемещения: " + СвободныхМестПосле;
	
КонецПроцедуры

Если табличная часть "Откуда" пустая, то производится поиск недозаполненных мест с целью их оптимального размещения. Если указаны конкретные позиции, то производится поиск места только под них (этого не требовалось по условиям задачи, но захотелось сделать).

Обработка проведения документа по аналогии с предыдущими документами.

Отчеты

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

Загруженность склада строится несколько сложнее. Используются три набора данных: один набор формирует перечень дат, на которые будет формироваться каждый "столбик" загруженности, второй набор - количество занятых мест, третий - общее количество мест. Устанавливаем связь между первым и вторым набором по параметру "Период", добавляем вычисляемое поле "Загруженность" и размещаем его на диаграмме.

Замечания проверяющего

1. Не оптимальный алгоритм приемки - все данные вытаскиваем из базы и потом с ними работаем, вместо того, чтобы получить только необходимую информацию. Например, нужны только ячейки, в которых есть остатки по товарам из документа и пустые ячейки.
2. Обращение к реквизитам справочника через точку в цикле, хотя до этого был запрос в котором все данные можно было по товару получить.

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

4.Документ инвентаризация мог бы быть более эргономичным, например заполнить по остаткам учетной системы.

5.Структура регистров и справочников не оптимальная, при добавлении иной схемы адресации ячеек придется изменять 2 таблицы.

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

Выводы

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

П.С. Чтобы код в статье выглядел нормально, использовал прежнюю разметку кода.

Скачать файлы

Наименование Файл Версия Размер
Решение тестового задания

.dt 115,79Kb
17
.dt 115,79Kb 17 Скачать

Специальные предложения

Комментарии
В избранное Подписаться на ответы Сортировка: Древо развёрнутое
Свернуть все
1. CheBurator 3438 22.10.16 16:07 Сейчас в теме
замечания проверяющего №3 - с точки зрения правильности/адекватности рабоыт - основное. для складской системы - это неуд. так что задача конечно выполнена, но... ;_)
2. vasvl123 103 22.10.16 17:04 Сейчас в теме
(1) CheBurator, перед записью документов производится контроль наличия мест / остатков
3. rpgshnik 2454 24.10.16 04:29 Сейчас в теме
А тестовое задание куда такое?
4. vasvl123 103 24.10.16 08:09 Сейчас в теме
(3) rpgshnik, участие в проектах разработки на платформе 1С 8.х опыт программирования на платформе 1С 8.х от 3х лет з/п до 60к
5. AlexO 129 15.12.18 16:04 Сейчас в теме
1. Не оптимальный алгоритм приемки - все данные вытаскиваем из базы и потом с ними работаем, вместо того, чтобы получить только необходимую информацию. Например, нужны только ячейки, в которых есть остатки по товарам из документа и пустые ячейки.
Спорный вопрос.
1С не имеет механизмов выборки-из-выборки в одном запросе (a la "выборка в окне" в SQL), потому что зачастую невозможно указать сразу все условия выборки, и требуется сначала получить "хоть что-то" (обычно это и есть "получить все" с минимально наложенными условиями - период, организация, etc), а уже потом "это все" анализируется, и, в зависимости от того, что попало в выборку, из этого "все" выбирается нужное. Причем, тут могут быть и последовательно три-четыре уровня отбор-выборка, а не два.
Применительно к Вашему примеру: это хорошо, если в нужном регистре (выборку по документам не рассматриваем - тут вообще не имеет смысла говорить о скорости, такая выборка сама по себе будет в разы тормозней любой "неоптимальности" наподобие "выборка всего") - есть поле "Регистратор" (можно сразу выбрать номенклатуру по документу).
А если нет? То что?
Совершенно верно - сначала выбираем всю номенклатуру, потом находим номенклатуру по документу, потом сравниваем результат 1-го запроса со вторым... Вот уже три разных запроса, с "выборкой всего". И будут они хоть вложенные, хоть пакетные, хоть отдельно - разница только в сортах тормозов.

2. Обращение к реквизитам справочника через точку в цикле, хотя до этого был запрос в котором все данные можно было по товару получить.
Ну и отлично. Только "проверяющий" забыл указать маленький нюанс - этот самый запрос "до этого" выбирал бы вместе с нужными данными - данные по всем позициям, попавшим в запрос (мы ведь помним, из выше, что в 1С нельзя реализовать выборку "одним запросом" данных, условия отбора по которым определяются по результату предварительной выборки, а до этого момента - не известны?), и сколько бы там предварительно таблиц соединялось? И миллионы строк в первоначальной выборке получить - очень легко.
А соединение "через точку" к справочнику, к чему придрался "проверяющий" - это всего лишь запрос-отбор по справочнику, и запрос к смежным таблицам все тех же "данных по товару", если они есть.
И в чем разница? Если тут хоть так, хоть эдак - все реализуется одинаково неоптимально.

3.Алгоритмы проведения построены так, что есть возможноСТЬ двум операторам произвести распределение В одну и ту же ячейку. Не используется блокировка в транзакции необходимого диапазона ресурсов.
Ну пусть бы сразу и объяснил, как он предполагал "заблокировать" ячейку при отсутствии в 1С блокировки отдельной записи (только всего регистра-таблицы), и отсутствия "уведомления" об апдейте записи тем, кто уже использует данные из неё в режиме чтения (т.е. запрос уже прочитал таблицу, "освободил" её, и ждет действий другого оператора).
Т.е. если один оператор успел прочитать, что ячейка пуста, а второй заблокировал и изменил запись (внес товар в ячейку), то кто виноват? Первый получил данные, что ячейка пуста, инициирует запрос на открытие и блокировку таблицы под запись, ждет окончание выполнения транзакции второго (с записью), подсоединяется, блокирует и уже сам и меняет состояние того же адреса другим содержимым.
То есть "проверяющий" посетовал на отсутствие механизма обратной связи? Ну извините, тут тогда целый дополнительный модуль проверок и противовесов еще писать надо.

4.Документ инвентаризация мог бы быть более эргономичным, например заполнить по остаткам учетной системы.
Ну, а при открытии программа могла бы сразу сообщать, что-где в документах-ячейках-регистрах недозаполнено, незабито, или не соответствует одно другому и требует перепроверки и контроля.
Но все это - расширение требований к системе, и дополнительные затраты на разработку. Ок, если "проверяющий" именно это и хотел сказать.

5.Структура регистров и справочников не оптимальная, при добавлении иной схемы адресации ячеек придется изменять 2 таблицы.
При добавлении "иной схемы адресации", скорей всего придется переделывать вообще всю структуру, а не "2 таблицы изменить", потому что "изменение адресации" - это изменение базовой методики и алгоритмов запроса и хранения.
С чего "проверяющий" взял, что только две таблицы? Он думает, что "добавление иной схемы адресации" - это оно везде у всех одинаково, и всегда содержит одни и те же "изменения"?

6.Не оптимальный алгоритм проведения уплотнения (в системе почему-то назван Перемещением). Опять получаем все данные из базы и потом в циклах пробегаем и ищем то, что нужно. Хотя нужно получить из базы только то, что необходимо уплотнять, т.е. где остаток меньше чем коэффициент паллетирования.
Интересно, а структура организации данных вообще позволяет сразу отобрать остаток, чтобы по нему можно было ориентироваться, сравнивать с коэффициентом, и принимать решение? Как-то странно "проверяющий" проверяет - сравнивает результат с неким своим шаблоном решения, как-будто для него - все БД одинаковы, с едиными таблицами, полями, и наполнением.
В итоге что.
Скажу, что попали вы - под обычный "поиск идеальности в шаблонности", когда оценивают по шаблонам и держат в голове уже свое готовое решение "идеальной задачи", а не конкретное решение конкретной задачи-проблемы.
Ну так пусть для начала создадут себе идеальную базу с идеальными пользователями, а уже потом и решают в ней свои идеальные задачи.
6. vasvl123 103 15.12.18 19:49 Сейчас в теме
(5)Спасибо за подробный разбор. Причина придирок проверяющего в том,
что вакансию они закрыли раньше, чем я сделал тестовое задание. В пятницу дали задание, а в воскресенье уже закрыли. Было обидно, да. Мне тогда работа нужна была очень, но судьба распорядилась иначе. Может оно и к лучшему. Я сейчас свой проект пилю, скоро планирую здесь опубликовать.
Оставьте свое сообщение

См. также

Безопасная работа с транзакциями во встроенном языке Промо

Практика программирования v8 1cv8.cf Абонемент ($m)

Разбираемся с опасностями использования транзакций во встроенном языке 1С. Познаем ошибку "В данной транзакции уже происходили ошибки". Учимся защищаться от них.

1 стартмани

25.03.2019    37282    tormozit    54    

СКД: все, что вы хотели знать о подмене схемы компоновки данных в отчетах и обработках

Практика программирования v8 v8::СКД 1cv8.cf Абонемент ($m)

Довольно часто на различных тематических форумах задается вопрос, можно ли использовать в отчете/обработке несколько схем компоновки данных, подменяя одну другой по мере надобности? При этом желательно, чтобы и пользовательские настройки при смене схемы менялись соответственно.

1 стартмани

07.12.2020    1541    user1502278    15    

Проблема сопоставления товара при приемке маркированной продукции на примере обуви в конфигурации 1С:Розница

Оптовая торговля Розничная торговля v8 Розница Розничная и сетевая торговля (FMCG) Оптовая торговля, дистрибуция, логистика Россия УУ Абонемент ($m)

В статье описывается проблема сопоставления товара при приемке товаров маркированной продукции применительно к типовым конфигурациям на примере 1С:Розница.

1 стартмани

16.11.2020    1553    gzharkoj    3    

Cбор и анализ ошибок при помощи Sentry, или как упростить жизнь себе и пользователям

Практика программирования Интеграция v8 Абонемент ($m)

Цель данной статьи - сделать процесс сбора и анализа ошибок, происходящих в базе, максимально простым, быстрым и удобным, собирать статистику по ошибкам, местам их возникновения и частоте их появления, а также в деталях разобрать все тонкости по интеграции 1С с Sentry.

1 стартмани

09.10.2020    3376    hexhoc    12    

Как выполнить отчет на СКД через COM и получить данные отчета? Промо

Практика программирования v8 УПП1 Россия Абонемент ($m)

Для чего это нужно. Например, нужно в одной базе получить какой-либо показатель из другой базы. Этот показатель вычисляется в каком-либо сложном отчете, который написан на СКД. Можно, конечно, "скопипастить" текст запроса из другой базы, немного подправить его и выполнять в том же COM подключении. Но с этим теряется гибкость: если отчет изменился, то нужно помнить о том, что где-то есть его "немного модифицированная" копия. В статье будет рассмотрен пример получения данных из базы ЗУП.

2 стартмани

08.05.2018    27413    wowik    3    

Программная корректировка при выводе отчета СКД

Практика программирования v8 v8::СКД 1cv8.cf Абонемент ($m)

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

1 стартмани

08.10.2020    4331    dabu-dabu    10    

Загрузка, скачивание, удаление файлов с помощью НачатьПомещениеФайлаНаСервер() и НачатьПолучениеФайлаССервера()

Практика программирования v8 1cv8.cf Абонемент ($m)

В платформе 8.3.15 появились новые методы НачатьПомещениеФайлаНаСервер() и НачатьПолучениеФайлаССервера(). В данной статье рассмотрено готовое решение проверенное и прекрасно работающее на тонком и веб-клиенте.

1 стартмани

25.07.2020    4948    Flashill    10    

Параллельные вычисления расчета факториала числа N

Практика программирования v8 1cv8.cf Абонемент ($m)

Распараллеливание алгоритма с помощью фоновых заданий (асинхронные вычисления)

1 стартмани

29.06.2020    3119    Rustig    17    

Как нарисовать граф на 1С Промо

Практика программирования v8 Абонемент ($m)

Описывается реализация на языке запросов 1С метода расположения вершин графа на плоскости, основанного на использовании электромеханической аналогии. При этом вершины графа представляются одноименными электрическими зарядами, дуги - пружинками. Силы взаимодействия вершин в этой системе переводят их из случайного начального в нужное конечное положение. Приведена обработка рисования графов "ГрафОграф", реализующая данный подход, показывающая также динамику процесса. Граф можно задать списком ребер вручную, выбрать из нескольких предопределенных примеров или сформировать по данным информационной базы.

1 стартмани

09.08.2013    71110    ildarovich    117    

Универсальная печатная форма Приказа/Договора с возможностью настройки макета в пользовательском режиме

Практика программирования Универсальные печатные формы v8 1cv8.cf Абонемент ($m)

В данной статье я опишу реализацию универсальной (в кавычках) печати Приказа (Договора или чего пожелаете) с возможностью настройки выводимого текста с параметрами из пользовательского режима

1 стартмани

24.06.2020    1564    BuriyLesha    0    

Методика обновления формы объекта данных при изменении объекта

Практика программирования v8 v8::УФ 1cv8.cf Абонемент ($m)

В формах объектов данных часто встречаются элементы, косвенно связанные с объектом. Логику обновления этих элементов при изменении объекта обычно вызывают из обработчиков ПриСозданнииНаСервере и ПриОткрытии, забывая про наличие других способов изменения объекта. В статье предложена методика для обычных и управляемых форм, учитывающая все способы.

1 стартмани

09.03.2020    9977    tormozit    14    

Отправка уведомлений с помощью командной строки, Оповещения с сервера на клиент с помощью командной строки

Практика программирования v8 1cv8.cf Россия Абонемент ($m)

Отправка уведомлений с помощью команды командной строки msg. Оповестить пользователей из серверного модуля или регламентного задания, с помощью командной строки msg.

1 стартмани

05.03.2020    6218    user5300    3    

Простой способ индексирования интервалов Промо

Практика программирования v8 Абонемент ($m)

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

1 стартмани

28.09.2016    40133    ildarovich    22    

Вывод сообщений в HTML поле средствами 1С

Практика программирования v8 v8::УФ Абонемент ($m)

Пример использования вывода большого количества сообщений в поле HTML. С возможностью открывать ссылочные объекты и создавать новые объекты передавая параметры прямо из HTML поля. Протестировано на релизах 8.3.12 и 8.3.15+

2 стартмани

31.01.2020    6348    burni4    16    

Краткое руководство по внесению изменений в конфигурацию

Практика программирования v8 1cv8.cf Абонемент ($m)

Кратко описаны основополагающие моменты при старте групповой разработки конфигурации несколькими программистами. Полезно для проектной документации как требование к разработчикам или сопровождающей компании.

1 стартмани

13.01.2020    18529    sapervodichka    41    

Универсальные функции: разложение произвольной строки адреса в структуру

Практика программирования Универсальные функции v8 1cv8.cf Абонемент ($m)

Процедуры и функции раскладывают произвольную строку адрес в структуру по ключевым словам.

1 стартмани

30.12.2019    4238    vik070777    10    

Бесплатная проверка контрагентов в ФНС (общий модуль с алгоритмом). На примере выводим статус в список справочника контрагентов Промо

Практика программирования v8 1cv8.cf Абонемент ($m)

Если вам интересно проверить контрагенте в ФНС, вам поможет данная публикация. Весь алгоритм работы строится на основе данных, полученных с сервиса http://npchk.nalog.ru совершенно бесплатно.

1 стартмани

01.02.2018    35626    rpgshnik    49    

"Живые" картинки со Snap.SVG

Практика программирования WEB Работа с интерфейсом v8 Абонемент ($m)

В статье рассмотрен пример использования http-сервисов для визуализации данных

1 стартмани

24.10.2019    13998    blackhole321    7    

RLS - дубли условий в запросах к СУБД

Практика программирования Роли и права v8 v8::Права 1cv8.cf Абонемент ($m)

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

1 стартмани

07.10.2019    8763    geron4    4    

Полное копирование одной формы в другую

Практика программирования Универсальные обработки Работа с интерфейсом v8 1cv8.cf Абонемент ($m)

Однажды я столкнулся с необходимостью открыть форму ЛЮБОГО документа с определенными изменениями, не зависящими от структуры объекта (например, заблокировать все кнопки). В интернете решения я не нашел. Обычно на форумах на запросы подобного рода отвечают чем-то вроде "покажи первоначальную задачу, а не спрашивай как реализовать то, что ты придумал". Тем не менее, мне стало интересно, как это можно сделать.

1 стартмани

03.10.2019    5728    nekit_rdx    24    

БСП: Дополнительная обработка (Регламенты), примеры от простого к сложному Промо

Практика программирования БСП (Библиотека стандартных подсистем) v8 1cv8.cf Абонемент ($m)

Очень много попадается странных решений, которые можно решить через БСП:Дополнительные отчеты и обработки. Я бы вообще БСП из-за этой подсистемы переименовал в «Большое Спасибо Программистам». Поработаем с подсистемой в части написания регламентных заданий.

1 стартмани

10.05.2018    46532    dsdred    43    

Многопоточная обработка данных на примере перепроведения документов

Обработка документов Практика программирования v8 ERP2 УТ11 КА2 Абонемент ($m)

Дальнейшее развитие темы фоновой обработки данных - проведение документов в потоках. Настройка параметров и запуск основного процесса (менеджера потоков). Разбивка документов для проведения на не связанные друг с другом наборы и запуск дополнительных фоновых заданий для отдельных потоков. Отслеживание выполнения каждого потока в родительском сеансе.

1 стартмани

17.09.2019    9858    ids79    46    

Отображение истории выполнения по всем задачам комплексного процесса в документообороте

Документооборот и делопроизводство Практика программирования v8 ДО Абонемент ($m)

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

1 стартмани

15.09.2019    7268    pavelpribytkin96    8    

Описание формата внутреннего представления данных 1С в контексте обмена данными

Практика программирования Внешние источники данных v8 v8::УФ 1cv8.cf Абонемент ($m)

Фирма 1С не рекомендует использовать внутреннее представление данных для любых целей, которые отличны от обмена с 1С:Предприятием 7.7. Но сама возможность заглянуть на "внутреннюю кухню" платформы с помощью функций ЗначениеВСтрокуВнутр(), ЗначениеВФайл(), ЗначениеИзСтрокиВнутр() и ЗначениеИзФайла(), дала возможность сообществу программистов 1С разработать новые приемы разработки и анализа. Так, именно на использовании внутреннего представления был построен алгоритм "быстрого массива", который позволяет практически мгновенно создать массив в памяти на основании строки с разделителями. С помощью разбора внутреннего представления можно "на лету" программным кодом выполнить анализ обычной формы и даже сделать редактор графической схемы. Во внутреннем формате сохраняют свои данные между сеансами различные популярные внешние обработки. А еще это возможность сделать быстрый обмен с внешними системами.

1 стартмани

06.09.2019    20110    Dementor    30    

Некоторая работа с данными через COM Промо

Практика программирования v8 Абонемент ($m)

В статье приведены примеры работы с Платформой 8.X через COM (точнее, через объект COMConnector). Примеры кода были использованы при реализации прикладных задач в процессе трудовой деятельности.

2 стартмани

05.12.2012    58198    wowik    32    

Удобный просмотр результата запроса с большим количеством временных таблиц

Практика программирования v8 Абонемент ($m)

Если Вам часто приходится просматривать в отладчике сложные пакетные запросы с большим количеством временных таблиц, то эта статья для Вас.

1 стартмани

27.08.2019    11305    ids79    22    

Запуск фонового задания во внешней обработке. Отключение предупреждений защиты от опасных действий в фоновом задании

Практика программирования v8 1cv8.cf Абонемент ($m)

Как запустить фоновое задание из модуля внешней обработки используя БСП. Как отключить безопасный режим и сообщения защиты от опасных действий независимо от профиля безопасности пользователя в фоновом задании во внешней обработке.

2 стартмани

24.08.2019    12151    BenGunn    22    

Изменяющееся контекстное меню в 1С 8.3

Практика программирования Работа с интерфейсом Разработка v8 v8::УФ Абонемент ($m)

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

1 стартмани

06.08.2019    17241    signum2009    16    

Работа со схемой запроса Промо

Инструментарий разработчика Практика программирования v8 v8::Запросы Абонемент ($m)

Стандартом взаимодействия с реляционной базой данных стал язык SQL. Приемником SQL в 1С является язык запросов. Язык запросов, также как и SQL, является структурированным. Составляющие структуры запроса отвечают на разные вопросы о том, какие данные требуется получить и какие манипуляции с множествами данных необходимо произвести при получении. В простых случаях текст запроса можно написать вручную, однако в сложных случаях, а также при программном формировании, - лучше воспользоваться объектной моделью запроса и использовать объект "Схема запроса". В статье дается описание объектной модели и особенностей работы с ней, а также приводится решение, упрощающее взаимодействие с объектом "Схема запроса".

1 стартмани

24.04.2018    45533    kalyaka    35    

Процедура ПриКомпоновкеРезультата

Практика программирования v8 1cv8.cf Абонемент ($m)

Коллекция кода

1 стартмани

26.07.2019    43588    vasilev2015    64    

10 способов получить модуль числа (а может, и больше)

Практика программирования Разработка v8 1cv8.cf Абонемент ($m)

Пишем функцию вычисления модуля числа. Сколько способов существует? Давайте посчитаем!

1 стартмани

11.07.2019    9530    sam441    29    

Ловец дедлоков СУБД

Производительность и оптимизация (HighLoad) Практика программирования Разработка v8 Россия Абонемент ($m)

Анализ простейшего дедлока СУБД в рабочей базе с использованием ЦУП (центра управления производительностью) и profiler MS SQL (Microsoft SQL Server). Эта статья будет полезна людям, изучающим вопросы оптимизации работы 1С, или тем, у кого возникают дедлоки в рабочей базе. UPD 09.07.2019 добавлено воспроизведение блокировки в случае установки управляемой блокировки перед чтением набора записей регистра сведений. UPD 10.07.2019 добавлена тестовая база с примером.

1 стартмани

08.07.2019    11502    azazana    79    

Многопоточность. Универсальный «Менеджер потоков» (фреймворк) с отслеживанием зависимости объектов Промо

Практика программирования Математика и алгоритмы Универсальные функции Производительность и оптимизация (HighLoad) v8 1cv8.cf Россия Абонемент ($m)

Восстановление партий, расчет зарплаты, пакетное формирование документов или отчетов - теперь все это стало доступнее. * Есть желание повысить скорость работы медленных алгоритмов! Но... * Нет времени думать о реализации многопоточности? * о запуске и остановке потоков? * о поддержании потоков в рабочем состоянии? * о передаче данных в потоки и как получить ответ из потока? * об организации последовательности? Тогда ЭТО - то что надо!!!

26.05.2017    49689    DarkAn    86    

Мониторинг производительности и искусственный интеллект

Производительность и оптимизация (HighLoad) Практика программирования Разработка v8 Абонемент ($m)

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

1 стартмани

01.07.2019    9590    ivanov660    28    

"Убер на складе": динамический расчет маршрутов с учетом реальных расстояний

Учет ТМЦ Практика программирования Учет ТМЦ v8 УУ Абонемент ($m)

Представляю методику и инструмент для динамического расчета маршрутов отбора на высоконагруженных складах для максимального повышения эффективности склада, ускорения проходимости и, как следствие, экономии денег. Это методика и обработка для интеграции в WMS решения. Тестировалось на 1С 8.3.14.1565.

3 стартмани

24.06.2019    17424    informa1555    17    

1С:Ассемблер. Немного летнего веселья!

Практика программирования Разработка v8 1cv8.cf Абонемент ($m)

Все вы, наверное, слышали, что 1С-ники жалуются на свою систему, считая язык 1С недостаточно низкоуровневым, скучным и т.п. Все они с тоской поглядывают в сторону "настоящих" языков программирования. Так вот, господа, они неправы. В системе 1С есть места, где можно размять программерский мозг и получить удовольствие от низкоуровневой техники. Предлагаю вам погрузиться в недра виртуальной машины 1С и понять, как она работает. Там есть свой "ассемблер" и мы попробуем его в действии!

1 стартмани

21.06.2019    30466    Evil Beaver    134    

Новый запрос и новая таблица значений как функции Промо

Практика программирования v8 Абонемент ($m)

Предлагается две простые функции, использование которых уменьшает объем кода в конфигурациях на платформе «1С:Предприятие 8». Эти функции можно добавлять к своему общему модулю, что сделает процесс программирования более эффективным.

1 стартмани

27.11.2012    45516    ildarovich    46    

Простые примеры сложных отчетов на СКД

Практика программирования v8 v8::СКД 1cv8.cf Абонемент ($m)

Подписи в отчете. Особенности соединения наборов: как соединить несоединяемое. Остатки на дату и обороты по месяцам в одном отчете. Курс валюты на каждую дату без группировок и соединений в запросе. Отчет с произвольными колонками и с произвольной последовательностью. "Неадекватный отчет".

1 стартмани

12.06.2019    31399    Hatson    31    

Создание внешней печатной формы в формате документа Word

Практика программирования Разработка v8 1cv8.cf Абонемент ($m)

В статье написано, как создать внешнюю печатную форму (для конфигураций с БСП) в формате Word.

1 стартмани

17.05.2019    15936    ВикторП    21    

Пример настройки шаблонов и реализации печати отчетов в документ MS Word используя функциональную часть "Библиотеки Стандартных Подсистем 1С" (БСП)

Практика программирования Разработка v8 Россия Абонемент ($m)

В конфигурации выбраны и использованы только необходимые объекты библиотеки стандартных подсистем для реализации вывода отчёта, с табличными частями, в документ MS Word. Показан пример создания необходимых областей в шаблоне для вывода параметров в отчёт.

1 стартмани

23.04.2019    6819    olegpkc    11    

Уровни, глубина, прародители, циклы и аналоги запросом Промо

Практика программирования v8 1cv8.cf Абонемент ($m)

В продолжение публикации «Транзитивное замыкание запросом» [http://infostart.ru/public/158512/] добавлены другие варианты использования того же приема. Приведены запросы для быстрого определения уровней всех элементов справочника, максимальной глубины справочника, прародителей произвольных элементов справочника, запрос для быстрого определения циклов (на примере справочника спецификаций «1С:Управление производственным предприятием») и определения множеств аналогов номенклатуры (также на примере конфигурации «1С:Управление производственным предприятием»).

1 стартмани

13.11.2012    113955    ildarovich    98    

Ops средствами 1С:Предприятие

Практика программирования Разработка v8 1cv8.cf Абонемент ($m)

В статье описан программный пакет "Автоматизация ИТ-процессов" (АИТП), позволяющий автоматизировать задачи по администрированию, управлению и обслуживанию ИТ-инфраструктуры.

1 стартмани

23.04.2019    17710    blackhole321    28    

1C + Python + Django Rest Framework + Vue.js. Опыт несложной full-stack разработки

Практика программирования Внешние источники данных Обмен через XML WEB Разработка v8 1cv8.cf Абонемент ($m)

В этой статье мы рассмотрим путь и основные моменты создания небольшого вэб-сервиса, который мы называем "Онлайн Прайс-лист". Выгрузка из 1С, бэкенд, фронтенд, получение заказов в 1С.

1 стартмани

22.04.2019    35078    riposte    66    

Вывод вариантов СКД в таблицы на управляемой форме

Практика программирования Работа с интерфейсом v8 v8::УФ v8::СКД 1cv8.cf Абонемент ($m)

Задача стояла такая: есть 2 различных запроса, результаты которых выгружаются на форму обработки в таблицы значений (далее ТЗ) и программно "соприкасаются" между собой определенным образом (как именно- в рамках данной статьи неважно). Нюанс в том, что запросы должны иметь свой компоновщик настроек и могут интерактивно на форме изменяться пользователем. На оригинальность публикации не претендую - изначально в рамках поставленной задачи пытался найти что-то подобное (уже готовый шаблон) на инфостарте, возможно "плохо искал" ;)

05.04.2019    11756    artkor    1    

Неоплаченные долги при распределении оплаты по правилу ФИФО одним запросом и намного быстрее, чем Вы думали Промо

Практика программирования Дебиторская и кредиторская задолженность Дебиторская и кредиторская задолженность v8 v8::СКД КА1 УТ10 УПП1 УУ Абонемент ($m)

Предлагается метод для быстрого нахождения неоплаченных долгов при распределении оплаты по правилу ФИФО, основанный на дихотомии. Описывается реализация метода в виде достаточно простого запроса, решающего за линейное время указанную задачу, считавшуюся ранее существенно более трудоемкой. Приводятся примеры использования запроса в отчетах на СКД для конфигураций УТ, КА, УПП.

1 стартмани

28.02.2014    68955    ildarovich    125    

[EnterpriseData] Антисвертка характеристик номенклатуры при выгрузке в Бухгалтерию

Практика программирования Перенос данных из 1C8 в 1C8 Разработка v8 v8::ПВХ КД УНФ БП3.0 Россия БУ Абонемент ($m)

Рассмотрена выгрузка каждой пары значений Номенклатура - Характерстика из УНФ 1.6 в отдельную номенклатуру в Бухгалтерию 3.0 путём доработки правил обмена в формате EnterpriseData.

1 стартмани

27.03.2019    4983    nforce    6    

Интеграция 1С и SharePoint

Практика программирования Разработка v8 УНФ ДО ERP2 БП3.0 УТ11 УХ КА2 Россия Абонемент ($m)

Заказчики поставили задачу автоматизации согласования заявок на оплату в программе 1С:Бухгалтерия предприятия 3.0. Согласно ТЗ, данные должны подтягиваться из действующей электронной системы документаоборота на MS SharePoint (в дальнейшем СЭД MS SP).

1 стартмани

22.03.2019    5763    -I-    4    

Пример использования СКД и данных расшифровки на мобильной платформе

Практика программирования Разработка v8 v8::Mobile v8::СКД 1cv8.cf Россия Абонемент ($m)

СКД в мобильном приложении и меню действий на основе данных расшифровки (отчет, совместимый с мобильной платформой 8.3.13.45).

1 стартмани

12.03.2019    5707    majoram    0    

Транзитивное замыкание запросом Промо

Практика программирования v8 1cv8.cf Абонемент ($m)

В частности, показывается, как одним пакетным запросом найти ВСЕХ предков (потомков) в иерархическом справочнике. Аналогично можно определять входимость деталей в узлы и готовые изделия по их спецификациям, определять подмножества аналогичных запчастей по цепочке аналогов, решать другие подобные задачи. Приложен файл с примером отчета для замыкания иерархии произвольного справочника, позволяющий протестировать быстродействие запроса в разных условиях.

1 стартмани

29.10.2012    87336    ildarovich    118    

Программное создание реквизита управляемой формы с помощью механизма расширений

Практика программирования Разработка v8 v8::УФ 1cv8.cf Абонемент ($m)

В ЗУП 3 возникла задача добавить реквизит в справочник не внося изменений в конфигурацию. БСП с механизмом дополнительных реквизитов использовать было нежелательно, поэтому был использован механизм расширений. Для вывода данного реквизита на форму добавлять саму форму в расширение не хотелось по ряду причин, описанных ниже. Создание реквизита и элемента формы, соответствующего данному реквизиту было решено сделать программно в самом расширении, следуя принципу минимального воздействия на конфигурацию.

1 стартмани

12.03.2019    40257    ni_cola    32    

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

Практика программирования Математика и алгоритмы Разработка v8 Абонемент ($m)

В статье рассмотрен один из вариантов библиотечного подхода к разработке, позволяющий организовать иерархический вызов библиотечных процедур и упростить автоматическую сборку готового продукта из нескольких библиотек. Предлагаемый подход может служить одним из элементов CI/CD при разработке ПО на платформе 1С.

1 стартмани

04.03.2019    5894    Alxby    4    

Асинхронная работа с текстовыми файлами в 1С 8.3

Практика программирования Разработка v8 1cv8.cf Абонемент ($m)

В этой статье я рассмотрю основные моменты работы с текстовым файлом в 1С 8.3. (загрузка - выгрузка) в режиме отключенной модальности (асинхронно).

1 стартмани

28.02.2019    8120    signum2009    7