Как не проводить документ при ошибке 1с

Проведение внутри проведения — как пропустить ошибки

Я
   3flight

24.06.11 — 13:38

В процедуру «ОбработкаПроведения» Объекта «А» я добавил вызов процедуры написанного мной общего модуля, где я из таблицы в этом объекте получаю ссылки на другие объекты, получаю объекты, меняю их и провожу с помощью «ОбъектБ.Записать». Делаю я это внутри блока «Попытка-Исключение», дабы уйти от ошибок проведения, если они вдруг будут. Мне нужно чтобы 1С попробовал провести ОбъектБ, и если есть ошибка, продолжил дальше. Но так не работает, если есть ошибка в проведении Объекта «Б», то не проводится и Объект «А». (т.е. ничего не проводится). Как обойти?

Код:

[CODE]Процедура ИзменитьСтатусыЗаказовНаОснованииПоступленияБДС(ОбъектПоступлениеБДС) Экспорт

   Для Каждого РасшифровкаПлатежа Из ОбъектПоступлениеБДС.РасшифровкаПлатежа Цикл

       Попытка

           Заказ = РасшифровкаПлатежа.Заказ.ПолучитьОбъект();

           Если Заказ.Статус = Перечисления.СтатусыЗаказовКлиентов.Согласован Или

                Заказ.Статус = Перечисления.СтатусыЗаказовКлиентов.КОбеспечению Тогда

               Заказ.Статус = Перечисления.СтатусыЗаказовКлиентов.КОтгрузке;

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

                   СтрокаТовар.ДатаОтгрузки = ТекущаяДата();

               КонецЦикла;

           КонецЕсли;

           Попытка

               Заказ.Записать(РежимЗаписиДокумента.Проведение);

           Исключение

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

       Исключение

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

   КонецЦикла;

КонецПроцедуры[/CODE]

   Ksandr

1 — 24.06.11 — 13:40

делать в событии ПриЗаписи

   3flight

2 — 24.06.11 — 15:04

Создал процедуру «ПриЗаписи(Отказ)», поместил вызов процедуры «ИзменитьСтатусыЗаказовНаОснованииПоступленияБДС(ОбъектПоступлениеБДС)» в неё, но результат тот же.

   Defender aka LINN

3 — 24.06.11 — 15:07

»    3flight

4 — 24.06.11 — 15:13

Порой меня поражает насколько «бывалые» пользователи форума любят бесполезно нафлудить, подразумевая свою высокую осведомленность и одновременно полную неосведомленность автора в обсуждаемой теме. Кстати, как тут в ответе сослаться на другой ответ? (Типа «(3)» )

   3flight

5 — 24.06.11 — 15:29

(3) — Подскажите, пожалуйста, если знаете, как реализовать.

   3flight

6 — 24.06.11 — 16:41

Кто-нибудь? Очень хочется решить эту задачу до следующей недели. Я уверен что тут какая-то принципиальная ошибка. Я не учился программированию на 1С, так что могу не знать каких-то нюансов или даже основ. Можно конечно делать проверки вручную, и вызывать метод «Записать» только если ошибок точно не будет, но это получится как-то громоздко.

   unregistered

7 — 24.06.11 — 16:49

(4) >> Порой меня поражает …

И меня тоже.

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

Это как бы давно известный факт.

Ну а менять при записи или проведении объекта другие объекты — не есть хорошо. Лучше поменять логику, алгоритм.

   unregistered

8 — 24.06.11 — 16:51

+ к (7):

Как вариант — хранить всю эту ересь про статусы заказов и даты отгрузки не в документе Заказ, а в регистре сведений.

   fisher

9 — 24.06.11 — 16:53

(0) Никак. Народ бает, что попытка/исключение реализовано в виде неявной транзакции. Так что исключение гарантированно откатывает все вышестоящие транзакции.

   Сияющий Асинхраль

10 — 24.06.11 — 16:53

(5) Вообще, проведение одного документа в модуле проведения второго уже не первый год, считается очень плохим тоном, поэтому и было сказано (3)

   Живой Ископаемый

11 — 24.06.11 — 16:53

зачем заказы перепроводить?

   Господин ПЖ

13 — 24.06.11 — 16:57

подписка спасет любителя извратов…

   unregistered

14 — 24.06.11 — 17:05

(13) Хммм… на какое событие?

   3flight

15 — 24.06.11 — 17:07

Спасибо за ответы! Попробую реализовать задачу иначе. (11) Заказы перепроводить чтобы проверялись условия оплаты и прочее, и статус менялся только если его можно поменять. Нужно сделать что-то вроде автоматизации статусов, чтобы их меняла программа при соответствующих событиях (в основном это оплата), а не люди.

   Живой Ископаемый

16 — 24.06.11 — 17:10

2(15) еще раз — зачем перепроводить целый документ если нужно только поменять статусы, то есть изменить что — какой-то РС?

Вот неужели когда тебе задают вопрос «Зачем ты одел шубу» ты начинаешь рассказывать что это хорошее вложение денег, она удобная, и так далее, вместо того чтобы сказать «чтобы согреться когда на улице холодно»?

   3flight

17 — 24.06.11 — 17:11

(12) Я сисадмин в небольшой организации %) Мне платят всего 180р в час.

   3flight

18 — 24.06.11 — 17:14

(15) Я пошёл простым путём. Склад по статусам может определить, с какими заказами работать. Поэтому я решил сделать, чтобы статусы менялись автоматически, чтобы избавить людей от ненужной работы. Я не знаю как поменять статус и потом сохранить документ, не используя метод «Записать», который проводит документ.

   Живой Ископаемый

19 — 24.06.11 — 17:15

2(18) нет, вы пошли неправильным, неналазящим на голову здоровым людям и системе путем… Надо было просто озвучить конечную цель и вам бы подсказали…

   3flight

20 — 24.06.11 — 17:37

19)

   3flight

21 — 24.06.11 — 17:40

(19) А теперь подскажут? Задача — чтобы статусы заказов менялись на ‘к обеспечению’ или ‘к отгрузке’ автоматически при проведении поступления безналичных дс, в  зависимости от выполнения условий оплаты.

   Живой Ископаемый

22 — 24.06.11 — 17:46

2(21) какой регистр меняется после вашего кода в случае все-таки успешного перепроведения заказа?

   3flight

23 — 24.06.11 — 18:32

(22) Регистр? У меня меня меняются реквизиты «статус» у заказов. потом склад смотрит заказы, через форму списка заказов, где и видят статусы.

   3flight

24 — 24.06.11 — 18:33

(22) конфигурация на основе УТ 11.0.5.4

   vs84

25 — 24.06.11 — 18:40

(17) А что сисадмин в 1Се делает?

Сварщики, сисадмины — все хотят вкусить запретного плода.

   Jolly Roger

26 — 24.06.11 — 18:50

(17) Я очень бедный… я год не был в бане… я старый… меня девушки не любят… Я сисадмин в небольшой организации %) Мне платят всего 180р в час…

зы: извините, не удержался…

   3flight

27 — 24.06.11 — 19:11

(26) :D а по теме что-нибудь?

(25) Я делаю «всё» :) что связано с компами

   Jolly Roger

28 — 24.06.11 — 19:15

(27) по теме тебе уже все сказали — вложенные транзакции не поддерживаются…

   Живой Ископаемый

29 — 24.06.11 — 20:42

2(23) в коде у тебя меняется вообще дата…

а раз проводить не нужно то записывай без режима проведения:

Заказ.ОбменДанными.Загрузка = Истина;

Заказ.Записать(РежимЗаписиДокумента.Запись);

таким образом ошибка может возникнуть только в одном исключительном случае — если этот же Заказ записывается или заблокирован кем-то другим

   NcSteel

30 — 24.06.11 — 20:52

(0) Нужен РН .

   Amiralnar

32 — 25.06.11 — 06:15

(30) Не обязательно. Можно РС.

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

   Jolly Roger

33 — 25.06.11 — 07:33

(29) ну так транзакция все-равно откатится…

   3flight

34 — 25.06.11 — 11:16

(29) Меняется Заказ.Статус, а СтрокаТовар.ДатаОтгрузки устанавливается для того чтобы не было ошибки проведения (нельзя ставить статус «К отгрузке», если не заполнены даты отгрузки — документ не проведётся). Если записывать без проведения, то наверно не будут выполняться проверки, которые выполняются при проведении? А мне они нужны. Мне нужно чтобы программа попробовала поменять статус, но не сделала этого если какие-то условия не выполняются. Единственная причина, по которой я использую проведение — именно запуск всех проверок.

(31) Я уже давно умер

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

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

   Живой Ископаемый

35 — 25.06.11 — 11:30

2(34) а вот зачем тебе чтобы они выполнялись?

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

   3flight

36 — 25.06.11 — 11:50

(34) Пример: бухгалтер вводит поступление БДС. Какая-то часть заказа оплачивается (не 100%). Нужно, чтобы программа, незаметно для бухгалтера (которому на заказы всё равно) проверила, достаточно ли оплачено по заказу, чтобы перевести его обработку в логистику (статус «к обеспечению») или чтобы начать его отгружать («к отгрузке») и если «да» то поменяла бы статус на соответствующий. Бухгалтер только жмёт «провести и закрыть» в своём поступлении БДС, потому что всё остальное можно сделать кодом, не заставляя бухгалтера проверять вручную условия оплаты по заказу и проставлять или не проставлять соответствующий статус. Ключевой пункт «если да» — вот зачем мне проверки, которые выполняются при проведении. Там проверяется оплата, дата отгрузки и всё остальное. Будет неправильно, если какой-нибудь недозаполненный заказ перевелся в «к отгрузке», потому что склад потом будет иметь проблемы с этой отгрузкой.

   vmv

37 — 25.06.11 — 12:13

мы сделали справочник «Статусы» и реквизит «Статус» в документах и все, зачем это гемор с кодом.

Для юзера все должно быть наглядно, очевидно и аццке жостко.

Инструментарий БП слишком сложен для многих реальных бизнес-процессов и нагружать им юзера похабно

   ДенисЧ

38 — 25.06.11 — 12:17

(36) я бы в регламенты эту проверку перенес…

   dimoff

39 — 25.06.11 — 12:17

(29) «таким образом ошибка может возникнуть только в одном исключительном случае — если этот же Заказ записывается или заблокирован кем-то другим»

Есть метод Заблокирован(), если его проверять тогда ошибки не возникнет

(34) «Это я понял, значит видимо буду делать без вложенных транзакций, придется отдельную кнопку повесить в форму документа для вызова этой процедуры.»

Не надо, если меняешь реквизит делай это через Записать() без всяких проведений и никаких ошибюок не возникнет.

   Живой Ископаемый

40 — 25.06.11 — 12:23

2(39) ошибок-то не возникнет — но тогда и статус не сменится… а если не сменится статус — должен ли проводиться изначально проводимый документ? Кк по мне — то нет, но автор вроде  хочет именно этого.

   dimoff

41 — 25.06.11 — 12:24

(40) Это уже вопрос логики автора, которой он может управлять по своему усмотрению

   3flight

42 — 25.06.11 — 13:25

(38) Думал об этом, наверно будет лучше всего. Не создавал ещё ни разу собственных регламентных заданий, поэтому не знаю как это делать. Щас поковыряю, разберусь наверно =)

(40) Конечно, если заказ уже «к отгрузке» или «к обеспечению», то я его проводить заново не буду, я его вообще пропущу. А вот «согласованные» придется проводить, чтобы проверки запускать.

(37) Вы имеете ввиду что можно задействовать БП, чтобы не писать код? БП для меня тема нераскрытая, поэтому я до понедельника наверно не успею эту штуку освоить. И с БП ведь придется всю фирму переучивать работе.

   NcSteel

43 — 25.06.11 — 14:22

(32) РС нельзя схлопнуть.

   3flight

44 — 25.06.11 — 14:58

(43) Что значит «схлопнуть»?

   vmv

45 — 25.06.11 — 15:03

(42) думаю вам и до осени БП — не освоить, лучьше свою статустную простую подсистему сделать.

Не трать время на БП, пусть разработчики типовых ваяют)

   3flight

46 — 25.06.11 — 15:31

Итого — сделал регламентное задание, которое каждые полчаса проверяет ПБДС за последние 60 минут и прогоняет по указанным в них заказам нужные проверки и, если нужно, меняет статусы и перепроводит. Всем спасибо за подсказки и пояснения! По-моему, получилось вполне оптимально.

   Сияющий Асинхраль

47 — 25.06.11 — 15:36

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

   vmv

48 — 25.06.11 — 15:41

(47) закрываться заказ будет по последнему платежу в статусе «Оплачено», который «закроет» сумму по всему заказу

   3flight

49 — 25.06.11 — 15:48

(47) Бухгалтерии вообще статусы не нужны. У нас бухгалтерия в УТ только разносит оплату и больше ничего не делает. Основная работа у них в БП, куда производится выгрузка. А склад всегда использует статусы — если нужно отгрузить, ставит «К отгрузке», если программа не даёт — звонят менеджеру и говорят что так и так — условия не выполнены — либо меняйте условия либо не отгружаем. Автомат я делаю для того чтобы «если нужно отгрузить» происходило в том числе автоматически. Сейчас у нас менеджер звонит на склад и говорит «отгружайте пожалуйста, клиент оплатил». Эту работу можно автоматизировать. Договора у нас никак на проверку оплаты не влияют.

   Сияющий Асинхраль

50 — 25.06.11 — 15:50

(48) Вот именно, это автоматическое закрытие, но очень часто платежи от контрагентов приходят не по последнему заказу и даже не по первому, а по тому, который ему нужнее в данный момент, причем это происходит очень часто, такой вариант при наличии нескольких заказов практически не автоматизируется…

   Сияющий Асинхраль

51 — 25.06.11 — 15:51

(49) Еще раз прочитай (50)

   vmv

52 — 25.06.11 — 15:52

(49) когда вы продавец, то да — договора делать статусными не обязательно, вас беспокоит оплата контргента и наличие у вас на складе спецификации поставки ему.

А когда вы покупатель и договора долгоиграющие на месяцы, годы, то …это уже совсем другая история)

   vmv

53 — 25.06.11 — 15:54

(50) Вам нужно рабочее место и роль «Обработка платежей», пользователь этой роли будет делать сопоставление(связь) платежей с заказами(договорами). Это сопоставление должно иметь авто/ручные/аналитические режимы

   Сияющий Асинхраль

54 — 25.06.11 — 15:54

Или еще вариант, два заказа — ранний на большую сумму и поздний на малую — клиент закрывает оплату по второй сумме (малой), а у тебя эта проплата скинется на первый заказ не зккрывая и первый заказ и второй…

   vmv

55 — 25.06.11 — 15:58

(54) читай (53) — без статусов и рабочего места по обработке платежей от клиен-банков такое решить только в коде НЕ реально. мы год ломали голову пока пришли к простым и логичным решениям

   3flight

56 — 25.06.11 — 15:58

(50) Бухгалтер при вводе ПБДС подвязывает сумму и к договору и к заказу, т.к. когда клиент платит, он указывает в платёжке, какой заказ он оплачивает. У нас так, по крайней мере. Моя автоматизация проверяет свежие ПБДС. Не совсем понимаю как договор может помешать в этой схеме автоматически поменять статус заказу.

(51) Как я мог прочитать (50), если мой ответ был раньше? :D

   Сияющий Асинхраль

57 — 25.06.11 — 15:58

(53) Это не мне нужно, это ТС нужно, я и говорю, что данный процесс не сильно поддается алгоритмизации, точнее его нельзя сделать автономным без вмешательства человека, поэтому и не стоит делать регламентных заданий, должно быть нечто вроде обработки которую запскает менеджер и только менеджер решает по какому заказу прошла проплата, единственное что стоит сделать для упрощения — это дать возможность выбирать менеджеру сразу группу заказов в которых по нажатию некой кнопки «Изменить статус» менять статус групповым образом…

естественно без участия человека тут никакой регламент не спасет. Пример навскидку, «так все по фиг — по этому договру немедленно сделать оплату эээ на ээээ NNN, потом разберемся»)

  1. Всем привет!

    В обработке проведения делаю проверку на наличие проведенных документов на основании, и если таковые есть — выдаю ошибку, что нужно их распровести и делаю «Отказ = Истина». При этом выдается сервисное сообщение «Не удалось провести [название документа]. Ок, Подробно…».

    Начальника хочет, чтобы выводилось одно сообщение о том, что не проведено, т.к. есть документы на основании. Как вывести свое сообщение и не выводить сервисное?


  2. alexburn

    Offline

    alexburn
    Модераторы
    Команда форума
    Модератор

    Регистрация:
    5 янв 2009
    Сообщения:
    15.150
    Симпатии:
    560
    Баллы:
    204

  3. Если можно, чуть подробнее. В каком месте использовать попытку и что в ней пытаться сделать? Я же не программно провожу, а стандартными средствами.


  4. alexburn

    Offline

    alexburn
    Модераторы
    Команда форума
    Модератор

    Регистрация:
    5 янв 2009
    Сообщения:
    15.150
    Симпатии:
    560
    Баллы:
    204

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


  5. shurikvz

    Offline

    shurikvz
    Модераторы
    Команда форума
    Модератор

    Регистрация:
    1 окт 2009
    Сообщения:
    8.547
    Симпатии:
    344
    Баллы:
    104

    TylerDurdenIII
    в суть не вдумывался. Пока вопросы:
    1) почему вы это делаете (проверку) именно в обработке проведения документа? Почему например нельзя сделать это раньше, например перед записью документа?
    2) всю задачу не знаю, это зависит уже от нее, поэтому может быть не актуально, но: судя по первому посту подразумевается что это проведение ваше запускает пользователь, и ему выводится какое-то сообщение. В итоге: вашу проверку действительно в модуле объекта надо делать, или же допустимо вообще убрать ее в модуль формы?

  6. 1) Если делать в процедуре ПередЗаписью также придется ставить Отказ=Истина, который приведет к сообщению «Не удалось провести [название документа]».
    2) Если в форму поместить код, то не отработает при проведении из списка.


  7. alexburn

    Offline

    alexburn
    Модераторы
    Команда форума
    Модератор

    Регистрация:
    5 янв 2009
    Сообщения:
    15.150
    Симпатии:
    560
    Баллы:
    204

    Главный вопрос — для чего это ????
    Это влияет на бизнес-логику ?
    Это влияет на скорость работы ИБ ?
    Это влияет на оперативность ?
    На что это влияет ????

  8. Есть такие люди, которые хотят и все тут. Мешает им видите ли лишнее отвлекающее от основного сообщение. Буду убеждать, что не надо это, просто уже интересно как же можно это сделать если это возможно.


  9. shurikvz

    Offline

    shurikvz
    Модераторы
    Команда форума
    Модератор

    Регистрация:
    1 окт 2009
    Сообщения:
    8.547
    Симпатии:
    344
    Баллы:
    104

    2) Понял. Принимается.
    1) ПередЗаписью() использовать в любом случае лучше, не будет лишних расчетов, выполняемых в процедуре проведения

    Еще уточняющий вопрос: контролировать (выводить ваше сообщение) надо именно при проведении документа или при отмене проведения?


  10. shurikvz

    Offline

    shurikvz
    Модераторы
    Команда форума
    Модератор

    Регистрация:
    1 окт 2009
    Сообщения:
    8.547
    Симпатии:
    344
    Баллы:
    104

    Ну ок.
    Смотрите, я не знаю как вы выводите ваше сообщение (Предупреждение())? Т.е. модальным окном что-ли, что у вас два она появляется?
    Если так, то рекомендуемый мной вариант: сделать точно также как реализовано стандартно. Т.е. выводите причину ошибки при помощи «ОбщегоНазначения.СообщитьОбОшибке()», она появляется внизу экрана в окне сообщений, и на экране это ваше системное окно о том что невозможно провести (записать) документ.
    Если же упорно так не хотите, ну единственный вариант который я знаю: вызовите собственное исключение в процедуре проведения (ВызватьИсключение <Текст>).

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


  12. shurikvz

    Offline

    shurikvz
    Модераторы
    Команда форума
    Модератор

    Регистрация:
    1 окт 2009
    Сообщения:
    8.547
    Симпатии:
    344
    Баллы:
    104

    Да нет. Чего она важного может делать? Вызываете исключение — транзакция записи прерывается.

Похожие темы

  1. Vertex
    Ответов:
    12
    Просмотров:
    1.235


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

Попытка проведения и записи документа в одной процедуре

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

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

Комментарии

В статье описано, как добиться оптимальной записи с отменой проведения или проведением перенесенных документов  при написании правил обмена в системе Конвертации Данных (КД).

При переносе данных между базами часто возникает ситуация, когда движения документов переносить не требуется, а перенесенные документы следует проводить в базе-приёмнике. Например, в базе-источнике ведется управленческий учет, а в базе-приемнике  регламентированный.  Если при переносе не учитывать свойство «Проведен» документа, то можно получить в приемнике проведенные документы, у которых данные в движениях и в объекте не соответствуют друг другу.

 В правилах конвертации объектов (ПКО) в обработчике «Перед загрузкой» существуют параметры «РежимЗаписи» и «РежимПроведения», указание которых обеспечивает необходимый режим записи объекта, но в этом случае, запись происходит во время загрузки данных и если, по каким-то причинам, документ не запишется, загрузка данных будет прервана. Правильней записывать новые документы в конце загрузки, когда все перенесенные объекты уже будут в базе — приемнике.

Несколько основных моментов:

  1. Нам необходим параметр конвертации с типом «Таблица значений», куда можно будет записывать ссылки на документ и информацию о том, что с документом делать. Создать параметр на вкладке «Параметры» конвертации – не получится, но его спокойно можно создать программным способом. После использования наш параметр следует удалить, в противном случае при использовании управляемой формы обработки система будет выдавать сообщение об ошибке, т.к. управляемая форма не использует таблицу значений. Несмотря на сообщение об ошибке, обработка все действия выполнит, но нервировать пользователей подобными сообщениями не следует.
  2. Для анализа, новый это объект или существующий в обработке используется параметр ОбъектНайден.
  3. Для анализа состояния ранее записанного объекта в приемнике используем обращение к его ссылке (Объект.Ссылка).
  4. Для записи ссылки нового для приемника документа нам необходимо документ записать. Чтобы избежать повторной записи документа обработкой обмена следует выставить параметр ОбъектМодифицирован в значение Ложь.
  5. Обработка обмена данными при записи документа обнуляет перенесенную пометку удаления. Это необходимо учитывать.
  6.  Для решения стоящей задачи наиболее удобно использовать обработчики событий конвертации в целом. Но нам необходимо определить – объект  — это документ, и если документ – то проводится ли он. Для идентификации документа используем параметр обработчика ИмяТипаОбъекта.

I. Первый, более простой, случай: требуется оставлять в базе-приемнике документы непроведенными.

      Подразумевается, что пользователи в базе-приемнике проверят документы и потом их проведут. Если не переносить движения и просто указать в свойстве «Проведен»  — «Значение = Ложь», то можем получить при повторном переносе документы внешне не проведенные, но с движениями. К этому получим справедливое возмущение пользователей, которые не смогут понять результатов отчетов.

     Свойство «Проведен» необходимо исключить из переноса в каждом документе. Нам необходимо при выгрузке данных запоминать необходимые для отмены проведения документы и после загрузки данных записать их с режимом отмены проведения. Помимо ссылки на документ необходимо сохранять и информацию об его пометке удаления. Для получения информации о пометке удаления данное свойство каждого проводимого документа необходимо передавать в параметр, который назовем также, как и имя свойства — ПометкаУдаления. (Рис.1)

1. В обработчике «Перед загрузкой данных» конвертации создаем параметр с типом значений «Таблица значений».  В колонку «Действие» строкой будем записывать – что делать с документом: просто отменять проведение или еще проставлять пометку на удаление.

     ТаблицаДокументов = Новый ТаблицаЗначений;
     ТаблицаДокументов.Колонки.Добавить(«Ссылка»);
     ТаблицаДокументов.Колонки.Добавить(«Действие»);
     Параметры.Вставить(«ТаблицаДокументов»,ТаблицаДокументов);

2. В обработчике «После загрузки объекта» конвертации, определяем найден ли объект, является ли объект документом, проводится ли он, и если в приемнике он проведен, то только тогда помещаем ссылку на него в наш параметр ТаблицаДокументов.

    Если ОбъектНайден
        И ИмяТипаОбъекта = «Документ»
        И
Объект.Метаданные().Проведение = Метаданные.СвойстваОбъектов.Проведение.Разрешить
        И Объект.Ссылка.Проведен Тогда
        
НоваяСтрока = Параметры.ТаблицаДокументов.Добавить();
        
НоваяСтрока.Ссылка = Объект.Ссылка;
        Если
ПараметрыОбъекта.Получить(«ПометкаУдаления») Тогда
            
НоваяСтрока.Действие = «Удаление»;
        Иначе
            
НоваяСтрока.Действие = «Отмена»;
        КонецЕсли;
    ИначеЕсли 
ПараметрыОбъекта <> Неопределено И Лев(Строка(ТипЗнч(Объект)),8) = «Документ»  Тогда
        
Объект.ПометкаУдаления = ПараметрыОбъекта.Получить(«ПометкаУдаления»); //Пометка удаления у новых объектов и непроведенных старых
    КонецЕсли;

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

     ТекстСообщенияОтмены = «»;
     
ТекстСообщенияОшибки = «»;
     Для каждого
СтрокаТч Из Параметры.ТаблицаДокументов Цикл
         Попытка
             
ДокОбъект = СтрокаТч.Ссылка.ПолучитьОбъект();
             Если
СтрокаТч.Ссылка.Проведен Тогда
                 
ДокОбъект.Записать(РежимЗаписиДокумента.ОтменаПроведения);
             КонецЕсли;
             Если
СтрокаТч.Действие = «Удаление» Тогда
                 
ДокОбъект.ПометкаУдаления = Истина;
                 
ДокОбъект.Записать();
             КонецЕсли;
             
ТекстСообщенияОтмены = ТекстСообщенияОтмены + Строка(СтрокаТч.Ссылка) + Символы.ПС;
         Исключение
             ТекстСообщенияОшибки 
= ТекстСообщенияОшибки + Строка(СтрокаТч.Ссылка) + » : «+ ОписаниеОшибки() + Символы.ПС;
         КонецПопытки;
     КонецЦикла;

     Если Не ПустаяСтрока(ТекстСообщенияОтмены) Тогда
         
Сообщить(«Отменено проведение документов:» + Символы.ПС + ТекстСообщенияОтмены);
     КонецЕсли;
     Если Не
ПустаяСтрока(ТекстСообщенияОшибки) Тогда
         
Сообщить(«Ошибки при отмене проведения: «+ Символы.ПС + ТекстСообщенияОшибки);
     КонецЕсли;
     
Параметры.Удалить(«ТаблицаДокументов»);

II. Требуется обеспечить проведение документов в базе-приемнике при переносе.

   В этом случае необходимо помимо пометки удаления передавать значение свойства «Проведен» в параметр «Проведен» и данный параметр анализировать в обработчике «После загрузки объекта» (Рис.2).

1. «Перед загрузкой данных» Повторяем создание параметра конвертации, как в первом примере

ТаблицаДокументов = Новый ТаблицаЗначений;
ТаблицаДокументов.Колонки.Добавить(«Ссылка»);
ТаблицаДокументов.Колонки.Добавить(«Действие»);
Параметры.Вставить(«ТаблицаДокументов»,ТаблицаДокументов);

2. «После загрузки объекта»  После загрузки мы должны уже работать с объектами, которые еще не записаны в базе. Документы можно выделить по типу значения, а новый объект, перед внесением в таблицу параметра, необходимо предварительно записать. Не забываем установить параметр «ОбъектМодифицирован» в «Ложь». 

Если ИмяТипаОбъекта = «Документ»
   
И Объект.Метаданные().Проведение = Метаданные.СвойстваОбъектов.Проведение.Разрешить Тогда

    Если Не ОбъектНайден  Тогда
       
Объект.Записать();
       
ОбъектМодифицирован = Ложь;
    КонецЕсли;

    НоваяСтрока Параметры.ТаблицаДокументов.Добавить();
   
НоваяСтрока.Ссылка = Объект.Ссылка;

    Если ПараметрыОбъекта.Получить(«Проведен»)  Тогда
       
НоваяСтрока.Действие = «Проведение»;
    ИначеЕсли
ПараметрыОбъекта.Получить(«ПометкаУдаления»)  Тогда
       
НоваяСтрока.Действие = «Удаление»;
    Иначе
       
НоваяСтрока.Действие = «Отмена»;
    КонецЕсли;
КонецЕсли;

3. «После загрузки данных» После загрузки мы должны пропустить запись документа, если он не проведен в базе-источнике и в базе приемника. Также необходимо проследить за пометкой удаления.

ТекстСообщенияЗаписи = «»;
ТекстСообщенияОшибки = «»;

Для каждого СтрокаТч Из Параметры.ТаблицаДокументов Цикл


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

        Продолжить;

    КонецЕсли;

    Если СтрокаТч.Действие = «Проведение» Тогда
       
РежимЗаписи = РежимЗаписиДокумента.Проведение;
    Иначе
       
РежимЗаписи = РежимЗаписиДокумента.ОтменаПроведения;
    КонецЕсли;

    Попытка
        ДокОбъект = СтрокаТч.Ссылка.ПолучитьОбъект();
        Если (
СтрокаТч.Действие <> «Удаление» Или  СтрокаТч.Ссылка.Проведен) Тогда
           
ДокОбъект.Записать(РежимЗаписи);
           
ТекстСообщенияЗаписи = ТекстСообщенияЗаписи +?(РежимЗаписи = РежимЗаписиДокумента.Проведение,
           
«Проведен «,«Отменено проведение «)
            +
Строка(СтрокаТч.Ссылка) + Символы.ПС;
        КонецЕсли;

        Если СтрокаТч.Действие = «Удаление» Тогда
           
ДокОбъект.ПометкаУдаления = Истина;
           
ДокОбъект.Записать();
        ИначеЕсли
СтрокаТч.Ссылка.ПометкаУдаления Тогда
           
ДокОбъект.ПометкаУдаления = Ложь;
           
ДокОбъект.Записать();
        КонецЕсли;
    Исключение    

    ТекстСообщенияОшибки = ТекстСообщенияОшибки Строка(СтрокаТч.Ссылка)+ » : «+ОписаниеОшибки()+ Символы.ПС;

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

Если Не ПустаяСтрока(ТекстСообщенияЗаписи) Тогда
   
Сообщить(ТекстСообщенияЗаписи);
КонецЕсли;

Если Не ПустаяСтрока(ТекстСообщенияОшибки) Тогда
   
Сообщить(«Ошибки при отмене проведения: «+ Символы.ПС + ТекстСообщенияОшибки);
КонецЕсли;
Параметры.Удалить(«ТаблицаДокументов»);

Содержание:

1.      Обработка исключительной ситуации

2.      Совершаем ошибку в 1С 8.3

3.      А что еще можно делать с результатом попытки?

4.      А ваши транзакции то здесь при чём?  

1.      Обработка исключительной ситуации

—        Приветствую, Амиго! Ты, как я понял, пришёл на мою лекцию по физическим основам изготовления термитных пирамидок для заряда аппаратов гиперболоидной конструкции? Нет? А зачем тогда?

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

—        А… Это… Ну, тогда вот:

—        Кажется, понятно. А можно примеров добавить?

—        Ох уж эти юные роботы, всегда хотят практики. С примерами это будет выглядеть вот так:

Ох, извини, это для старых баз. На новых космолётах с прошивкой выше 8.1 есть более удобный способ узнать код ошибки.  

2.      Совершаем ошибку в 1С 8.3

Ты и сам можешь попробовать. Главное – придумать ошибку в 1С 8.3. Самая простая ошибка – это разделить что-нибудь на нуль или на, как это говорят на современном сленге, ноль.

В ответ получим:

Нажимаем на кнопку «Подробно…» и видим: Деление на 0 {NudlsProff_Расширение.NudlsProff_ФормаОшибок.Форма(96)}: Результат = 1/0

Добавляем нашей красоты:

Теперь пользователю ВИДНО, что случилось. И ПОНЯТНО, что с этим делать.

Описание=’Деление на 0′

ИмяМодуля=’NudlsProff_Расширение.NudlsProff_ФормаОшибок.Форма’

НомерСтроки=99

ИсходнаяСтрока=’        Результат = 1 / 0;’

Позвоните Профессору Нудлсупо тел+7 (495) 125-23-77

и ознакомьтесь с теорией деления на ноль

https://elementy.ru/email/1530320/Pochemu_nelzya_delit_na_nol     

3.      А что еще можно делать с результатом попытки?

—        А что ещё мы можем делать в результате с попыткой?

—        Мы можем обработать попытку в попытке.

По своей сути Попытка-Исключение – это отлов исключительной ситуации. Ситуации, которая может произойти. Возможно, даже и не по вине юного робота. Робот же должен учесть все возможные ситуации при написании кода и обработать их. Но наш мир не идеален и даже программы не всегда работают идеально. Именно тогда мы и должны проанализировать возможные последствия и понять, что для нас важнее: чтобы код выполнился до конца или вызвать прерывание работы ошибочного кусочка кода, но дать пользователю исправить ситуацию и продолжить работу.

—        Профессор, Вы опять забыли про примеры.

—        Ах, да, конечно. Например, мы записывали файл на диск. Пользователь, конечно, выбрал папку для записи файла, но случайно удалил её во время работы программы. Вся наша программа рухнет из-за невнимательности.

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

4.      А ваши транзакции то здесь при чем?

—        То есть если в программе что-то может пойти не так, например, при записи файла на диск, обработке web-hook, работе с API, синхронизации с другими базами, записи изменений в справочник или документ, для безопасности я должен обернуть потенциально опасный кусочек кода в Попытку-Исключение, и тем самым пользователь сможет продолжить работу, а мы всегда будем знать, где именно и почему возникает ошибка?

—        Да, Амиго, все верно! Кстати, поскольку уж речь зашла о записи объектов баз данных, очень важно не забывать правильно закрывать ваши транзакции:

 

Специалист компании «Кодерлайн» 

Алексей Зятнин

Понравилась статья? Поделить с друзьями:
  • Как не допустить ошибок при начале отношений
  • Как не правильно приседать ошибки
  • Как не зделать ошибки в слове
  • Как не допустить ошибок при макияже
  • Как не повторять старые ошибки