v3.0.0.4: DDD-рефакторинг, динамические заголовки, архив версий
This commit is contained in:
@@ -45,10 +45,46 @@
|
|||||||
|
|
||||||
#КонецОбласти
|
#КонецОбласти
|
||||||
|
|
||||||
#Область РаботаСExcel
|
#Область ЧтениеExcel_Домен
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// ДОМЕН: Чтение Excel
|
||||||
|
// Ответственность: открытие файла, поиск листов, чтение ячеек
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
// Создаёт COM-объект Excel и открывает файл.
|
||||||
|
// Возвращает структуру {Книга, Excel} или Неопределено при ошибке.
|
||||||
&НаКлиенте
|
&НаКлиенте
|
||||||
Функция ПрочитатьЯчейку(Лист, Строка, Колонка, ФИО, ВидДанных)
|
Функция ОткрытьФайлExcel(ПутьКФайлу)
|
||||||
|
Попытка
|
||||||
|
Excel = Новый COMОбъект("Excel.Application");
|
||||||
|
Excel.Visible = Ложь;
|
||||||
|
Excel.DisplayAlerts = Ложь;
|
||||||
|
Книга = Excel.Workbooks.Open(ПутьКФайлу);
|
||||||
|
Возврат Новый Структура("Книга, Excel", Книга, Excel);
|
||||||
|
Исключение
|
||||||
|
Сообщить("Не удалось открыть Excel: " + ОписаниеОшибки());
|
||||||
|
Возврат Неопределено;
|
||||||
|
КонецПопытки;
|
||||||
|
КонецФункции
|
||||||
|
|
||||||
|
// Закрывает книгу и приложение Excel, удаляет временный файл.
|
||||||
|
&НаКлиенте
|
||||||
|
Процедура ЗакрытьExcel(КонтекстExcel, ВременныйФайл)
|
||||||
|
Если КонтекстExcel = Неопределено Тогда Возврат; КонецЕсли;
|
||||||
|
Попытка
|
||||||
|
КонтекстExcel.Книга.Close(Ложь);
|
||||||
|
КонтекстExcel.Excel.Quit();
|
||||||
|
Исключение
|
||||||
|
КонецПопытки;
|
||||||
|
Если ЗначениеЗаполнено(ВременныйФайл) Тогда
|
||||||
|
УдалитьФайлы(ВременныйФайл);
|
||||||
|
КонецЕсли;
|
||||||
|
КонецПроцедуры
|
||||||
|
|
||||||
|
// Читает числовое значение ячейки с обработкой ошибок.
|
||||||
|
&НаКлиенте
|
||||||
|
Функция ПрочитатьЯчейкуЧисло(Лист, Строка, Колонка, КонтекстОшибки)
|
||||||
Попытка
|
Попытка
|
||||||
Значение = Лист.Cells(Строка, Колонка).Value;
|
Значение = Лист.Cells(Строка, Колонка).Value;
|
||||||
Если Значение = Неопределено ИЛИ Значение = "" Тогда
|
Если Значение = Неопределено ИЛИ Значение = "" Тогда
|
||||||
@@ -56,15 +92,16 @@
|
|||||||
КонецЕсли;
|
КонецЕсли;
|
||||||
Возврат Число(Значение);
|
Возврат Число(Значение);
|
||||||
Исключение
|
Исключение
|
||||||
Сообщить("Ошибка: " + ФИО + " | " + ВидДанных
|
Сообщить("Ошибка чтения числа: " + КонтекстОшибки
|
||||||
+ " | строка " + Строка + " колонка " + Колонка
|
+ " | строка " + Строка + " колонка " + Колонка
|
||||||
+ " | значение: """ + Значение + """ | " + ОписаниеОшибки());
|
+ " | значение: """ + Значение + """ | " + ОписаниеОшибки());
|
||||||
Возврат 0;
|
Возврат 0;
|
||||||
КонецПопытки;
|
КонецПопытки;
|
||||||
КонецФункции
|
КонецФункции
|
||||||
|
|
||||||
|
// Читает строковое значение ячейки.
|
||||||
&НаКлиенте
|
&НаКлиенте
|
||||||
Функция ПрочитатьСтроку(Лист, Строка, Колонка)
|
Функция ПрочитатьЯчейкуСтрока(Лист, Строка, Колонка)
|
||||||
Попытка
|
Попытка
|
||||||
Значение = Лист.Cells(Строка, Колонка).Value;
|
Значение = Лист.Cells(Строка, Колонка).Value;
|
||||||
Если Значение = Неопределено Тогда Возврат ""; КонецЕсли;
|
Если Значение = Неопределено Тогда Возврат ""; КонецЕсли;
|
||||||
@@ -74,6 +111,67 @@
|
|||||||
КонецПопытки;
|
КонецПопытки;
|
||||||
КонецФункции
|
КонецФункции
|
||||||
|
|
||||||
|
// Ищет лист по имени (регистронезависимо).
|
||||||
|
&НаКлиенте
|
||||||
|
Функция НайтиЛист(Книга, ИмяЛиста)
|
||||||
|
Для Каждого Лист Из Книга.Sheets Цикл
|
||||||
|
Если ВРег(Лист.Name) = ВРег(ИмяЛиста) Тогда
|
||||||
|
Возврат Лист;
|
||||||
|
КонецЕсли;
|
||||||
|
КонецЦикла;
|
||||||
|
Возврат Неопределено;
|
||||||
|
КонецФункции
|
||||||
|
|
||||||
|
#КонецОбласти
|
||||||
|
|
||||||
|
#Область МаппингЗаголовков_Домен
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// ДОМЕН: Маппинг заголовков
|
||||||
|
// Ответственность: сопоставление имён колонок Excel с полями данных
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
// Создаёт Соответствие для поиска колонок по имени заголовка.
|
||||||
|
// Ключ — имя заголовка (нижний регистр), значение — номер колонки (0-based).
|
||||||
|
&НаКлиенте
|
||||||
|
Функция СоздатьИндексЗаголовков(Лист, НомерСтрокиЗаголовков)
|
||||||
|
Индекс = Новый Соответствие;
|
||||||
|
Для Колонка = 0 По Лист.Cells(НомерСтрокиЗаголовков, 1).End(-4161).Column - 1 Цикл
|
||||||
|
Имя = СокрЛП(НРег(Лист.Cells(НомерСтрокиЗаголовков, Колонка + 1).Value));
|
||||||
|
Если ЗначениеЗаполнено(Имя) Тогда
|
||||||
|
Индекс.Вставить(Имя, Колонка);
|
||||||
|
КонецЕсли;
|
||||||
|
КонецЦикла;
|
||||||
|
Возврат Индекс;
|
||||||
|
КонецФункции
|
||||||
|
|
||||||
|
// Находит номер колонки по ключевому слову в заголовке.
|
||||||
|
// Возвращает номер колонки (0-based) или -1 если не найдено.
|
||||||
|
&НаКлиенте
|
||||||
|
Функция НайтиКолонкуПоЗаголовку(ИндексЗаголовков, КлючевоеСлово)
|
||||||
|
Ключ = НРег(КлючевоеСлово);
|
||||||
|
Для Каждого Эл Из ИндексЗаголовков Цикл
|
||||||
|
Если СтрНайти(Эл.Ключ, Ключ) > 0 Тогда
|
||||||
|
Возврат Эл.Значение;
|
||||||
|
КонецЕсли;
|
||||||
|
КонецЦикла;
|
||||||
|
Возврат -1;
|
||||||
|
КонецФункции
|
||||||
|
|
||||||
|
// Определяет номер строки первого сотрудника (первая непустая строка после заголовков).
|
||||||
|
&НаКлиенте
|
||||||
|
Функция НайтиСтрокуПервогоСотрудника(ЛистРасчет, НомерСтрокиЗаголовков)
|
||||||
|
Для Ном = НомерСтрокиЗаголовков + 1 По ЛистРасчет.Rows.Count Цикл
|
||||||
|
Значение = ЛистРасчет.Cells(Ном, 1).Value;
|
||||||
|
Если ЗначениеЗаполнено(Значение)
|
||||||
|
И Не СтрНачинаетсяС(ВРег(СокрЛП("" + Значение)), "ИТОГО") Тогда
|
||||||
|
Возврат Ном;
|
||||||
|
КонецЕсли;
|
||||||
|
КонецЦикла;
|
||||||
|
Возврат -1;
|
||||||
|
КонецФункции
|
||||||
|
|
||||||
|
// Извлекает значение из текста вида "ИНН 990100718541" → "990100718541"
|
||||||
&НаКлиенте
|
&НаКлиенте
|
||||||
Функция ИзвлечьЗначениеИзТекста(Текст, Префикс)
|
Функция ИзвлечьЗначениеИзТекста(Текст, Префикс)
|
||||||
Если Не ЗначениеЗаполнено(Текст) Тогда Возврат ""; КонецЕсли;
|
Если Не ЗначениеЗаполнено(Текст) Тогда Возврат ""; КонецЕсли;
|
||||||
@@ -82,183 +180,230 @@
|
|||||||
Возврат СокрЛП(Сред(Текст, Позиция + СтрДлина(Префикс)));
|
Возврат СокрЛП(Сред(Текст, Позиция + СтрДлина(Префикс)));
|
||||||
КонецФункции
|
КонецФункции
|
||||||
|
|
||||||
|
#КонецОбласти
|
||||||
|
|
||||||
|
#Область ЧтениеДанныхСотрудника_Домен
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// ДОМЕН: Чтение данных сотрудника
|
||||||
|
// Ответственность: извлечение данных из строки листа "Расчет"
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
// Читает одну строку данных сотрудника из листа "Расчет".
|
||||||
|
// ИндексЗаголовков — Соответствие для динамического поиска колонок.
|
||||||
|
&НаКлиенте
|
||||||
|
Функция ПрочитатьСтрокуРасчета(ЛистРасчет, Ном, ФИО, ИндексЗаголовков)
|
||||||
|
Строка = Новый Структура;
|
||||||
|
Строка.Вставить("ФИО", ФИО);
|
||||||
|
|
||||||
|
// Поиск колонок по заголовкам
|
||||||
|
КолДолжность = НайтиКолонкуПоЗаголовку(ИндексЗаголовков, "должность");
|
||||||
|
КолСчетБК = НайтиКолонкуПоЗаголовку(ИндексЗаголовков, "счет");
|
||||||
|
КолВидЗанятости = НайтиКолонкуПоЗаголовку(ИндексЗаголовков, "вид занятости");
|
||||||
|
КолОклад = НайтиКолонкуПоЗаголовку(ИндексЗаголовков, "оклад");
|
||||||
|
КолСтавки = НайтиКолонкуПоЗаголовку(ИндексЗаголовков, "ставок");
|
||||||
|
КолОтработано = НайтиКолонкуПоЗаголовку(ИндексЗаголовков, "отработано");
|
||||||
|
КолИтогоНачислено = НайтиКолонкуПоЗаголовку(ИндексЗаголовков, "итого начислено");
|
||||||
|
КолНДФЛ = НайтиКолонкуПоЗаголовку(ИндексЗаголовков, "ндфл");
|
||||||
|
КолИтогоУдержано = НайтиКолонкуПоЗаголовку(ИндексЗаголовков, "итого удержано");
|
||||||
|
КолВсегоНаРуки = НайтиКолонкуПоЗаголовку(ИндексЗаголовков, "всего на руки");
|
||||||
|
|
||||||
|
Строка.Вставить("Должность", ПрочитатьЯчейкуСтроку(ЛистРасчет, Ном, КолДолжность));
|
||||||
|
Строка.Вставить("СчетБК", ПрочитатьЯчейкуСтроку(ЛистРасчет, Ном, КолСчетБК));
|
||||||
|
Строка.Вставить("ВидЗанятости", ПрочитатьЯчейкуСтроку(ЛистРасчет, Ном, КолВидЗанятости));
|
||||||
|
Строка.Вставить("Оклад", ПрочитатьЯчейкуЧисло(ЛистРасчет, Ном, КолОклад, ФИО + " Оклад"));
|
||||||
|
Строка.Вставить("КоличествоСтавок", ПрочитатьЯчейкуЧисло(ЛистРасчет, Ном, КолСтавки, ФИО + " Ставки"));
|
||||||
|
Строка.Вставить("ОтработаноДней", ПрочитатьЯчейкуЧисло(ЛистРасчет, Ном, КолОтработано, ФИО + " Отработано"));
|
||||||
|
Строка.Вставить("ИтогоНачислено", ПрочитатьЯчейкуЧисло(ЛистРасчет, Ном, КолИтогоНачислено, ФИО + " Итого начислено"));
|
||||||
|
Строка.Вставить("НДФЛ", ПрочитатьЯчейкуЧисло(ЛистРасчет, Ном, КолНДФЛ, ФИО + " НДФЛ"));
|
||||||
|
Строка.Вставить("ИтогоУдержано", ПрочитатьЯчейкуЧисло(ЛистРасчет, Ном, КолИтогоУдержано, ФИО + " Итого удержано"));
|
||||||
|
Строка.Вставить("ВсегоНаРуки", ПрочитатьЯчейкуЧисло(ЛистРасчет, Ном, КолВсегоНаРуки, ФИО + " Всего на руки"));
|
||||||
|
|
||||||
|
Возврат Строка;
|
||||||
|
КонецФункции
|
||||||
|
|
||||||
|
// Читает страховые взносы из строки листа "Расчет".
|
||||||
|
&НаКлиенте
|
||||||
|
Функция ПрочитатьСтрокуВзносов(ЛистРасчет, Ном, ФИО, ИндексЗаголовков)
|
||||||
|
КолДТ6 = НайтиКолонкуПоЗаголовку(ИндексЗаголовков, "дт 6");
|
||||||
|
КолДТ4 = НайтиКолонкуПоЗаголовку(ИндексЗаголовков, "дт 4");
|
||||||
|
КолПФ = НайтиКолонкуПоЗаголовку(ИндексЗаголовков, "пф страховая");
|
||||||
|
КолФСС = НайтиКолонкуПоЗаголовку(ИндексЗаголовков, "фсс");
|
||||||
|
КолНСПЗ = НайтиКолонкуПоЗаголовку(ИндексЗаголовков, "нс и пз");
|
||||||
|
КолСВИтого = НайтиКолонкуПоЗаголовку(ИндексЗаголовков, "св итого");
|
||||||
|
|
||||||
|
СВ = ПрочитатьЯчейкуЧисло(ЛистРасчет, Ном, КолСВИтого, ФИО + " СВ итого");
|
||||||
|
Если СВ <= 0 Тогда Возврат Неопределено; КонецЕсли;
|
||||||
|
|
||||||
|
СтрВзносов = Новый Структура;
|
||||||
|
СтрВзносов.Вставить("ФИО", ФИО);
|
||||||
|
СтрВзносов.Вставить("ДТ6Процент", ПрочитатьЯчейкуЧисло(ЛистРасчет, Ном, КолДТ6, ФИО + " ДТ 6%"));
|
||||||
|
СтрВзносов.Вставить("ДТ4Процент", ПрочитатьЯчейкуЧисло(ЛистРасчет, Ном, КолДТ4, ФИО + " ДТ 4%"));
|
||||||
|
СтрВзносов.Вставить("ПФСтраховая", ПрочитатьЯчейкуЧисло(ЛистРасчет, Ном, КолПФ, ФИО + " ПФ"));
|
||||||
|
СтрВзносов.Вставить("ФССФОМС", ПрочитатьЯчейкуЧисло(ЛистРасчет, Ном, КолФСС, ФИО + " ФСС/ФОМС"));
|
||||||
|
СтрВзносов.Вставить("НСПЗ", ПрочитатьЯчейкуЧисло(ЛистРасчет, Ном, КолНСПЗ, ФИО + " НС и ПЗ"));
|
||||||
|
СтрВзносов.Вставить("Итого", СВ);
|
||||||
|
|
||||||
|
Возврат СтрВзносов;
|
||||||
|
КонецФункции
|
||||||
|
|
||||||
|
// Читает личные данные из листа сотрудника (шапка строк 0-3).
|
||||||
|
&НаКлиенте
|
||||||
|
Функция ПрочитатьЛичныеДанные(Книга, ФИО)
|
||||||
|
ЛичныеДанные = Новый Структура("ИНН, СНИЛС, Паспорт, Адрес", "", "", "", "");
|
||||||
|
|
||||||
|
ЛистСотрудника = НайтиЛист(Книга, ФИО);
|
||||||
|
Если ЛистСотрудника = Неопределено Тогда
|
||||||
|
Возврат ЛичныеДанные;
|
||||||
|
КонецЕсли;
|
||||||
|
|
||||||
|
ЛичныеДанные.ИНН = ИзвлечьЗначениеИзТекста(
|
||||||
|
ПрочитатьЯчейкуСтроку(ЛистСотрудника, 0, 10), "ИНН");
|
||||||
|
ЛичныеДанные.СНИЛС = ИзвлечьЗначениеИзТекста(
|
||||||
|
ПрочитатьЯчейкуСтроку(ЛистСотрудника, 1, 10), "СНИЛС");
|
||||||
|
ЛичныеДанные.Паспорт = ИзвлечьЗначениеИзТекста(
|
||||||
|
ПрочитатьЯчейкуСтроку(ЛистСотрудника, 2, 10), "Паспорт");
|
||||||
|
ЛичныеДанные.Адрес = ПрочитатьЯчейкуСтроку(ЛистСотрудника, 3, 10);
|
||||||
|
|
||||||
|
Возврат ЛичныеДанные;
|
||||||
|
КонецФункции
|
||||||
|
|
||||||
|
#КонецОбласти
|
||||||
|
|
||||||
|
#Область ОсновнаяПроцедура_Домен
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// ДОМЕН: Оркестрация загрузки
|
||||||
|
// Ответственность: координация всех этапов загрузки
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
&НаКлиенте
|
&НаКлиенте
|
||||||
Процедура ПрочитатьExcelНаКлиенте()
|
Процедура ПрочитатьExcelНаКлиенте()
|
||||||
|
|
||||||
Попытка
|
// Этап 1: Подготовка файла
|
||||||
СтатусЗагрузки = "Копирование файла...";
|
СтатусЗагрузки = "Копирование файла...";
|
||||||
Прогресс = 5;
|
Состояние("Копирование файла...", 5);
|
||||||
Состояние("Копирование файла...", 5);
|
|
||||||
|
|
||||||
ВременныйФайл = КаталогВременныхФайлов() + "temp_data.xls";
|
ВременныйФайл = КаталогВременныхФайлов() + "temp_data.xls";
|
||||||
КопироватьФайл(Объект.ПутьКФайлу, ВременныйФайл);
|
КопироватьФайл(Объект.ПутьКФайлу, ВременныйФайл);
|
||||||
|
|
||||||
СтатусЗагрузки = "Открытие Excel...";
|
// Этап 2: Открытие Excel
|
||||||
Прогресс = 10;
|
СтатусЗагрузки = "Открытие Excel...";
|
||||||
Состояние("Открытие Excel...", 10);
|
Состояние("Открытие Excel...", 10);
|
||||||
|
|
||||||
Excel = Новый COMОбъект("Excel.Application");
|
КонтекстExcel = ОткрытьФайлExcel(ВременныйФайл);
|
||||||
Excel.Visible = Ложь;
|
Если КонтекстExcel = Неопределено Тогда
|
||||||
Excel.DisplayAlerts = Ложь;
|
УдалитьФайлы(ВременныйФайл);
|
||||||
|
Возврат;
|
||||||
|
КонецЕсли;
|
||||||
|
|
||||||
Книга = Excel.Workbooks.Open(ВременныйФайл);
|
// Этап 3: Поиск листа "Расчет"
|
||||||
|
СтатусЗагрузки = "Поиск листа 'Расчет'...";
|
||||||
|
Состояние("Поиск листа 'Расчет'...", 15);
|
||||||
|
|
||||||
СтатусЗагрузки = "Поиск листа 'Расчет'...";
|
ЛистРасчет = НайтиЛист(КонтекстExcel.Книга, "Расчет");
|
||||||
Прогресс = 15;
|
Если ЛистРасчет = Неопределено Тогда
|
||||||
Состояние("Поиск листа 'Расчет'...", 15);
|
Сообщить("Лист 'Расчет' не найден!");
|
||||||
|
ЗакрытьExcel(КонтекстExcel, ВременныйФайл);
|
||||||
|
СтатусЗагрузки = "Ошибка: лист не найден";
|
||||||
|
Состояние("Ошибка: лист 'Расчет' не найден", 0);
|
||||||
|
Возврат;
|
||||||
|
КонецЕсли;
|
||||||
|
|
||||||
ЛистРасчет = Неопределено;
|
// Этап 4: Определение месяца
|
||||||
Для Каждого Лист Из Книга.Sheets Цикл
|
СтатусЗагрузки = "Определение месяца...";
|
||||||
Если ВРег(Лист.Name) = "РАСЧЕТ" Тогда
|
Состояние("Определение месяца...", 20);
|
||||||
ЛистРасчет = Лист;
|
|
||||||
Прервать;
|
|
||||||
КонецЕсли;
|
|
||||||
КонецЦикла;
|
|
||||||
|
|
||||||
Если ЛистРасчет = Неопределено Тогда
|
МесяцЗначение = ЛистРасчет.Cells(4, 1).Value;
|
||||||
Сообщить("Лист 'Расчет' не найден!");
|
Если ЗначениеЗаполнено(МесяцЗначение) Тогда
|
||||||
Книга.Close(Ложь);
|
Попытка
|
||||||
Excel.Quit();
|
Объект.МесяцЗагрузки = Число(МесяцЗначение);
|
||||||
УдалитьФайлы(ВременныйФайл);
|
Исключение
|
||||||
СтатусЗагрузки = "Ошибка: лист не найден";
|
Сообщить("Не удалось определить месяц: " + МесяцЗначение);
|
||||||
Состояние("Ошибка: лист 'Расчет' не найден", 0);
|
КонецПопытки;
|
||||||
Прогресс = 0;
|
КонецЕсли;
|
||||||
Возврат;
|
|
||||||
|
// Этап 5: Построение индекса заголовков
|
||||||
|
СтатусЗагрузки = "Анализ заголовков...";
|
||||||
|
Состояние("Анализ заголовков...", 22);
|
||||||
|
|
||||||
|
НомерСтрокиЗаголовков = 15;
|
||||||
|
ИндексЗаголовков = СоздатьИндексЗаголовков(ЛистРасчет, НомерСтрокиЗаголовков);
|
||||||
|
|
||||||
|
// Этап 6: Определение строки первого сотрудника
|
||||||
|
СтатусЗагрузки = "Поиск данных...";
|
||||||
|
Состояние("Поиск данных...", 25);
|
||||||
|
|
||||||
|
Ном = НайтиСтрокуПервогоСотрудника(ЛистРасчет, НомерСтрокиЗаголовков);
|
||||||
|
Если Ном = -1 Тогда
|
||||||
|
Сообщить("Данные сотрудников не найдены!");
|
||||||
|
ЗакрытьExcel(КонтекстExcel, ВременныйФайл);
|
||||||
|
Возврат;
|
||||||
|
КонецЕсли;
|
||||||
|
|
||||||
|
// Этап 7: Чтение данных
|
||||||
|
МассивДанных = Новый Массив;
|
||||||
|
МассивВзносов = Новый Массив;
|
||||||
|
ПустыхПодряд = 0;
|
||||||
|
МаксПустых = 5;
|
||||||
|
КоличествоСтрок = ЛистРасчет.Rows.Count;
|
||||||
|
|
||||||
|
Пока Истина Цикл
|
||||||
|
ФИО = ПрочитатьЯчейкуСтроку(ЛистРасчет, Ном, 0);
|
||||||
|
|
||||||
|
Если Не ЗначениеЗаполнено(ФИО) Тогда
|
||||||
|
ПустыхПодряд = ПустыхПодряд + 1;
|
||||||
|
Если ПустыхПодряд >= МаксПустых Тогда Прервать; КонецЕсли;
|
||||||
|
Ном = Ном + 1;
|
||||||
|
Продолжить;
|
||||||
КонецЕсли;
|
КонецЕсли;
|
||||||
|
|
||||||
СтатусЗагрузки = "Определение месяца...";
|
|
||||||
Прогресс = 20;
|
|
||||||
Состояние("Определение месяца...", 20);
|
|
||||||
|
|
||||||
МесяцЗначение = ЛистРасчет.Cells(4, 1).Value;
|
|
||||||
Если ЗначениеЗаполнено(МесяцЗначение) Тогда
|
|
||||||
Попытка
|
|
||||||
Объект.МесяцЗагрузки = Число(МесяцЗначение);
|
|
||||||
Исключение
|
|
||||||
Сообщить("Не удалось определить месяц: " + МесяцЗначение);
|
|
||||||
КонецПопытки;
|
|
||||||
КонецЕсли;
|
|
||||||
|
|
||||||
СтатусЗагрузки = "Подсчет строк...";
|
|
||||||
Прогресс = 25;
|
|
||||||
Состояние("Подсчет строк...", 25);
|
|
||||||
|
|
||||||
МассивДанных = Новый Массив;
|
|
||||||
МассивВзносов = Новый Массив;
|
|
||||||
|
|
||||||
СтатусЗагрузки = "Чтение данных...";
|
|
||||||
|
|
||||||
ПустыхПодряд = 0;
|
ПустыхПодряд = 0;
|
||||||
МаксПустых = 5;
|
|
||||||
Ном = 16;
|
|
||||||
|
|
||||||
Пока Истина Цикл
|
Если СтрНачинаетсяС(ВРег(ФИО), "ИТОГО") Тогда Прервать; КонецЕсли;
|
||||||
|
|
||||||
ФИО = ПрочитатьСтроку(ЛистРасчет, Ном, 1);
|
ПрогрессЗаписи = 25 + 65 * (Ном - 1) / Макс(КоличествоСтрок, 1);
|
||||||
|
Состояние("Расчет ЗП: " + ФИО, ПрогрессЗаписи);
|
||||||
|
|
||||||
Если Не ЗначениеЗаполнено(ФИО) Тогда
|
// Чтение расчетных данных
|
||||||
ПустыхПодряд = ПустыхПодряд + 1;
|
Строка = ПрочитатьСтрокуРасчета(ЛистРасчет, Ном, ФИО, ИндексЗаголовков);
|
||||||
Если ПустыхПодряд >= МаксПустых Тогда
|
|
||||||
Прервать;
|
|
||||||
КонецЕсли;
|
|
||||||
Ном = Ном + 1;
|
|
||||||
Продолжить;
|
|
||||||
КонецЕсли;
|
|
||||||
|
|
||||||
ПустыхПодряд = 0;
|
|
||||||
|
|
||||||
Если СтрНачинаетсяС(ВРег(ФИО), "ИТОГО") Тогда
|
|
||||||
Прервать;
|
|
||||||
КонецЕсли;
|
|
||||||
|
|
||||||
// Статус: загрузка расчетов
|
|
||||||
СтатусЗагрузки = "Расчет ЗП: " + ФИО + " (строка " + Ном + ")";
|
|
||||||
Состояние("Расчет ЗП: " + ФИО, 25 + 65 * (Ном - 16) / Макс(Ном, 1));
|
|
||||||
|
|
||||||
Строка = Новый Структура;
|
|
||||||
Строка.Вставить("ФИО", ФИО);
|
|
||||||
Строка.Вставить("Должность", ПрочитатьСтроку(ЛистРасчет, Ном, 2));
|
|
||||||
Строка.Вставить("СчетБК", ПрочитатьСтроку(ЛистРасчет, Ном, 3));
|
|
||||||
Строка.Вставить("ВидЗанятости", ПрочитатьСтроку(ЛистРасчет, Ном, 4));
|
|
||||||
Строка.Вставить("Оклад", ПрочитатьЯчейку(ЛистРасчет, Ном, 8, ФИО, "Оклад"));
|
|
||||||
Строка.Вставить("КоличествоСтавок", ПрочитатьЯчейку(ЛистРасчет, Ном, 7, ФИО, "Кол-во ставок"));
|
|
||||||
Строка.Вставить("ОтработаноДней", ПрочитатьЯчейку(ЛистРасчет, Ном, 6, ФИО, "ОтработаноДней"));
|
|
||||||
Строка.Вставить("ИтогоНачислено", ПрочитатьЯчейку(ЛистРасчет, Ном, 39, ФИО, "Итого начислено"));
|
|
||||||
Строка.Вставить("НДФЛ", ПрочитатьЯчейку(ЛистРасчет, Ном, 40, ФИО, "НДФЛ"));
|
|
||||||
Строка.Вставить("ИтогоУдержано", ПрочитатьЯчейку(ЛистРасчет, Ном, 53, ФИО, "Итого удержано"));
|
|
||||||
Строка.Вставить("ВсегоНаРуки", ПрочитатьЯчейку(ЛистРасчет, Ном, 55, ФИО, "Всего на руки"));
|
|
||||||
|
|
||||||
// Чтение личных данных из листа сотрудника
|
|
||||||
ЛистСотрудника = Неопределено;
|
|
||||||
Для Каждого Лист Из Книга.Sheets Цикл
|
|
||||||
Если ВРег(Лист.Name) = ВРег(ФИО) Тогда
|
|
||||||
ЛистСотрудника = Лист;
|
|
||||||
Прервать;
|
|
||||||
КонецЕсли;
|
|
||||||
КонецЦикла;
|
|
||||||
|
|
||||||
Если ЛистСотрудника <> Неопределено Тогда
|
|
||||||
Строка.Вставить("ИНН", ИзвлечьЗначениеИзТекста(ПрочитатьСтроку(ЛистСотрудника, 0, 10), "ИНН"));
|
|
||||||
Строка.Вставить("СНИЛС", ИзвлечьЗначениеИзТекста(ПрочитатьСтроку(ЛистСотрудника, 1, 10), "СНИЛС"));
|
|
||||||
Строка.Вставить("Паспорт", ИзвлечьЗначениеИзТекста(ПрочитатьСтроку(ЛистСотрудника, 2, 10), "Паспорт"));
|
|
||||||
Строка.Вставить("Адрес", ПрочитатьСтроку(ЛистСотрудника, 3, 10));
|
|
||||||
Иначе
|
|
||||||
Строка.Вставить("ИНН", "");
|
|
||||||
Строка.Вставить("СНИЛС", "");
|
|
||||||
Строка.Вставить("Паспорт", "");
|
|
||||||
Строка.Вставить("Адрес", "");
|
|
||||||
КонецЕсли;
|
|
||||||
|
|
||||||
МассивДанных.Добавить(Строка);
|
|
||||||
|
|
||||||
// Страховые взносы
|
|
||||||
СтатусЗагрузки = "Страховые взносы: " + ФИО;
|
|
||||||
СВ = ПрочитатьЯчейку(ЛистРасчет, Ном, 63, ФИО, "СВ итого");
|
|
||||||
Если СВ > 0 Тогда
|
|
||||||
СтрВзносов = Новый Структура;
|
|
||||||
СтрВзносов.Вставить("ФИО", ФИО);
|
|
||||||
СтрВзносов.Вставить("ДТ6Процент", ПрочитатьЯчейку(ЛистРасчет, Ном, 58, ФИО, "ДТ 6%"));
|
|
||||||
СтрВзносов.Вставить("ДТ4Процент", ПрочитатьЯчейку(ЛистРасчет, Ном, 59, ФИО, "ДТ 4%"));
|
|
||||||
СтрВзносов.Вставить("ПФСтраховая", ПрочитатьЯчейку(ЛистРасчет, Ном, 60, ФИО, "ПФ"));
|
|
||||||
СтрВзносов.Вставить("ФССФОМС", ПрочитатьЯчейку(ЛистРасчет, Ном, 61, ФИО, "ФСС/ФОМС"));
|
|
||||||
СтрВзносов.Вставить("НСПЗ", ПрочитатьЯчейку(ЛистРасчет, Ном, 62, ФИО, "НС и ПЗ"));
|
|
||||||
СтрВзносов.Вставить("Итого", СВ);
|
|
||||||
МассивВзносов.Добавить(СтрВзносов);
|
|
||||||
КонецЕсли;
|
|
||||||
|
|
||||||
Ном = Ном + 1;
|
|
||||||
|
|
||||||
|
// Чтение личных данных
|
||||||
|
ЛичныеДанные = ПрочитатьЛичныеДанные(КонтекстExcel.Книга, ФИО);
|
||||||
|
Для Каждого КлючЗначение Из ЛичныеДанные Цикл
|
||||||
|
Строка.Вставить(КлючЗначение.Ключ, КлючЗначение.Значение);
|
||||||
КонецЦикла;
|
КонецЦикла;
|
||||||
|
|
||||||
СтатусЗагрузки = "Закрытие Excel...";
|
МассивДанных.Добавить(Строка);
|
||||||
Прогресс = 95;
|
|
||||||
Состояние("Закрытие Excel...", 95);
|
|
||||||
|
|
||||||
Книга.Close(Ложь);
|
// Чтение страховых взносов
|
||||||
Excel.Quit();
|
СтрВзносов = ПрочитатьСтрокуВзносов(ЛистРасчет, Ном, ФИО, ИндексЗаголовков);
|
||||||
УдалитьФайлы(ВременныйФайл);
|
Если СтрВзносов <> Неопределено Тогда
|
||||||
|
МассивВзносов.Добавить(СтрВзносов);
|
||||||
|
КонецЕсли;
|
||||||
|
|
||||||
СтатусЗагрузки = "Передача данных на сервер...";
|
Ном = Ном + 1;
|
||||||
Прогресс = 98;
|
КонецЦикла;
|
||||||
Состояние("Передача данных на сервер...", 98);
|
|
||||||
|
|
||||||
ЗаполнитьТаблицыНаСервере(МассивДанных, МассивВзносов);
|
// Этап 8: Закрытие Excel
|
||||||
|
СтатусЗагрузки = "Закрытие Excel...";
|
||||||
|
Состояние("Закрытие Excel...", 95);
|
||||||
|
ЗакрытьExcel(КонтекстExcel, ВременныйФайл);
|
||||||
|
|
||||||
// Обновление табличных частей на форме
|
// Этап 9: Передача на сервер
|
||||||
Элементы.ТаблицаРасчетЗП.ОбновитьСтроки();
|
СтатусЗагрузки = "Передача данных на сервер...";
|
||||||
Элементы.ТаблицаСтраховыеВзносы.ОбновитьСтроки();
|
Состояние("Передача данных на сервер...", 98);
|
||||||
|
ЗаполнитьТаблицыНаСервере(МассивДанных, МассивВзносов);
|
||||||
|
|
||||||
Прогресс = 100;
|
// Этап 10: Обновление формы
|
||||||
СтатусЗагрузки = "Готово! Загружено: " + МассивДанных.Количество() + " сотрудников";
|
Прогресс = 100;
|
||||||
Состояние("Готово! Загружено: " + МассивДанных.Количество() + " сотрудников", 100);
|
СтатусЗагрузки = "Готово! Загружено: " + МассивДанных.Количество() + " сотрудников";
|
||||||
Сообщить(СтатусЗагрузки);
|
Состояние("Готово! Загружено: " + МассивДанных.Количество() + " сотрудников", 100);
|
||||||
|
Сообщить(СтатусЗагрузки);
|
||||||
|
|
||||||
Исключение
|
// Обновление табличных частей
|
||||||
Сообщить("Ошибка чтения Excel: " + ОписаниеОшибки());
|
Элементы.ТаблицаРасчетЗП.ОбновитьСтроки();
|
||||||
СтатусЗагрузки = "Ошибка: " + ОписаниеОшибки();
|
Элементы.ТаблицаСтраховыеВзносы.ОбновитьСтроки();
|
||||||
Состояние("Ошибка: " + ОписаниеОшибки(), 0);
|
|
||||||
Прогресс = 0;
|
|
||||||
КонецПопытки;
|
|
||||||
|
|
||||||
КонецПроцедуры
|
КонецПроцедуры
|
||||||
|
|
||||||
@@ -266,10 +411,16 @@
|
|||||||
|
|
||||||
#Область СерверныеПроцедуры
|
#Область СерверныеПроцедуры
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// ДОМЕН: Серверная обработка данных
|
||||||
|
// Ответственность: заполнение таблиц значений, запись в 1С
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
&НаСервере
|
&НаСервере
|
||||||
Процедура ИнициализироватьТаблицы()
|
Процедура ИнициализироватьТаблицы()
|
||||||
КонецПроцедуры
|
КонецПроцедуры
|
||||||
|
|
||||||
|
// Заполняет таблицы значений на сервере из массивов структур.
|
||||||
&НаСервере
|
&НаСервере
|
||||||
Процедура ЗаполнитьТаблицыНаСервере(МассивДанных, МассивВзносов)
|
Процедура ЗаполнитьТаблицыНаСервере(МассивДанных, МассивВзносов)
|
||||||
ТЗРасчет = РеквизитФормыВЗначение("Объект.ДанныеРасчетаЗП");
|
ТЗРасчет = РеквизитФормыВЗначение("Объект.ДанныеРасчетаЗП");
|
||||||
@@ -289,6 +440,7 @@
|
|||||||
ЗначениеВРеквизитФормы(ТЗВзносы, "Объект.ДанныеСтраховыхВзносов");
|
ЗначениеВРеквизитФормы(ТЗВзносы, "Объект.ДанныеСтраховыхВзносов");
|
||||||
КонецПроцедуры
|
КонецПроцедуры
|
||||||
|
|
||||||
|
// Записывает данные в документы 1С.
|
||||||
&НаСервере
|
&НаСервере
|
||||||
Процедура ЗаписатьДанныеНаСервере()
|
Процедура ЗаписатьДанныеНаСервере()
|
||||||
ГодЗагрузки = ТекущаяДата().Год();
|
ГодЗагрузки = ТекущаяДата().Год();
|
||||||
|
|||||||
Reference in New Issue
Block a user