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

Приведенный текст ошибки программисту 1С скажет, что в модуле формы обработки «ЧтениеЗаписьXML на 152 строчке кода не может выполниться запрос. Причина в том, что на 17 строчке запроса нет чего-то, что ждал компилятор. Таким образом, чтобы убрать подобное сообщение, необходимо выяснить, что там должно быть и написать недостающий код.
Увидев вышеприведенный кусок кода, разработчик заметит, что в запросе есть служебное слово «ГДЕ», дающее сигнал 1С, что дальше будет условие. Но мы забыли дописать его и, естественно, система с помощью сообщения об ошибке спрашивает нас – «а где условие?». Чтобы исправить эту ситуацию необходимо либо убрать оператор «ГДЕ» из запроса, либо добавить условие.
Но ошибки могут быть не только в текстах запросов. Допустим, мы хотим выбрать всю номенклатуру и узнать, входит ли она в определенную группу. Проверка происходит с помощью метода «ПринадлежитЭлементу» и его параметра, который должен быть типа СправочникСсылка. Мы опять допускаем ошибку и вместо ссылки в параметр метода помещаем строку, содержащую имя переменной.
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Номенклатура.Ссылка КАК Ссылка,
| Номенклатура.ВерсияДанных КАК ВерсияДанных,
| Номенклатура.ПометкаУдаления КАК ПометкаУдаления,
| Номенклатура.Родитель КАК Родитель,
| Номенклатура.ЭтоГруппа КАК ЭтоГруппа,
| Номенклатура.Код КАК Код,
| Номенклатура.Наименование КАК Наименование,
| Номенклатура.Артикул КАК Артикул,
| Номенклатура.ЕдиницаИзмерения КАК ЕдиницаИзмерения,
| Номенклатура.ТипНоменклатуры КАК ТипНоменклатуры,
| Номенклатура.Предопределенный КАК Предопределенный,
| Номенклатура.ИмяПредопределенныхДанных КАК ИмяПредопределенныхДанных
|ИЗ
| Справочник.Номенклатура КАК Номенклатура
|ГДЕ
| НЕ Номенклатура.ЭтоГруппа ";
НужнаяГруппаЭлементов = Справочники.Номенклатура.НайтиПоНаименованию("Мебель");
РезультатЗапроса = Запрос.Выполнить();
ВыборкаДетальныеЗаписи = РезультатЗапроса.Выбрать();
Пока ВыборкаДетальныеЗаписи.Следующий() Цикл
Сообщить(ВыборкаДетальныеЗаписи.Ссылка.ПринадлежитЭлементу("НужнаяГруппаЭлементов"));
КонецЦикла;

1С выдает настолько же информативное сообщение, из которого мы понимаем, что на 158 строке у 1 параметра неправильный тип. Но что же делать, если мы не знаем, какой тип должен быть? В этом нам поможет Синтакс-помощник, встроенный в платформу 1С.

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

