Обработка "Заполнение табличной части документа" из Эксель в бух. 3.0, дополнительно передача значения из модуля объекта обработки в модуль формы

1. user1056127 09.10.18 07:34 Сейчас в теме
Собственно сабж: нашел на просторах обработку "Заполнение табличной части документа из Эксель". В общем-то обработка создавалась для старых версий 1С, но там работоспособность ее мне удалось довести до требуемой. Обработка интегрируется как внешняя обработка и заполняет табличную часть, например, документа "Поступление товаров и услуг" добавляя кнопку на форму редактирования документа.
Естественно в модуле объекта прописал:
Функция СведенияОВнешнейОбработке() Экспорт
	РегистрационныеДанные = Новый Структура;
	МассивНазначений = Новый Массив;
	
	РегистрационныеДанные.Вставить("Вид", "ЗаполнениеОбъекта");
	РегистрационныеДанные.Вставить("Наименование", "Заполнение табличной части из Эксель");
	РегистрационныеДанные.Вставить("БезопасныйРежим", Истина);
	РегистрационныеДанные.Вставить("Версия", "1.0");
	РегистрационныеДанные.Вставить("Информация", "Обработка заполняет текстовую часть документов типа поступление/реализация товаров и услуг или счет");
	
	МассивНазначений.Добавить("Документ.ПоступлениеТоваровУслуг");
	МассивНазначений.Добавить("Документ.РеализацияТоваровУслуг");
	МассивНазначений.Добавить("Документ.ЗаказПокупателя");
    РегистрационныеДанные.Вставить("Назначение", МассивНазначений);
	
	ТаблицаКоманд = ПолучитьТаблицуКоманд();
    ДобавитьКоманду(ТаблицаКоманд, "Изменить реквизиты табличной части", "ИзменитьРеквизитыТабличнойЧасти", "ОткрытиеФормы", Ложь, );
	РегистрационныеДанные.Вставить("Команды", ТаблицаКоманд);
    
	Возврат РегистрационныеДанные;
КонецФункции

Функция ПолучитьТаблицуКоманд()
    
    // Создадим пустую таблицу команд и колонки в ней
    Команды = Новый ТаблицаЗначений;

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

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

    // Тут задается, как должна вызваться команда обработки
    // Возможные варианты:
    // - ОткрытиеФормы - в этом случае в колонке идентификатор должно быть указано имя формы, которое должна будет открыть система
    // - ВызовКлиентскогоМетода - вызвать клиентскую экспортную процедуру из модуля формы обработки
    // - ВызовСерверногоМетода - вызвать серверную экспортную процедуру из модуля объекта обработки
    Команды.Колонки.Добавить("Использование", Новый ОписаниеТипов("Строка"));

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

    // Для печатной формы должен содержать строку ПечатьMXL 
    Команды.Колонки.Добавить("Модификатор", Новый ОписаниеТипов("Строка"));
    Возврат Команды;
   
КонецФункции


Процедура ДобавитьКоманду(ТаблицаКоманд, Представление, Идентификатор, Использование, ПоказыватьОповещение = Ложь, Модификатор="")
    
    // Добавляем команду в таблицу команд по переданному описанию.
    // Параметры и их значения можно посмотреть в функции ПолучитьТаблицуКоманд
    НоваяКоманда = ТаблицаКоманд.Добавить();
    НоваяКоманда.Представление = Представление;
    НоваяКоманда.Идентификатор = Идентификатор;
    НоваяКоманда.Использование = Использование;
    НоваяКоманда.ПоказыватьОповещение = ПоказыватьОповещение;
    НоваяКоманда.Модификатор = Модификатор;

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

Самое интересное ждало меня дальше )))
ранее в обработке стояло объявление переменной (естественно в начале модуля) 

Перем мОбъект Экспорт;

а далее служебная процедура обработки

Процедура Инициализировать(Объект, ИмяТабличнойЧасти, ТабличноеПолеОбъекта) Экспорт
	Попытка
		ТабличнаяЧасть = Объект[ИмяТабличнойЧасти];
	Исключение
		Сообщить("Отсутствует табличная часть "+ИмяТабличнойЧасти + " в документе");
		Возврат;
	КонецПопытки;
	ФормаОбработки = ЭтотОбъект.ПолучитьФорму("Форма");
	мОбъект = Объект;
	ФормаОбработки.ОткрытьМодально();
КонецПроцедуры

То, что работало в бухгалтерии 2.0, по воле разработчиков перестало работать в 3.0.
Я так и не нашел нормальный способ передачи переменной "мОбъект" в модуль формы. Отсюда вопрос номер 1 кто имел опыт реальной передачи данных, тк я после кучи попыток отказался (и через дополнительные свойства, через реквизиты, и через ПолучитьОбъект и через функцию)?

Туда же можно отнести проблему с тем, что я так и не понял как передать значения реквизитам формы перед ее открытием, можно считать вопросом 2.

Решил что получить Объект в форме проще, чем его туда передать

&НаКлиенте  
Процедура КнопкаВыполнитьНажатие(Кнопка)
мОбъект = ВладелецФормы.Объект.Ссылка;
...
а в серверных процедурах получаю объект:
&НаСервере
Функция мОбъектТоварыОчистить(мОбъект)
	ммОбъект = мОбъект.ПолучитьОбъект();
	ммОбъект.Товары.Очистить();

Тут меня смущает вопрос номер 3: почему опять же работавшая нормально программа дает сбой - ругается, сообщает "Использование модальных окон в данном режиме запрещено!". Я понимаю, что разработчики решили отказаться от модальных окон, запретив их, но их можно принудительно разрешить, но как тогда "заморозить" форму редактирования документа, пока с ним работает обработка?

Возможно именно по этому на данном этапе у меня так и не очищаются судя по форме  редактирования документа строки табличной части...
Вопрос 4: возникает ошибка при вызове функции:
&НаКлиенте  
Процедура КнопкаВыполнитьНажатие(Кнопка)
мОбъект = ВладелецФормы.Объект.Ссылка;
...
НоваяСтрока = мОбъектТоварыДобавить(мОбъект);
.....

&НаСервере
Функция мОбъектТоварыДобавить(мОбъект)
	ммОбъект = мОбъект.ПолучитьОбъект();
	Результат = ммОбъект.Товары.Добавить();
	Возврат Результат;	
КонецФункции
Показать

ошибка следующая:

{ВнешняяОбработка.ЗаполнениеПоступленияИзЭксель.Форма.Форма.Форма(231)}: Ошибка при вызове метода контекста (мОбъектТоварыДобавить)
НоваяСтрока = мОбъектТоварыДобавить(мОбъект);
по причине:
Ошибка передачи данных между клиентом и сервером. Значение недопустимого типа.
по причине:
Ошибка преобразования данных XDTO:
Запись значения свойства 'ret':
форма: Элемент
имя: {http://v8.1c.ru/8.2/managed-application/modules}ret
по причине:
Ошибка отображения типов:
Отсутствует отображение для типа 'ДокументТабличнаяЧастьСтрока.ПоступлениеТоваровУслуг.Товары'

В общем кто что скажет в помощь? Обсудим?
Ответы
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
4. ysobol 09.10.18 08:57 Сейчас в теме
(1) и (2) и (3) Вопрос номер 0 - неужто так часто используется заполнение из эксель что нужна педаль прямо на форме? Просто обработку нельзя открыть?

Теперь по вопросу 3: Модальные формы в управляемом режиме не работают никак. Передача параметров происходит через ПолучитьФорму().Открыть либо через ОткрытьФорму(). При этом (если мне не изменяет память) набор передаваемых параметров в них разный, но обе не ко всем объектам применимы... Я еще извращаюсь передачей через ВладелецФормы - рекомендую

Вопрос 4 в части (1) передавать параметры между объектами (ИМХО) лучше структурой. Я столкнулся года три назад с невозможностью передавать ТЗ в параметрах, пересел на структуру и наслаждаюсь - рекомендую
Вопрос 4 в части (2) скорее всего "Метод объекта не обнаружен (РассчитатьСуммуТабЧасти)" не может быть отработан ТАМ где он отрабатывается (сервер/клиент) (кстати еще зависит от типа клиента (тонкий/толстый)
А ну и вопрос 2: Отладчиком ловил "ПриОткрытии"? Должны заполняться нормально. В крайнем случае через Элементы (зависит от версии платформы). А вообще использовать реквизиты формы это пожизненный гемор )
5. user1056127 09.10.18 09:13 Сейчас в теме
(4) to ysobol: Ну вообще во-первых педаль на форме дает ссылку на документ, который необходимо заполнить, опять же уже открытая форма , а этим можно обойти работу с датой, заполнением по контрагенту, что собственно мне (а пишу я сам себе как это не странно) удобно, да и вообще привык именно к такому принципу, когда открываешь форму, ищешь "заполнить по" если оно есть, короче автоматизируешь процесс.
по вопросу 3: есть какие-то примеры, ибо получается надо переучиваться, настолько привык к концепции 2.0 и более ранних, а тут черт дернул обновить конфигурацию до 3.0 и поимел все плюсы :) .
Вопрос 4 в части (2) хм, у меня НаСервере, странно...по логике работа с данными...
16. user1056127 12.10.18 12:42 Сейчас в теме
в общем получилось то что получилось, пользуйтесь, мне не жалко:
&НаСервере
Функция ЗапросПоискНоменклатуры(АртикулТекст)
	Запрос = Новый Запрос;
	Запрос.Текст = "ВЫБРАТЬ
		|	Номенклатура.Ссылка
		|ИЗ
		|	Справочник.Номенклатура КАК Номенклатура
		|ГДЕ
		|	Номенклатура.Наименование ПОДОБНО &Наименование
		|	ИЛИ Номенклатура.Артикул ПОДОБНО &Наименование";
	Запрос.УстановитьПараметр("Наименование","%"+АртикулТекст+"%");
	Выборка = Запрос.Выполнить().Выбрать();
	Пока Выборка.Следующий() Цикл
		Результат = Выборка.Ссылка;	
	КонецЦикла;	
	Возврат Результат;	
КонецФункции	
	
&НаСервере  
Функция ЗапросТипЦен(ТипЦен,Товар)
	Запрос = Новый Запрос;
	Запрос.Текст = "ВЫБРАТЬ
		|	ЦеныНоменклатурыСрезПоследних.Номенклатура,
		|	ЕСТЬNULL(ЦеныНоменклатурыСрезПоследних.Цена, 0) КАК Цена
		|ИЗ
		|	РегистрСведений.ЦеныНоменклатуры.СрезПоследних(
		|			,
		|			ТипЦен = &ТипЦен
		|				И Номенклатура = &Номенклатура) КАК ЦеныНоменклатурыСрезПоследних";
	Запрос.УстановитьПараметр("ТипЦен",ТипЦен);
	Запрос.УстановитьПараметр("Номенклатура", Товар);
	Выборка = Запрос.Выполнить().Выбрать();
	Пока Выборка.Следующий() Цикл
		Результат = Выборка.Цена;	
	КонецЦикла;
	Возврат Результат;	
КонецФункции	

&НаСервере
Функция НайтиПоРеквизиту(АртикулТекст)
	Результат = Справочники.Номенклатура.НайтиПоРеквизиту("Артикул", АртикулТекст);
	Возврат Результат;	
КонецФункции

&НаСервере
Функция НайтиПоНаименованию(АртикулТекст)
	Результат = Справочники.Номенклатура.НайтиПоНаименованию(АртикулТекст,Ложь);
	Возврат Результат;	
КонецФункции

&НаСервере
Функция СтраныМираНайтиПоНаименованию(Страна_ГТД_Текст)
	Результат = Справочники.СтраныМира.НайтиПоНаименованию(Страна_ГТД_Текст);
	Возврат Результат;	
КонецФункции

&НаСервере
Функция СтранаГТДСоздатьЭлемент(Страна_ГТД_Текст)
	НоваяСтрана = УправлениеКонтактнойИнформацией.ДанныеКлассификатораСтранМираПоНаименованию(ВРег(Страна_ГТД_Текст));
	Если НоваяСтрана <> Справочники.СтраныМира.ПустаяСсылка() Тогда
		НовыйЭлСпр = Справочники.СтраныМира.СоздатьЭлемент();
		НовыйЭлСпр.Наименование = НоваяСтрана.Наименование;
		НовыйЭлСпр.Код = НоваяСтрана.Код;
		НовыйЭлСпр.НаименованиеПолное = НоваяСтрана.НаименованиеПолное;
		НовыйЭлСпр.КодАльфа2 = НоваяСтрана.КодАльфа2;
		НовыйЭлСпр.КодАльфа3 = НоваяСтрана.КодАльфа3;
		НовыйЭлСпр.УчастникЕАЭС = НоваяСтрана.УчастникЕАЭС;
		НовыйЭлСпр.Записать();
		Результат = НовыйЭлСпр.Ссылка;
	Иначе
		Сообщить("Страна ~" + Страна_ГТД_Текст + "~ не найдена в ОКСМ");
		Результат = Неопределено;
	КонецЕсли;
	Возврат Результат;	
КонецФункции

&НаСервере
Функция НомераГТДНайтиПоКоду(Номер_ГТД_Текст)
	Результат = Справочники.НомераГТД.НайтиПоКоду(Номер_ГТД_Текст);
	Возврат Результат;	
КонецФункции

&НаСервере
Функция НомераГТДСоздатьЭлемент(Номер_ГТД_Текст)
	ОбъектНомераГТД  = Справочники.НомераГТД.СоздатьЭлемент();
	ОбъектНомераГТД.Код = Номер_ГТД_Текст;
	ОбъектНомераГТД.Записать();
	Результат = ОбъектНомераГТД.Ссылка;
	Возврат Результат;	
КонецФункции

&НаСервере
Функция ПеречисленияСтавкиНДСНДС18()
	Результат=Перечисления.СтавкиНДС.НДС18;
	Возврат Результат;	
КонецФункции

&НаСервере
Функция ПланыСчетовХозрасчетныйТоварыНаСкладах ()
	Результат = ПланыСчетов.Хозрасчетный.ТоварыНаСкладах;
	Возврат Результат;	
КонецФункции
	
&НаСервере
Функция ПланыСчетовХозрасчетныйНДСпоПриобретеннымМПЗ()
	Результат = ПланыСчетов.Хозрасчетный.НДСпоПриобретеннымМПЗ;
	Возврат Результат;	
КонецФункции

&НаСервере
Функция ТипЗнчДокументОбъектПоступлениеТоваровУслуг(мСсылкаНаОбъект)
	мОбъект = мСсылкаНаОбъект.ПолучитьОбъект();
	Если ТипЗнч(мОбъект) = Тип("ДокументОбъект.ПоступлениеТоваровУслуг") Тогда
		Результат = Истина;
	Иначе
		Результат = Ложь;
	КонецЕсли;
	Возврат Результат;	
КонецФункции

&НаСервере
Функция ПустаяСсылка()
	Результат = Справочники.Номенклатура.ПустаяСсылка();
	Возврат Результат;	
КонецФункции

&НаКлиенте  
Процедура КнопкаВыполнитьНажатие(Кнопка)
	Если ВсеРеквизитыЗаполнены() Тогда
		Если ВладелецФормы.Объект.Товары.Количество() > 0 Тогда
			Ответ = Вопрос("Табличная часть будет очищена. Да ""Очистить"", Нет ""Добавить"" или ""Отмена""?", РежимДиалогаВопрос.ДаНетОтмена);
			Если Ответ = КодВозвратаДиалога.Отмена Тогда
				Возврат;
			ИначеЕсли Ответ = КодВозвратаДиалога.Да Тогда
				ВладелецФормы.Объект.Товары.Очистить();
			КонецЕсли;
		КонецЕсли;
		Попытка 
			Excel = Новый COMОбъект("Excel.Application");
			Книга = Excel.WorkBooks.Open(СОКРЛП(Объект.ИмяФайла));
			Лист = Книга.WorkSheets(1);
		Исключение
			Excel.WorkBooks.Close();
			Предупреждение("Ошибка при открытии файла!");
			Возврат ;
		КонецПопытки;	
		//
		Номер = 0;
		Для К = Объект.НомерПервойСтроки ПО Объект.НомерПоследнейСтроки Цикл
			//читаем артикул
			//если умный поиск, то отрезаем правую часть начиная с пробела
			Если Объект.ВыборУмныйПоиск Тогда
				//читаем из номенклатуры, содержащей артикул
				АртикулТекст = СОКРЛП(Лист.Cells(К,Объект.Наша_Номенклатура).Text);
				Если Найти(АртикулТекст," ") > 0 Тогда
					АртикулТекст = Лев(АртикулТекст,Найти(АртикулТекст," ")-1);
				Иначе
					АртикулТекст = СОКРЛП(Лист.Cells(К,Объект.Артикул).Text);
				КонецЕсли;
			Иначе //читаем из артикула
				АртикулТекст = СОКРЛП(Лист.Cells(К,Объект.Артикул).Text);
			КонецЕсли;
			//ищем артикул либо в артикулах, либо в описании номенклатуры
			Если Объект.Выбор_Ищем_в_артикулах Тогда
				Товар = НайтиПоРеквизиту(АртикулТекст);
			Иначе
				Товар = НайтиПоНаименованию(АртикулТекст); 
				Если Товар = ПустаяСсылка() И АртикулТекст <> "" Тогда
					Товар = ЗапросПоискНоменклатуры(АртикулТекст);	
				КонецЕсли;
			КонецЕсли;
			//обработчик добавления номенклатуры в справочник при АртикулТекст <> ""
			Если Товар = Неопределено И АртикулТекст <> "" Тогда
				Если Объект.Сцеплять_Артикул_Номенклатуру Тогда
					МояНоменклатура = СОКРЛП(Лист.Cells(К,Объект.Артикул).Text) + " " + СОКРЛП(Лист.Cells(К,Объект.Наша_Номенклатура).Text);
				Иначе
					МояНоменклатура = СОКРЛП(Лист.Cells(К,Объект.Наша_Номенклатура).Text);
				КонецЕсли;
				ФормаЭлементаНоменклатуры = ПолучитьФорму("Справочник.Номенклатура.Форма.ФормаЭлемента");
				ФормаЭлементаНоменклатуры.Объект.Наименование = Лев(МояНоменклатура,100);
				ФормаЭлементаНоменклатуры.Объект.НаименованиеПолное = МояНоменклатура;
				ФормаЭлементаНоменклатуры.Объект.Артикул = АртикулТекст;
				ФормаЭлементаНоменклатуры.Объект.Родитель = Объект.ТоварнаяГруппа;
				ФормаЭлементаНоменклатуры.Объект.НоменклатурнаяГруппа = Объект.НашаНоменклатурнаяГруппа;
				ФормаЭлементаНоменклатуры.Объект.СтавкаНДС = ПеречисленияСтавкиНДСНДС18();
				Ответ = ФормаЭлементаНоменклатуры.ОткрытьМодально();
				//снова ищем артикул либо в артикулах, либо в описании номенклатуры
				Если Объект.Выбор_Ищем_в_артикулах Тогда
					Товар = НайтиПоРеквизиту(АртикулТекст);
				Иначе
					Товар = НайтиПоНаименованию(АртикулТекст); 
					Если Товар = ПустаяСсылка() И АртикулТекст <> "" Тогда
						Товар = ЗапросПоискНоменклатуры(АртикулТекст);
					КонецЕсли;
				КонецЕсли;
			КонецЕсли;			
			//ссылку получили, определяем что нашли строку и артикул был настоящий
			Если Товар <> Неопределено И Товар <> ПустаяСсылка() И АртикулТекст <> "" Тогда
				Если Объект.Цена > 0 Тогда
					Ценник	= СОКРЛП(Лист.Cells(К,Объект.Цена).Text);
					Ценник = СтрЗаменить(Ценник," руб.","");
					Ценник = СтрЗаменить(Ценник," руб","");
					Ценник = СтрЗаменить(Ценник,"руб.","");
					Ценник = СтрЗаменить(Ценник,"руб","");
					Ценник = СтрЗаменить(Ценник," ","");
					Попытка
						Ценник = Число(СокрЛП(Ценник));	
					Исключение 
						Ценник = 0;
					КонецПопытки;
				Иначе
					Ценник = 0;
					Ценник = ЗапросТипЦен(Объект.ТипЦен,Товар);	
				КонецЕсли;
				Попытка
					Колво = Число(СокрЛП(Лист.Cells(К,Объект.Количество).Text));
				Исключение
					Колво = 0;
				КонецПопытки;
				НоваяСтрока = ВладелецФормы.Объект.Товары.Добавить();
				// Заполнить значения реквизитов. 
				НоваяСтрока.Номенклатура = Товар;
				НоваяСтрока.Количество = Колво; 
				НоваяСтрока.Цена = Ценник;
				//пишем сумму
				Если Объект.Сумма = 0 Тогда
					//НоваяСтрока.Сумма = Колво*Ценник;
					ОбработкаТабличныхЧастейКлиентСервер.РассчитатьСуммуТабЧасти(НоваяСтрока, );
				Иначе
					СумБезНДС = СОКРЛП(Лист.Cells(К,Объект.Сумма).Text);
					СумБезНДС = СтрЗаменить(СумБезНДС," руб.","");
					СумБезНДС = СтрЗаменить(СумБезНДС," руб","");
					СумБезНДС = СтрЗаменить(СумБезНДС,"руб.","");
					СумБезНДС = СтрЗаменить(СумБезНДС,"руб","");
					СумБезНДС = СтрЗаменить(СумБезНДС," ","");
					Попытка
						СумБезНДС = Число(СокрЛП(СумБезНДС));	
					Исключение
						СумБезНДС = 0;
					КонецПопытки;
					НоваяСтрока.Сумма = СумБезНДС;
				КонецЕсли;
				//НДС
				НоваяСтрока.СтавкаНДС = ПеречисленияСтавкиНДСНДС18();
				//суммаНДС
				Если Объект.НДС = 0 Тогда
					ОбработкаТабличныхЧастейКлиентСервер.РассчитатьСуммуНДСТабЧасти(НоваяСтрока,,);
				Иначе
					СумНДС = СОКРЛП(Лист.Cells(К,Объект.НДС).Text);
					СумНДС = СтрЗаменить(СумНДС," руб.","");
					СумНДС = СтрЗаменить(СумНДС," руб","");
					СумНДС = СтрЗаменить(СумНДС,"руб.","");
					СумНДС = СтрЗаменить(СумНДС,"руб","");
					СумНДС = СтрЗаменить(СумНДС," ","");
					Попытка
						СумНДС = Число(СокрЛП(СумНДС));	
					Исключение
						СумНДС = 0;
					КонецПопытки;
					НоваяСтрока.СуммаНДС = СумНДС;
				КонецЕсли;
				//проверяем, если документ-поступление, значит ставим счета учета
				Если ТипЗнчДокументОбъектПоступлениеТоваровУслуг(ВладелецФормы.Объект.Ссылка) Тогда
					НоваяСтрока.СчетУчета = ПланыСчетовХозрасчетныйТоварыНаСкладах();
					НоваяСтрока.СчетУчетаНДС = ПланыСчетовХозрасчетныйНДСпоПриобретеннымМПЗ();
				КонецЕсли;
				//ГТД страна
				Если Объект.Страна_ГТД > 0 Тогда
					Страна_ГТД_Текст = СОКРЛП(Лист.Cells(К,Объект.Страна_ГТД).Text);
					Если Страна_ГТД_Текст <> "" Тогда
						СсылкаСтраны = СтраныМираНайтиПоНаименованию(Страна_ГТД_Текст);
						Если  СсылкаСтраны.Пустая() Тогда
							//заполняем страну по ОКСМ
							Ответ = Вопрос("Страна ~" + Страна_ГТД_Текст + "~ не найдена. Искать в ОКСМ?", РежимДиалогаВопрос.ОКОтмена);
							Если Ответ = КодВозвратаДиалога.Отмена Тогда
							Иначе
								НоваяСтрока.СтранаПроисхождения = СтранаГТДСоздатьЭлемент(Страна_ГТД_Текст);
							КонецЕсли;
						Иначе
							НоваяСтрока.СтранаПроисхождения = СсылкаСтраны;
						КонецЕсли;
					КонецЕсли;
				КонецЕсли;
				//ГТД номер
				Если Объект.Номер_ГТД > 0 Тогда
					Номер_ГТД_Текст = СОКРЛП(Лист.Cells(К,Объект.Номер_ГТД).Text);
					СсылкаНомераГТД =  НомераГТДНайтиПоКоду(Номер_ГТД_Текст);
					Если  СсылкаНомераГТД.Пустая() Тогда
						Ответ = Вопрос("Номер ГТД ~" + Номер_ГТД_Текст + "~ не найден. Создать?", РежимДиалогаВопрос.ОКОтмена);
						Если Ответ = КодВозвратаДиалога.Отмена Тогда
						Иначе
						НоваяСтрока.НомерГТД = НомераГТДСоздатьЭлемент(Номер_ГТД_Текст);
						КонецЕсли;
					Иначе
						НоваяСтрока.НомерГТД = СсылкаНомераГТД;
					КонецЕсли;
				КонецЕсли;
				//Всего
				НоваяСтрока.Всего = НоваяСтрока.Сумма + НоваяСтрока.СуммаНДС;
			Иначе
				ВладелецФормы.Объект.Товары.Добавить();
				Сообщить("Номенклатура с артикулом "+АртикулТекст+" не найдена!");
				Лист.Cells(К,1).value = "Не найден";
			КонецЕсли;
			
		КонецЦикла;
		
		Лист.Cells(Объект.НомерПоследнейСтроки+2, 1).Value = "Загрузка приходной накладной закончена "+ТекущаяДата();
		Лист.Cells(Объект.НомерПоследнейСтроки+3, 1).Value = "Из Эксель получено "+Строка(Объект.НомерПоследнейСтроки - Объект.НомерПервойСтроки + 1)+" строк"; 
		Лист.Cells(Объект.НомерПоследнейСтроки+4, 1).Value = "В документе "+ ВладелецФормы.Объект.Товары.Количество()+" строк";
		Попытка
			Книга.SaveAs(Объект.ИмяФайла);
			Excel.WorkBooks.Close();
			Excel.Application.Quit();
			ЗапуститьПриложение(Объект.ИмяФайла);
		Исключение
			Excel.WorkBooks.Close();
			Excel.Application.Quit();
			ЗапуститьПриложение(Объект.ИмяФайла);	
		КонецПопытки;
		
	КонецЕсли;
	
КонецПроцедуры

&НаКлиенте
Процедура ИмяФайлаНачалоВыбора(Элемент, СтандартнаяОбработка)
	Режим = РежимДиалогаВыбораФайла.Открытие;
	ДиалогОткрытияФайла = Новый ДиалогВыбораФайла(Режим);
	ДиалогОткрытияФайла.ПолноеИмяФайла = "";
	Фильтр = "Эксель(*.xls;*.xlsx)|*.xls;*.xlsx";
	ДиалогОткрытияФайла.Фильтр = Фильтр;
	ДиалогОткрытияФайла.МножественныйВыбор =ложь;
	ДиалогОткрытияФайла.Заголовок = "Выберите файл";
	Если ДиалогОткрытияФайла.Выбрать() Тогда
		МассивФайлов = ДиалогОткрытияФайла.ВыбранныеФайлы;
		Объект.ИмяФайла = МассивФайлов[0];
	Иначе
		Предупреждение("Файл не выбран!");
	КонецЕсли;
КонецПроцедуры

&НаКлиенте
Процедура ИмяФайлаОткрытие(Элемент, СтандартнаяОбработка)
	Ком = ""+СокрЛП(Объект.ИмяФайла);
	//КомандаСистемы(Ком);     
	ЗапуститьПриложение(Ком);
	СтандартнаяОбработка = ложь;
КонецПроцедуры

&НаКлиенте
Функция ВсеРеквизитыЗаполнены()
	Результат = Истина;
	
	Если Объект.ИмяФайла = "" Тогда
		Сообщить("Выберите файл!");
		Результат = Ложь;
	КонецЕсли;
	Если Объект.НомерПервойСтроки = 0 Тогда
		Сообщить("Задайте номер первой строки!");
		Результат = Ложь;
	КонецЕсли;
	Если Объект.НомерПоследнейСтроки = 0 Тогда
		Сообщить("Задайте номер последней строки!");
		Результат = Ложь;
	КонецЕсли;
	Если Объект.Артикул = 0 Тогда
		Сообщить("Задайте номер колонки с артикулом");
		Результат = Ложь;
	КонецЕсли;
	Если Объект.Наша_Номенклатура = 0 Тогда
		Сообщить("Задайте номер колонки с номенклатурой");
		Результат = Ложь;
	КонецЕсли;
	Если Объект.Количество = 0 Тогда
		Сообщить("Задайте номер колонки с количеством!");
		Результат = Ложь;
	КонецЕсли;
	Если Объект.Цена = 0 И (НЕ ЗначениеЗаполнено(Объект.ТипЦен)) Тогда
		Сообщить("Задайте номер колонки с ценой (чтобы вытащить ее из Эксель) или укажите тип цен (чтобы вытащить из регистра)!");
		Результат = Ложь;
	КонецЕсли;
	
	Возврат Результат;
	
КонецФункции

&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
	ОбъектСсылка = Параметры.ДополнительнаяОбработкаСсылка;
	ИдентификаторКоманды = Параметры.ИдентификаторКоманды;
	ИмяФормыВладельца = Параметры.ИмяФормы;
	ИнформацияОВладельце = ДополнительныеОтчетыИОбработкиПовтИсп.ПараметрыФормыНазначаемогоОбъекта(ИмяФормыВладельца);
	СсылкаРодителя  = ИнформацияОВладельце.СсылкаРодителя;
	ЭтоФормаОбъекта = ИнформацияОВладельце.ЭтоФормаОбъекта;
	Объект.Сцеплять_Артикул_Номенклатуру=Истина;
	Объект.НомерПервойСтроки=25;
	Объект.НомерПоследнейСтроки=37;
	Объект.Артикул=11;
	Объект.Наша_Номенклатура=3;
	Объект.Количество=36;
	Объект.Цена=39;
	Объект.Сумма=43;
	Объект.НДС=52;
КонецПроцедуры
Показать
2. user1056127 09.10.18 08:39 Сейчас в теме
Немного поменял концепцию, теперь
Процедура КнопкаВыполнитьНажатие(Кнопка)
мОбъект = ВладелецФормы.Объект.Ссылка;
...
мОбъектТоварыДобавить(мОбъект, куча параметров связанных с ценой количеством гтд итп);

а в функции теперь возвращаю просто 0, тк по сути НаКлиенте возвращаемое ммОбъект.Товары.Добавить() особо и не нужно. Проблема 4 переросла в следующую:
{ВнешняяОбработка.ЗаполнениеПоступленияИзЭксель.Форма.Форма.Форма(110)}: Метод объекта не обнаружен (РассчитатьСуммуТабЧасти)
ОбработкаТабличныхЧастей.РассчитатьСуммуТабЧасти(НоваяСтрока, ммОбъект);

Как повторяюсь рабочая строчка вдруг перестает работать?
10. ysobol 11.10.18 12:10 Сейчас в теме
(2)
{ВнешняяОбработка.ЗаполнениеПоступленияИзЭксель.Форма.Форма.Форма(110)}: Метод объекта не обнаружен (РассчитатьСуммуТабЧасти)
ОбработкаТабличныхЧастей.РассчитатьСуммуТабЧасти(НоваяСтрока, ммОбъект);

Как повторяюсь рабочая строчка вдруг перестает работать?


Скорее всего при переходе из одного объекта в другой где-то меняется НаСервере/НаКлиенте и этот механизм не отрабатывается...

Пробовал менять клиента толстый/тонкий?
12. user1056127 11.10.18 15:07 Сейчас в теме
(10) собственно у меня толстый ))) ну в моем понимании, короче файловая база, и если что-то не идет, я не пытаюсь сделать универсальную, на многое могу забить, могу вообще не указать директиву, потому спрашиваю, как лучше поступить? пока что это вызывается НаСервере.
3. user1056127 09.10.18 08:45 Сейчас в теме
Заодно можно сразу обсудить
{ВнешняяОбработка.ЗаполнениеПоступленияИзЭксель.Форма.Форма.Форма(124)}: Метод объекта не обнаружен (ТоварыНаСкладах)
НоваяСтрока.СчетУчета = ПланыСчетов.Хозрасчетный.ТоварыНаСкладах();
9. ysobol 11.10.18 12:07 Сейчас в теме
(3)
Заодно можно сразу обсудить
{ВнешняяОбработка.ЗаполнениеПоступленияИзЭксель.Форма.Форма.Форма(124)}: Метод объекта не обнаружен (ТоварыНаСкладах)
НоваяСтрока.СчетУчета = ПланыСчетов.Хозрасчетный.ТоварыНаСкладах();


Ты уверен что у "ПланыСчетов.Хозрасчетный" есть процедура "ТоварыНаСкладах()"? Может скобочки убрать?
6. user1056127 09.10.18 10:13 Сейчас в теме
Ваще))) счас смотрю на стандартную форму выбора номенклатуры вызываемую из стандартной формы редактирования документа поступления, и она !!! МОДАЛЬНАЯ!!! но как?
8. ysobol 11.10.18 12:06 Сейчас в теме
(6)
Ваще))) счас смотрю на стандартную форму выбора номенклатуры вызываемую из стандартной формы редактирования документа поступления, и она !!! МОДАЛЬНАЯ!!! но как?

Ну вот они такие... себе (из движка платформы) разрешают это делать, а нам (простым смертным) - кукишь с маслом...
Они создали набор стандартных команд, в которые нельзя ни заглянуть ни отладить (поставляется "как есть"...)
Скорее всего их можно использовать, но я не нашел ни справки ни примеров (может так искал?...) какие туда параметры передаются хз...
7. user1056127 11.10.18 08:53 Сейчас в теме
ваще ниче не пойму:
{ВнешняяОбработка.ЗаполнениеДокументовИзЭксель.Форма.Форма.Форма(160)}: Недостаточно фактических параметров
Если СтандартныеПодсистемыВызовСервера.ПараметрыРаботыКлиента().ИнформационнаяБазаФайловая Тогда
вроде абсолютно стандартная запись, что в ней не так?
19. ysobol 14.10.18 20:44 Сейчас в теме
(7)
Если СтандартныеПодсистемыВызовСервера.ПараметрыРаботыКлиента().ИнформационнаяБазаФайловая Тогда

А в общем модуле какие параметры у функции? И возвращает ли она булево?
22. user1056127 15.10.18 10:41 Сейчас в теме
(19) учитывая, что обошелся без нее, чет даже не хочется заморачиваться. Как уже писал, нет цели писать универсальный продукт, у меня все предопределено, потому от данной проверки отказался. Просто странно как-то...потому решил спросить, может у кого ответ есть готовый.
11. user1056127 11.10.18 14:03 Сейчас в теме
Обработка значительно продвинулась в развитии, теперь она реально очищает ТЧ, заполняет методом поиска номенклатуру, оставляя пока пустые строки там, где она не найдена (почему-то пока не вызывается форма создания номенклатуры, но это пока не главное), остались вопросы касаемо заполнения сумм методом 1С: (на клиенте она не видит переменную ОбработкаТабличныхЧастей, а на сервере метод РассчитатьСуммуТабЧасти) кто бы подсказал, где искать правду?
ОбработкаТабличныхЧастей.РассчитатьСуммуТабЧасти(НоваяСтрока, ВладелецФормы.Объект);
Аналогично и с ОбработкаТабличныхЧастей.РассчитатьСуммуНДСТабЧасти(НоваяСтрока, ВладелецФормы.Объект);
ПланыСчетов.Хозрасчетный.ТоварыНаСкладах и ....НДСпоПриобретеннымМПЗ решено, все ставит, сам затупил не заметил как добавил () в конце строки, соответственно обратился не как к полю а как к методу.
Что удивило в отличии от 2.0 конфы у меня не проставляются значения в колонку "Всего", что тоже через обработку? странновато, уж это то могла посчитать, причем считает, если в форме документа цену или количество или НДС поменять, а сама никак...
Появилась правда другая проблема, до которой пока не доходил, с ГТД: вроде все взято стандартно, что работало на 2.0
{ВнешняяОбработка.ЗаполнениеПоступленияИзЭксель.Форма.Форма.Форма(53)}: Поле объекта не обнаружено (КлассификаторСтранМира)
Результат = Справочники.КлассификаторСтранМира.НайтиПоНаименованию(Страна_ГТД_Текст);

&НаСервере
Функция КлассификаторСтранМираНайтиПоНаименованию(Страна_ГТД_Текст)
	Результат = Справочники.КлассификаторСтранМира.НайтиПоНаименованию(Страна_ГТД_Текст);
	Возврат Результат;	
КонецФункции
15. user1056127 12.10.18 07:51 Сейчас в теме
(11) сам себе же и отвечу: https://www.forum(.)mista(.)ru/topic.php?id=673725
и цитирую:
Делаю во внешней обработке проверку:
Если в справочнике стран нет нужной страны, то
надо подгрузить программно страну в справочник из встроенного классификатора.

Давно такое сделал для БП 2.0. Сегодня глянул в БП 3.0 и охренел:
Нет справочника ОКСМ теперь: СтраныМира
Раньше макет Классификатора был табличным документом - сейчас какая-то хрень типа xml.
18. ysobol 14.10.18 20:41 Сейчас в теме
(15) только делай Результат = Справочники.КлассификаторСтранМира.НайтиПоНаименованию(Страна_ГТД_Текст, Истина);
На случай ядерной войны
17. user1056127 12.10.18 12:47 Сейчас в теме
Жаль только пока не разобрался, как получить ссылку на созданную после открытия формы
ФормаЭлементаНоменклатуры = ПолучитьФорму("Справочник.Номенклатура.Форма.ФормаЭлемента");
.....
Ответ = ФормаЭлементаНоменклатуры.ОткрытьМодально();
Пробовал покопаться через уведомления, но чет полезного не нашел ничего, если кто чего подбросит за спасибо, буду рад.
20. ysobol 14.10.18 20:48 Сейчас в теме
(17)
как получить ссылку на созданную после открытия формы

Хых... Только сегодня делал - СП рулит, рекомендую ;)

СтруктураПараметра = Новый Структура("Ключ",ВыборкаРеализации.Ссылка);
ФормаДока = ОткрытьФорму("Документ.РеализацияТоваровУслуг.ФормаОбъекта",СтруктураПараметра);

У справочника будет так (дословно из СП:

П = Новый Структура("Ключ", Поставщик);
Форма = ПолучитьФорму("Справочник.Контрагенты.ФормаОбъекта", П);
Форма.Открыть();
21. user1056127 15.10.18 10:40 Сейчас в теме
(20) чет почитал - не в себе был ))) сам не понял что написал, а надо было вот что:
Я открываю форму "Справочник.Номенклатура.Форма.ФормаЭлемента" для создания нового элемента справочника, хотя ее и по другому можно открыть, но не суть, делаю я это для того, чтобы дать "оператору" (в данном случае себе) возможность проверить заполненные поля и откорректировать при необходимости. Потом я хочу по аналогии с работой со стандартной формой справочника, когда там создаешь новую номенклатуру, он выбор делает именно на вновь созданную, короче не ищешь ее, вот и здесь также хочу добавлять по ссылке новую номенклатуру, тк она создана как раз из "файла Экселя". По факту приходится заново искать номенклатуру программно, мне это конечно не нравится.
24. ysobol 15.10.18 14:15 Сейчас в теме
(21)
По факту приходится заново искать номенклатуру программно, мне это конечно не нравится.

Ну это другое дело.
А нельзя отловить момент записи элемента справочника и отхватить оттуда ссылку?
25. user1056127 16.10.18 07:19 Сейчас в теме
(24) у меня простая бухгалтерия базовая вся закрытая, я бы давно дописал методы, но приходится работать с тем что есть. В принципе работает )), просто хотелось улучшить ну и так в познаниях расширить кругозор методов.
23. user1056127 15.10.18 11:24 Сейчас в теме
К слову для поиска в ОКСМ в 2.0 я воспользовался макетом этого самого ОКСМ, тк в УправлениеКонтактнойИнформацией метода ДанныеКлассификатораСтранМираПоНаименованию попросту нет.
может это немного и криво, но сама конфигурация так берет данные из макета.

Если Страна_ГТД > 0 Тогда
Страна_ГТД_Текст = СОКРЛП(Лист.Cells(К,Страна_ГТД).Text);
Если Страна_ГТД_Текст <> "" Тогда
СсылкаСтраны = Справочники.КлассификаторСтранМира.НайтиПоНаименованию(Страна_ГТД_Текст,Истина);
Если СсылкаСтраны.Пустая() Тогда
//заполняем страну по ОКСМ
Ответ = Вопрос("Страна ~" + Страна_ГТД_Текст + "~ не найдена. Искать в ОКСМ?", РежимДиалогаВопрос.ОКОтмена);
Если Ответ = КодВозвратаДиалога.Отмена Тогда
Иначе
Макет = Справочники.КлассификаторСтранМира.ПолучитьМакет("КлассификаторСтранМира");
Макет.Параметры.Расшифровка = Истина; // чтобы работала расшифровка
//Считываем макет
Для Стр=1 По Макет.ВысотаТаблицы Цикл
Яч=Макет.Область(Стр, 3).Текст; //НаименованиеКраткое
Сообщить("Макет.Область(Стр, 3)="+Макет.Область(Стр, 3).Текст);
Если Яч = ВРег(Страна_ГТД_Текст) Тогда
Сообщить("тут");
НовыйЭлСпр = Справочники.КлассификаторСтранМира.СоздатьЭлемент();
НовыйЭлСпр.Наименование = Макет.Область(Стр, 3).Текст;//НаименованиеКраткое
НовыйЭлСпр.Код = Макет.Область(Стр, 2).Текст;//КодЧисловой
НовыйЭлСпр.НаименованиеПолное = Макет.Область(Стр, 6).Текст;//НаименованиеПолное
НовыйЭлСпр.КодАльфа2 = Макет.Область(Стр, 4).Текст;//КодАльфа2
НовыйЭлСпр.Записать();
СсылкаСтраны = НовыйЭлСпр.Ссылка;
КонецЕсли;
КонецЦикла;
НоваяСтрока.СтранаПроисхождения = СсылкаСтраны;
КонецЕсли;
Иначе
НоваяСтрока.СтранаПроисхождения = СсылкаСтраны;
КонецЕсли;
КонецЕсли;
КонецЕсли;
Оставьте свое сообщение

Для получения уведомлений об ответах подключите телеграм бот:
Инфостарт бот