Имя: Пароль:
1C
1С v8
Отмена транзакции распространяется на процедуры, не входящие в саму транзакцию
,
0 МастерВопросов
 
13.09.12
13:24
В 1С8КА есть типова обработка "ЗакрытиеКассовойСмены".
На её форме есть кнопка "ЗакрытьСмену" при её нажатии отрабатывает процедура "КоманднаяПанельДействийЗакрытьСмену".

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

Внутри процедуры "ОбработкаЧековККМ()" начинается и отменяется транзакция, т.к. чеков за смену не было. При этом моя процедура "МК_РозничнаяПродажа.ДействияПослеЗакрытияСмены(Дата,КассаККМ,"");" благополучно отрабатывает. Точки останова внутри неё срабатывают, реквизиты показывают новые значения.
Но по завершению работы процедуры "КоманднаяПанельДействийЗакрытьСмену(Кнопка)" все сделанные изменения в моей процедуре возвращаются к старым значениям. Если чеки за смену есть, то и изменения сделанные моей процедурой вполне присутствую в базе.

Еще раз обращаю внимание вызов моей процедуры стоит ПОСЛЕ "ОбработкаЧековККМ();", в которой начинается, а потом отменяется или фиксируется транзакцияю
1 МастерВопросов
 
13.09.12
13:26
// Процедура представляет обработчик события "Нажатие" кнопки
// "ЗакрытьСмену" командной панели "КоманднаяПанельДействий".
//
// Параметры:
//  Кнопка - <КнопкаКоманднойПанели>
//         - Кнопка, с которой связано данное событие (кнопка "ЗакрытьСмену").
//
Процедура КоманднаяПанельДействийЗакрытьСмену(Кнопка)

   МассивOnline  = ПолучитьСерверТО().ПолучитьСписокУстройств(мВидOnline,  КассаККМ);
   МассивOffline = ПолучитьСерверТО().ПолучитьСписокУстройств(мВидOffline, КассаККМ);
   МассивФР      = ПолучитьСерверТО().ПолучитьСписокУстройств(мВидФР,      КассаККМ);

   Если ВыполнитьСверкуИтоговПоПлатежнымКартам Тогда
       Если мМассивЭС.Количество() = 1 Тогда
           ТекМассивЭС = мМассивЭС;
       Иначе
           ТекМассивЭС = Новый Массив;

           СписокЭС = РаботаСТорговымОборудованием.ПолучитьСписокУстройствТОДляВыбора(мМассивЭС);
           СписокЭС.ЗаполнитьПометки(Истина);

           Если СписокЭС.ОтметитьЭлементы("Укажите эквайринговые системы...") Тогда
               Для Каждого ТекЭС Из СписокЭС Цикл
                   Если ТекЭС.Пометка Тогда
                       ТекМассивЭС.Добавить(ТекЭС.Значение);
                   КонецЕсли;
               КонецЦикла;
           КонецЕсли;
       КонецЕсли;

       Если МассивФР.Количество() = 0 Тогда
           ФР = Неопределено;
       ИначеЕсли МассивФР.Количество() = 1 Тогда
           ФР = МассивФР[0];
       Иначе
           ФР = РаботаСТорговымОборудованием.ПолучитьСписокУстройствТОДляВыбора(МассивФР).ВыбратьЭлемент("Необходимо выбрать фискальный регистратор");
           Если ФР <> Неопределено Тогда
               ФР = ФР.Значение;
           КонецЕсли;
       КонецЕсли;

       Если ФР <> Неопределено Тогда
           Для Каждого ЭС Из ТекМассивЭС Цикл
               ПолучитьСерверТО().ИтогиДняПоКартам(ЭС, ФР);
           КонецЦикла;
       КонецЕсли;
   КонецЕсли;

   Если МассивOnline.Количество() > 0
        Или МассивФР.Количество() > 0 Тогда
       ОбработкаЧековККМ();
       Пароль    = ПолучитьСерверТО().ПолучитьПарольАдминистратораККМ();
       Результат = Неопределено;
       ФР        = Неопределено;
       Для Каждого ФР Из МассивФР Цикл
           Результат = ПолучитьСерверТО().ОтчетСГашением(ФР, Пароль);
           Если ЗначениеЗаполнено(Результат) Тогда
               ТекстОшибки = ПолучитьСерверТО().ПолучитьТекстОшибкиФРТО(Результат);
               Сообщить(ТекстОшибки, СтатусСообщения.Важное);
           КонецЕсли;
       КонецЦикла;
   ИначеЕсли МассивOnline.Количество() = 0 И МассивOffline.Количество() = 0 И МассивФР.Количество() = 0 Тогда
       ОбработкаЧековККМ();
   КонецЕсли;

   Результат = Неопределено;
   ККМ       = Неопределено;
   Для Каждого ККМ Из МассивOffline Цикл
       ОбработкаЧековOffline(ККМ);
   КонецЦикла;
   
   МК_РозничнаяПродажа.ДействияПослеЗакрытияСмены(Дата,КассаККМ,"");
   
КонецПроцедуры // КоманднаяПанельДействийЗакрытьСмену()
2 Рэйв
 
13.09.12
13:27
ДействияПослеЗакрытияСмены(Дата,КассаККМ,"") покажи
3 МастерВопросов
 
13.09.12
13:29
(2)
Процедура  ДействияПослеЗакрытияСмены(ВыбДата,КассаККМ,ОтчетОЗакрытии) Экспорт
   
   //инициируем файл лога
   ЛогФайл = "";  
   Попытка
       КудаСохранять = "\\192.168.0.102\Для всех\Переход на 1С82\ЛОГ\ДействияПослеЗакрытияСмены.txt";
       Если КудаСохранять<>"" Тогда
           ЛогФайл=Новый ТекстовыйДокумент;
           Файл = Новый Файл(КудаСохранять);
           Если Файл.Существует() Тогда
               ЛогФайл.Прочитать(КудаСохранять);
           КонецЕсли;
       КонецЕсли;
       ЗаписатьВЛог(ЛогФайл,КудаСохранять,"");
       ЗаписатьВЛог(ЛогФайл,КудаСохранять,"*********************** Закрытие смены от "+СокрЛП(ВыбДата)+"***********************");
       ЗаписатьВЛог(ЛогФайл,КудаСохранять,"*** КассаККМ "+СокрЛП(КассаККМ)+" *** ОтчетОЗакрытии="+СокрЛП(ОтчетОЗакрытии)+"***");
       ЗаписатьВЛог(ЛогФайл,КудаСохранять," Текущий пользователь = "+СокрЛП(ПараметрыСеанса.ТекущийПользователь));
   Исключение
       Сообщить(ОписаниеОшибки());
       ЛогФайл = "";
   КонецПопытки;
   
   //теперь поменяем в МК_РозничнаяПродажаЧек ссылку на удаленный чек на ОтчетОЗакрытии
   Если СокрЛП(ОтчетОЗакрытии) <> "" Тогда
       ЗапросПоМК_РПЧ = новый запрос;
       ЗапросПоМК_РПЧ.Текст = "ВЫБРАТЬ
       |    МК_РозничнаяПродажаЧек.Ссылка
       |ИЗ
       |    Документ.МК_РозничнаяПродажаЧек КАК МК_РозничнаяПродажаЧек
       |ГДЕ
       |    МК_РозничнаяПродажаЧек.Дата >= &НачДата
       |    И МК_РозничнаяПродажаЧек.Проведен
       |    И МК_РозничнаяПродажаЧек.Дата <= &КонДата
       |    И (МК_РозничнаяПродажаЧек.ЕстьЧекНаОсновании.Ссылка ЕСТЬ NULL И НЕ МК_РозничнаяПродажаЧек.ЕстьЧекНаОсновании = &ПустаяСсылкаДокумента)
       |    И МК_РозничнаяПродажаЧек.КассаККМ = &КассаККМ
       |    И МК_РозничнаяПродажаЧек.Склад = &Склад
       |";
       
       ЗапросПоМК_РПЧ.УстановитьПараметр("НачДата",НачалоДня(ВыбДата));
       ЗапросПоМК_РПЧ.УстановитьПараметр("КонДата",КонецДня(ВыбДата));
       ЗапросПоМК_РПЧ.УстановитьПараметр("КассаККМ",КассаККМ);
       ЗапросПоМК_РПЧ.УстановитьПараметр("Склад",ОтчетОЗакрытии.Склад);
       ЗапросПоМК_РПЧ.УстановитьПараметр("ПустаяСсылкаДокумента",Неопределено);
       Выборка = ЗапросПоМК_РПЧ.Выполнить().Выбрать();
       ЗаписатьВЛог(ЛогФайл,КудаСохранять,"*** Выполнили запрос по МК_РозничнаяПродажаЧек ***");
       Пока Выборка.Следующий() Цикл
           Попытка
               ОбъектПоМК_РПЧ = Выборка.Ссылка.ПолучитьОбъект();
               ОбъектПоМК_РПЧ.ЕстьЧекНаОсновании = ОтчетОЗакрытии;
               ОбъектПоМК_РПЧ.Записать();
               Сообщить("Изменили документ оплаты в: "+СокрЛП(Выборка.Ссылка),СтатусСообщения.Информация);
               ЗаписатьВЛог(ЛогФайл,КудаСохранять,"Изменили документ оплаты в: "+СокрЛП(Выборка.Ссылка));
           Исключение
               Сообщить("Ошибка при изменениии: "+СокрЛП(Выборка.Ссылка),СтатусСообщения.Важное);
               Сообщить("--"+ОписаниеОшибки());
               ЗаписатьВЛог(ЛогФайл,КудаСохранять,"--- ВАЖНО: Ошибка при изменениии: "+СокрЛП(Выборка.Ссылка));
               ЗаписатьВЛог(ЛогФайл,КудаСохранять,"--- ОписаниеОшибки= "+СокрЛП(ОписаниеОшибки()));
           КонецПопытки;
       КонецЦикла;
   Иначе
       ЗаписатьВЛог(ЛогФайл,КудаСохранять,"*** ОтчетОЗакрытии='' запрос по МК_РозничнаяПродажаЧек не выполняли ***");
   КонецЕсли;
   
   
   //очищаем регистр сведений  МК_СоответствиеЧекаИРозничнойПродажи
   //поидее при удалении чекаККМ записи сами удаляются, но на всякий случай - вдруг остались записи без чеков
   
   ЗапросКРегистру = Новый Запрос;
   ЗапросКРегистру.Текст = "ВЫБРАТЬ
                           |    МК_СоответствиеЧекаИРозничнойПродажи.РозничнаяПродажаЧек
                           |ИЗ
                           |    РегистрСведений.МК_СоответствиеЧекаИРозничнойПродажи КАК МК_СоответствиеЧекаИРозничнойПродажи
                           |ГДЕ
                           |    МК_СоответствиеЧекаИРозничнойПродажи.РозничнаяПродажаЧек.Дата >= &НачДата
                           |    И МК_СоответствиеЧекаИРозничнойПродажи.РозничнаяПродажаЧек.Дата <= &КонДата
                           |    И МК_СоответствиеЧекаИРозничнойПродажи.РозничнаяПродажаЧек.КассаККМ = &КассаККМ";
   
   ЗапросКРегистру.УстановитьПараметр("НачДата",НачалоДня(ВыбДата));
   ЗапросКРегистру.УстановитьПараметр("КонДата",КонецДня(ВыбДата));
   ЗапросКРегистру.УстановитьПараметр("КассаККМ",КассаККМ);
   РезЗапроса = ЗапросКРегистру.Выполнить();
   Если РезЗапроса.Пустой() Тогда
       ЗаписатьВЛог(ЛогФайл,КудаСохранять,"*** Запрос к РегистрСведений.МК_СоответствиеЧекаИРозничнойПродажи вернулся пустой ***");
   Иначе    
       ЗаписатьВЛог(ЛогФайл,КудаСохранять,"");
       ЗаписатьВЛог(ЛогФайл,КудаСохранять,"*** ВАЖНО: Запрос к РегистрСведений.МК_СоответствиеЧекаИРозничнойПродажи вернулся НЕ пустой ***");

       Выборка = РезЗапроса.Выбрать();
       Пока Выборка.Следующий() Цикл
           НаборЗаписей = РегистрыСведений.МК_СоответствиеЧекаИРозничнойПродажи.СоздатьНаборЗаписей();
           НаборЗаписей.Отбор.РозничнаяПродажаЧек.Установить(Выборка.РозничнаяПродажаЧек);
           НаборЗаписей.Записать();
           ЗаписатьВЛог(ЛогФайл,КудаСохранять,"Удалили из регистра запись по "+СокрЛП(Выборка.РозничнаяПродажаЧек));
       КонецЦикла;
   КонецЕсли;
   
   //перепроводим документы РОзничная продажа с заполненным РКОПриВозврате
   
   ЗапросКРегистру = новый Запрос;
   ЗапросКРегистру.Текст = "ВЫБРАТЬ
                           |    РозничнаяВыручка.Регистратор,
                           |    МК_РозничнаяПродажаЧек.РКОПриВозврате
                           |ИЗ
                           |    РегистрНакопления.РозничнаяВыручка КАК РозничнаяВыручка
                           |        ВНУТРЕННЕЕ СОЕДИНЕНИЕ Документ.МК_РозничнаяПродажаЧек КАК МК_РозничнаяПродажаЧек
                           |        ПО РозничнаяВыручка.Регистратор = МК_РозничнаяПродажаЧек.Ссылка
                           |ГДЕ
                           |    РозничнаяВыручка.Регистратор.Дата >= &НачДата
                           |    И РозничнаяВыручка.Регистратор.Дата <= &КонДата
                           |    И МК_РозничнаяПродажаЧек.РКОПриВозврате <> &РКОПриВозврате";
   
   ЗапросКРегистру.УстановитьПараметр("НачДата",НачалоДня(ВыбДата));
   ЗапросКРегистру.УстановитьПараметр("КонДата",КонецДня(ВыбДата));
   ЗапросКРегистру.УстановитьПараметр("РКОПриВозврате",Документы.РасходныйКассовыйОрдер.ПустаяСсылка());
   РезЗапроса = ЗапросКРегистру.Выполнить();
   
   Если РезЗапроса.Пустой() Тогда
       ЗаписатьВЛог(ЛогФайл,КудаСохранять,"*** Запрос к Регистру.РозничнаяВыручка вернулся пустой ***");
   Иначе    
       ЗаписатьВЛог(ЛогФайл,КудаСохранять,"");
       ЗаписатьВЛог(ЛогФайл,КудаСохранять,"*** Запрос по ВОЗВРАТАМ к Регистру.РозничнаяВыручка вернулся НЕ пустой ***");

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

           //перепроводим МК_РозничнаяПРодажа
           Попытка
               ОбъектДокумента = Выборка.Регистратор.ПолучитьОбъект();
               ОбъектДокумента.Записать(РежимЗаписиДокумента.Проведение);
               // Удаление движений происходит без контроля доступа - передаем пустую таблицу движений
               //ПолныеПрава.ЗаписатьНаборЗаписейНаСервере("РозничнаяВыручка",Выборка.Регистратор,,"РегистрНакопления");

               ЗаписатьВЛог(ЛогФайл,КудаСохранять,"Перепровели "+СокрЛП(Выборка.Регистратор));
               Сообщить("Перепровели "+СокрЛП(Выборка.Регистратор));
           Исключение
               ЗаписатьВЛог(ЛогФайл,КудаСохранять,"Ошибка при проведении "+СокрЛП(Выборка.Регистратор)+"ОписаниеОшибки= "+ОписаниеОшибки());
               Сообщить("Ошибка при проведении "+СокрЛП(Выборка.Регистратор)+"ОписаниеОшибки= "+ОписаниеОшибки());
               Сообщить("==ОписаниеОшибки= "+ОписаниеОшибки());
           КонецПопытки;
       КонецЦикла;
   КонецЕсли;

   
   ЗаписатьВЛог(ЛогФайл,КудаСохранять,"*********************** Конец процедуры ***********************");

КонецПроцедуры //  ДействияПослеЗакрытияСмены()
4 Рэйв
 
13.09.12
13:35
Может в исключения вываливается
5 Reset
 
13.09.12
13:43
В "ОбработкаЧековККМ" проверь соответвие количества НачатьТранзакцию и Зафиксировать (отменить) транзакцию.
6 Reset
 
13.09.12
13:44
Для теста в начало ДействияПослеЗакрытияСмены помести
Сообщить(ТранзакцияАктивна());
7 МастерВопросов
 
13.09.12
13:49
(6) сейчас попробую
(4) нет, я вижу на экране сообщения "Перепровели Розничная продажа чек 00000000422 от 13.09.2012 16:47:00" и срабатывают точки останова внутри модуля перепроводимого документа.
8 МастерВопросов
 
13.09.12
13:52
(6) ТранзакцияАктивна() = ИСТИНА

внутри моей  "ДействияПослеЗакрытияСмены()"
9 Reset
 
13.09.12
13:53
(8) Ну вот и ответ
10 Reset
 
13.09.12
13:53
"распространяется на процедуры, не входящие в саму транзакцию"

==> Входящие
11 МастерВопросов
 
13.09.12
13:58
(10) сейчас буду ловить с помощью "ТранзакцияАктивна()" где эта транзакция включается и где потом отменяется ?
12 МастерВопросов
 
13.09.12
14:13
(11) нашел.

Процедура ОбработкаЧековККМ()
   ОтменитьТранзакцию = Ложь;
   НачатьТранзакцию();
   ...
   Если РезультатЗапроса.Пустой() Тогда
       ТекстСообщения = "За кассовую смену не продано ни одного товара по выбранной кассе ККМ.";
       ОбщегоНазначения.СообщитьОбОшибке(ТекстСообщения);
       ОтменитьТранзакцию = Истина;
   Иначе
       ...
       Если ОтменитьТранзакцию Тогда
           ОтменитьТранзакцию();
       Иначе
           ЗафиксироватьТранзакцию();
       КонецЕсли;
   КонецЕсли;
КонецПроцедуры // ОбработкаЧековККМ()


Код типовой.
13 МихаилМ
 
13.09.12
14:22
если база клиентсерверная можно
изолировать транзакции фоновыми заданиями
14 Reset
 
13.09.12
14:23
(12) Ну да, отмена реально не выполняется в определенной ветке
15 Reset
 
13.09.12
14:25
Типовой код тоже люди пишут :)