Чаще всего причиной подобных ошибок выступают следующие факторы:
- Невнимательность;
- Отсутствие опыта или знаний;
- Несогласованность действий разработчиков друг с другом;
- Изменения в методах контекста в новых версиях платформы.
Но ошибки при разработке ПО случаются постоянно, поскольку иногда ошибаются даже специалисты с многолетним опытом. Самое главное – уметь исправлять их и учиться на них. Постепенно вы будете видеть сообщения об ошибках все реже и научитесь замечать подобные «опечатки» еще до запуска 1С.
9 — 11.07.19 — 09:50
(8) А в какой именно строке? Просмотрела всю процедуру, не могу понять.
Процедура ЗаполнитьОперативныеВзаиморасчеты(ОсновныеПараметры) Экспорт
#Область ИнициализацияЗапросаИПеременных
АналитикаУчетаПоПартнерам = ОсновныеПараметры.АналитикаУчетаПоПартнерам;
ОбъектРасчетов = ОсновныеПараметры.ОбъектРасчетов;
ВалютаРасчетов = ОсновныеПараметры.ВалютаРасчетов;
ЭтоРасчетыСКлиентами = ОсновныеПараметры.ЭтоРасчетыСКлиентами;
Регистратор = ОсновныеПараметры.Регистратор;
Порядок = ОсновныеПараметры.Порядок;
ВалютаРегламентированногоУчета = Константы.ВалютаРегламентированногоУчета.Получить();
ВалютаУправленческогоУчета = Константы.ВалютаУправленческогоУчета.Получить();
АналитикаОбъектаРасчета = ОбщегоНазначения.ЗначенияРеквизитовОбъекта(АналитикаУчетаПоПартнерам,»Организация»);
Организация = АналитикаОбъектаРасчета.Организация;
//Если график исполнения в договоре, то вместо графика заказа будет уточняться график договора.
//Если пользователь каким-то образом ввел заказы с графиками по такому договору, то все этапы таких заказов будут отнесены к графику договора
//и закрываться будут по ФИФО независимо от привязки накладных к заказам
Если ТипЗнч(ОбъектРасчетов) = Тип(«СправочникСсылка.ДоговорыКонтрагентов») Тогда
ГрафикИсполненияДоговора = ОбщегоНазначения.ЗначениеРеквизитаОбъекта(ОбъектРасчетов,»ГрафикИсполненияДоговора»);
ГрафикВДоговоре = ЗначениеЗаполнено(ГрафикИсполненияДоговора);
Иначе
ГрафикИсполненияДоговора = Неопределено;
ГрафикВДоговоре = ЛОЖЬ;
КонецЕсли;
Если ЭтоРасчетыСКлиентами Тогда
РасчетыПоЗаказу = ТипЗнч(ОбъектРасчетов) = Тип(«ДокументСсылка.ЗаказКлиента»)
ИЛИ ТипЗнч(ОбъектРасчетов) = Тип(«ДокументСсылка.ЗаявкаНаВозвратТоваровОтКлиента»);
Иначе
РасчетыПоЗаказу = ТипЗнч(ОбъектРасчетов) = Тип(«ДокументСсылка.ЗаказПоставщику»);
КонецЕсли;
СписокТиповПлатежек = ТипыПлатежныхДокументов();
РасчетыПоПлатежке = СписокТиповПлатежек.Найти(ТипЗнч(ОбъектРасчетов)) <> Неопределено;
ХозяйственныеОперацииНеОтгрузка = ХозяйственныеОперацииНеОтгрузка();
Если НЕ РасчетыПоПлатежке И ТипЗнч(ОбъектРасчетов) = Тип(«ДокументСсылка.ПервичныйДокумент») Тогда
ТипПервичногоДокумента = ОбщегоНазначения.ЗначениеРеквизитаОбъекта(ОбъектРасчетов,»ТипПервичногоДокумента»);
РасчетыПоПлатежке = ТипПервичногоДокумента = Перечисления.ТипыПервичныхДокументов.ОплатаПоставщику
ИЛИ ТипПервичногоДокумента = Перечисления.ТипыПервичныхДокументов.ОплатаОтКлиента;
КонецЕсли;
ГлобальныеПеременные = Новый Структура;
ГлобальныеПеременные.Вставить(«ЕжедневнаяПереоценка», Константы.ПереоцениватьВалютныеСредстваПоДням.Получить());
//Для уточнения плана оплат — в переменной хранится последний момент времени плана оплат,
//чтобы при добавлении записи в план оплат можно было сразу определить есть ли планы оплат с датой больше, чем добавляемая запись.
ГлобальныеПеременные.Вставить(«МаксимальныйПорядокПланаОплат»,»»);
ГлобальныеПеременные.Вставить(«ВалютаРасчетов», ВалютаРасчетов);
ГлобальныеПеременные.Вставить(«ГрафикВДоговоре», ГрафикВДоговоре);
ГлобальныеПеременные.Вставить(«ЭтоРасчетыСКлиентами», ЭтоРасчетыСКлиентами);
ГлобальныеПеременные.Вставить(«ПорядокПереоценки», Новый Соответствие);
//Хозяйственные операции для заполнения.
ХозяйственныеОперации = Новый Соответствие;
Если ЭтоРасчетыСКлиентами Тогда
ХозяйственныеОперации.Вставить(«ЗачетАванса», Перечисления.ХозяйственныеОперации.ЗачетАвансаКлиента);
ХозяйственныеОперации.Вставить(«ПогашениеЗадолженности», Перечисления.ХозяйственныеОперации.ПогашениеЗадолженностиКлиента);
ХозяйственныеОперации.Вставить(«ВозвратАванса», Перечисления.ХозяйственныеОперации.ВозвратОплатыКлиенту);
ХозяйственныеОперации.Вставить(«ПереоценкаПоложительная», Перечисления.ХозяйственныеОперации.КурсовыеРазницыКлиентыПрибыль);
ХозяйственныеОперации.Вставить(«ПереоценкаОтрицательная», Перечисления.ХозяйственныеОперации.КурсовыеРазницыКлиентыУбыток);
ХозяйственныеОперации.Вставить(«Планирование», Перечисления.ХозяйственныеОперации.ПланированиеПоЗаказуКлиента);
Иначе
ХозяйственныеОперации.Вставить(«ЗачетАванса», Перечисления.ХозяйственныеОперации.ЗачетАвансаПоставщику);
ХозяйственныеОперации.Вставить(«ПогашениеЗадолженности», Перечисления.ХозяйственныеОперации.ПогашениеЗадолженностиПоставщику);
ХозяйственныеОперации.Вставить(«ВозвратАванса», Перечисления.ХозяйственныеОперации.ВозвратДенежныхСредствОтПоставщика);
ХозяйственныеОперации.Вставить(«ПереоценкаПоложительная», Перечисления.ХозяйственныеОперации.КурсовыеРазницыПоставщикиУбыток);
ХозяйственныеОперации.Вставить(«ПереоценкаОтрицательная», Перечисления.ХозяйственныеОперации.КурсовыеРазницыПоставщикиПрибыль);
ХозяйственныеОперации.Вставить(«Планирование», Перечисления.ХозяйственныеОперации.ПланированиеПоЗаказуПоставщику);
КонецЕсли;
ХозяйственныеОперации.Вставить(«ПереносАванса», Перечисления.ХозяйственныеОперации.ПереносАванса);
ГлобальныеПеременные.Вставить(«ХозяйственныеОперации», ХозяйственныеОперации);
Запрос = Новый Запрос;
Менеджер = Новый МенеджерВременныхТаблиц;
Запрос.МенеджерВременныхТаблиц = Менеджер;
Запрос.УстановитьПараметр(«ОбъектРасчетов», ОбъектРасчетов);
Запрос.УстановитьПараметр(«АналитикаУчетаПоПартнерам», АналитикаУчетаПоПартнерам);
Запрос.УстановитьПараметр(«Организация», Организация);
Запрос.УстановитьПараметр(«ВалютаУпр», ВалютаУправленческогоУчета);
Запрос.УстановитьПараметр(«ВалютаРегл», ВалютаРегламентированногоУчета);
Запрос.УстановитьПараметр(«СписокТиповЗаказов», СписокТиповРегистраторовПланов());
Запрос.УстановитьПараметр(«ВалютаРасчетов», ВалютаРасчетов);
Запрос.УстановитьПараметр(«Порядок», Порядок);
Запрос.УстановитьПараметр(«ГрафикВДоговоре», ГрафикВДоговоре);
Запрос.УстановитьПараметр(«ГрафикИсполненияДоговора», ГрафикИсполненияДоговора);
Запрос.УстановитьПараметр(«РасчетыПоЗаказу», РасчетыПоЗаказу);
Запрос.УстановитьПараметр(«ЭтоРасчетыСКлиентами», ЭтоРасчетыСКлиентами);
Запрос.УстановитьПараметр(«Регистратор», Регистратор);
Запрос.УстановитьПараметр(«ПорядокЗачетаПоДатеПлатежа», Константы.ПорядокЗачетаДокументовПоДатеОперации.Получить() = 1);
#КонецОбласти
#Область ИнициализацияНаборовЗаписей
Если ЭтоРасчетыСКлиентами Тогда
НаборЗаписейПоСрокам = РегистрыНакопления.РасчетыСКлиентамиПоСрокам.СоздатьНаборЗаписей();
НаборЗаписейПланОплат = РегистрыНакопления.РасчетыСКлиентамиПланОплат.СоздатьНаборЗаписей();
НаборЗаписейПланОтгрузокПоставок = РегистрыНакопления.РасчетыСКлиентамиПланОтгрузок.СоздатьНаборЗаписей();
Иначе
НаборЗаписейПоСрокам = РегистрыНакопления.РасчетыСПоставщикамиПоСрокам.СоздатьНаборЗаписей();
НаборЗаписейПланОплат = РегистрыНакопления.РасчетыСПоставщикамиПланОплат.СоздатьНаборЗаписей();
НаборЗаписейПланОтгрузокПоставок = РегистрыНакопления.РасчетыСПоставщикамиПланПоставок.СоздатьНаборЗаписей();
КонецЕсли;
Если ОсновныеПараметры.Свойство(«ДополнительныеСвойстваПроведения») И ОсновныеПараметры.ДополнительныеСвойстваПроведения <> Неопределено Тогда
НаборЗаписейПоСрокам.ДополнительныеСвойства.Вставить(«ПроверятьИзмененияРегистра», Истина);
Если ОсновныеПараметры.Свойство(«Регистратор») Тогда
// При изменении проведения документа будут изменения в регистре, но по ним не следует регистрировать документ к отражению,
// так как он в любом случае изменит свои данные отражения при проведении (или распроведении).
НаборЗаписейПоСрокам.ДополнительныеСвойства.Вставить(«НеотражаемыйДокумент», ОсновныеПараметры.Регистратор);
КонецЕсли;
КонецЕсли;
РегистраторРасчетовОбъект = РегистраторРасчетов(ОбъектРасчетов, АналитикаУчетаПоПартнерам, ВалютаРасчетов, ЭтоРасчетыСКлиентами, Организация);
РегистраторРасчетов = РегистраторРасчетовОбъект.Ссылка;
НаборЗаписейПоСрокам.Отбор.Регистратор.Установить(РегистраторРасчетов);
НаборЗаписейПланОплат.Отбор.Регистратор.Установить(РегистраторРасчетов);
НаборЗаписейПланОтгрузокПоставок.Отбор.Регистратор.Установить(РегистраторРасчетов);
#КонецОбласти
//Движения до начала пересчета и остатки.
СформироватьВТДанныхРегистровДоНачалаРасчетов(Запрос, ЭтоРасчетыСКлиентами);
//Данные регистров с порядком меньше порядка начала расчета, далее дополняются.
ТаблицаРасчетовПоСрокам = Менеджер.Таблицы[«ВТРасчетыПоСрокамДо»].ПолучитьДанные().Выгрузить();
ТаблицаПланОплат = Менеджер.Таблицы[«ВТРасчетыПланОплатДо»].ПолучитьДанные().Выгрузить();
ТаблицаПланОтгрузокПоставок = Менеджер.Таблицы[«ВТРасчетыПланОтгрузокПоставокДо»].ПолучитьДанные().Выгрузить();
//Движения после начала пересчета и остатки до начала пересчета для распределения.
РасчетыОтгрузкиПоставки = ПолучитьОтгрузкиПоставки(Запрос, Порядок);
ПланыОплат = ПолучитьПланыОплат(Запрос, Порядок, ЭтоРасчетыСКлиентами);
ПланыОтгрузокПоставок = ПолучитьПланыОтгрузокПоставок(Запрос, Порядок, ЭтоРасчетыСКлиентами);
РасчетыОплаты = ПолучитьОплаты(Запрос, Порядок);
Если РасчетыОплаты.Количество() = 0 И РасчетыОтгрузкиПоставки.Количество() = 0 И ТаблицаРасчетовПоСрокам.Количество() = 0 И НЕ ОсновныеПараметры.ТолькоПланы Тогда
НаборЗаписейПоСрокам.Записать();
КонецЕсли;
Если ПланыОплат.Количество() = 0 И РасчетыОтгрузкиПоставки.Количество() = 0 И ТаблицаПланОплат.Количество() = 0 Тогда
НаборЗаписейПланОплат.Записать();
КонецЕсли;
Если ПланыОтгрузокПоставок.Количество() = 0 И ТаблицаПланОтгрузокПоставок.Количество() = 0 Тогда
НаборЗаписейПланОтгрузокПоставок.Записать();
КонецЕсли;
НужнаПереоценка = (ВалютаРасчетов <> ВалютаРегламентированногоУчета ИЛИ ВалютаРасчетов <> ВалютаУправленческогоУчета)
И РасчетыОтгрузкиПоставки.Количество() > 0
И НЕ ОсновныеПараметры.ТолькоПланы;
Если НужнаПереоценка Тогда
ДатаНачалаКурсов = Мин(РасчетыОтгрузкиПоставки[0].Период,
?(РасчетыОплаты.Количество() > 0,
РасчетыОплаты[0].Период,
РасчетыОтгрузкиПоставки[0].Период));
ТаблицаКурсовВалют = ПолучитьКурсыВалют(Запрос, ДатаНачалаКурсов, ГлобальныеПеременные);
ГлобальныеПеременные.Вставить(«ТаблицаКурсовВалют», ТаблицаКурсовВалют);
КонецЕсли;
ДокументыРасчетаКурсовыхРазниц = Документы.РасчетКурсовыхРазниц.ДокументыПереоценки(Организация,
?(РасчетыОтгрузкиПоставки.Количество() > 0, РасчетыОтгрузкиПоставки[0].ДатаВозникновения, ТекущаяДатаСеанса()),
ТекущаяДатаСеанса(),
ЭтоРасчетыСКлиентами);
ГлобальныеПеременные.Вставить(«ДокументыРасчетаКурсовыхРазниц», ДокументыРасчетаКурсовыхРазниц);
//Добавляем приходные записи по плану оплаты (заказы , график договора)
//накладные не добавляем, т.к они могут быть уменьшены авансами.
Для Каждого Стр Из ПланыОплат Цикл
Если НЕ Стр.ПриходДобавлен Тогда
НовСтр = ТаблицаПланОплат.Добавить();
НовСтр.ВидДвижения = ВидДвиженияНакопления.Приход;
НовСтр.ДокументРегистратор = Стр.Регистратор;
НовСтр.ДокументПлан = Стр.Регистратор;
НовСтр.ВариантОплаты = Стр.ВариантОплаты;
НовСтр.Период = Стр.Период;
НовСтр.ДатаВозникновения = Стр.ДатаВозникновения;
НовСтр.ДатаПлановогоПогашения = Стр.ДатаПлановогоПогашения;
НовСтр.КОплате = Стр.КОплате;
НовСтр.ПорядокОперации = Стр.ПорядокОперации;
НовСтр.ПорядокЗачета = Стр.ПорядокОперации;
НовСтр.ХозяйственнаяОперация = ГлобальныеПеременные.ХозяйственныеОперации[«Планирование»];
КонецЕсли;
КонецЦикла;
//Добавляем приходные записи планов отгрузок.
Для Каждого Стр Из ПланыОтгрузокПоставок Цикл
Если НЕ Стр.ПриходДобавлен Тогда
НовСтр = ТаблицаПланОтгрузокПоставок.Добавить();
НовСтр.ВидДвижения = ВидДвиженияНакопления.Приход;
НовСтр.ДокументРегистратор = Стр.Регистратор;
НовСтр.ДокументПлан = Стр.Регистратор;
НовСтр.Период = Стр.Период;
НовСтр.ДатаВозникновения = Стр.ДатаВозникновения;
НовСтр.ДатаПлановогоПогашения = Стр.ДатаПлановогоПогашения;
НовСтр.Сумма = Стр.КОтгрузкеПоставке;
НовСтр.ПорядокЗачета = Стр.ПорядокОперации;
НовСтр.ПорядокОперации = Стр.ПорядокОперации;
КонецЕсли;
КонецЦикла;
//Для определения курса корректировки реализации в минус.
//Ключ — ДокументСсылка.РеализациТоваровУслуг, ДокументСсылка.АктВыполненныхРабот
//Значение — Структура
// * СуммаДокумента, СуммаДокументаРегл, СуммаДокументаУпр — нужны для определения среднего курса реализации при проведении корректировок.
ДанныеНакладных = Новый Соответствие;
ТаблицаДанныхНакладных = ПолучитьДанныеНакладных(Запрос);
Для Каждого Строка Из ТаблицаДанныхНакладных Цикл
ДанныеНакладных.Вставить(Строка.Накладная,
СтруктураСумм(Строка.Сумма,
Строка.СуммаРегл,
Строка.СуммаУпр));
КонецЦикла;
ГлобальныеПеременные.Вставить(«ДанныеНакладных», ДанныеНакладных);
ЗаписейОплаты = РасчетыОплаты.Количество();
ЗаписейОтгрузкиПоставки = РасчетыОтгрузкиПоставки.Количество();
ЗаписейОбработать = ЗаписейОплаты + ЗаписейОтгрузкиПоставки;
Индексы = Новый Структура;
//Индекс текущей обрабатываемой строки отгрузок.
Индексы.Вставить(«ИндексОтгрузкиПоставки», 0);
//Индекс текущей обрабатываемой строки оплат.
Индексы.Вставить(«ИндексОплаты», 0);
//Для распределения копеек в рамках документа.
ТекущийДокументОплаты = Неопределено;
ТекущийДокументОтгрузкиПоставки = Неопределено;
//Сколько строк отгрузки пропущено для зачета корректировкой реализации.
ПропускОтгрузкиПоставки = 0;
Пока Индексы.ИндексОплаты + Индексы.ИндексОтгрузкиПоставки < ЗаписейОбработать Цикл
Если Индексы.ИндексОплаты <= ЗаписейОплаты — 1 И Индексы.ИндексОтгрузкиПоставки <= ЗаписейОтгрузкиПоставки — 1 Тогда
СтрокаОплаты = РасчетыОплаты[Индексы.ИндексОплаты];
СтрокаОтгрузкиПоставки = РасчетыОтгрузкиПоставки[Индексы.ИндексОтгрузкиПоставки];
//Оплата раньше отгрузки.
Если СтрокаОплаты.ПорядокОперации < СтрокаОтгрузкиПоставки.ПорядокОперации
//В пределах регистратора (при расчетах по накладным) должен происходить зачет аванса.
ИЛИ СтрокаОплаты.Регистратор = СтрокаОтгрузкиПоставки.Регистратор Тогда
//Переброс аванса на расчетный документ — накладную.
НеОтгрузка = ХозяйственныеОперацииНеОтгрузка.Найти(СтрокаОтгрузкиПоставки.ХозяйственнаяОперация) <> Неопределено;
ДвойнаяЗаписьНеНужна = НеОтгрузка
//Если расчеты по платежке, то эти движения уже отражены в оперативных расчетах в рамках переноса с одного объекта расчетов на другой.
ИЛИ РасчетыПоПлатежке;
//Приход предоплаты.
Если НЕ СтрокаОплаты.ПриходДобавлен Тогда
ПересчитатьСуммыЕслиЭтоКорректировка(ГлобальныеПеременные, СтрокаОплаты);
ДобавитьПриход(ГлобальныеПеременные, ТаблицаРасчетовПоСрокам, СтрокаОплаты, «Оплата»);
КонецЕсли;
//Уменьшаем план отгрузки, если есть.
Если НЕ СтрокаОтгрузкиПоставки.ПланОтгрузокПоставокСписан Тогда
СписатьПланОтгрузкиПоставки(ГлобальныеПеременные, ТаблицаПланОтгрузокПоставок, СтрокаОтгрузкиПоставки, ПланыОтгрузокПоставок);
КонецЕсли;
Если СтрокаОтгрузкиПоставки.Сумма <> 0 Тогда
Если ТекущийДокументОплаты <> СтрокаОплаты.РасчетныйДокумент Тогда
ПредоплатаРаспределеноРегл = 0;
ПредоплатаРаспределеноУпр = 0;
ТекущийДокументОплаты = СтрокаОплаты.РасчетныйДокумент;
КонецЕсли;
Если ТекущийДокументОтгрузкиПоставки <> СтрокаОтгрузкиПоставки.РасчетныйДокумент Тогда
ДолгРаспределеноРегл = 0;
ДолгРаспределеноУпр = 0;
ТекущийДокументОтгрузкиПоставки = СтрокаОтгрузкиПоставки.РасчетныйДокумент;
КонецЕсли;
//Добавляем запись списания предоплаты.
НовСтр_Предоплата_Расход = ТаблицаРасчетовПоСрокам.Добавить();
НовСтр_Предоплата_Расход.ВидДвижения = ВидДвиженияНакопления.Расход;
НовСтр_Предоплата_Расход.ДокументРегистратор = СтрокаОтгрузкиПоставки.Регистратор;
НовСтр_Предоплата_Расход.ВалютаДокумента = СтрокаОтгрузкиПоставки.ВалютаДокумента;
НовСтр_Предоплата_Расход.Период = СтрокаОтгрузкиПоставки.Период;
НовСтр_Предоплата_Расход.РасчетныйДокумент = СтрокаОплаты.РасчетныйДокумент;
НовСтр_Предоплата_Расход.ДатаВозникновения = СтрокаОплаты.ДатаВозникновения;
НовСтр_Предоплата_Расход.ДатаПлановогоПогашения = Дата(1,1,1);
НовСтр_Предоплата_Расход.ПорядокЗачета = СтрокаОплаты.ПорядокОперации;
НовСтр_Предоплата_Расход.ПорядокОперации = СтрокаОтгрузкиПоставки.ПорядокОперации;
НовСтр_Предоплата_Расход.СтатьяДвиженияДенежныхСредств = СтрокаОтгрузкиПоставки.СтатьяДвиженияДенежныхСредств;
НовСтр_Предоплата_Расход.КорОбъектРасчетов = СтрокаОплаты.КорОбъектРасчетов;
СуммаСписания = Мин(СтрокаОплаты.Сумма, СтрокаОтгрузкиПоставки.Сумма);
//Возврат аванса с ручным курсом отражаем по курсу возврата.
Если СтрокаОтгрузкиПоставки.ЭтоВозвратАванса И СтрокаОтгрузкиПоставки.РучнойКурсРегл Тогда
ПредоплатаРеглПредв = СтрокаОтгрузкиПоставки.СуммаРегл / СтрокаОтгрузкиПоставки.Сумма * СуммаСписания;
//Ошибки округления сразу зачитываем, если что они переоценятся.
ИначеЕсли СтрокаОтгрузкиПоставки.РучнойКурсРегл И СтрокаОтгрузкиПоставки.Сумма = СуммаСписания Тогда
ПредоплатаРеглПредв = СтрокаОтгрузкиПоставки.СуммаРегл;
//Остальные авансы по курсу аванса.
Иначе
ПредоплатаРеглПредв = СтрокаОплаты.СуммаРегл / СтрокаОплаты.Сумма * СуммаСписания;
КонецЕсли;
Если СтрокаОтгрузкиПоставки.ЭтоВозвратАванса И СтрокаОтгрузкиПоставки.РучнойКурсУпр Тогда
ПредоплатаУпрПредв = СтрокаОтгрузкиПоставки.СуммаУпр / СтрокаОтгрузкиПоставки.Сумма * СуммаСписания;
ИначеЕсли СтрокаОтгрузкиПоставки.РучнойКурсУпр И СтрокаОтгрузкиПоставки.Сумма = СуммаСписания Тогда
ПредоплатаУпрПредв = СтрокаОтгрузкиПоставки.СуммаУпр;
Иначе
ПредоплатаУпрПредв = СтрокаОплаты.СуммаУпр / СтрокаОплаты.Сумма * СуммаСписания;
КонецЕсли;
Если СтрокаОтгрузкиПоставки.ЭтоВозвратАванса Тогда
НовСтр_Предоплата_Расход.ХозяйственнаяОперация = ХозяйственныеОперации[«ВозвратАванса»];
ИначеЕсли РасчетыПоПлатежке И НЕ СтрокаОтгрузкиПоставки.ХозяйственнаяОперация = Перечисления.ХозяйственныеОперации.ВзаимозачетЗадолженности Тогда
НовСтр_Предоплата_Расход.ХозяйственнаяОперация = ХозяйственныеОперации[«ПереносАванса»];
ИначеЕсли НеОтгрузка Тогда
НовСтр_Предоплата_Расход.ХозяйственнаяОперация = СтрокаОтгрузкиПоставки.ХозяйственнаяОперация;
Иначе
НовСтр_Предоплата_Расход.ХозяйственнаяОперация = ХозяйственныеОперации[«ЗачетАванса»];
КонецЕсли;
НовСтр_Предоплата_Расход.Предоплата = СуммаСписания;
НовСтр_Предоплата_Расход.ПредоплатаРегл = Окр(ПредоплатаРеглПредв + ПредоплатаРаспределеноРегл — Окр(ПредоплатаРаспределеноРегл, 2), 2);
НовСтр_Предоплата_Расход.ПредоплатаУпр = Окр(ПредоплатаУпрПредв + ПредоплатаРаспределеноУпр — Окр(ПредоплатаРаспределеноУпр, 2), 2);
ПредоплатаРаспределеноРегл = ПредоплатаРаспределеноРегл + ПредоплатаРеглПредв;
ПредоплатаРаспределеноУпр = ПредоплатаРаспределеноУпр + ПредоплатаУпрПредв;
//Уменьшаем строку оплаты на сумму зачета
СтрокаОплаты.Сумма = СтрокаОплаты.Сумма — НовСтр_Предоплата_Расход.Предоплата;
СтрокаОплаты.СуммаРегл = СтрокаОплаты.СуммаРегл — НовСтр_Предоплата_Расход.ПредоплатаРегл;
СтрокаОплаты.СуммаУпр = СтрокаОплаты.СуммаУпр — НовСтр_Предоплата_Расход.ПредоплатаУпр;
Если НЕ ДвойнаяЗаписьНеНужна Тогда
//Отражаем приход на сумму долга по курсу предоплаты.
НовСтр_Долг_Приход = ТаблицаРасчетовПоСрокам.Добавить();
ЗаполнитьЗначенияСвойств(НовСтр_Долг_Приход, НовСтр_Предоплата_Расход , ,»Предоплата, ПредоплатаУпр, ПредоплатаРегл, КорОбъектРасчетов»);
НовСтр_Долг_Приход.ВидДвижения = ВидДвиженияНакопления.Приход;
НовСтр_Долг_Приход.Период = СтрокаОтгрузкиПоставки.Период;
НовСтр_Долг_Приход.ДатаВозникновения = СтрокаОтгрузкиПоставки.Период;
НовСтр_Долг_Приход.ДатаПлановогоПогашения = СтрокаОтгрузкиПоставки.ДатаПлановогоПогашения;
НовСтр_Долг_Приход.РасчетныйДокумент = СтрокаОтгрузкиПоставки.Регистратор;
НовСтр_Долг_Приход.ПорядокЗачета = СтрокаОтгрузкиПоставки.ПорядокЗачета;
НовСтр_Долг_Приход.ХозяйственнаяОперация = СтрокаОтгрузкиПоставки.ХозяйственнаяОперация;
НовСтр_Долг_Приход.СтатьяДвиженияДенежныхСредств = Справочники.СтатьиДвиженияДенежныхСредств.ПустаяСсылка();
НовСтр_Долг_Приход.Долг = НовСтр_Предоплата_Расход.Предоплата;
Если СтрокаОтгрузкиПоставки.РучнойКурсУпр Тогда
НовСтр_Долг_Приход.ДолгУпр = СтрокаОтгрузкиПоставки.КурсУпр * СуммаСписания;
Иначе
НовСтр_Долг_Приход.ДолгУпр = НовСтр_Предоплата_Расход.ПредоплатаУпр;
КонецЕсли;
Если СтрокаОтгрузкиПоставки.РучнойКурсРегл Тогда
НовСтр_Долг_Приход.ДолгРегл = СтрокаОтгрузкиПоставки.КурсРегл * СуммаСписания;
Иначе
НовСтр_Долг_Приход.ДолгРегл = НовСтр_Предоплата_Расход.ПредоплатаРегл;
КонецЕсли;
//Переносим предоплату на расчетный документ отгрузки.
НовСтр_Долг_Расход = ТаблицаРасчетовПоСрокам.Добавить();
ЗаполнитьЗначенияСвойств(НовСтр_Долг_Расход, НовСтр_Долг_Приход);
НовСтр_Долг_Расход.ВидДвижения = ВидДвиженияНакопления.Расход;
НовСтр_Долг_Расход.ХозяйственнаяОперация = ХозяйственныеОперации[«ЗачетАванса»];
НовСтр_Долг_Расход.ДатаПлановогоПогашения = СтрокаОтгрузкиПоставки.ДатаПлановогоПогашения;
НовСтр_Долг_Расход.РасчетныйДокумент = СтрокаОтгрузкиПоставки.Регистратор;
НовСтр_Долг_Расход.ДатаВозникновения = СтрокаОтгрузкиПоставки.Период;
НовСтр_Долг_Расход.ПорядокЗачета = СтрокаОтгрузкиПоставки.ПорядокЗачета;
НовСтр_Долг_Расход.ДокументРегистратор = СтрокаОтгрузкиПоставки.Регистратор;
НовСтр_Долг_Расход.СтатьяДвиженияДенежныхСредств = СтрокаОтгрузкиПоставки.СтатьяДвиженияДенежныхСредств;
НовСтр_Долг_Расход.Долг = НовСтр_Предоплата_Расход.Предоплата;
НовСтр_Долг_Расход.ДолгУпр = НовСтр_Предоплата_Расход.ПредоплатаУпр;
НовСтр_Долг_Расход.ДолгРегл = НовСтр_Предоплата_Расход.ПредоплатаРегл;
//Если курс переноса предоплаты и прихода по долгу не совпал, делаем переоценку.
//Возможно, когда и в оплате и в накладной ручные суммы в валюте регл. или упр. учета.
Если НовСтр_Долг_Приход.ДолгРегл <> НовСтр_Долг_Расход.ДолгРегл
ИЛИ НовСтр_Долг_Приход.ДолгУпр <> НовСтр_Долг_Расход.ДолгУпр Тогда
ДобавитьЗаписьПереоценки(ГлобальныеПеременные,
ТаблицаРасчетовПоСрокам,
СтрокаОтгрузкиПоставки.Период,
НовСтр_Долг_Приход,
«Долг»,
НовСтр_Долг_Расход.ДолгРегл — НовСтр_Долг_Приход.ДолгРегл,
НовСтр_Долг_Расход.ДолгУпр — НовСтр_Долг_Приход.ДолгУпр);
КонецЕсли;
КонецЕсли;
Если СтрокаОтгрузкиПоставки.РучнойКурсРегл И НЕ ДвойнаяЗаписьНеНужна Тогда
//Остаток должен быть уменьшен ровно на ту сумму, на которую уже сформирован приход в двойной записи.
ДолгРеглПредв = НовСтр_Долг_Приход.ДолгРегл;
Иначе
//Иначе пропорционально уменьшаем остаток строки.
ДолгРеглПредв = СтрокаОтгрузкиПоставки.КурсРегл * СуммаСписания;
КонецЕсли;
Если СтрокаОтгрузкиПоставки.РучнойКурсУпр И НЕ ДвойнаяЗаписьНеНужна Тогда
ДолгУпрПредв = НовСтр_Долг_Приход.ДолгУпр;
Иначе
ДолгУпрПредв = СтрокаОтгрузкиПоставки.КурсУпр * СуммаСписания;
КонецЕсли;
Если ГлобальныеПеременные.ДанныеНакладных[СтрокаОтгрузкиПоставки.Регистратор] = Неопределено Тогда
ГлобальныеПеременные.ДанныеНакладных.Вставить(СтрокаОтгрузкиПоставки.Регистратор, СтруктураСумм());
КонецЕсли;
СтрокаОтгрузкиПоставки.Сумма = СтрокаОтгрузкиПоставки.Сумма — СуммаСписания;
СтрокаОтгрузкиПоставки.СуммаРегл = СтрокаОтгрузкиПоставки.СуммаРегл — Окр(ДолгРеглПредв + ДолгРаспределеноРегл — Окр(ДолгРаспределеноРегл,2),2);
СтрокаОтгрузкиПоставки.СуммаУпр = СтрокаОтгрузкиПоставки.СуммаУпр — Окр(ДолгУпрПредв + ДолгРаспределеноУпр — Окр(ДолгРаспределеноУпр,2),2);
ДолгРаспределеноРегл = ДолгРаспределеноРегл + ДолгРеглПредв;
ДолгРаспределеноУпр = ДолгРаспределеноУпр + ДолгУпрПредв;
ДанныеНакладной = ГлобальныеПеременные.ДанныеНакладных[СтрокаОтгрузкиПоставки.Регистратор];
ДанныеНакладной.СуммаДокумента = ДанныеНакладной.СуммаДокумента + СуммаСписания;
ДанныеНакладной.СуммаДокументаРегл = ДанныеНакладной.СуммаДокументаРегл + НовСтр_Предоплата_Расход.ПредоплатаРегл; //-
ДанныеНакладной.СуммаДокументаУпр = ДанныеНакладной.СуммаДокументаУпр + НовСтр_Предоплата_Расход.ПредоплатаУпр;
//Уменьшаем график оплаты условной задолженности на разницу суммы зачтенного аванса и строк накладной сверх заказа.
СуммаУменьшенияГрафика = ВзаиморасчетыСервер.СписатьСумму(СуммаСписания, СтрокаОтгрузкиПоставки.КОплате);
Если СуммаСписания > 0 И НЕ СтрокаОплаты.ГрафикСписан Тогда
СкорректироватьПлановыеОплаты(ГлобальныеПеременные, ТаблицаПланОплат, СтрокаОплаты, СуммаСписания, «Аванс», ПланыОплат);
КонецЕсли;
Если СтрокаОплаты.Сумма = 0 Тогда
Индексы.ИндексОплаты = Индексы.ИндексОплаты + 1;
Если Окр(СтрокаОплаты.СуммаРегл, 2) <> 0 ИЛИ Окр(СтрокаОплаты.СуммаУпр, 2) <> 0 Тогда
ДобавитьЗаписьПереоценки(ГлобальныеПеременные, ТаблицаРасчетовПоСрокам, СтрокаОтгрузкиПоставки.Период,
СтрокаОплаты, «Предоплата», -Окр(СтрокаОплаты.СуммаРегл, 2), -Окр(СтрокаОплаты.СуммаУпр, 2));
КонецЕсли;
КонецЕсли;
КонецЕсли;
Если СтрокаОтгрузкиПоставки.Сумма = 0 Тогда
Индексы.ИндексОтгрузкиПоставки = Индексы.ИндексОтгрузкиПоставки + 1;
Если СтрокаОтгрузкиПоставки.СуммаРегл <> 0 ИЛИ СтрокаОтгрузкиПоставки.СуммаУпр <> 0 Тогда
ДобавитьЗаписьПереоценки(ГлобальныеПеременные, ТаблицаРасчетовПоСрокам, НачалоДня(СтрокаОплаты.Период),
СтрокаОтгрузкиПоставки, «Долг», -Окр(СтрокаОтгрузкиПоставки.СуммаРегл, 2), -Окр(СтрокаОтгрузкиПоставки.СуммаУпр, 2));
КонецЕсли;
КонецЕсли;
//Отгрузка раньше оплаты.
Иначе
//Обычная оплата.
Если НЕ СтрокаОплаты.ЭтоКорректировка Тогда
//Добавляем строку прихода долга по отгрузке/поставке.
Если НЕ СтрокаОтгрузкиПоставки.ПриходДобавлен И СтрокаОтгрузкиПоставки.Сумма <> 0 Тогда
ПересчитатьСуммыЕслиЭтоКорректировка(ГлобальныеПеременные, СтрокаОтгрузкиПоставки);
ДобавитьПриход(ГлобальныеПеременные, ТаблицаРасчетовПоСрокам, СтрокаОтгрузкиПоставки, «ОтгрузкаПоставка»);
//Уточняется план только на сумму по заказу.
СкорректироватьПлановыеОплаты(ГлобальныеПеременные, ТаблицаПланОплат, СтрокаОтгрузкиПоставки, СтрокаОтгрузкиПоставки.Сумма — СтрокаОтгрузкиПоставки.КОплате, «УточнениеПлана»,ПланыОплат);
//Добавляются записи плана на всю сумму включая уточнение и сверхзаказа.
СкорректироватьПлановыеОплаты(ГлобальныеПеременные, ТаблицаПланОплат, СтрокаОтгрузкиПоставки, СтрокаОтгрузкиПоставки.Сумма, «ОтгрузкаПоставка», ПланыОплат);
КонецЕсли;
//Списываем план отгрузки если есть.
Если НЕ СтрокаОтгрузкиПоставки.ПланОтгрузокПоставокСписан Тогда
СписатьПланОтгрузкиПоставки(ГлобальныеПеременные, ТаблицаПланОтгрузокПоставок, СтрокаОтгрузкиПоставки, ПланыОтгрузокПоставок);
КонецЕсли;
Если СтрокаОтгрузкиПоставки.Сумма <> 0 Тогда
//Переоценка накладной до даты оплаты.
Если НужнаПереоценка Тогда
ПереоценитьДолг(ГлобальныеПеременные, ТаблицаРасчетовПоСрокам, СтрокаОтгрузкиПоставки, СтрокаОплаты);
КонецЕсли;
//Если расчетный документ накладная изменился, то сбрасываем служебные реквизиты распределения копеек.
Если ТекущийДокументОтгрузкиПоставки <> СтрокаОтгрузкиПоставки.РасчетныйДокумент Тогда
ДолгРаспределеноРегл = 0;
ДолгРаспределеноУпр = 0;
ТекущийДокументОтгрузкиПоставки = СтрокаОтгрузкиПоставки.РасчетныйДокумент;
КонецЕсли;
//Добавляем строку погашения задолженности.
НовСтр_Долг_Расход = ТаблицаРасчетовПоСрокам.Добавить();
НовСтр_Долг_Расход.ВидДвижения = ВидДвиженияНакопления.Расход;
НовСтр_Долг_Расход.ДокументРегистратор = СтрокаОплаты.Регистратор;
//Взаимозачет считаем взаимозачетом
Если СтрокаОплаты.ХозяйственнаяОперация = Перечисления.ХозяйственныеОперации.ВзаимозачетЗадолженности Тогда
НовСтр_Долг_Расход.ХозяйственнаяОперация = СтрокаОплаты.ХозяйственнаяОперация;
Иначе
НовСтр_Долг_Расход.ХозяйственнаяОперация = ХозяйственныеОперации[«ПогашениеЗадолженности»];
КонецЕсли;
НовСтр_Долг_Расход.ВалютаДокумента = СтрокаОплаты.ВалютаДокумента;
НовСтр_Долг_Расход.Период = СтрокаОплаты.Период;
НовСтр_Долг_Расход.ПорядокОпера
Ошибка Записать(РежимЗаписиДокумента.ОтменаПроведения)
Автор dimanuga, 31 окт 2018, 18:14
0 Пользователей и 1 гость просматривают эту тему.
К кнопке на форме привязана отмена проведения:
&НаКлиенте
Процедура ОтменитьПроведение(Команда)
ПоказатьВопрос(Новый ОписаниеОповещения(«ПередОтменойПроведения», ЭтотОбъект),
«Отменить проведение документов?», РежимДиалогаВопрос.ДаНет);
КонецПроцедуры
&НаКлиенте
Процедура ПередОтменойПроведения(Результат, Отказ) Экспорт
Если Результат = КодВозвратаДиалога.Да Тогда
ВызовОтменыПроведения();
КонецЕсли;
КонецПроцедуры
&НаСервере
Процедура ВызовОтменыПроведения()Экспорт
ЭтаФорма.Записать(РежимЗаписиДокумента.ОтменаПроведения);
ЭтаФорма.Модифицированность = Ложь;
Закрыть();
КонецПроцедуры
Ошибка:
{Документ.ПоступлениеЖивотных.Форма.ФормаДокумента.Форма(242)}: Ошибка при вызове метода контекста (Записать)
ЭтаФорма.Записать(РежимЗаписиДокумента.ОтменаПроведения);
по причине:
Несоответствие типов (параметр номер ‘1’)
Несоответствие типов (параметр номер ‘1’)
В чем моя ошибка?
Скорее всего, потому что у формы записать может быть только так ЭтаФорма.Записать();
Если передавать какой либо параметр, то только через структуру, а не как обычно с объектами.
Читайте справку.
Помог, нажми спасибо. Не помог, нажми спасибо 🙂
Если у Вас есть проблема, то её уже кто то решил @Yandex, @Google
Ну хорошо, а как передать РежимЗаписи.ОтменаРедактирования ?
Можно на примере ?
Цитата: dimanuga от 31 окт 2018, 19:42
Ну хорошо, а как передать РежимЗаписи.ОтменаРедактирования ?
Можно на примере ?
Ни разу не делал, попробуй так
Структура.Вставить(«РежимЗаписиДокумента», РежимЗаписиДокумента.ОтменаПроведения);
Помог, нажми спасибо. Не помог, нажми спасибо 🙂
Если у Вас есть проблема, то её уже кто то решил @Yandex, @Google
Почему и зачем ЭтаФорма, а не ЭтотОбъект?
Ну да ладно.
ЭтаФорма.Записать(Новый Структура("РежимЗаписи", РежимЗаписиДокумента.ОтменаПроведения));
ЭтаФорма.Записать(Новый Структура(«РежимЗаписи», РежимЗаписиДокумента.ОтменаПроведения));
{Документ.ПоступлениеЖивотных.Форма.ФормаДокумента.Форма(262)}: Поле объекта недоступно для записи (РежимЗаписиДокумента)
РежимЗаписиДокумента = ПараметрыЗаписи;
Или так:
ПараметрыФ = Новый Структура(«РежимЗаписиДокумента», РежимЗаписиДокумента.ОтменаПроведения);
ЭтаФорма.Записать(ПараметрыФ);
{Документ.ПоступлениеЖивотных.Форма.ФормаДокумента.Форма(266)}: Поле объекта недоступно для записи (РежимЗаписиДокумента)
РежимЗаписиДокумента = ПараметрыЗаписи;
РежимЗаписиДокумента = ПараметрыЗаписи;
Ты уверен, что этого нигде не писал? Например в строке 262 или 266
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 |
Процедура ВыполнитьФормированиеПлан() //Состояние("Выборка данных (план)..."); Запр = Новый Запрос; Запр.Текст = "ВЫБРАТЬ | осиПЭОПриказ1.Наименование КАК НоменклатураПЭО, | осиПЭОПриказ1.Количество * осиПЭОПриказ1.Цена * 1000 КАК Сумма, | осиПЭОПриказ1.Подразделение КАК ПодразделениеПЭО, | ВЫБОР | КОГДА осиПЭОПриказ1.Пассив = &Строительство | ТОГДА &Счет106 | КОГДА осиПЭОПриказ1.Пассив = &Приобретение | ТОГДА &Счет107 | КОГДА осиПЭОПриказ1.Пассив = &ИнвестПроекты | ТОГДА &Счет108 | КОНЕЦ КАК СчетПЭО, | ВЫБОР | КОГДА осиПЭОПриказ1.Пассив = &Строительство | ТОГДА NULL | ИНАЧЕ осиПЭОПриказ1.Количество | КОНЕЦ КАК Количество |ИЗ | РегистрСведений.осиПЭОПриказ1 КАК осиПЭОПриказ1 |ГДЕ | осиПЭОПриказ1.Период МЕЖДУ &НачДата И &КонДата | И (осиПЭОПриказ1.Пассив = &Приобретение | ИЛИ осиПЭОПриказ1.Пассив = &Строительство ИЛИ осиПЭОПриказ1.Пассив = &ИнвестПроекты) | И осиПЭОПриказ1.Приоритет = 0"; Запр.УстановитьПараметр("НачДата", НачалоМесяца(Объект.ЗаПериод)); Запр.УстановитьПараметр("КонДата", КонецМесяца(Объект.ЗаПериод)); Запр.УстановитьПараметр("Приобретение", ПолучитьЭлементСправочникаПоРеквизиту("осиПЭОПассив", "Наименование", "_Приобретение оборудования")); Запр.УстановитьПараметр("Строительство", ПолучитьЭлементСправочникаПоРеквизиту("осиПЭОПассив", "Наименование", "Капитальное строительство")); Запр.УстановитьПараметр("ИнвестПроекты", ПолучитьЭлементСправочникаПоРеквизиту("осиПЭОПассив", "Наименование", "_Инвестиционные проекты")); Запр.УстановитьПараметр("Счет106", ПолучитьЭлемент("ПланСчетов", "Инт_Управленческий2", "Код", "106")); Запр.УстановитьПараметр("Счет107", ПолучитьЭлемент("ПланСчетов", "Инт_Управленческий2", "Код", "107")); Запр.УстановитьПараметр("Счет108", ПолучитьЭлемент("ПланСчетов", "Инт_Управленческий2", "Код", "108")); ТЗ=Запр.Выполнить().Выгрузить(); Выборка = Запр.Выполнить().Выбрать(); //Состояние("Формирование проводок (план)..."); Сценарий = ПолучитьЭлемент("Справочник", "Инт_Сценарии", "Наименование", "План"); ЦФО = ПолучитьЭлемент("Справочник", "Инт_ЦФО", "Наименование", "ЦЗ ""Оренбургские минералы"""); ВидСубконтоНоменклатураПЭО = ПолучитьЭлемент("ПланВидовХарактеристик", "ИНТ_Аналитика", "Код", "00000000042");//Номенклатура ПЭО ВидСубконтоПодразделенияПЭО = ПолучитьЭлемент("ПланВидовХарактеристик", "ИНТ_Аналитика", "Код", "00000000053");//Подразделения ПЭО Счет00 = ПолучитьЭлемент("ПланСчетов", "Инт_Управленческий2", "Код", "0"); Проформа = ПолучитьПроформу(Сценарий).ПолучитьОбъект(); ДвиженияУпр2 = Проформа.Движения.Инт_Управленческий2; ДвиженияУпр2.Очистить(); Пока Выборка.Следующий() Цикл Проводка = ДвиженияУпр2.Добавить(); Проводка.Период = КонецМесяца(Объект.ЗаПериод); Проводка.Содержание = "авт.загр."; Проводка.СчетДт = Выборка.СчетПЭО; Проводка.СчетКт = Счет00; Проводка.Сценарий = Сценарий; Проводка.Сумма = Выборка.Сумма; Проводка.ЦФОДт = ЦФО; Если Выборка.Количество<> 0 Тогда Проводка.КоличествоДт = Выборка.Количество; КонецЕсли; Проводка.Субконто1Дт= Выборка.НоменклатураПЭО; Проводка.Субконто2Дт = Выборка.ПодразделениеПЭО; КонецЦикла; ДвиженияУпр2.Записать(); //Состояние(); КонецПроцедуры |
Довольно часто начинающие 1С разработчики сталкиваются с ошибками, которых достаточно легко избежать. Ниже мы рассмотрим топ 11 ошибок и способы их исправления. Также доступна видеоверсия статьи
Содержание
Поле объекта не обнаружено
Существует множество статей, которые описывают возможные причины возникновения в 1С ошибки “Поле объекта не обнаружено”. Порой это связывают с обновлением платформы, обновлением типового релиза, или с какими-то другими причинами.
Мы же будем оперировать фактами. В конце статьи прилагается внешняя обработка, в которой воспроизведена данная ошибка.
Такое сообщение платформа выдает, когда пытается обратиться к свойству объекта языка, которого у данного объекта нет. Не важно, что это за объект – документ, справочник, таблица значений , или сообщение пользователю.
- Удалили табличную часть, к которой обращаемся в коде?
- Переименовали реквизит, а в коде не исправили?
- Заменили значение со ссылки на неопределено?
Вуаля – платформа выдаст ошибку “Поле объекта не обнаружено”!
Как исправить? Исходя из природы ошибки – переименовать реквизит на нужное имя, отредактировать код, или использовать правильные обращения к стандартным свойствам объекта.
Например, у объекта “СообщениеПользователю” нет свойства “Таблица”, и следующий код приведет к ошибке:
Сообщение = Новый СообщениеПользователю;
Сообщение.Таблица = “Ошибка”;
Индекс находится за границами массива
Что означает такое сообщение системы? Как правило, с данной ошибкой разработчик сталкивается при некорректной работе с коллекциями. Самые частые случаи появления ошибки “Индекс находится за границами массива”.
- Использование при обходе коллекции количества элементов вместо индекса. Индексы начинаются с нуля, а количество элементов – с единицы. Поэтому следующий код гарантированно приведет к ошибке: Массив[Массив.Количество()]
- Последствия удаления элементов из коллекции, очистки коллекции или замены коллекции на пустую
- Ошибочное увеличение счетчика в цикле “Для”
Как исправить? Для удаления элементов из коллекции по условию – использовать обратный цикл. Добавлять условие на соответствие счетчика цикла и индекса массива. Не увеличивать счетчик внутри кода цикла Для … Цикл … КонецЦикла
Обращение к процедуре как к функции
Суть этой ошибки в том, что процедура не может возвращать значение. И если мы в коде используем вызов процедуры справа от знака присваивания, это приведет к ошибке.
Данная ошибка имеет две вариации – если используется стандартная процедура из методов какого-нибудь объекта, то фраза будет звучать “Обращение к процедуре объекта как к функции”. Если же использовать процедуру, объявленную в коде, то текст ошибки будет “Обращение к процедуре как к функции”.
При этом ошибка использования процедуры объекта является ошибкой времени выполнения – т.е. на этапе сохранения и проверки конфигурации платформа эту ошибку не обнаружит.
А вот неправильное использование процедуры синтаксическая проверка (Ctrl + F7) успешно обнаруживает, и не даст сохранить конфигурацию или внешнюю обработку/отчет, пока ошибка не будет устранена.
Рассмотрим два примера:
1. Воспроизведем ошибку “Обращение к процедуре как к функции”. При этом платформа не даст сохранить изменения, т.к. не проходит синтакс-контроль.
2. Воспроизведем ошибку “Обращение к процедуре объекта как к функции”. Здесь мы неверно используем метод объекта массива “Добавить”, который является процедурой.
Как исправить? Ошибка тривиальная, и исправление тоже. Чаще всего, достаточно внимательно прочитать описание методов объекта во встроенной справке или синтакс-помощнике. Если метод является процедурой, то значений он возвращать не может. Следовательно, нужно модифицировать код так, чтобы такого ошибочного вызова не было.
Если же используется процедура, объявленная в коде, возможно, есть необходимость изменить ее на функцию, либо также скорректировать код, который эту процедуру использует.
Процедура не может возвращать значение
Родственная предыдущей ошибка. Для того, чтобы код возвращал какое-то значение, следует этот код размещать в функции, а не в процедуре.
В процедуре можно написать ключевое слово “Возврат” без параметров. Это будет означать выход из процедуры.
Следующий код является ошибочным, т.к. в теле процедуры Возврат используется с параметром:
Процедура ПроцедураНеМожетВозвращатьЗначение(Команда) Возврат "Ошибка"; КонецПроцедуры
Как исправить? Платформа сама подсказывает, в каком месте кода ошибка. Нужно изменить текст модуля – либо удалить параметр у ключевого слова Возврат, либо убрать его вовсе, либо изменить процедуру на функцию – зависит от того, какая логика у вашей процедуры, и как вы предполагаете ее использовать.
Переменная не определена
Такой текст ошибки платформа 1С выдает на этапе синтаксического контроля, при сохранении конфигурации, внешнего отчета или обработки.
Причин у этой ошибки может быть несколько.
- Опечатка в имени переменной
- Обращение к переменной, которая нигде в области видимости не объявлена (неявной инициализацией с присвоением значения, явным образом с использованием ключевого слова “Перем”, или передана в качестве параметра)
- Написание на клиенте серверного кода. Например, обращение к менеджеру справочников “Справочники”, и т.п. Клиентская часть приложения “не видит ” серверные объекты языка
- Также ошибка может появиться, если ранее код использовался в режиме толстого клиента, но после был запущен в тонком клиенте.
Как исправить?
Внимательно следить за правильностью набранного кода, своевременно объявлять переменные или передавать их в качестве параметров. Писать серверный код только в серверных модулях, а также использовать соответствующие инструкции препроцессора, например “&НаСервере”.
Значение не является значением объектного типа
Ошибка “Значение не является значением объектного типа” может возникнуть при неверном обращении к объекту языка. Объектный тип – это такие объекты языка, которые содержат в себе другие объекты – свойства, реквизиты и т.п. Эти свойства доступны через точку, например “Объект.СвойствоЭтогоОбъекта”
Но если через точку попытаться использовать какое-то значение, которое внутри себя свойств не имеет – например, любое значение примитивного типа – это и приведет к ошибке.
Разберем более сложный пример:
&НаСервере Процедура ЗначениеНеЯвляетсяЗначениемОбъектногоТипаНаСервере(Справочники = Ложь) Сообщить(Справочники.Сотрудники.ПустаяСсылка()); КонецПроцедуры
Ошибка может быть “плавающей”. Если вместо параметра по умолчанию “Справочники = Ложь” будет передан менеджер справочников, то ошибки возникать не будет. А если вызвать процедуру без параметров, то будет использоваться параметр по умолчанию с типом Булево, что и приведет к ошибке.
Чаще всего чтобы исправить ошибку, нужно в отладчике посмотреть, какой тип значения используется. Можно внести изменения в код, чтобы обеспечить корректное поведение (например, в запросе вместо наименования товара выбрать ссылку, и в коде через точку уже обращаться к свойствам ссылки, а не текстового наименования). А можно добавить проверку на нужный тип значения. Т.е. – если значение того типа, который мы ожидаем – выполняем код. Иначе – не выполняем.
Ошибка при вызове метода контекста
В языке 1С у разных объектов (запросов, справочников, табличных документов и др.) есть предопределенные методы, предусмотренные платформой. Обращение к этим методам требует соблюдения порядка и параметров, правильного синтаксиса и соблюдения условий использования. Например, при чтении табличного документа из файла он не должен быть открыт в другой программе, при подключении к http-соединению оно должно быть доступно, и т.п.
Если эти условия не соблюдать, платформа в зависимости от версии может выдавать сообщения вида “Ошибка при вызове метода контекста”, и далее будут следовать более подробные сведения об ошибке – стек вызовов, приведших к ошибке, номер строки и позиции в строке, где произошла ошибка.
Чаще всего ошибка при вызове метода контекста встречается в следующих методах:
- Записать
- Прочитать
- Выполнить
- Создать
- ПроверитьВывод
Разберем эту ошибку на примере метода Выполнить объекта Запрос:
Запрос = Новый Запрос("ВЫБРАТЬ ПЕРВЫЕ 1 1 ГДЕ ИСТИНА И");
Запрос.Выполнить();
В тексте запроса допущена ошибка – после первого условия “ГДЕ ИСТИНА” указан оператор И, но после него нет еще одного условия. В результате при попытке выполнения запроса, платформа вернет ошибку.
Для исправления ошибки зачастую достаточно внимательно использовать методы, при необходимости уточнять порядок, количество и тип параметров – это можно сделать в справке или синтакс-помощнике (встать курсором на имя метода в коде, и нажать сочетание клавиш Ctrl+F1). В случае запроса – нужно передавать синтаксически корректный текст запроса; в случае проверки вывода на печать – в системе должен быть установлен принтер; в случае подключения к почте – должны быть корректно указаны логин и пароль, и т.п.
Тип не может быть выбран в запросе в 1С 8.3 (8.2)
С такой ошибкой начинающие разработчики (да и не только начинающие 😉 ) сталкиваются чаще всего, при чтении запросом данных из таблиц значений, либо из регистров сведений. Все дело в том, что запросы поддерживают далеко не все типы значений. Так, например, нельзя запросом выбрать тип Картинка, ХранилищеЗначений, Шрифт, и многие другие типы, которые не относятся к примитивным или ссылочным типам значений.
Так, если ресурс регистра сведений имеет тип ХранилищеЗначений, выбрать его запросом будет нельзя. Также, если в таблицу значений поместить значения не подходящих типов, а после передать эту таблицу в качестве параметра-источника данных, выполнение запроса также приведет к ошибке “Тип не может быть выбран в запросе”.
Еще одна ситуация, когда запрос будет выдавать ошибку – если таблица значений, которая передается в качестве параметра, имеет не типизированные колонки.
Неверно:
//ТЗОшибочныйТип.Колонки.Добавить("Контрагент");
Верно:
//ТЗОшибочныйТип.Колонки.Добавить("Контрагент", Новый ОписаниеТипов("СправочникСсылка.Контрагенты"));
Для исправления ошибки нужно правильным образом инициализировать колонки таблицы значений, а также не обращаться в запросе к полям, типы которых запросами не поддерживаются.
Использование в 1С модальных окон в данном режиме запрещено
Платформа будет выдавать такое сообщение, если в коде используются методы, приводящие к открытию модальных окон. Модальные окна – это окна, которые при открытии блокируют весь остальной интерфейс. В 1С есть несколько модальных методов – например – “Вопрос”, “ОткрытьЗначение”, “Предупреждение”. Кроме того, в коде может использоваться модальный синтаксис открытия форм: “ОткрытьМодально()”
Если в свойствах конфигурации выбран режим использования модальности “Не использовать”, то выполнение модальных методов будет приводить к этой ошибке “Использование в 1С модальных окон в данном режиме запрещено”.
Для устранения ошибки можно пойти несколькими путями. Как водится, один – быстрый, другой – правильный 🙂
Быстрый способ – переключить режим использования модальности в положение “Использовать”.
Более правильный способ – использовать в коде немодальные вызовы методов. Например, у метода “Вопрос” есть немодальный аналог – “ПоказатьВопрос”, у метода “Предупреждение” – “ПоказатьПредупреждение”, и т.п. Чаще всего об этих методах дополнительно указано в синтакс-помощнике и справке.
Кроме того, в последних версиях платформы появились асинхронные методы – “ВопросАсинх”, “ПредупреждениеАсинх” и др. Появление этих методов позволяет писать более простой и понятный асинхронный код, и направлено в первую очередь, на более полноценную поддержку браузерами и работу в веб-клиенте.
1С 8.3 и 8.2: Запись с такими ключевыми полями существует!
Данная ошибка появляется при некорректной записи в регистр сведений. Чаще всего с этой ошибкой сталкиваются начинающие разработчики, не до конца понимающие механизмы работы с ключевыми полями (измерениями).
Суть ошибки следующая – регистр сведений позволяет записать запись (строку таблицы) с уникальным набором ключевых полей – а для периодических регистров также и поля Период. Если следующая запись полностью повторяет значение ключевых полей, но осуществляется методом Записать с параметром Замещать = Истина, то запись в таблице регистра просто заменится на идентичную.
Однако если поместить две абсолютно одинаковые записи в набор записей, и попытаться его записать – платформа выдаст ошибку. Еще один распространенный случай, когда 1С сообщает “Запись с такими ключевыми полями существует” – это запись в периодический регистр сведений с периодичностью от “День” и выше, подчиненный регистратору.
В типовых конфигурациях часто эту ошибку можно воспроизвести, если в пользовательском режиме создать два документа “Установка цен номенклатуры” с одной и той же номенклатурой и за один и тот же день. Попытка провести второй документ приведет к ошибке.
В случае, когда ошибка возникает не в результате действий пользователя, а при выполнении кода, чтобы устранить ее, чаще всего необходимо проанализировать алгоритм записи в регистр. Если запись осуществляется одним набором данных, его предварительно нужно свернуть до уникальных записей. Например, выгрузить в таблицу значений, свернуть, и загрузить в набор записей.
Поле объекта недоступно для записи в 1С
Чаще всего начинающие программисты 1С сталкиваются с этой ошибкой в двух ситуациях.
Первый случай – это попытка редактирования системных полей, недоступных для записи. Например, в модуле формы сама форма будет содержаться в объекте ЭтаФорма. И попытка присвоить этому реквизиту любое значение приведет к ошибке “Поле объекта недоступно для записи”.
Второй случай – и с ним новички как раз допускают больше всего ошибок – это попытка редактирования полей ссылки, а не самого объекта. Чаще всего код выглядит примерно так:
Элемент = Справочники.Сотрудники.НайтиПоКоду("12345");
Элемент.Наименование = "Новое наименование";
Исполнение данного кода приведет к ошибке, т.к. поля ссылки доступны только для чтения, а метод НайтиПоКоду вернет именно ссылку. Чтобы можно было внести изменения, следует из ссылки получить сам объект – используя соответствующий метод ПолучитьОбъект().
Для исправления ошибки зачастую достаточно получить объект из ссылки. В случае же попытки редактирования свойств, доступных только на чтение самый правильный подход – анализировать имеющуюся документацию по этим свойствам, и не пытаться присваивать им значения, если платформа этого не предусматривает.
Ссылка на обработку
По ссылке вы можете скачать внешнюю обработку, в которой воспроизводится большая часть ошибок, описанных в статье. Для воспроизведения части ошибок нужно будет убрать комментарии в коде.
Заключение
Как видите, зачастую ошибки тривиальны, и достаточно просто исправляются. Общие рекомендации – внимательно читать документацию и справку, корректно использовать методы, активно пользоваться отладчиком. Если вы новичок, и хотите освоить программирование в 1С с нуля – могу предложить приобрести мой базовый курс для начинающих. Более подробная информация – по ссылке.