Created
December 24, 2018 15:06
-
-
Save FragsterAt/30a1e89ae709b12d16903ff9eeca6469 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#Область БазоваяФункциональность | |
Функция ПолучитьМаркиPDF417(Знач ДанныеОМарках, РегистрироватьОшибкиВЖурнале = Ложь) Экспорт | |
Если ДанныеОМарках = Неопределено Или ДанныеОМарках.Количество() = 0 Тогда | |
Возврат Новый Соответствие; | |
КонецЕсли; | |
// Определяем параметры выполнения. | |
Если ДанныеОМарках.Количество() < 1000 Тогда | |
ЧислоПотоков = 1; | |
Иначе | |
ОбъектРасширения = АСФРасширенияФункционала.ПолучитьОбъектРасширения(); | |
ЧислоПотоков = Неопределено; | |
Если ОбъектРасширения <> Неопределено Тогда | |
Попытка | |
ЧислоПотоков = ОбъектРасширения.ПолучитьЧислоЯдерПроцессора(); | |
Если ЧислоПотоков = Неопределено Тогда | |
ОписаниеОшибки = ОбъектРасширения.ОписаниеОшибки(); | |
КонецЕсли; | |
Исключение | |
ОписаниеОшибки = ОписаниеОшибки(); | |
КонецПопытки; | |
Иначе | |
ОписаниеОшибки = """Не удалось подключить внешнюю компоненту лицензирования"""; | |
КонецЕсли; | |
Если ЧислоПотоков = Неопределено Тогда | |
ОписаниеОшибки = АСФОбщегоНазначенияКлиентСервер.ПодставитьПараметрыВСтроку("Не удалось получить информацию о количестве ядер сервера по причине: ""%1""" + Символы.ПС + "Получение/генерация марок будут выполнены в однопоточном режиме", ОписаниеОшибки); | |
ЗаписьЖурналаРегистрации("АСФ. Генерация марок", УровеньЖурналаРегистрации.Предупреждение, Метаданные.Справочники.АСФМаркиPDF417,, ОписаниеОшибки, РежимТранзакцииЗаписиЖурналаРегистрации.Независимая); | |
ЧислоПотоков = 1; | |
ИначеЕсли АСФОбщегоНазначенияКлиентСервер.ИнформационнаяБазаФайловая() Тогда | |
ЧислоПотоков = Мин(ЧислоПотоков, ?(АСФОбщегоНазначенияПовторноеИспользование.ФоновыеЗаданияТребуютОбработкиОжидания() = Истина, 1, 2)); | |
КонецЕсли; | |
КонецЕсли; | |
// Готовим данные для запуска. | |
ТаблицаДанныхМарокШаблон = Новый ТаблицаЗначений; | |
ТаблицаДанныхМарокШаблон.Колонки.Добавить("Код", Новый ОписаниеТипов("Строка",, Новый КвалификаторыСтроки(150))); | |
ТаблицаДанныхМарокШаблон.Колонки.Добавить("Владелец"); | |
ДанныеПоПотокам = Новый Массив; | |
МаксимальныйИндексПотока = ЧислоПотоков - 1; | |
Для ИндексПотока = 0 По МаксимальныйИндексПотока Цикл | |
Поток = Новый Структура("ТаблицаДанныхМарок, ИдентификаторФоновогоЗадания, АдресРезультата, ВыполненоУспешно, Результат", ТаблицаДанныхМарокШаблон.СкопироватьКолонки(),, ПоместитьВоВременноеХранилище(Неопределено, Новый УникальныйИдентификатор), Ложь, Новый Соответствие); | |
ДанныеПоПотокам.Добавить(Поток); | |
КонецЦикла; | |
КэшКодовМарок = Новый Соответствие; | |
ТекущийИндексПотока = 0; | |
Для Каждого ЭлементДанных Из ДанныеОМарках Цикл | |
Если ТипЗнч(ЭлементДанных) = Тип("Строка") Тогда | |
КодМарки = ЭлементДанных; | |
Владелец = Неопределено; | |
Иначе | |
КодМарки = ЭлементДанных.Код; | |
Владелец = ЭлементДанных.Владелец; | |
КонецЕсли; | |
КодМарки = ВРег(КодМарки); | |
Если Не ЗначениеЗаполнено(КодМарки) Тогда | |
Продолжить; | |
КонецЕсли; | |
// Если код марки уже встречался (не знаю, почему такое может быть, но раз ранее была предварительная свёртка массива, считаем что это неспроста) - игнорируем строку данных. Ибо нехер. | |
// Во избежание пересечения ключей блокировок и изобретания космических кораблей на ровном месте. | |
Если КэшКодовМарок.Получить(КодМарки) <> Неопределено Тогда | |
Продолжить; | |
КонецЕсли; | |
КэшКодовМарок.Вставить(КодМарки, Истина); | |
ТекущийПоток = ДанныеПоПотокам[ТекущийИндексПотока]; | |
ТекущийИндексПотока = ?(ТекущийИндексПотока = МаксимальныйИндексПотока, 0, ТекущийИндексПотока + 1); | |
НоваяСтрока = ТекущийПоток.ТаблицаДанныхМарок.Добавить(); | |
НоваяСтрока.Код = КодМарки; | |
НоваяСтрока.Владелец = Владелец; | |
КонецЦикла; | |
// Запуск потоков на исполнение. | |
МассивЗаданийНаОжидание = Новый Массив; | |
Для ИндексПотока = 0 По МаксимальныйИндексПотока Цикл | |
ТекущийПоток = ДанныеПоПотокам[ИндексПотока]; | |
Если ИндексПотока = МаксимальныйИндексПотока Тогда | |
// Выполнение в основном потоке. | |
СоответствиеМарок = ПолучитьМаркиPDF417Служебный(ТекущийПоток.ТаблицаДанныхМарок, РегистрироватьОшибкиВЖурнале, Ложь); | |
ТекущийПоток.ВыполненоУспешно = Истина; | |
Иначе | |
// Выполнение в фоновом потоке. | |
ПараметрыВыполнения = Новый Массив; | |
ПараметрыВыполнения.Добавить(ТекущийПоток.ТаблицаДанныхМарок); | |
ПараметрыВыполнения.Добавить(ТекущийПоток.АдресРезультата); | |
ПараметрыВыполнения.Добавить(РегистрироватьОшибкиВЖурнале); | |
ПараметрыВыполнения.Добавить(Ложь); | |
ФоновоеЗадание = ФоновыеЗадания.Выполнить("АСФМаркировкаБазоваяФункциональность.ПолучитьМаркиPDF417ВФоне", ПараметрыВыполнения,, "АСФ. Получение/генерация марок"); | |
ТекущийПоток.ИдентификаторФоновогоЗадания = ФоновоеЗадание.УникальныйИдентификатор; | |
МассивЗаданийНаОжидание.Добавить(ФоновоеЗадание); | |
КонецЕсли; | |
КонецЦикла; | |
// Ждём завершения, фиксируем результаты. | |
Пока МассивЗаданийНаОжидание.Количество() > 0 Цикл | |
Попытка | |
ФоновыеЗадания.ОжидатьЗавершения(МассивЗаданийНаОжидание); | |
Исключение | |
КонецПопытки; | |
МассивЗаданийНаОжидание.Очистить(); | |
Для ИндексПотока = 0 По МаксимальныйИндексПотока - 1 Цикл | |
ТекущийПоток = ДанныеПоПотокам[ИндексПотока]; | |
Если Не ЗначениеЗаполнено(ТекущийПоток.ИдентификаторФоновогоЗадания) Тогда | |
Продолжить; | |
КонецЕсли; | |
ФоновоеЗадание = ФоновыеЗадания.НайтиПоУникальномуИдентификатору(ТекущийПоток.ИдентификаторФоновогоЗадания); | |
Если ФоновоеЗадание = Неопределено Тогда | |
ТекущийПоток.ИдентификаторФоновогоЗадания = Неопределено; | |
ОписаниеОшибки = "Фоновое задание не найдено"; | |
Иначе | |
Если ФоновоеЗадание.Состояние = СостояниеФоновогоЗадания.Активно Тогда | |
МассивЗаданийНаОжидание.Добавить(ФоновоеЗадание); | |
Продолжить; | |
КонецЕсли; | |
ТекущийПоток.ИдентификаторФоновогоЗадания = Неопределено; | |
Если ФоновоеЗадание.Состояние = СостояниеФоновогоЗадания.Завершено Тогда | |
Результат = ПолучитьИзВременногоХранилища(ТекущийПоток.АдресРезультата); | |
Если ТипЗнч(Результат) = Тип("Соответствие") Тогда | |
ТекущийПоток.Результат = Результат; | |
ТекущийПоток.ВыполненоУспешно = Истина; | |
Продолжить; | |
КонецЕсли; | |
ОписаниеОшибки = "Не удалось получить результат работы фонового задания"; | |
ИначеЕсли ФоновоеЗадание.Состояние = СостояниеФоновогоЗадания.Отменено Тогда | |
ОписаниеОшибки = "Фоновое задание было отменено"; | |
Иначе | |
ОписаниеОшибки = КраткоеПредставлениеОшибки(ФоновоеЗадание.ИнформацияОбОшибке); | |
КонецЕсли; | |
КонецЕсли; | |
ОписаниеОшибки = АСФОбщегоНазначенияКлиентСервер.ПодставитьПараметрыВСтроку("Получение/генерацию марок не удалось выполнить в фоновом режиме по причине: ""%1"". Процедура будет продолжена в основном потоке", ОписаниеОшибки); | |
ЗаписьЖурналаРегистрации("АСФ. Генерация марок", УровеньЖурналаРегистрации.Предупреждение, Метаданные.Справочники.АСФМаркиPDF417,, ОписаниеОшибки, РежимТранзакцииЗаписиЖурналаРегистрации.Независимая); | |
КонецЦикла; | |
КонецЦикла; | |
// Выполненяем в основном потоке неудавшиеся фоновые. | |
Для ИндексПотока = 0 По МаксимальныйИндексПотока - 1 Цикл | |
ТекущийПоток = ДанныеПоПотокам[ИндексПотока]; | |
Если ТекущийПоток.ВыполненоУспешно Тогда | |
Продолжить; | |
КонецЕсли; | |
ТекущийПоток.Результат = ПолучитьМаркиPDF417Служебный(ТекущийПоток.ТаблицаДанныхМарок, РегистрироватьОшибкиВЖурнале, Истина); | |
КонецЦикла; | |
// Собираем результат. | |
Для ИндексПотока = 0 По МаксимальныйИндексПотока - 1 Цикл | |
ТекущийПоток = ДанныеПоПотокам[ИндексПотока]; | |
РезультатЛокальный = ТекущийПоток.Результат; | |
Для Каждого ЭлементСоответствия Из РезультатЛокальный Цикл | |
СоответствиеМарок.Вставить(ЭлементСоответствия.Ключ, ЭлементСоответствия.Значение); | |
КонецЦикла; | |
КонецЦикла; | |
Возврат СоответствиеМарок; | |
КонецФункции | |
Процедура ПолучитьМаркиPDF417ВФоне(Знач ТаблицаДанныхМарок = Неопределено, АдресРезультата, РегистрироватьОшибкиВЖурнале = Ложь, ОтключатьИспользованиеЖурнала = Истина) Экспорт | |
Результат = ПолучитьМаркиPDF417Служебный(ТаблицаДанныхМарок, РегистрироватьОшибкиВЖурнале, ОтключатьИспользованиеЖурнала); | |
ПоместитьВоВременноеХранилище(Результат, АдресРезультата); | |
КонецПроцедуры | |
Функция ПолучитьМаркиPDF417Служебный(Знач ТаблицаДанныхМарок = Неопределено, РегистрироватьОшибкиВЖурнале = Ложь, ОтключатьИспользованиеЖурнала = Истина) Экспорт | |
Если ТаблицаДанныхМарок = Неопределено Или ТаблицаДанныхМарок.Количество() = 0 Тогда | |
Возврат Новый Соответствие; | |
КонецЕсли; | |
СоответствиеМарок = Новый Соответствие; | |
СоответствиеМарокСПустымКодом = Новый Соответствие; | |
СоответствиеВладельцевИКодовАП = Новый Соответствие; | |
УстановитьПривилегированныйРежим(Истина); | |
УстановитьБлокировкуИнициироватьСоответствия(ТаблицаДанныхМарок, СоответствиеМарок, СоответствиеМарокСПустымКодом, СоответствиеВладельцевИКодовАП); | |
КоличествоМарок = ТаблицаДанныхМарок.Количество(); | |
РегистрацияБылаОтключена = Ложь; | |
ИспользованиеСобытияЖурналаРегистрации = Новый ИспользованиеСобытияЖурналаРегистрации(); | |
Для СчетчикМарок = 1 По КоличествоМарок Цикл | |
ИндексМарки = КоличествоМарок - СчетчикМарок; | |
ЭлементДанных = ТаблицаДанныхМарок[ИндексМарки]; | |
КодМарки = ЭлементДанных.Код; | |
ВладелецМарки = ЭлементДанных.Владелец; | |
ТаблицаДанныхМарок.Удалить(ИндексМарки); | |
Если ТипЗнч(ВладелецМарки) = Тип("Строка") Тогда | |
КодАП = ВладелецМарки; | |
ИначеЕсли ВладелецМарки = Неопределено Тогда | |
КодАП = Неопределено; | |
Иначе | |
КодАП = СоответствиеВладельцевИКодовАП.Получить(ВладелецМарки); | |
КонецЕсли; | |
МаркаСсылка = СоответствиеМарок.Получить(КодМарки); | |
Если МаркаСсылка <> Неопределено Тогда | |
МаркаСсылкаСПустымКодом = СоответствиеМарокСПустымКодом.Получить(КодМарки); | |
Если МаркаСсылкаСПустымКодом = Неопределено Или КодАП = Неопределено Тогда | |
Продолжить; | |
КонецЕсли; | |
КонецЕсли; | |
Если РегистрацияБылаОтключена И СчетчикМарок = КоличествоМарок Тогда | |
ИспользованиеСобытияЖурналаРегистрации.Использование = Истина; | |
УстановитьИспользованиеСобытияЖурналаРегистрации("_$Data$_.New", ИспользованиеСобытияЖурналаРегистрации); | |
УстановитьИспользованиеСобытияЖурналаРегистрации("_$Data$_.Update", ИспользованиеСобытияЖурналаРегистрации); | |
РегистрацияБылаОтключена = Ложь; | |
ИначеЕсли РегистрацияБылаОтключена = Ложь И СчетчикМарок > 1 И ОтключатьИспользованиеЖурнала = Истина Тогда | |
ИспользованиеСобытияЖурналаРегистрации.Использование = Ложь; | |
УстановитьИспользованиеСобытияЖурналаРегистрации("_$Data$_.New", ИспользованиеСобытияЖурналаРегистрации); | |
УстановитьИспользованиеСобытияЖурналаРегистрации("_$Data$_.Update", ИспользованиеСобытияЖурналаРегистрации); | |
РегистрацияБылаОтключена = Истина; | |
КонецЕсли; | |
Попытка | |
Если ЗначениеЗаполнено(МаркаСсылка) Тогда | |
МаркаОбъект = МаркаСсылка.ПолучитьОбъект(); | |
Иначе | |
МаркаОбъект = Справочники.АСФМаркиPDF417.СоздатьЭлемент(); | |
МаркаОбъект.Наименование = КодМарки; | |
КонецЕсли; | |
Если КодАП <> Неопределено Тогда | |
МаркаОбъект.Код = КодАП; | |
КонецЕсли; | |
Если Не ЗначениеЗаполнено(МаркаОбъект.Код) И СтрДлина(МаркаОбъект.Наименование) <> 150 Тогда | |
МаркаОбъект.Код = АСФОбщегоНазначенияКлиентСервер.ПолучитьКодАПИзКодаPDF417(МаркаОбъект.Наименование); | |
КонецЕсли; | |
МаркаОбъект.ОбменДанными.Загрузка = Истина; | |
МаркаОбъект.Записать(); | |
СоответствиеМарок.Вставить(КодМарки,МаркаОбъект.Ссылка); | |
Исключение | |
Если РегистрироватьОшибкиВЖурнале = Истина Тогда | |
ИнформацияОбОшибке = ИнформацияОбОшибке(); | |
ИмяСобытия = "Не удалось записать марку"; | |
КомментарийЖурнала = ИмяСобытия + Символы.ПС + ПодробноеПредставлениеОшибки(ИнформацияОбОшибке); | |
ЗаписьЖурналаРегистрации(ИмяСобытия, УровеньЖурналаРегистрации.Ошибка, Метаданные.Справочники.АСФМаркиPDF417,, КомментарийЖурнала, РежимТранзакцииЗаписиЖурналаРегистрации.Независимая); | |
КонецЕсли; | |
ЗафиксироватьТранзакцию(); | |
УстановитьБлокировкуИнициироватьСоответствия(ТаблицаДанныхМарок, СоответствиеМарок, СоответствиеМарокСПустымКодом, СоответствиеВладельцевИКодовАП); | |
КонецПопытки; | |
КонецЦикла; | |
Если РегистрацияБылаОтключена = Истина Тогда | |
ИспользованиеСобытияЖурналаРегистрации.Использование = Истина; | |
УстановитьИспользованиеСобытияЖурналаРегистрации("_$Data$_.New", ИспользованиеСобытияЖурналаРегистрации); | |
УстановитьИспользованиеСобытияЖурналаРегистрации("_$Data$_.Update", ИспользованиеСобытияЖурналаРегистрации); | |
КонецЕсли; | |
ЗафиксироватьТранзакцию(); | |
Возврат СоответствиеМарок; | |
КонецФункции | |
Процедура УстановитьБлокировкуИнициироватьСоответствия(ТаблицаДанныхМарок, СоответствиеМарок, СоответствиеМарокСПустымКодом, СоответствиеВладельцевИКодовАП) | |
УстановитьПривилегированныйРежим(Истина); | |
НачатьТранзакцию(); | |
Блокировка = Новый БлокировкаДанных; | |
ЭлементБлокировки = Блокировка.Добавить("Справочник.АСФМаркиPDF417"); | |
ЭлементБлокировки.Режим = РежимБлокировкиДанных.Исключительный; | |
ЭлементБлокировки.ИсточникДанных = ТаблицаДанныхМарок; | |
ЭлементБлокировки.ИспользоватьИзИсточникаДанных("Наименование", "Код"); | |
Блокировка.Заблокировать(); | |
МассивИдентификаторовМарок = ТаблицаДанныхМарок.ВыгрузитьКолонку("Код"); | |
Запрос = Новый Запрос; | |
Запрос.Текст = | |
"ВЫБРАТЬ | |
| АСФМаркиPDF417.Ссылка КАК Ссылка, | |
| АСФМаркиPDF417.Наименование КАК Код, | |
| АСФМаркиPDF417.Код КАК АлкогольнаяПродукцияКод | |
|ИЗ | |
| Справочник.АСФМаркиPDF417 КАК АСФМаркиPDF417 | |
|ГДЕ | |
| АСФМаркиPDF417.Наименование В(&МассивИдентификаторовМарок)"; | |
Запрос.УстановитьПараметр("МассивИдентификаторовМарок", МассивИдентификаторовМарок); | |
Выборка = Запрос.Выполнить().Выбрать(); | |
Пока Выборка.Следующий() Цикл | |
СоответствиеМарок.Вставить(ВРЕГ(Выборка.Код), Выборка.Ссылка); | |
Если Не ЗначениеЗаполнено(Выборка.АлкогольнаяПродукцияКод) Тогда | |
СоответствиеМарокСПустымКодом.Вставить(ВРЕГ(Выборка.Код), Выборка.Ссылка); | |
КонецЕсли; | |
КонецЦикла; | |
МассивВладельцевМарок = Новый Массив; | |
Для Каждого ЭлементДанных Из ТаблицаДанныхМарок Цикл | |
КодМарки = ЭлементДанных.Код; | |
МаркаСсылка = СоответствиеМарок.Получить(КодМарки); | |
Если МаркаСсылка <> Неопределено Тогда | |
МаркаСсылка = СоответствиеМарокСПустымКодом.Получить(КодМарки); | |
Если МаркаСсылка = Неопределено Тогда | |
Продолжить; | |
КонецЕсли; | |
КонецЕсли; | |
ВладелецМарки = ЭлементДанных.Владелец; | |
Если ТипЗнч(ВладелецМарки) = Тип("Строка") Или ВладелецМарки = Неопределено Тогда | |
Продолжить; | |
КонецЕсли; | |
МассивВладельцевМарок.Добавить(ВладелецМарки); | |
КонецЦикла; | |
МассивВладельцевМарок = АСФОбщегоНазначенияКлиентСервер.ВыполнитьСверткуМассива(МассивВладельцевМарок, Истина); | |
Если МассивВладельцевМарок.Количество() > 0 Тогда | |
Если ТипЗнч(МассивВладельцевМарок[0]) = Тип("СправочникСсылка.АСФАлкогольнаяПродукция") Тогда | |
Запрос = Новый Запрос; | |
Запрос.Текст = | |
"ВЫБРАТЬ | |
| СправочникАлкогольнаяПродукция.Ссылка КАК Ссылка, | |
| СправочникАлкогольнаяПродукция.Код КАК Код | |
|ИЗ | |
| Справочник.АСФАлкогольнаяПродукция КАК СправочникАлкогольнаяПродукция | |
|ГДЕ | |
| СправочникАлкогольнаяПродукция.Ссылка В(&МассивВладельцевМарок)"; | |
Запрос.УстановитьПараметр("МассивВладельцевМарок", МассивВладельцевМарок); | |
Выборка = Запрос.Выполнить().Выбрать(); | |
Пока Выборка.Следующий() Цикл | |
СоответствиеВладельцевИКодовАП.Вставить(Выборка.Ссылка, Выборка.Код); | |
КонецЦикла; | |
ИначеЕсли ТипЗнч(МассивВладельцевМарок[0]) = Тип("СправочникСсылка.Номенклатура") Тогда | |
Запрос = Новый Запрос; | |
Запрос.Текст = | |
"ВЫБРАТЬ | |
| СправочникНоменклатура.Ссылка КАК Ссылка, | |
| ЕСТЬNULL(АСФСоответствияАлкогольнойПродукцииИНоменклатуры.АлкогольнаяПродукция.Код, СправочникНоменклатура.АСФКодЕГАИС) КАК Код | |
|ИЗ | |
| РегистрСведений.АСФСоответствияАлкогольнойПродукцииИНоменклатуры КАК АСФСоответствияАлкогольнойПродукцииИНоменклатуры | |
| ЛЕВОЕ СОЕДИНЕНИЕ Справочник.Номенклатура КАК СправочникНоменклатура | |
| ПО АСФСоответствияАлкогольнойПродукцииИНоменклатуры.Номенклатура = СправочникНоменклатура.Ссылка | |
|ГДЕ | |
| СправочникНоменклатура.Ссылка В(&МассивВладельцевМарок)"; | |
Запрос.УстановитьПараметр("МассивВладельцевМарок", МассивВладельцевМарок); | |
Выборка = Запрос.Выполнить().Выбрать(); | |
Пока Выборка.Следующий() Цикл | |
СоответствиеВладельцевИКодовАП.Вставить(Выборка.Ссылка, Выборка.Код); | |
КонецЦикла; | |
КонецЕсли; | |
КонецЕсли; | |
КонецПроцедуры | |
Функция ПолучитьМаркуPDF417(Знач КодМарки, РегистрироватьОшибкиВЖурнале = Ложь, Знач ВладелецМарки=Неопределено) Экспорт | |
Если Не ЗначениеЗаполнено(КодМарки) Тогда | |
Возврат Справочники.АСФМаркиPDF417.ПустаяСсылка(); | |
КонецЕсли; | |
ДанныеОМарках = Новый Массив; | |
Если ЗначениеЗаполнено(ВладелецМарки) Тогда | |
ДанныеОМарке=Новый Структура; | |
ДанныеОМарке.Вставить("Код",КодМарки); | |
ДанныеОМарке.Вставить("Владелец",ВладелецМарки); | |
ДанныеОМарках.Добавить(ДанныеОМарке); | |
Иначе | |
ДанныеОМарках.Добавить(КодМарки); | |
КонецЕсли; | |
СоответствиеМарок = ПолучитьМаркиPDF417(ДанныеОМарках, РегистрироватьОшибкиВЖурнале); | |
Возврат СоответствиеМарок.Получить(КодМарки); | |
КонецФункции | |
#КонецОбласти |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment