ИИ для конвертации кода 77 в 83. Розница 3

Понадобилось конвертировать старую обработку загрузки данных из Excel под Розница 3.

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

Т.к. я довольно основательно забыл 77, решил скормить код обработки ИИ.

Исходный код:

//*******************************************
Процедура Сформировать()
	//Создаем ОЛЕ подключение к Excel
	Excel = СоздатьОбъект("Excel.Application"); 
	
	СтрЗаголовок="Укажите, пожалуйста, файл загрузки реализации.";
	СтрПриглашение="Excel";
	НовыйФайл = "";
	НовыйКаталог = "C:\Documents and Settings\Администратор\Мои документы\Downloads";       
	Если ФС.ВыбратьФайл(0, НовыйФайл, НовыйКаталог, СтрЗаголовок, СтрПриглашение+"(*.xls)|*.xls", "xls") = 1 Тогда
		ПутьКФайлу = НовыйКаталог+НовыйФайл; 
	Иначе
		Предупреждение("Файл не выбран!"); Возврат;
	КонецЕсли;  
	Сообщить(НовыйФайл);
	
	//Открываем файл
	Excel.Workbooks.Open(ПутьКФайлу); 
	
	//Открываем активную книгу
	Книга = Excel.ActiveWorkbook;     
	
	КолЛистов = Excel.WorkSheets.Count; 
	
	СпрВалюты = СоздатьОбъект("Справочник.Валюты");
	СпрВалюты.НайтиПоКоду("0"); 
	ВалютаЦены = СпрВалюты.ТекущийЭлемент(); 
	
	СпрФ = СоздатьОбъект("Справочник.Фирма");
	СпрФ.НайтиПоКоду("3"); 
	Ф = СпрФ.ТекущийЭлемент();
	
	СпрС = СоздатьОбъект("Справочник.Склады");
	СпрС.НайтиПоКоду("1"); 
	С = СпрС.ТекущийЭлемент();
	                                           
	СпрТМЦ = СоздатьОбъект("Справочник.Товары");
	//СпрЦены = СоздатьОбъект("Справочник.Цены");        
	//СпрОКЕИ = СоздатьОбъект("Справочник.ОКЕИ");
	//СпрЕдиницы = СоздатьОбъект("Справочник.Единицы"); 
	
	ДокР=СоздатьОбъект("Документ.РасходнаяНал");
	
	Для а=1 по КолЛистов Цикл  
		
		ЛистExcel=Excel.Worksheets.Item(а);   
		
		psw="***";
		ЛистExcel.Unprotect(psw);
	
		ДокР.Новый();
		ДокР.ДатаДок=ДатаДокР;
		ДокР.УстановитьНовыйНомер();
		ДокР.Валюта=ВалютаЦены;
		ДокР.Фирма=Ф;
		ДокР.Склад=С;
		ДокР.ПризнакНакладной=Перечисление.ПризнРасхНакл.Продажа;
		
		СпрК = СоздатьОбъект("Справочник.Контрагенты");
		КодК=СпрК.НайтиПоКоду(СокрЛП(Строка(ЛистExcel.Cells(3, 2).Value)));
		К = СпрК.ТекущийЭлемент();   
		
		Сообщить("Загружается реализация для: "+СокрЛП(К));
		
		ДокР.Клиент=К;
		ДокР.Дата_курса=ДатаДокР;	
		ДокР.Курс=1; 
		ДокР.ТипЦен=Перечисление.ТипыРасхЦен.Розничные;
		
		//Получаем количество строк в книге
		Строк = ЛистExcel.Cells.CurrentRegion.Rows.Count;  
		Для х = 4 По Строк Цикл 
			       
			КодТМЦ      = СокрЛП(Строка(ЛистExcel.Cells(х, 1).Value));
			НаименованиеТМЦ = СокрЛП(Строка(ЛистExcel.Cells(х, 2).Value)); 
			Кол=СокрЛП(Строка(ЛистExcel.Cells(х, 3).Value)); 
			Если Кол="" Тогда Продолжить; КонецЕсли;
			КолТМЦ     = Число(Кол);	
			                                           
			Если КодТМЦ="" Тогда Продолжить; КонецЕсли;
			Если КолТМЦ=0 Тогда Продолжить; КонецЕсли;
		                                                              
			Если СпрТМЦ.НайтиПоРеквизиту("Штрихкод",КодТМЦ,1) = 1 Тогда 
				НайдТовар = СпрТМЦ.ТекущийЭлемент();     
			Иначе
				Сообщить("Не найдена номенклатура: """+НаименованиеТМЦ+""", код: "+КодТМЦ);
				Продолжить;
			Конецесли; 
			Если НайдТовар.ЭтоГруппа()=1 Тогда Продолжить; КонецЕсли;  
			 
			ДокР.НоваяСтрока();
			ДокР.Товар=НайдТовар; 
			ДокР.Количество=КолТМЦ;
				Спр=СоздатьОбъект("Справочник.Единицы");
				Спр.ИспользоватьДату(ДатаДокР);
				Спр.ИспользоватьВладельца(НайдТовар);
				Спр.ВыбратьЭлементы();
				Пока Спр.ПолучитьЭлемент()=1 Цикл
					Если Спр.Единица=НайдТовар.БазоваяЕдиница Тогда
						ЕдИзм=Спр.ТекущийЭлемент();
						КоэфЕдИзм=Спр.Коэффициент;
						Прервать;
					КонецЕсли;
				КонецЦикла;
			ДокР.Единица=ЕдИзм;
			ДокР.Коэффициент=КоэфЕдИзм; 
			Цена=НайдТовар.Розн_Цена.Получить(ДатаДокР);
			ЦенаС=НайдТовар.Прих_Цена.Получить(ДатаДокР);
			ДокР.Цена=Цена;
			ДокР.ЦенаС=ЦенаС;
			ДокР.Сумма=КолТМЦ*Цена;
			ДокР.СуммаС=КолТМЦ*ЦенаС;
		КонецЦикла;  
		
		ДокР.Записать();
		//ДокР.Провести();   
		
		//Прервать;
		ЛистExcel.Protect(psw);
	КонецЦикла;
	
	//После загрузки зарываем соединение с Excel
	Excel.Workbooks.Close();    
	
	Предупреждение("Обработка завершена!");
КонецПроцедуры 

Сырой результат от ИИ, клиенская часть:

&НаКлиенте
Процедура Загрузить(Команда)

	Диалог = Новый ДиалогВыбораФайла(РежимДиалогаВыбораФайла.Открытие);
	Диалог.Заголовок = "Укажите, пожалуйста, файл загрузки реализации";
	Диалог.Фильтр = "Файлы Excel (*.xls; *.xlsx)|*.xls;*.xlsx";
	Диалог.МножественныйВыбор = Ложь;

	Если Не Диалог.Выбрать() Тогда
		Возврат;
	КонецЕсли;

	ПутьКФайлу = Диалог.ПолноеИмяФайла;

	Попытка
		Excel = Новый COMОбъект("Excel.Application");
		Excel.DisplayAlerts = Ложь;
		Книга = Excel.Workbooks.Open(ПутьКФайлу);
	Исключение
		ВызватьИсключение "Не удалось инициализировать Microsoft Excel: " + ОписаниеОшибки();
	КонецПопытки;

	КоличествоЛистов = Книга.Sheets.Count;
	Пароль = "***";

	// Структура для передачи пакета данных на сервер
	МассивНакладных = Новый Массив;

	Для СчЛиста = 1 По КоличествоЛистов Цикл
		Лист = Книга.Sheets(СчЛиста);
		Попытка
			Лист.Unprotect(Пароль);
		Исключение
			// Лист без пароля или неверный пароль
		КонецПопытки;

		КодКонтрагента = СокрЛП(Строка(Лист.Cells(3, 2).Value));
		Если ПустаяСтрока(КодКонтрагента) Тогда
			Продолжить;
		КонецЕсли;

		СтрокаНакладной = Новый Структура;
		СтрокаНакладной.Вставить("КодКонтрагента", КодКонтрагента);
		СтрокаНакладной.Вставить("Товары", Новый Массив);

		// Чтение строк с товарами (CurrentRegion или проверка на заполненность)
		ВсегоСтрок = Лист.Cells.SpecialCells(11).Row; // xlCellTypeLastCell = 11

		Для СчСтроки = 4 По ВсегоСтрок Цикл
			Штрихкод = СокрЛП(Строка(Лист.Cells(СчСтроки, 1).Value));
			Если ПустаяСтрока(Штрихкод) Тогда
				Продолжить;
			КонецЕсли;

			Количество = Число(Лист.Cells(СчСтроки, 3).Value);
			Если Количество <= 0 Тогда
				Продолжить;
			КонецЕсли;

			ТоварДанные = Новый Структура;
			ТоварДанные.Вставить("Штрихкод", Штрихкод);
			ТоварДанные.Вставить("Наименование", СокрЛП(Строка(Лист.Cells(СчСтроки, 2).Value)));
			ТоварДанные.Вставить("Количество", Количество);

			СтрокаНакладной.Товары.Добавить(ТоварДанные);
		КонецЦикла;

		МассивНакладных.Добавить(СтрокаНакладной);
	КонецЦикла;

	Книга.Close(Ложь);
	Excel.Quit();

	// Создание документов на стороне сервера
	Результат = СоздатьДокументыНаСервере(МассивНакладных, Объект.Организация, Объект.Склад, Объект.ВидЦен);

	ПоказатьОповещениеПользователя("Загрузка завершена", ,
		СтрШаблон("Создано документов: %1. Ошибок: %2", Результат.Создано, Результат.Ошибок));

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

Серверная часть:

&НаСервере
Функция СоздатьДокументыНаСервере(МассивНакладных, Знач Организация = Неопределено, Знач Склад = Неопределено, Знач ВидЦен = Неопределено)

	Результат = Новый Структура("Создано,Ошибок", 0, 0);

	// Подстановка значений по умолчанию, если не заданы на форме
	Если Не ЗначениеЗаполнено(Организация) Тогда
		Организация = Справочники.Организации.НайтиПоКоду("00-000003"); // Соответствие коду из 7.7
		Если Организация.Пустая() Тогда
			Организация = Справочники.Организации.ОрганизацияПоУмолчанию();
		КонецЕсли;
	КонецЕсли;

	Если Не ЗначениеЗаполнено(Склад) Тогда
		Склад = Справочники.СтруктурныеЕдиницы.НайтиПоКоду("00-000001");
	КонецЕсли;

	Если Не ЗначениеЗаполнено(ВидЦен) Тогда
		ВидЦен = Справочники.ВидыЦен.НайтиПоНаименованию("Розничная");
	КонецЕсли;

	Для Каждого ДанныеНакладной Из МассивНакладных Цикл

		Контрагент = Справочники.Контрагенты.НайтиПоКоду(ДанныеНакладной.КодКонтрагента);
		Если Контрагент.Пустая() Тогда
			ОбщегоНазначения.СообщитьПользователю(
				СтрШаблон("Контрагент с кодом %1 не найден. Пропуск накладной.", ДанныеНакладной.КодКонтрагента));
			Результат.Ошибок = Результат.Ошибок + 1;
			Продолжить;
		КонецЕсли;

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

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

		// Валюта взаиморасчетов
		Если ЗначениеЗаполнено(ДоговорКонтрагента) Тогда
			Док.ВалютаДокумента = ДоговорКонтрагента.ВалютаВзаиморасчетов;
		Иначе
			Док.ВалютаДокумента = Константы.ОсновнаяВалютаУчета.Получить();
		КонецЕсли;
		Док.Курс = 1;
		Док.Кратность = 1;

		Для Каждого СтрТовар Из ДанныеНакладной.Товары Цикл

			// Поиск Номенклатуры по штрихкоду через регистр сведений
			ОтборШК = Новый Структура("Штрихкод", СтрТовар.Штрихкод);
			Номенклатура = РегистрыСведений.ШтрихкодыНоменклатуры.ПолучитьНоменклатуруПоШтрихкоду(СтрТовар.Штрихкод);

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

			Если Не ЗначениеЗаполнено(Номенклатура) Тогда
				ОбщегоНазначения.СообщитьПользователю(
					СтрШаблон("Штрихкод %1 (%2) не найден в базе. Строка пропущена.",
						СтрТовар.Штрихкод, СтрТовар.Наименование));
				Продолжить;
			КонецЕсли;

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

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

				// Вызов механизма ценообразования Розницы 3.0 / УНФ
				Цена = ЦенообразованиеСервер.ПолучитьЦенуНоменклатуры(Номенклатура, , ВидЦен, Док.Дата);
				НоваяСтрока.Цена = Цена;
			КонецЕсли;

			НоваяСтрока.Сумма = НоваяСтрока.Количество * НоваяСтрока.Цена;

			// Автоматическое заполнение ставки НДС из номенклатуры
			НоваяСтрока.СтавкаНДС = Номенклатура.СтавкаНДС;

		КонецЦикла;

		Если Док.Запасы.Количество() > 0 Тогда
			Попытка
				Док.Записать(РежимЗаписиДокумента.Запись);
				Результат.Создано = Результат.Создано + 1;
			Исключение
				Результат.Ошибок = Результат.Ошибок + 1;
				ОбщегоНазначения.СообщитьПользователю(
					СтрШаблон("Ошибка при записи документа для %1: %2", Контрагент, ОписаниеОшибки()));
			КонецПопытки;
		КонецЕсли;

	КонецЦикла;

	Возврат Результат;

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

В целом неплохо заменило синтаксис, вызвало даже некоторые функции БСП, разделило чтение файла на клиент-сервер. Т.е. сэкономило мне где-то час работы.

Исходя из своего опыта, я сделал следующие доработки:

  1. Сделал автосохранение полей.
  2. Поле выбора имени файла и кнопку выбора.
  3. Сделал выбор листа для загрузки, в файле более 20 листов, отлаживать долго, больше для себя.
  4. Сделал поля для ввода полей загрузки (организация, склад, вид цен), отметил их обязательным к заполнению. И добавил контроль их заполнения.
  5. Заменил функцию преобразования в Число на свою.
  6. Сделал файл Excel видимым, чтобы пользователь мог его закрыть при необходимости без диспетечра задач.
  7. С помощью ИИ написал функцию, которая ищет по контрагента по хвосту кода.
  8. Добавил прогон без записи документов.
  9. Поправил заполнение расходной накладной:
    • Определение договора по умолчанию.
    • Определение валюты расчетов из договора.
    • Поиск номенклатуры по штрих-коду.
    • Заполнение ставок НДС, налогообложения, суммы всего.

Форма получилась такая:

В общем, основная часть пришлась не на переписывание кода, а на адаптацию к УНФ/Рознице.

Итоговый код обработки:
&НаКлиенте
Процедура ВыбИмяФайлаНачалоВыбора(Элемент, ДанныеВыбора, ВыборДобавлением, СтандартнаяОбработка)
    РежимДиалога = РежимДиалогаВыбораФайла.Открытие;
    Диалог = Новый ДиалогВыбораФайла(РежимДиалога);
    Диалог.МножественныйВыбор = ложь;
    Диалог.ПолноеИмяФайла = ВыбИмяФайла;
    Диалог.Фильтр = "Файлы Excel (*.xls, *.xlsx)|*.xls;*.xlsx";
    Диалог.Показать(Новый ОписаниеОповещения("ВыбИмяФайлаОкончаниеВыбора", ЭтаФорма));
КонецПроцедуры

&НаКлиенте
Процедура ВыбИмяФайлаОкончаниеВыбора(ВыбранныеФайлы, ДополнительныеПараметры) Экспорт
    Если ВыбранныеФайлы <> Неопределено Тогда
        ВыбИмяФайла = ВыбранныеФайлы[0];
    КонецЕсли;
КонецПроцедуры   


&НаКлиенте
Процедура Загрузить(Команда)   
	
	Если Не ЗначениеЗаполнено(ВыбВидЦен) 
		ИЛИ Не ЗначениеЗаполнено(ВыбСклад) 
		ИЛИ Не ЗначениеЗаполнено(ВыбОрганизация) 
		ИЛИ Не ЗначениеЗаполнено(ВыбИмяФайла) 
		ИЛИ Не ЗначениеЗаполнено(ВыбДата) 
		//ИЛИ Не ЗначениеЗаполнено(ВыбПодразделение) 
	Тогда
		ПоказатьПредупреждение(, "Заполните поля для загрузки в форме!");
	КонецЕсли;


	Попытка
		Excel = Новый COMОбъект("Excel.Application");
		Excel.DisplayAlerts = Ложь;
		Excel.Visible = Истина; //Чтобы не зависало приложение
		Книга = Excel.Workbooks.Open(ВыбИмяФайла);
	Исключение
		ВызватьИсключение "Не удалось инициализировать Microsoft Excel: " + ОписаниеОшибки();
	КонецПопытки;

	КоличествоЛистов = Книга.Sheets.Count;
	Пароль = "***";

	// Структура для передачи пакета данных на сервер
	МассивНакладных = Новый Массив;

	Для СчЛиста = 1 По КоличествоЛистов Цикл   
		
		Если ВыбЛист <> 0 И СчЛиста <> ВыбЛист Тогда
			Продолжить;
		КонецЕсли;

		
		Лист = Книга.Sheets(СчЛиста);
		Попытка
			Лист.Unprotect(Пароль);
		Исключение
			// Лист без пароля или неверный пароль
		КонецПопытки;

		КодКонтрагента = СокрЛП(Строка(Лист.Cells(3, 2).Value));
		Если ПустаяСтрока(КодКонтрагента) Тогда
			Продолжить;
		КонецЕсли;

		СтрокаНакладной = Новый Структура;
		СтрокаНакладной.Вставить("КодКонтрагента", КодКонтрагента);
		СтрокаНакладной.Вставить("Товары", Новый Массив);

		// Чтение строк с товарами (CurrentRegion или проверка на заполненность)
		ВсегоСтрок = Лист.Cells.SpecialCells(11).Row; // xlCellTypeLastCell = 11

		Для СчСтроки = 4 По ВсегоСтрок Цикл
			Штрихкод = СокрЛП(Строка(Лист.Cells(СчСтроки, 1).Value));
			Если ПустаяСтрока(Штрихкод) Тогда
				Продолжить;
			КонецЕсли;

			Количество = ВЧисло(Лист.Cells(СчСтроки, 3).Value);
			Если Количество <= 0 Тогда
				Продолжить;
			КонецЕсли;

			ТоварДанные = Новый Структура;
			ТоварДанные.Вставить("Штрихкод", Штрихкод);
			ТоварДанные.Вставить("Наименование", СокрЛП(Строка(Лист.Cells(СчСтроки, 2).Value)));
			ТоварДанные.Вставить("Количество", Количество);

			СтрокаНакладной.Товары.Добавить(ТоварДанные);
		КонецЦикла;

		МассивНакладных.Добавить(СтрокаНакладной);
	КонецЦикла;

	Книга.Close(Ложь);
	Excel.Quit();

	// Создание документов на стороне сервера
	Результат = СоздатьДокументыНаСервере(МассивНакладных, ВыбОрганизация, ВыбСклад, ВыбВидЦен);

	ПоказатьОповещениеПользователя("Загрузка завершена", ,
		СтрШаблон("Создано документов: %1. Ошибок: %2", Результат.Создано, Результат.Ошибок));

	КонецПроцедуры  
	
	
&НаСервере
Функция СоздатьДокументыНаСервере(МассивНакладных, Знач Организация = Неопределено, Знач Склад = Неопределено, Знач ВидЦен = Неопределено)

	Результат = Новый Структура("Создано,Ошибок", 0, 0);


	Для Каждого ДанныеНакладной Из МассивНакладных Цикл

		//Контрагент = Справочники.Контрагенты.НайтиПоКоду(ДанныеНакладной.КодКонтрагента);
		Контрагент = НайтиКонтрагентаПоХвостуКода(ДанныеНакладной.КодКонтрагента);
		
		Если Контрагент.Пустая() Тогда
			ОбщегоНазначения.СообщитьПользователю(
				СтрШаблон("Контрагент с кодом %1 не найден. Пропуск накладной.", ДанныеНакладной.КодКонтрагента));
			Результат.Ошибок = Результат.Ошибок + 1;
			Продолжить;
		КонецЕсли;
		
		//Скопировано из формы контрагента    
		ВидОперации = Перечисления.ВидыОперацийРасходнаяНакладная.ПродажаПокупателю;


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

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

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

			// Поиск Номенклатуры по штрихкоду через регистр сведений
			ОтборШК = Новый Структура("Штрихкод", СтрТовар.Штрихкод);                                  
			ДанныеШтрихкода = Новый Структура("Штрихкод", СтрТовар.Штрихкод);
			Номенклатура = РегистрыСведений.ШтрихкодыНоменклатуры.ПолучитьНоменклатуруПоШтрихкоду(ДанныеШтрихкода);

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

			Если Не ЗначениеЗаполнено(Номенклатура) Тогда
				ОбщегоНазначения.СообщитьПользователю(
					СтрШаблон("Штрихкод %1 (%2) не найден в базе. Строка пропущена.",
						СтрТовар.Штрихкод, СтрТовар.Наименование));
				Продолжить;
			КонецЕсли;

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

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

				// Вызов механизма ценообразования Розницы 3.0 / УНФ                       
				СтруктураДанных = Новый Структура();            
				//  СтруктураДанных - Структура:
				СтруктураДанных.Вставить("ВидЦен", ВидЦен);
				СтруктураДанных.Вставить("ДатаОбработки", ВыбДата);
				СтруктураДанных.Вставить("Номенклатура", Номенклатура);
				СтруктураДанных.Вставить("Характеристика", Неопределено);
				СтруктураДанных.Вставить("Коэффициент", 1);
				СтруктураДанных.Вставить("ВалютаДокумента", Док.ВалютаДокумента);
				СтруктураДанных.Вставить("СуммаВключаетНДС", Док.СуммаВключаетНДС);

				Цена = ЦенообразованиеСервер.ПолучитьЦенуНоменклатурыПоВидуЦен(СтруктураДанных);
				НоваяСтрока.Цена = Цена;                     
			КонецЕсли;

			НоваяСтрока.Сумма = НоваяСтрока.Количество * НоваяСтрока.Цена;
			НоваяСтрока.Всего = НоваяСтрока.Сумма;
			НоваяСтрока.СтавкаНДС = Справочники.СтавкиНДС.СтавкаНДС(Перечисления.ВидыСтавокНДС.БезНДС, ВыбДата);

			// Автоматическое заполнение ставки НДС из номенклатуры
			//НоваяСтрока.СтавкаНДС = Номенклатура.СтавкаНДС;

		КонецЦикла;

		Если Док.Запасы.Количество() > 0 Тогда
			Попытка     
				Если НЕ БезЗаписи Тогда
					Док.Записать(РежимЗаписиДокумента.Запись);
					Сообщить("Записан документ: " + Док);
				КонецЕсли;
				Результат.Создано = Результат.Создано + 1;
			Исключение
				Результат.Ошибок = Результат.Ошибок + 1;
				ОбщегоНазначения.СообщитьПользователю(
					СтрШаблон("Ошибка при записи документа для %1: %2", Контрагент, ОписаниеОшибки()));
			КонецПопытки;
		КонецЕсли;

	КонецЦикла;

	Возврат Результат;

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

Функция ВЧисло(С, Р=Неопределено, ЭтоЧисло=ложь) Экспорт
	//Назначение: Преобразует строку в число
	//ДатаСоздания: 20070424
	//Автор: Fixin
	//Тестирована: Да
	//$С: Строка
	//$Р: В	переменную Р возвращает ту часть строки, которую можно распознать как число
	//Описание:
	//	Если преобразовать невозможно, возвращает 0

	Перем Симв;
	Р="";
	
	ЭтоЧисло=ложь;
	
	БылаТочка=ложь;
	БылЗнак=ложь;
	Для Инд=1 По СтрДлина(С) Цикл
		Симв=Сред(С, Инд,1);
		Если Симв=" " Тогда
			Продолжить;
		КонецЕсли;
		Если Симв="." ИЛИ Симв="," Тогда
			Если БылаТочка Тогда
				Возврат 0;
			КонецЕсли;
			Р=Р+".";
			БылаТочка=истина;
			Продолжить;
		КонецЕсли;
		Если Симв="+" ИЛИ Симв="-" Тогда
			Если БылЗнак ИЛИ Р<>"" Тогда
				Возврат 0;
			КонецЕсли;
			Р=Р+Симв;
			БылЗнак=истина;
			Продолжить;
		КонецЕсли;
		Если Найти("0123456789", Симв)=0 Тогда
			Возврат 0;
		КонецЕсли;
		Р=Р+Симв;
	КонецЦикла;
	Если Р="" Тогда
		Возврат 0;
	КонецЕсли;
	
	ЭтоЧисло=истина;
	Возврат Число(Р);
КонецФункции



// Функция выполняет поиск контрагента по окончанию кода (суффиксу).
// Возвращает ссылку на найденного контрагента или Справочники.Контрагенты.ПустаяСсылка()
//
// Параметры:
//  ХвостКода - Строка, Число - символы, которыми должен заканчиваться код контрагента.
//
Функция НайтиКонтрагентаПоХвостуКода(Знач ХвостКода) Экспорт
	
	ХвостКода = СокрЛП(Строка(ХвостКода));
	Если ПустаяСтрока(ХвостКода) Тогда
		Возврат Справочники.Контрагенты.ПустаяСсылка();
	КонецЕсли;
	
	Запрос = Новый Запрос;
	Запрос.Текст =
	"ВЫБРАТЬ ПЕРВЫЕ 2
	| Контрагенты.Ссылка КАК Контрагент,
	| Контрагенты.Код КАК Код
	|ИЗ
	| Справочник.Контрагенты КАК Контрагенты
	|ГДЕ
	| Контрагенты.Код ПОДОБНО &ШаблонПоиска
	| И НЕ Контрагенты.ЭтоГруппа
	| И НЕ Контрагенты.ПометкаУдаления
	|УПОРЯДОЧИТЬ ПО
	| Контрагенты.Код";
	
	// Шаблон "%123" отбирает строки, завершающиеся на переданное значение
	Запрос.УстановитьПараметр("ШаблонПоиска", "%" + ХвостКода);
	
	РезультатЗапроса = Запрос.Выполнить();
	Если РезультатЗапроса.Пустой() Тогда
		Возврат Справочники.Контрагенты.ПустаяСсылка();
	КонецЕсли;
	
	Выборка = РезультатЗапроса.Выбрать();
	Выборка.Следующий();
	НайденнаяСсылка = Выборка.Контрагент;
	
	// Проверка на неоднозначность соответствия
	//Если Выборка.Следующий() Тогда
	//	ОбщегоНазначения.СообщитьПользователю(
	//	СтрШаблон("По окончанию кода ""%1"" найдено более одного контрагента. Выбран первый найденный: %2",
	//	ХвостКода, НайденнаяСсылка));
	//КонецЕсли;
	
	Возврат НайденнаяСсылка;
	
КонецФункции


Среда: УНФ 3.0.14.100. Объем 2 час.

image_pdfimage_print

fixin

Программирую на 1С с 1999 года. В 1С просто Гений. В 2020 году ушел из офиса на вольные хлеба фриланса. Принимаю заказы.

Вам может также понравиться...

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *