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

ЗаписьЖурналаРегистрации

ЗаписьЖурналаРегистрации

Я
   IF_THEN

10.11.09 — 13:34

Добрый день, ребята кто подскажет что я делаю не так. Из 8 ки по ОЛЕ соединяюсь с 7.7. в 7 ой базе создаю объект. Далее хочу в журнал 7ой базы записать событие создания объякта. Пишу База77.ЗаписьЖурналаРегистрации(«Создан новый объект»,»Refs»,»RefNew»,справочник77,2); справочник77   = База77.CreateObject(«Справочник.Номенклатура»);

   ДенисЧ

1 — 10.11.09 — 13:35

не взлетит.

   IF_THEN

2 — 10.11.09 — 13:47

ща турбо надув дам и взлетит!

   dk

3 — 10.11.09 — 13:52

взлетит, если пнуть с подвывертом )

   dk

4 — 10.11.09 — 13:58

EvalExpr и ExecuteBatch еще никто не отменял )))

   IF_THEN

5 — 10.11.09 — 14:17

Щас протестю

   IF_THEN

6 — 10.11.09 — 15:10

База77.EvalExpr(«НайденныйОбъект=СоздатьОбъект(«»Справочник.Договоры»»);»)

{(1)}: Ошибка при вызове метода контекста (EvalExpr): Произошла исключительная ситуация (1С:Предприятие): 1    НайденныйОбъект<<?>>=СоздатьОбъект(«Справочник.Договоры»);

Переменная не определена (НайденныйОбъект)

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

   Михей

7 — 10.11.09 — 15:12

(6) CreateObject?

   IF_THEN

8 — 10.11.09 — 15:13

(7) смотри (0) надо взять ссылку на элемент 7 ки и подставить в процедуру регистрации события

   dk

9 — 10.11.09 — 15:13

(6) неправильно идею понял

   IF_THEN

10 — 10.11.09 — 15:14

(9) ммм, да? не подскажешь твою идею?

   dk

11 — 10.11.09 — 15:14

(8) ЗначениеИзСтрокиВнутр(ЗначениеВстрокуВнутр())

+ двойные кавычки учесть

   Шахид

12 — 10.11.09 — 15:15

(10) а может напрямую в mlg писать или режим разделенный?

   IF_THEN

13 — 10.11.09 — 15:16

(11) ну да, тема так можно передать объект. Но я вот выполнил запись в журнал без передачи объекта,и чет в журнал нече не добавилось.

   IF_THEN

14 — 10.11.09 — 15:16

(12) не напрямую не нужно писать

   Шахид

15 — 10.11.09 — 15:17

(14) жаль. такая идея пропадает :)

   dk

16 — 10.11.09 — 15:22

База77.ExecuteBatch(«ЗаписьЖурналаРегистрации(«»Создан новый объект»»,»»Refs»»,»»RefNew»»,ЗначениеИзСтрокиВнутр(«+База77.ЗначениеВстрокуВнутр(справочник77.ТекущийЭлемент())+»),2);»)

   dk

17 — 10.11.09 — 15:23

База77.ExecuteBatch(«ЗаписьЖурналаРегистрации(«»Создан новый объект»»,»»Refs»»,»»RefNew»»,ЗначениеИзСтрокиВнутр(«»»+СтрЗаменить(База77.ЗначениеВстрокуВнутр(справочник77.ТекущийЭлемент(),»»»»,»»»»»»))+»»»),2);»);

или так ))

   Шахид

18 — 10.11.09 — 15:24

ТекущийЭлемент() по оле вроде не летает?

   dk

19 — 10.11.09 — 15:29

Кто сказал?

   IF_THEN

20 — 10.11.09 — 15:29

(18) летает

   dk

21 — 10.11.09 — 15:29

напрямую нет, но обернутый летает

   IF_THEN

22 — 10.11.09 — 15:31

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

   dk

23 — 10.11.09 — 15:37

(15) эта идея давно реализована, у меня в том числе )

  

IF_THEN

24 — 10.11.09 — 15:38

в общем просто журнал регистраций настроен так что регистрируе пока только вход и выход))) p.s. на демке тестю

dk спасибо за инфо

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

Исправляем ситуацию

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

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


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

Приведенный текст ошибки программисту 1С скажет, что в модуле формы обработки «ЧтениеЗаписьXML на 152 строчке кода не может выполниться запрос. Причина в том, что на 17 строчке запроса нет чего-то, что ждал компилятор. Таким образом, чтобы убрать подобное сообщение, необходимо выяснить, что там должно быть и написать недостающий код.

Увидев вышеприведенный кусок кода, разработчик заметит, что в запросе есть служебное слово «ГДЕ», дающее сигнал 1С, что дальше будет условие. Но мы забыли дописать его и, естественно, система с помощью сообщения об ошибке спрашивает нас – «а где условие?». Чтобы исправить эту ситуацию необходимо либо убрать оператор «ГДЕ» из запроса, либо добавить условие.

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


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

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

Рис.3 Синтакс-помощник
Рис.3 Синтакс-помощник

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

Рис.4 Сверив пример с нашим кодом, приходит понимание, что кавычки не нужны и без них все работает
Рис.4 Сверив пример с нашим кодом, приходит понимание, что кавычки не нужны и без них все работает

Чаще всего причиной подобных ошибок выступают следующие факторы:

  1. Невнимательность;
  2. Отсутствие опыта или знаний;
  3. Несогласованность действий разработчиков друг с другом;
  4. Изменения в методах контекста в новых версиях платформы.

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

  1. Всем привет!
    Подскажите, пожалуйста, как решить проблему? У меня БП8.2 актуальный конфиг.
    Дело в том, что я пользуюсь процедурой ВыгрузитьЖурналРегистрации

        Отбор = Новый Структура("Метаданные", Метаданные.РегламентныеЗадания.Обмен_Логистика8_БИБ82);
        Задание = РегламентныеЗадания.ПолучитьРегламентныеЗадания(Отбор)[0];
        ДатаНач = Задание.ПоследнееЗадание.Начало;
        ЗаписьЖурналаРегистрации("Обмен.Логистика.Загрузка",УровеньЖурналаРегистрации.Информация, , ,ДатаНач);   
        ДатаКон = Задание.ПоследнееЗадание.Конец;
        ЗаписьЖурналаРегистрации("Обмен.Логистика.Загрузка",УровеньЖурналаРегистрации.Информация, , ,ДатаКон);   
       
        Фильтр = Новый Структура("ДатаНачала, ДатаОкончания", ДатаНач, ДатаКон);
        Журнал = Новый ТаблицаЗначений;
        ВыгрузитьЖурналРегистрации(Журнал, Фильтр);
    
    

    Когда вручную запускаю, то все ОК. Когда фоновое задание проходит этот код, то вылезает ошибка:
    Ошибка при загрузке файла обмена: ****Logistic8-BIB82-Data_0000000765.xml. {Обработка.ДТ_Обмен_Логистика8_БИБ82.МодульОбъекта(288)}: Ошибка при вызове метода контекста (ВыгрузитьЖурналРегистрации): Недопустимое значение параметра (параметр номер ‘2’)

    Это как раз второй аргумент процедуры.
    Не могу понять в чем дело. В журнал вывожу запись о том что помещается в Фильтр — все ОК — там две даты. Но ошибка все равно есть. Да, фоновое задание пробовал запускать от своего имени.

  2. Оказалось сам дурак (не удивительно как всегда). Когда запускал через обработку, то фоновое задание бралось предыдущее, а само фоновое задание видит себя, при этом ДатаОкончания не определена еще. И она не заполнялась.


  3. nomad_irk

    Offline

    nomad_irk
    Гуру в 1С

    Регистрация:
    20 окт 2008
    Сообщения:
    8.697
    Симпатии:
    889
    Баллы:
    204

    ну как бы логично :)
    дату окончания более определенно задайте и будет вам Щастье…..

Поделиться этой страницей


1C-pro.ru - форум по 1С:Предприятию 7.7, 8.0, 8.1, 8.2, 8.3

рубрики: Язык программирования 1С | Дата: 25 апреля, 2017

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

Если мы обратимся к технической документации или к диску ИТС, то увидим, что фирма 1С рекомендует следующий способ организации транзакции в попытке




Попытка

	//1. Начало транзакции.
	НачатьТранзакцию();

	//2. Блок операций, выполняющихся в транзакции.

	//3. Если все операции успешны, фиксируем транзакцию.
	ЗафиксироватьТранзакцию();

Исключение

	//4. Если при выполнении кода возникли ошибки, отменяем транзакцию.
	ОтменитьТранзакцию();

	//5. При необходимости запись в журнал регистрации.
	//6. При необходимости вывод сообщения пользователю.

КонецПопытки;

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




&НаСервереБезКонтекста
Процедура ВыполнитьТранзакциюНаСервере()

	НачатьТранзакцию();

	//записываем новый товар
	Товар = Справочники.Товары.СоздатьЭлемент();
	Товар.Наименование = "Дырокол";
	Товар.Записать();

	//записываем цену
	НаборЗаписей = РегистрыСведений.Цена.СоздатьНаборЗаписей();

	НоваяЗапись = НаборЗаписей.Добавить();
	НоваяЗапись.Период	= ТекущаяДата();
	НоваяЗапись.Товар	= Товар.Ссылка;
	НоваяЗапись.Сумма	= 100;

	НаборЗаписей.Записать();

	ЗафиксироватьТранзакцию();

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

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





&НаСервереБезКонтекста
Процедура ВыполнитьТранзакциюНаСервере()

	//создаем новый товар
	Товар = Справочники.Товары.СоздатьЭлемент();
	Товар.Наименование = "Дырокол";

	//Создаем запись с ценой
	НаборЗаписей = РегистрыСведений.Цена.СоздатьНаборЗаписей();

	НоваяЗапись = НаборЗаписей.Добавить();
	НоваяЗапись.Период	= ТекущаяДата();
	НоваяЗапись.Сумма	= 100;

	//Выполняем транзакцию в попытке
	Попытка

		НачатьТранзакцию();

		Товар.Записать();

		НоваяЗапись.Товар	= Товар.Ссылка;
		НаборЗаписей.Записать();

		ЗафиксироватьТранзакцию();

	Исключение

		ОтменитьТранзакцию();

		Сообщение = Новый СообщениеПользователю;
		Сообщение.Текст = "Произошла ошибка при записи товара и его цены";
		Сообщение.Сообщить();

		ЗаписьЖурналаРегистрации("Произошла ошибка при записи товара и его цены");

	КонецПопытки;

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

Как НЕ НАДО делать

У тех кто только начинает работать с транзакциями зачастую возникает желание сделать вот таким образом




НачатьТранзакцию();

Попытка
	НачатьТранзакцию();
	//Блок операций
	ЗафиксироватьТранзакцию();
Исключение
    ОтменитьТранзакцию();
КонецПопытки;

Попытка
	НачатьТранзакцию();
	//Блок операций
	ЗафиксироватьТранзакцию();
Исключение
    ОтменитьТранзакцию();
КонецПопытки;

ЗафиксироватьТранзакцию();

Или в цикле




НачатьТранзакцию();

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

	Попытка
		НачатьТранзакцию();
		Данные.Записать();
		ЗафиксироватьТранзакцию();
	Исключение
	    ОтменитьТранзакцию();
	КонецПопытки;

КонецЦикла;

ЗафиксироватьТранзакцию();

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




&НаСервереБезКонтекста
Процедура ВыполнитьТранзакциюНаСервере()

	НачатьТранзакцию();

	Попытка

		НачатьТранзакцию();

		Товар = Справочники.Товары.СоздатьЭлемент();
		Товар.Наименование = "Стол";
		Товар.Записать();

		ВызватьИсключение "Ошибка записи товара.";

		ЗафиксироватьТранзакцию();

	Исключение

		ОтменитьТранзакцию();

		Сообщение = Новый СообщениеПользователю;
		Сообщение.Текст = ОписаниеОшибки();
		Сообщение.Сообщить();

	КонецПопытки;

	Попытка

		НачатьТранзакцию();

		Товар = Справочники.Товары.СоздатьЭлемент();
		Товар.Наименование = "Стул";
		Товар.Записать();

		ЗафиксироватьТранзакцию();

	Исключение

		ОтменитьТранзакцию();

		Сообщение = Новый СообщениеПользователю;
		Сообщение.Текст = ОписаниеОшибки();
		Сообщение.Сообщить();

	КонецПопытки;

	ЗафиксироватьТранзакцию();

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

В результате выполнения этой процедуры увидим в окне сообщений следующее:


{ВнешняяОбработка.ТранзакцииВПопытке.Форма.Форма.Форма(20)}: Ошибка записи товара.
{ВнешняяОбработка.ТранзакцииВПопытке.Форма.Форма.Форма(40)}: Ошибка при вызове метода контекста (Записать): В данной транзакции уже происходили ошибки!

Таким образом, организация вложенных транзакций в 1С абсолютно бессмысленна.

Возможные варианты

Теперь вернемся к варианту, где мы записывали товар и цену для него. Если у нас при выполнении транзакции произойдет ошибка, то будет трудно понять в какой момент она произошла — при записи товара или при записи цены, поскольку и то и другое происходит в рамках одной попытки. Чтобы определить место возникновения ошибки, нам надо каждую операцию записи заключить в свою собственную попытку и при этом избежать вложенных транзакций. Для этого введем булеву переменную Отказ и в зависимости от ее значения в конце всех операций будем фиксировать или отменять транзакцию.




&НаСервереБезКонтекста
Процедура ВыполнитьТранзакциюНаСервере()

	// Начинаем транзакцию
	Отказ = Ложь;
	НачатьТранзакцию();

	// Пытаемся записать товар
	Попытка

		Товар = Справочники.Товары.СоздатьЭлемент();
		Товар.Наименование = "Дырокол";
		Товар.Записать();

	Исключение

		Отказ = Истина;

		Сообщение = Новый СообщениеПользователю;
		Сообщение.Текст = "Ошибка при записи товара";
		Сообщение.Сообщить();

	КонецПопытки;

	// Пытаемся записать цену
	Попытка

		НаборЗаписей = РегистрыСведений.Цена.СоздатьНаборЗаписей();

		НоваяЗапись = НаборЗаписей.Добавить();
		НоваяЗапись.Период	= ТекущаяДата();
		НоваяЗапись.Товар	= Товар.Ссылка;
		НоваяЗапись.Сумма	= 100;

		НаборЗаписей.Записать();

	Исключение

		Отказ = Истина;

		Сообщение = Новый СообщениеПользователю;
		Сообщение.Текст = "Ошибка при записи цены";
		Сообщение.Сообщить();

	КонецПопытки;

	// Фиксируем или отменяем транзакцию
	Если НЕ Отказ Тогда
		ЗафиксироватьТранзакцию();
	Иначе
		ОтменитьТранзакцию();
	КонецЕсли;

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

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

Понравилась статья? Поделить с друзьями:
  • Ошибка при включении компьютера reboot and select proper boot device or insert boot media
  • Ошибка при входе не удалось наладить безопасное соединение яндекс музыка iphone
  • Ошибка при вызове метода контекста записатьjson передано значение недопустимого типа
  • Ошибка превышения размера при подписи эцп pdf
  • Ошибка при включении компьютера inaccessible boot device