v3.0.0.17: NDFL/SV from employee sheets, employee IDs, DDD naming
This commit is contained in:
@@ -25,11 +25,11 @@
|
|||||||
Сообщить("Выберите файл!");
|
Сообщить("Выберите файл!");
|
||||||
Возврат;
|
Возврат;
|
||||||
КонецЕсли;
|
КонецЕсли;
|
||||||
|
|
||||||
Состояние("Инициализация загрузки...", 0);
|
Состояние("Инициализация загрузки...", 0);
|
||||||
Прогресс = 0;
|
Прогресс = 0;
|
||||||
СтатусЗагрузки = "Подготовка...";
|
СтатусЗагрузки = "Подготовка...";
|
||||||
|
|
||||||
ПрочитатьExcelНаКлиенте();
|
ПрочитатьExcelНаКлиенте();
|
||||||
КонецПроцедуры
|
КонецПроцедуры
|
||||||
|
|
||||||
@@ -52,8 +52,6 @@
|
|||||||
// Ответственность: открытие файла, поиск листов, чтение ячеек
|
// Ответственность: открытие файла, поиск листов, чтение ячеек
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
|
|
||||||
// Создаёт COM-объект Excel и открывает файл.
|
|
||||||
// Возвращает структуру {Книга, Excel} или Неопределено при ошибке.
|
|
||||||
&НаКлиенте
|
&НаКлиенте
|
||||||
Функция ОткрытьФайлExcel(ПутьКФайлу)
|
Функция ОткрытьФайлExcel(ПутьКФайлу)
|
||||||
Попытка
|
Попытка
|
||||||
@@ -68,7 +66,6 @@
|
|||||||
КонецПопытки;
|
КонецПопытки;
|
||||||
КонецФункции
|
КонецФункции
|
||||||
|
|
||||||
// Закрывает книгу и приложение Excel, удаляет временный файл.
|
|
||||||
&НаКлиенте
|
&НаКлиенте
|
||||||
Процедура ЗакрытьExcel(КонтекстExcel, ВременныйФайл)
|
Процедура ЗакрытьExcel(КонтекстExcel, ВременныйФайл)
|
||||||
Если КонтекстExcel = Неопределено Тогда Возврат; КонецЕсли;
|
Если КонтекстExcel = Неопределено Тогда Возврат; КонецЕсли;
|
||||||
@@ -82,7 +79,6 @@
|
|||||||
КонецЕсли;
|
КонецЕсли;
|
||||||
КонецПроцедуры
|
КонецПроцедуры
|
||||||
|
|
||||||
// Читает числовое значение ячейки с обработкой ошибок.
|
|
||||||
&НаКлиенте
|
&НаКлиенте
|
||||||
Функция ПрочитатьЯчейкуЧисло(Лист, Строка, Колонка, КонтекстОшибки)
|
Функция ПрочитатьЯчейкуЧисло(Лист, Строка, Колонка, КонтекстОшибки)
|
||||||
Попытка
|
Попытка
|
||||||
@@ -92,14 +88,13 @@
|
|||||||
КонецЕсли;
|
КонецЕсли;
|
||||||
Возврат Число(Значение);
|
Возврат Число(Значение);
|
||||||
Исключение
|
Исключение
|
||||||
Сообщить("Ошибка чтения числа: " + КонтекстОшибки
|
Сообщить("Ошибка чтения числа: " + КонтекстОшибки
|
||||||
+ " | строка " + Строка + " колонка " + Колонка
|
+ " | строка " + Строка + " колонка " + Колонка
|
||||||
+ " | значение: """ + Значение + """ | " + ОписаниеОшибки());
|
+ " | значение: """ + Значение + """ | " + ОписаниеОшибки());
|
||||||
Возврат 0;
|
Возврат 0;
|
||||||
КонецПопытки;
|
КонецПопытки;
|
||||||
КонецФункции
|
КонецФункции
|
||||||
|
|
||||||
// Читает строковое значение ячейки.
|
|
||||||
&НаКлиенте
|
&НаКлиенте
|
||||||
Функция ПрочитатьЯчейкуСтрока(Лист, Строка, Колонка)
|
Функция ПрочитатьЯчейкуСтрока(Лист, Строка, Колонка)
|
||||||
Попытка
|
Попытка
|
||||||
@@ -111,23 +106,19 @@
|
|||||||
КонецПопытки;
|
КонецПопытки;
|
||||||
КонецФункции
|
КонецФункции
|
||||||
|
|
||||||
// Извлекает имя листа сотрудника из формулы вида ='ИмяЛиста'!C2
|
|
||||||
// Возвращает имя листа или пустую строку.
|
|
||||||
&НаКлиенте
|
&НаКлиенте
|
||||||
Функция ИзвлечьИмяЛистаИзФормулы(Формула)
|
Функция ИзвлечьИмяЛистаИзФормулы(Формула)
|
||||||
Если Формула = Неопределено Тогда Возврат ""; КонецЕсли;
|
Если Формула = Неопределено Тогда Возврат ""; КонецЕсли;
|
||||||
ТекстФормулы = СокрЛП("" + Формула);
|
ТекстФормулы = СокрЛП("" + Формула);
|
||||||
Если Не СтрНачинаетсяС(ТекстФормулы, "='") Тогда Возврат ""; КонецЕсли;
|
Если Не СтрНачинаетсяС(ТекстФормулы, "='") Тогда Возврат ""; КонецЕсли;
|
||||||
|
|
||||||
// Ищем закрывающую кавычку после ='
|
ПозицияНачала = 3;
|
||||||
ПозицияНачала = 3; // после ='
|
|
||||||
ПозицияКонца = СтрНайти(ТекстФормулы, "'!", , , ПозицияНачала);
|
ПозицияКонца = СтрНайти(ТекстФормулы, "'!", , , ПозицияНачала);
|
||||||
Если ПозицияКонца = 0 Тогда Возврат ""; КонецЕсли;
|
Если ПозицияКонца = 0 Тогда Возврат ""; КонецЕсли;
|
||||||
|
|
||||||
Возврат Сред(ТекстФормулы, ПозицияНачала, ПозицияКонца - ПозицияНачала);
|
Возврат Сред(ТекстФормулы, ПозицияНачала, ПозицияКонца - ПозицияНачала);
|
||||||
КонецФункции
|
КонецФункции
|
||||||
|
|
||||||
// Ищет лист по имени (регистронезависимо).
|
|
||||||
&НаКлиенте
|
&НаКлиенте
|
||||||
Функция НайтиЛист(Книга, ИмяЛиста)
|
Функция НайтиЛист(Книга, ИмяЛиста)
|
||||||
Для Каждого Лист Из Книга.Sheets Цикл
|
Для Каждого Лист Из Книга.Sheets Цикл
|
||||||
@@ -147,12 +138,9 @@
|
|||||||
// Ответственность: сопоставление имён колонок Excel с полями данных
|
// Ответственность: сопоставление имён колонок Excel с полями данных
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
|
|
||||||
// Создаёт Соответствие для поиска колонок по имени заголовка.
|
|
||||||
// Ключ — имя заголовка (нижний регистр), значение — номер колонки (1-based).
|
|
||||||
&НаКлиенте
|
&НаКлиенте
|
||||||
Функция СоздатьИндексЗаголовков(Лист, НомерСтрокиЗаголовков)
|
Функция СоздатьИндексЗаголовков(Лист, НомерСтрокиЗаголовков)
|
||||||
Индекс = Новый Соответствие;
|
Индекс = Новый Соответствие;
|
||||||
// Определяем количество колонок: ищем последнюю непустую колонку
|
|
||||||
ПоследняяКолонка = 1;
|
ПоследняяКолонка = 1;
|
||||||
Для Колонка = 1 По 100 Цикл
|
Для Колонка = 1 По 100 Цикл
|
||||||
Значение = Лист.Cells(НомерСтрокиЗаголовков, Колонка).Value;
|
Значение = Лист.Cells(НомерСтрокиЗаголовков, Колонка).Value;
|
||||||
@@ -160,7 +148,7 @@
|
|||||||
ПоследняяКолонка = Колонка;
|
ПоследняяКолонка = Колонка;
|
||||||
КонецЕсли;
|
КонецЕсли;
|
||||||
КонецЦикла;
|
КонецЦикла;
|
||||||
|
|
||||||
Для Колонка = 1 По ПоследняяКолонка Цикл
|
Для Колонка = 1 По ПоследняяКолонка Цикл
|
||||||
Имя = СокрЛП(НРег(Лист.Cells(НомерСтрокиЗаголовков, Колонка).Value));
|
Имя = СокрЛП(НРег(Лист.Cells(НомерСтрокиЗаголовков, Колонка).Value));
|
||||||
Если ЗначениеЗаполнено(Имя) Тогда
|
Если ЗначениеЗаполнено(Имя) Тогда
|
||||||
@@ -170,8 +158,6 @@
|
|||||||
Возврат Индекс;
|
Возврат Индекс;
|
||||||
КонецФункции
|
КонецФункции
|
||||||
|
|
||||||
// Находит номер колонки по ключевому слову в заголовке.
|
|
||||||
// Возвращает номер колонки (1-based) или -1 если не найдено.
|
|
||||||
&НаКлиенте
|
&НаКлиенте
|
||||||
Функция НайтиКолонкуПоЗаголовку(ИндексЗаголовков, КлючевоеСлово)
|
Функция НайтиКолонкуПоЗаголовку(ИндексЗаголовков, КлючевоеСлово)
|
||||||
Ключ = НРег(КлючевоеСлово);
|
Ключ = НРег(КлючевоеСлово);
|
||||||
@@ -183,19 +169,14 @@
|
|||||||
Возврат -1;
|
Возврат -1;
|
||||||
КонецФункции
|
КонецФункции
|
||||||
|
|
||||||
// Находит строку заголовков таблицы данных.
|
|
||||||
// Ищет строку, содержащую ХОТЯ БЫ 2 ключевых слова из списка одновременно.
|
|
||||||
// Это исключает ложные срабатывания на метаданных (строки 0-14).
|
|
||||||
&НаКлиенте
|
&НаКлиенте
|
||||||
Функция НайтиСтрокуЗаголовков(ЛистРасчет)
|
Функция НайтиСтрокуЗаголовков(ЛистРасчет)
|
||||||
// Ключевые слова заголовков (в нижнем регистре)
|
|
||||||
КлючевыеСлова = Новый Массив;
|
КлючевыеСлова = Новый Массив;
|
||||||
КлючевыеСлова.Добавить("сотрудник");
|
КлючевыеСлова.Добавить("сотрудник");
|
||||||
КлючевыеСлова.Добавить("должность");
|
КлючевыеСлова.Добавить("должность");
|
||||||
КлючевыеСлова.Добавить("счет");
|
КлючевыеСлова.Добавить("счет");
|
||||||
КлючевыеСлова.Добавить("вид занятости");
|
КлючевыеСлова.Добавить("вид занятости");
|
||||||
|
|
||||||
// Ищем строку с минимум 2 совпадениями ключевых слов
|
|
||||||
Для Ном = 1 По Мин(30, ЛистРасчет.Rows.Count) Цикл
|
Для Ном = 1 По Мин(30, ЛистРасчет.Rows.Count) Цикл
|
||||||
КоличествоСовпадений = 0;
|
КоличествоСовпадений = 0;
|
||||||
Для Каждого КлючевоеСлово Из КлючевыеСлова Цикл
|
Для Каждого КлючевоеСлово Из КлючевыеСлова Цикл
|
||||||
@@ -209,53 +190,44 @@
|
|||||||
КонецЕсли;
|
КонецЕсли;
|
||||||
КонецЦикла;
|
КонецЦикла;
|
||||||
КонецЦикла;
|
КонецЦикла;
|
||||||
|
|
||||||
// Строка заголовков содержит 2+ ключевых слова
|
|
||||||
Если КоличествоСовпадений >= 2 Тогда
|
Если КоличествоСовпадений >= 2 Тогда
|
||||||
Возврат Ном;
|
Возврат Ном;
|
||||||
КонецЕсли;
|
КонецЕсли;
|
||||||
КонецЦикла;
|
КонецЦикла;
|
||||||
|
|
||||||
// Fallback: строка 15 (для старых xls)
|
|
||||||
Возврат 15;
|
Возврат 15;
|
||||||
КонецФункции
|
КонецФункции
|
||||||
|
|
||||||
// Читает данные из листа сотрудника напрямую из ячеек.
|
|
||||||
// Формулы в РАСЧЕТ ссылаются на: C2(ФИО), C3(Должность), D3(Счет), A5(Вид занятости),
|
|
||||||
// и OFFSET-формулы для месячных данных (строка 12 + смещение по A4).
|
|
||||||
&НаКлиенте
|
&НаКлиенте
|
||||||
Функция ПрочитатьДанныеИзЛистаСотрудника(ЛистСотрудника, ФИО)
|
Функция ПрочитатьДанныеИзЛистаСотрудника(ЛистСотрудника, ФИО)
|
||||||
Строка = Новый Структура;
|
Строка = Новый Структура;
|
||||||
Строка.Вставить("ФИО", ФИО);
|
Строка.Вставить("ФИО", ФИО);
|
||||||
Строка.Вставить("Должность", ПрочитатьЯчейкуСтрока(ЛистСотрудника, 3, 3)); // C3
|
Строка.Вставить("Должность", ПрочитатьЯчейкуСтрока(ЛистСотрудника, 3, 3));
|
||||||
Строка.Вставить("СчетБК", ПрочитатьЯчейкуСтрока(ЛистСотрудника, 3, 4)); // D3
|
Строка.Вставить("СчетБК", ПрочитатьЯчейкуСтрока(ЛистСотрудника, 3, 4));
|
||||||
Строка.Вставить("ВидЗанятости", ПрочитатьЯчейкуСтрока(ЛистСотрудника, 5, 1)); // A5
|
Строка.Вставить("ВидЗанятости", ПрочитатьЯчейкуСтрока(ЛистСотрудника, 5, 1));
|
||||||
|
|
||||||
// Месяц загрузки определяет смещение для OFFSET-формул
|
|
||||||
// Базовая строка данных — строка 12, смещение = месяц
|
|
||||||
БазоваяСтрока = 12;
|
БазоваяСтрока = 12;
|
||||||
Смещение = Объект.МесяцЗагрузки;
|
Смещение = Объект.МесяцЗагрузки;
|
||||||
Если Не ЗначениеЗаполнено(Смещение) Тогда Смещение = 1; КонецЕсли;
|
Если Не ЗначениеЗаполнено(Смещение) Тогда Смещение = 1; КонецЕсли;
|
||||||
СтрокаДанных = БазоваяСтрока + Смещение;
|
СтрокаДанных = БазоваяСтрока + Смещение;
|
||||||
|
|
||||||
// Часовая норма (столбец C, т.е. колонка 3)
|
|
||||||
Строка.Вставить("Оклад", ПрочитатьЯчейкуЧисло(ЛистСотрудника, СтрокаДанных, 3, ФИО + " Оклад"));
|
Строка.Вставить("Оклад", ПрочитатьЯчейкуЧисло(ЛистСотрудника, СтрокаДанных, 3, ФИО + " Оклад"));
|
||||||
Строка.Вставить("КоличествоСтавок", ПрочитатьЯчейкуЧисло(ЛистСотрудника, СтрокаДанных, 4, ФИО + " Ставки"));
|
Строка.Вставить("КоличествоСтавок", ПрочитатьЯчейкуЧисло(ЛистСотрудника, СтрокаДанных, 4, ФИО + " Ставки"));
|
||||||
Строка.Вставить("ОтработаноДней", ПрочитатьЯчейкуЧисло(ЛистСотрудника, СтрокаДанных, 5, ФИО + " Отработано"));
|
Строка.Вставить("ОтработаноДней", ПрочитатьЯчейкуЧисло(ЛистСотрудника, СтрокаДанных, 5, ФИО + " Отработано"));
|
||||||
Строка.Вставить("ИтогоНачислено", ПрочитатьЯчейкуЧисло(ЛистСотрудника, СтрокаДанных, 10, ФИО + " Итого начислено"));
|
Строка.Вставить("ИтогоНачислено", ПрочитатьЯчейкуЧисло(ЛистСотрудника, СтрокаДанных, 10, ФИО + " Итого начислено"));
|
||||||
Строка.Вставить("НДФЛ", 0); // НДФЛ не на листе сотрудника
|
Строка.Вставить("НДФЛ", 0);
|
||||||
Строка.Вставить("ИтогоУдержано", 0); // Удержания не на листе сотрудника
|
Строка.Вставить("ИтогоУдержано", 0);
|
||||||
Строка.Вставить("ВсегоНаРуки", 0); // Итого на руки не на листе сотрудника
|
Строка.Вставить("ВсегоНаРуки", 0);
|
||||||
|
|
||||||
Возврат Строка;
|
Возврат Строка;
|
||||||
КонецФункции
|
КонецФункции
|
||||||
|
|
||||||
// Определяет номер строки первого сотрудника (первая непустая строка после заголовков).
|
|
||||||
&НаКлиенте
|
&НаКлиенте
|
||||||
Функция НайтиСтрокуПервогоСотрудника(ЛистРасчет, НомерСтрокиЗаголовков)
|
Функция НайтиСтрокуПервогоСотрудника(ЛистРасчет, НомерСтрокиЗаголовков)
|
||||||
Для Ном = НомерСтрокиЗаголовков + 1 По ЛистРасчет.Rows.Count Цикл
|
Для Ном = НомерСтрокиЗаголовков + 1 По ЛистРасчет.Rows.Count Цикл
|
||||||
Значение = ЛистРасчет.Cells(Ном, 1).Value;
|
Значение = ЛистРасчет.Cells(Ном, 1).Value;
|
||||||
Если ЗначениеЗаполнено(Значение)
|
Если ЗначениеЗаполнено(Значение)
|
||||||
И Не СтрНачинаетсяС(ВРег(СокрЛП("" + Значение)), "ИТОГО") Тогда
|
И Не СтрНачинаетсяС(ВРег(СокрЛП("" + Значение)), "ИТОГО") Тогда
|
||||||
Возврат Ном;
|
Возврат Ном;
|
||||||
КонецЕсли;
|
КонецЕсли;
|
||||||
@@ -263,7 +235,6 @@
|
|||||||
Возврат -1;
|
Возврат -1;
|
||||||
КонецФункции
|
КонецФункции
|
||||||
|
|
||||||
// Извлекает значение из текста вида "ИНН 990100718541" → "990100718541"
|
|
||||||
&НаКлиенте
|
&НаКлиенте
|
||||||
Функция ИзвлечьЗначениеИзТекста(Текст, Префикс)
|
Функция ИзвлечьЗначениеИзТекста(Текст, Префикс)
|
||||||
Если Не ЗначениеЗаполнено(Текст) Тогда Возврат ""; КонецЕсли;
|
Если Не ЗначениеЗаполнено(Текст) Тогда Возврат ""; КонецЕсли;
|
||||||
@@ -278,18 +249,14 @@
|
|||||||
|
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
// ДОМЕН: Чтение данных сотрудника
|
// ДОМЕН: Чтение данных сотрудника
|
||||||
// Ответственность: извлечение данных из строки листа "Расчет"
|
// Ответственность: извлечение данных из строки листа "Расчет" и листов сотрудников
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
|
|
||||||
// Читает одну строку данных сотрудника из листа "Расчет".
|
|
||||||
// ИндексЗаголовков — Соответствие для динамического поиска колонок.
|
|
||||||
&НаКлиенте
|
&НаКлиенте
|
||||||
Функция ПрочитатьСтрокуРасчета(ЛистРасчет, Ном, ФИО, ИндексЗаголовков)
|
Функция ПрочитатьСтрокуРасчета(ЛистРасчет, Ном, ФИО, ИндексЗаголовков)
|
||||||
Строка = Новый Структура;
|
Строка = Новый Структура;
|
||||||
Строка.Вставить("ФИО", ФИО);
|
Строка.Вставить("ФИО", ФИО);
|
||||||
|
|
||||||
// Поиск колонок по заголовкам
|
|
||||||
// Маппинг: "Счет БК" в Excel = "Лицевой счет сотрудника в банке для зарплатного проекта" в 1С ЗиКГУ
|
|
||||||
КолДолжность = НайтиКолонкуПоЗаголовку(ИндексЗаголовков, "должность");
|
КолДолжность = НайтиКолонкуПоЗаголовку(ИндексЗаголовков, "должность");
|
||||||
КолСчетБК = НайтиКолонкуПоЗаголовку(ИндексЗаголовков, "счет");
|
КолСчетБК = НайтиКолонкуПоЗаголовку(ИндексЗаголовков, "счет");
|
||||||
КолВидЗанятости = НайтиКолонкуПоЗаголовку(ИндексЗаголовков, "вид занятости");
|
КолВидЗанятости = НайтиКолонкуПоЗаголовку(ИндексЗаголовков, "вид занятости");
|
||||||
@@ -300,7 +267,7 @@
|
|||||||
КолНДФЛ = НайтиКолонкуПоЗаголовку(ИндексЗаголовков, "ндфл");
|
КолНДФЛ = НайтиКолонкуПоЗаголовку(ИндексЗаголовков, "ндфл");
|
||||||
КолИтогоУдержано = НайтиКолонкуПоЗаголовку(ИндексЗаголовков, "итого удержано");
|
КолИтогоУдержано = НайтиКолонкуПоЗаголовку(ИндексЗаголовков, "итого удержано");
|
||||||
КолВсегоНаРуки = НайтиКолонкуПоЗаголовку(ИндексЗаголовков, "всего на руки");
|
КолВсегоНаРуки = НайтиКолонкуПоЗаголовку(ИндексЗаголовков, "всего на руки");
|
||||||
|
|
||||||
Строка.Вставить("Должность", ПрочитатьЯчейкуСтрока(ЛистРасчет, Ном, КолДолжность));
|
Строка.Вставить("Должность", ПрочитатьЯчейкуСтрока(ЛистРасчет, Ном, КолДолжность));
|
||||||
Строка.Вставить("СчетБК", ПрочитатьЯчейкуСтрока(ЛистРасчет, Ном, КолСчетБК));
|
Строка.Вставить("СчетБК", ПрочитатьЯчейкуСтрока(ЛистРасчет, Ном, КолСчетБК));
|
||||||
Строка.Вставить("ВидЗанятости", ПрочитатьЯчейкуСтрока(ЛистРасчет, Ном, КолВидЗанятости));
|
Строка.Вставить("ВидЗанятости", ПрочитатьЯчейкуСтрока(ЛистРасчет, Ном, КолВидЗанятости));
|
||||||
@@ -311,11 +278,10 @@
|
|||||||
Строка.Вставить("НДФЛ", ПрочитатьЯчейкуЧисло(ЛистРасчет, Ном, КолНДФЛ, ФИО + " НДФЛ"));
|
Строка.Вставить("НДФЛ", ПрочитатьЯчейкуЧисло(ЛистРасчет, Ном, КолНДФЛ, ФИО + " НДФЛ"));
|
||||||
Строка.Вставить("ИтогоУдержано", ПрочитатьЯчейкуЧисло(ЛистРасчет, Ном, КолИтогоУдержано, ФИО + " Итого удержано"));
|
Строка.Вставить("ИтогоУдержано", ПрочитатьЯчейкуЧисло(ЛистРасчет, Ном, КолИтогоУдержано, ФИО + " Итого удержано"));
|
||||||
Строка.Вставить("ВсегоНаРуки", ПрочитатьЯчейкуЧисло(ЛистРасчет, Ном, КолВсегоНаРуки, ФИО + " Всего на руки"));
|
Строка.Вставить("ВсегоНаРуки", ПрочитатьЯчейкуЧисло(ЛистРасчет, Ном, КолВсегоНаРуки, ФИО + " Всего на руки"));
|
||||||
|
|
||||||
Возврат Строка;
|
Возврат Строка;
|
||||||
КонецФункции
|
КонецФункции
|
||||||
|
|
||||||
// Читает страховые взносы из строки листа "Расчет".
|
|
||||||
&НаКлиенте
|
&НаКлиенте
|
||||||
Функция ПрочитатьСтрокуВзносов(ЛистРасчет, Ном, ФИО, ИндексЗаголовков)
|
Функция ПрочитатьСтрокуВзносов(ЛистРасчет, Ном, ФИО, ИндексЗаголовков)
|
||||||
КолДТ6 = НайтиКолонкуПоЗаголовку(ИндексЗаголовков, "дт 6");
|
КолДТ6 = НайтиКолонкуПоЗаголовку(ИндексЗаголовков, "дт 6");
|
||||||
@@ -324,10 +290,10 @@
|
|||||||
КолФСС = НайтиКолонкуПоЗаголовку(ИндексЗаголовков, "фсс");
|
КолФСС = НайтиКолонкуПоЗаголовку(ИндексЗаголовков, "фсс");
|
||||||
КолНСПЗ = НайтиКолонкуПоЗаголовку(ИндексЗаголовков, "нс и пз");
|
КолНСПЗ = НайтиКолонкуПоЗаголовку(ИндексЗаголовков, "нс и пз");
|
||||||
КолСВИтого = НайтиКолонкуПоЗаголовку(ИндексЗаголовков, "св итого");
|
КолСВИтого = НайтиКолонкуПоЗаголовку(ИндексЗаголовков, "св итого");
|
||||||
|
|
||||||
СВ = ПрочитатьЯчейкуЧисло(ЛистРасчет, Ном, КолСВИтого, ФИО + " СВ итого");
|
СВ = ПрочитатьЯчейкуЧисло(ЛистРасчет, Ном, КолСВИтого, ФИО + " СВ итого");
|
||||||
Если СВ <= 0 Тогда Возврат Неопределено; КонецЕсли;
|
Если СВ <= 0 Тогда Возврат Неопределено; КонецЕсли;
|
||||||
|
|
||||||
СтрВзносов = Новый Структура;
|
СтрВзносов = Новый Структура;
|
||||||
СтрВзносов.Вставить("ФИО", ФИО);
|
СтрВзносов.Вставить("ФИО", ФИО);
|
||||||
СтрВзносов.Вставить("ДТ6Процент", ПрочитатьЯчейкуЧисло(ЛистРасчет, Ном, КолДТ6, ФИО + " ДТ 6%"));
|
СтрВзносов.Вставить("ДТ6Процент", ПрочитатьЯчейкуЧисло(ЛистРасчет, Ном, КолДТ6, ФИО + " ДТ 6%"));
|
||||||
@@ -336,20 +302,19 @@
|
|||||||
СтрВзносов.Вставить("ФССФОМС", ПрочитатьЯчейкуЧисло(ЛистРасчет, Ном, КолФСС, ФИО + " ФСС/ФОМС"));
|
СтрВзносов.Вставить("ФССФОМС", ПрочитатьЯчейкуЧисло(ЛистРасчет, Ном, КолФСС, ФИО + " ФСС/ФОМС"));
|
||||||
СтрВзносов.Вставить("НСПЗ", ПрочитатьЯчейкуЧисло(ЛистРасчет, Ном, КолНСПЗ, ФИО + " НС и ПЗ"));
|
СтрВзносов.Вставить("НСПЗ", ПрочитатьЯчейкуЧисло(ЛистРасчет, Ном, КолНСПЗ, ФИО + " НС и ПЗ"));
|
||||||
СтрВзносов.Вставить("Итого", СВ);
|
СтрВзносов.Вставить("Итого", СВ);
|
||||||
|
|
||||||
Возврат СтрВзносов;
|
Возврат СтрВзносов;
|
||||||
КонецФункции
|
КонецФункции
|
||||||
|
|
||||||
// Читает личные данные из листа сотрудника (шапка строк 0-3).
|
|
||||||
&НаКлиенте
|
&НаКлиенте
|
||||||
Функция ПрочитатьЛичныеДанные(Книга, ФИО)
|
Функция ПрочитатьЛичныеДанные(Книга, ФИО)
|
||||||
ЛичныеДанные = Новый Структура("ИНН, СНИЛС, Паспорт, Адрес", "", "", "", "");
|
ЛичныеДанные = Новый Структура("ИНН, СНИЛС, Паспорт, Адрес", "", "", "", "");
|
||||||
|
|
||||||
ЛистСотрудника = НайтиЛист(Книга, ФИО);
|
ЛистСотрудника = НайтиЛист(Книга, ФИО);
|
||||||
Если ЛистСотрудника = Неопределено Тогда
|
Если ЛистСотрудника = Неопределено Тогда
|
||||||
Возврат ЛичныеДанные;
|
Возврат ЛичныеДанные;
|
||||||
КонецЕсли;
|
КонецЕсли;
|
||||||
|
|
||||||
ЛичныеДанные.ИНН = ИзвлечьЗначениеИзТекста(
|
ЛичныеДанные.ИНН = ИзвлечьЗначениеИзТекста(
|
||||||
ПрочитатьЯчейкуСтрока(ЛистСотрудника, 0, 10), "ИНН");
|
ПрочитатьЯчейкуСтрока(ЛистСотрудника, 0, 10), "ИНН");
|
||||||
ЛичныеДанные.СНИЛС = ИзвлечьЗначениеИзТекста(
|
ЛичныеДанные.СНИЛС = ИзвлечьЗначениеИзТекста(
|
||||||
@@ -357,56 +322,183 @@
|
|||||||
ЛичныеДанные.Паспорт = ИзвлечьЗначениеИзТекста(
|
ЛичныеДанные.Паспорт = ИзвлечьЗначениеИзТекста(
|
||||||
ПрочитатьЯчейкуСтрока(ЛистСотрудника, 2, 10), "Паспорт");
|
ПрочитатьЯчейкуСтрока(ЛистСотрудника, 2, 10), "Паспорт");
|
||||||
ЛичныеДанные.Адрес = ПрочитатьЯчейкуСтрока(ЛистСотрудника, 3, 10);
|
ЛичныеДанные.Адрес = ПрочитатьЯчейкуСтрока(ЛистСотрудника, 3, 10);
|
||||||
|
|
||||||
Возврат ЛичныеДанные;
|
Возврат ЛичныеДанные;
|
||||||
КонецФункции
|
КонецФункции
|
||||||
|
|
||||||
|
// Читает данные НДФЛ и страховых взносов из блока внизу листа сотрудника.
|
||||||
|
// Блок НДФЛ/СВ начинается с строки 31 ("Расчет НДФЛ и страховых взносов (СВ)").
|
||||||
|
// Заголовки: строки 33-35. Данные по месяцам: строки 36-47 (Январь-Декабрь). Итого: строка 48.
|
||||||
|
// Месяц выбирается по Объект.МесяцЗагрузки: строка = 35 + Месяц.
|
||||||
|
&НаКлиенте
|
||||||
|
Функция ПрочитатьНДФЛСоЛистаСотрудника(ЛистСотрудника, ФИО)
|
||||||
|
Если ЛистСотрудника = Неопределено Тогда
|
||||||
|
Возврат Неопределено;
|
||||||
|
КонецЕсли;
|
||||||
|
|
||||||
|
// Проверяем наличие блока НДФЛ: ячейка A31 содержит "Расчет НДФЛ"
|
||||||
|
ЗаголовокБлока = ПрочитатьЯчейкуСтрока(ЛистСотрудника, 31, 1);
|
||||||
|
Если СтрНайти(НРег(ЗаголовокБлока), "ндфл") = 0
|
||||||
|
И СтрНайти(НРег(ЗаголовокБлока), "расчет") = 0 Тогда
|
||||||
|
// Проверяем строку 33 (альтернативное расположение)
|
||||||
|
ЗаголовокБлока33 = ПрочитатьЯчейкуСтрока(ЛистСотрудника, 33, 1);
|
||||||
|
Если СтрНайти(НРег(ЗаголовокБлока33), "период") = 0 Тогда
|
||||||
|
Возврат Неопределено;
|
||||||
|
КонецЕсли;
|
||||||
|
КонецЕсли;
|
||||||
|
|
||||||
|
// Определяем строку данных для выбранного месяца: 35 + МесяцЗагрузки
|
||||||
|
Смещение = Объект.МесяцЗагрузки;
|
||||||
|
Если Не ЗначениеЗаполнено(Смещение) Тогда Смещение = 1; КонецЕсли;
|
||||||
|
СтрокаДанных = 35 + Смещение; // Строка 36 = Январь, 37 = Февраль, ...
|
||||||
|
|
||||||
|
// Названия месяцев для проверки
|
||||||
|
МассивМесяцев = Новый Массив;
|
||||||
|
МассивМесяцев.Добавить("январь");
|
||||||
|
МассивМесяцев.Добавить("февраль");
|
||||||
|
МассивМесяцев.Добавить("март");
|
||||||
|
МассивМесяцев.Добавить("апрель");
|
||||||
|
МассивМесяцев.Добавить("май");
|
||||||
|
МассивМесяцев.Добавить("июнь");
|
||||||
|
МассивМесяцев.Добавить("июль");
|
||||||
|
МассивМесяцев.Добавить("август");
|
||||||
|
МассивМесяцев.Добавить("сентябрь");
|
||||||
|
МассивМесяцев.Добавить("октябрь");
|
||||||
|
МассивМесяцев.Добавить("ноябрь");
|
||||||
|
МассивМесяцев.Добавить("декабрь");
|
||||||
|
|
||||||
|
// Проверяем что в найденной строке действительно данные за месяц
|
||||||
|
ТекстМесяца = НРег(ПрочитатьЯчейкуСтрока(ЛистСотрудника, СтрокаДанных, 1));
|
||||||
|
Если МассивМесяцев.Найти(ТекстМесяца) = Неопределено Тогда
|
||||||
|
// Попробуем найти строку по названию месяца
|
||||||
|
Для Строка = 36 По 47 Цикл
|
||||||
|
Текст = НРег(ПрочитатьЯчейкуСтрока(ЛистСотрудника, Строка, 1));
|
||||||
|
Если МассивМесяцев.Найти(Текст) <> Неопределено Тогда
|
||||||
|
СтрокаДанных = Строка;
|
||||||
|
Прервать;
|
||||||
|
КонецЕсли;
|
||||||
|
КонецЦикла;
|
||||||
|
КонецЕсли;
|
||||||
|
|
||||||
|
НДФЛ = Новый Структура;
|
||||||
|
НДФЛ.Вставить("ФИО", ФИО);
|
||||||
|
НДФЛ.Вставить("МесяцРасчета", ПрочитатьЯчейкуСтрока(ЛистСотрудника, СтрокаДанных, 1));
|
||||||
|
|
||||||
|
// Колонки блока НДФЛ/СВ на листе сотрудника:
|
||||||
|
// col 4: Сумма валового дохода (за месяц)
|
||||||
|
// col 6: Сумма валового дохода с начала года
|
||||||
|
// col 7: Сумма дохода (за месяц)
|
||||||
|
// col 8: Скидка для НДФЛ (за месяц)
|
||||||
|
// col 9: Скидка для НДФЛ (за год)
|
||||||
|
// col 10: Скидка для СВ (за месяц)
|
||||||
|
// col 11: Скидка для СВ (за год)
|
||||||
|
// col 12: Вычет на работника (за месяц)
|
||||||
|
// col 13: Вычет на иждивенцев (за месяц)
|
||||||
|
// col 14: Всего вычетов (за год)
|
||||||
|
// col 15: Облагаемый доход (за год)
|
||||||
|
// col 16: Начисленный НДФЛ (за год)
|
||||||
|
// col 17: Удержанный НДФЛ (за год)
|
||||||
|
// col 18: Итого НДФЛ (за месяц)
|
||||||
|
// col 19: Выплаты по больничному (за год)
|
||||||
|
// col 20: Налоговая база по СВ (за год)
|
||||||
|
// col 23: Налоговая база по СВ (за месяц)
|
||||||
|
// col 24: Страховая часть ПФ
|
||||||
|
// col 25: Накопительная часть ПФ
|
||||||
|
// col 31: ФСС начислено с начала года
|
||||||
|
// col 33: ФСС Итого (за месяц)
|
||||||
|
// col 34: НС и ПЗ начислено с начала года
|
||||||
|
// col 36: НС и ПЗ Итого (за месяц)
|
||||||
|
// col 37: Страховые взносы Итого (за месяц)
|
||||||
|
|
||||||
|
НДФЛ.Вставить("СуммаВаловогоДохода",
|
||||||
|
ПрочитатьЯчейкуЧисло(ЛистСотрудника, СтрокаДанных, 4, ФИО + " Сумма валового дохода"));
|
||||||
|
НДФЛ.Вставить("СуммаВаловогоДоходаСНачалаГода",
|
||||||
|
ПрочитатьЯчейкуЧисло(ЛистСотрудника, СтрокаДанных, 6, ФИО + " Доход с начала года"));
|
||||||
|
НДФЛ.Вставить("СкидкаДляНДФЛЗаМесяц",
|
||||||
|
ПрочитатьЯчейкуЧисло(ЛистСотрудника, СтрокаДанных, 8, ФИО + " Скидка НДФЛ месяц"));
|
||||||
|
НДФЛ.Вставить("СкидкаДляНДФЛЗаГод",
|
||||||
|
ПрочитатьЯчейкуЧисло(ЛистСотрудника, СтрокаДанных, 9, ФИО + " Скидка НДФЛ год"));
|
||||||
|
НДФЛ.Вставить("СкидкаДляСВЗаМесяц",
|
||||||
|
ПрочитатьЯчейкуЧисло(ЛистСотрудника, СтрокаДанных, 10, ФИО + " Скидка СВ месяц"));
|
||||||
|
НДФЛ.Вставить("ВычетНаРаботникаЗаМесяц",
|
||||||
|
ПрочитатьЯчейкуЧисло(ЛистСотрудника, СтрокаДанных, 12, ФИО + " Вычет работника"));
|
||||||
|
НДФЛ.Вставить("ВычетНаРаботникаЗаГод",
|
||||||
|
0); // не отображается отдельно, входит в ВсегоВычетовЗаМесяц
|
||||||
|
НДФЛ.Вставить("ВычетНаИждивенцевЗаМесяц",
|
||||||
|
ПрочитатьЯчейкуЧисло(ЛистСотрудника, СтрокаДанных, 13, ФИО + " Вычет иждивенцев"));
|
||||||
|
НДФЛ.Вставить("ВсегоВычетовЗаМесяц",
|
||||||
|
ПрочитатьЯчейкуЧисло(ЛистСотрудника, СтрокаДанных, 14, ФИО + " Всего вычетов"));
|
||||||
|
НДФЛ.Вставить("ОблагаемыйДоходЗаМесяц",
|
||||||
|
0); // за месяц не выделяется отдельно
|
||||||
|
НДФЛ.Вставить("ОблагаемыйДоходЗаГод",
|
||||||
|
ПрочитатьЯчейкуЧисло(ЛистСотрудника, СтрокаДанных, 15, ФИО + " Облагаемый доход"));
|
||||||
|
НДФЛ.Вставить("НачисленныйНДФЛЗаГод",
|
||||||
|
ПрочитатьЯчейкуЧисло(ЛистСотрудника, СтрокаДанных, 16, ФИО + " НДФЛ начисленный"));
|
||||||
|
НДФЛ.Вставить("ИтогоНДФЛЗаМесяц",
|
||||||
|
ПрочитатьЯчейкуЧисло(ЛистСотрудника, СтрокаДанных, 18, ФИО + " Итого НДФЛ"));
|
||||||
|
НДФЛ.Вставить("НалоговаяБазаПоСВЗаМесяц",
|
||||||
|
ПрочитатьЯчейкуЧисло(ЛистСотрудника, СтрокаДанных, 23, ФИО + " База СВ месяц"));
|
||||||
|
НДФЛ.Вставить("ИтогоФСС",
|
||||||
|
ПрочитатьЯчейкуЧисло(ЛистСотрудника, СтрокаДанных, 37, ФИО + " Итого СВ"));
|
||||||
|
|
||||||
|
Возврат НДФЛ;
|
||||||
|
КонецФункции
|
||||||
|
|
||||||
|
&НаКлиенте
|
||||||
|
Функция ПрочитатьДанныеСотрудника(ЛистСотрудника)
|
||||||
|
Данные = Новый Структура;
|
||||||
|
Данные.Вставить("ФИО", ПрочитатьЯчейкуСтрока(ЛистСотрудника, 2, 3)); // C3: ФИО
|
||||||
|
Данные.Вставить("ИНН", ИзвлечьЗначениеИзТекста(
|
||||||
|
ПрочитатьЯчейкуСтрока(ЛистСотрудника, 0, 10), "ИНН"));
|
||||||
|
Данные.Вставить("СНИЛС", ИзвлечьЗначениеИзТекста(
|
||||||
|
ПрочитатьЯчейкуСтрока(ЛистСотрудника, 1, 10), "СНИЛС"));
|
||||||
|
Данные.Вставить("ЛицевойСчетВБанке", ПрочитатьЯчейкуСтрока(ЛистСотрудника, 3, 4)); // D4: Номер
|
||||||
|
Данные.Вставить("ВидЗанятости", ПрочитатьЯчейкуСтрока(ЛистСотрудника, 5, 1)); // A6
|
||||||
|
Данные.Вставить("АдресРегистрации", ПрочитатьЯчейкуСтрока(ЛистСотрудника, 3, 10)); // K4
|
||||||
|
|
||||||
|
Возврат Данные;
|
||||||
|
КонецФункции
|
||||||
|
|
||||||
#КонецОбласти
|
#КонецОбласти
|
||||||
|
|
||||||
#Область ОсновнаяПроцедура_Домен
|
#Область ОсновнаяПроцедура_Домен
|
||||||
|
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
// ДОМЕН: Оркестрация загрузки
|
// ДОМЕН: Оркестрация загрузки
|
||||||
// Ответственность: координация всех этапов загрузки
|
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
|
|
||||||
&НаКлиенте
|
&НаКлиенте
|
||||||
Процедура ПрочитатьExcelНаКлиенте()
|
Процедура ПрочитатьExcelНаКлиенте()
|
||||||
|
|
||||||
// Этап 1: Подготовка файла
|
|
||||||
СтатусЗагрузки = "Копирование файла...";
|
СтатусЗагрузки = "Копирование файла...";
|
||||||
Состояние("Копирование файла...", 5);
|
Состояние("Копирование файла...", 5);
|
||||||
|
|
||||||
ВременныйФайл = КаталогВременныхФайлов() + "temp_data.xls";
|
ВременныйФайл = КаталогВременныхФайлов() + "temp_data.xls";
|
||||||
КопироватьФайл(Объект.ПутьКФайлу, ВременныйФайл);
|
КопироватьФайл(Объект.ПутьКФайлу, ВременныйФайл);
|
||||||
|
|
||||||
// Этап 2: Открытие Excel
|
|
||||||
СтатусЗагрузки = "Открытие Excel...";
|
СтатусЗагрузки = "Открытие Excel...";
|
||||||
Состояние("Открытие Excel...", 10);
|
Состояние("Открытие Excel...", 10);
|
||||||
|
|
||||||
КонтекстExcel = ОткрытьФайлExcel(ВременныйФайл);
|
КонтекстExcel = ОткрытьФайлExcel(ВременныйФайл);
|
||||||
Если КонтекстExcel = Неопределено Тогда
|
Если КонтекстExcel = Неопределено Тогда
|
||||||
УдалитьФайлы(ВременныйФайл);
|
УдалитьФайлы(ВременныйФайл);
|
||||||
Возврат;
|
Возврат;
|
||||||
КонецЕсли;
|
КонецЕсли;
|
||||||
|
|
||||||
// Этап 3: Поиск листа "Расчет"
|
|
||||||
СтатусЗагрузки = "Поиск листа 'Расчет'...";
|
СтатусЗагрузки = "Поиск листа 'Расчет'...";
|
||||||
Состояние("Поиск листа 'Расчет'...", 15);
|
Состояние("Поиск листа 'Расчет'...", 15);
|
||||||
|
|
||||||
ЛистРасчет = НайтиЛист(КонтекстExcel.Книга, "Расчет");
|
ЛистРасчет = НайтиЛист(КонтекстExcel.Книга, "Расчет");
|
||||||
Если ЛистРасчет = Неопределено Тогда
|
Если ЛистРасчет = Неопределено Тогда
|
||||||
Сообщить("Лист 'Расчет' не найден!");
|
Сообщить("Лист 'Расчет' не найден!");
|
||||||
ЗакрытьExcel(КонтекстExcel, ВременныйФайл);
|
ЗакрытьExcel(КонтекстExcel, ВременныйФайл);
|
||||||
СтатусЗагрузки = "Ошибка: лист не найден";
|
СтатусЗагрузки = "Ошибка: лист не найден";
|
||||||
Состояние("Ошибка: лист 'Расчет' не найден", 0);
|
|
||||||
Возврат;
|
Возврат;
|
||||||
КонецЕсли;
|
КонецЕсли;
|
||||||
|
|
||||||
// Этап 4: Определение месяца
|
|
||||||
СтатусЗагрузки = "Определение месяца...";
|
СтатусЗагрузки = "Определение месяца...";
|
||||||
Состояние("Определение месяца...", 20);
|
Состояние("Определение месяца...", 20);
|
||||||
|
|
||||||
МесяцЗначение = ЛистРасчет.Cells(4, 1).Value;
|
МесяцЗначение = ЛистРасчет.Cells(4, 1).Value;
|
||||||
Если ЗначениеЗаполнено(МесяцЗначение) Тогда
|
Если ЗначениеЗаполнено(МесяцЗначение) Тогда
|
||||||
Попытка
|
Попытка
|
||||||
@@ -415,37 +507,37 @@
|
|||||||
Сообщить("Не удалось определить месяц: " + МесяцЗначение);
|
Сообщить("Не удалось определить месяц: " + МесяцЗначение);
|
||||||
КонецПопытки;
|
КонецПопытки;
|
||||||
КонецЕсли;
|
КонецЕсли;
|
||||||
|
|
||||||
// Этап 5: Построение индекса заголовков
|
|
||||||
СтатусЗагрузки = "Анализ заголовков...";
|
СтатусЗагрузки = "Анализ заголовков...";
|
||||||
Состояние("Анализ заголовков...", 22);
|
Состояние("Анализ заголовков...", 22);
|
||||||
|
|
||||||
НомерСтрокиЗаголовков = НайтиСтрокуЗаголовков(ЛистРасчет);
|
НомерСтрокиЗаголовков = НайтиСтрокуЗаголовков(ЛистРасчет);
|
||||||
ИндексЗаголовков = СоздатьИндексЗаголовков(ЛистРасчет, НомерСтрокиЗаголовков);
|
ИндексЗаголовков = СоздатьИндексЗаголовков(ЛистРасчет, НомерСтрокиЗаголовков);
|
||||||
|
|
||||||
// Этап 6: Определение строки первого сотрудника
|
|
||||||
СтатусЗагрузки = "Поиск данных...";
|
СтатусЗагрузки = "Поиск данных...";
|
||||||
Состояние("Поиск данных...", 25);
|
Состояние("Поиск данных...", 25);
|
||||||
|
|
||||||
Ном = НайтиСтрокуПервогоСотрудника(ЛистРасчет, НомерСтрокиЗаголовков);
|
Ном = НайтиСтрокуПервогоСотрудника(ЛистРасчет, НомерСтрокиЗаголовков);
|
||||||
Если Ном = -1 Тогда
|
Если Ном = -1 Тогда
|
||||||
Сообщить("Данные сотрудников не найдены!");
|
Сообщить("Данные сотрудников не найдены!");
|
||||||
ЗакрытьExcel(КонтекстExcel, ВременныйФайл);
|
ЗакрытьExcel(КонтекстExcel, ВременныйФайл);
|
||||||
Возврат;
|
Возврат;
|
||||||
КонецЕсли;
|
КонецЕсли;
|
||||||
|
|
||||||
// Этап 7: Чтение данных
|
// Основные массивы данных
|
||||||
МассивДанных = Новый Массив;
|
МассивДанных = Новый Массив;
|
||||||
МассивВзносов = Новый Массив;
|
МассивВзносов = Новый Массив;
|
||||||
|
МассивНДФЛ = Новый Массив;
|
||||||
|
МассивСотрудников = Новый Массив;
|
||||||
|
СчетчикСотрудников = 0;
|
||||||
|
|
||||||
ПустыхПодряд = 0;
|
ПустыхПодряд = 0;
|
||||||
МаксПустых = 5;
|
МаксПустых = 5;
|
||||||
КоличествоСтрок = ЛистРасчет.Rows.Count;
|
КоличествоСтрок = ЛистРасчет.Rows.Count;
|
||||||
|
|
||||||
Пока Истина Цикл
|
Пока Истина Цикл
|
||||||
// Попытка 1: читаем значение напрямую (xls)
|
|
||||||
ФИО = ПрочитатьЯчейкуСтрока(ЛистРасчет, Ном, 1);
|
ФИО = ПрочитатьЯчейкуСтрока(ЛистРасчет, Ном, 1);
|
||||||
|
|
||||||
// Попытка 2: если значение пустое — проверяем формулу (xlsm)
|
|
||||||
ЛистСотрудника = Неопределено;
|
ЛистСотрудника = Неопределено;
|
||||||
Если Не ЗначениеЗаполнено(ФИО) Тогда
|
Если Не ЗначениеЗаполнено(ФИО) Тогда
|
||||||
Формула = ЛистРасчет.Cells(Ном, 1).Formula;
|
Формула = ЛистРасчет.Cells(Ном, 1).Formula;
|
||||||
@@ -459,64 +551,90 @@
|
|||||||
КонецЕсли;
|
КонецЕсли;
|
||||||
КонецЕсли;
|
КонецЕсли;
|
||||||
КонецЕсли;
|
КонецЕсли;
|
||||||
|
|
||||||
Если Не ЗначениеЗаполнено(ФИО) Тогда
|
Если Не ЗначениеЗаполнено(ФИО) Тогда
|
||||||
ПустыхПодряд = ПустыхПодряд + 1;
|
ПустыхПодряд = ПустыхПодряд + 1;
|
||||||
Если ПустыхПодряд >= МаксПустых Тогда Прервать; КонецЕсли;
|
Если ПустыхПодряд >= МаксПустых Тогда Прервать; КонецЕсли;
|
||||||
Ном = Ном + 1;
|
Ном = Ном + 1;
|
||||||
Продолжить;
|
Продолжить;
|
||||||
КонецЕсли;
|
КонецЕсли;
|
||||||
|
|
||||||
ПустыхПодряд = 0;
|
ПустыхПодряд = 0;
|
||||||
|
|
||||||
Если СтрНачинаетсяС(ВРег(ФИО), "ИТОГО") Тогда Прервать; КонецЕсли;
|
Если СтрНачинаетсяС(ВРег(ФИО), "ИТОГО") Тогда Прервать; КонецЕсли;
|
||||||
|
|
||||||
|
// Уникальный идентификатор сотрудника
|
||||||
|
СчетчикСотрудников = СчетчикСотрудников + 1;
|
||||||
|
ИДСотрудника = СчетчикСотрудников;
|
||||||
|
|
||||||
ПрогрессЗаписи = 25 + 65 * (Ном - 1) / Макс(КоличествоСтрок, 1);
|
ПрогрессЗаписи = 25 + 65 * (Ном - 1) / Макс(КоличествоСтрок, 1);
|
||||||
Состояние("Расчет ЗП: " + ФИО, ПрогрессЗаписи);
|
Состояние("Расчет ЗП: " + ФИО, ПрогрессЗаписи);
|
||||||
|
|
||||||
// Если есть лист сотрудника — читаем напрямую из его ячеек
|
// Чтение данных ЗП
|
||||||
Если ЛистСотрудника <> Неопределено Тогда
|
Если ЛистСотрудника <> Неопределено Тогда
|
||||||
Строка = ПрочитатьДанныеИзЛистаСотрудника(ЛистСотрудника, ФИО);
|
Строка = ПрочитатьДанныеИзЛистаСотрудника(ЛистСотрудника, ФИО);
|
||||||
Иначе
|
Иначе
|
||||||
Строка = ПрочитатьСтрокуРасчета(ЛистРасчет, Ном, ФИО, ИндексЗаголовков);
|
Строка = ПрочитатьСтрокуРасчета(ЛистРасчет, Ном, ФИО, ИндексЗаголовков);
|
||||||
КонецЕсли;
|
КонецЕсли;
|
||||||
|
Строка.Вставить("ИдентификаторСотрудника", ИДСотрудника);
|
||||||
// Чтение личных данных
|
|
||||||
|
// Личные данные (ИНН, СНИЛС, адрес)
|
||||||
ЛичныеДанные = ПрочитатьЛичныеДанные(КонтекстExcel.Книга, ФИО);
|
ЛичныеДанные = ПрочитатьЛичныеДанные(КонтекстExcel.Книга, ФИО);
|
||||||
Для Каждого КлючЗначение Из ЛичныеДанные Цикл
|
Для Каждого КлючЗначение Из ЛичныеДанные Цикл
|
||||||
Строка.Вставить(КлючЗначение.Ключ, КлючЗначение.Значение);
|
Если Не Строка.Свойство(КлючЗначение.Ключ) Тогда
|
||||||
|
Строка.Вставить(КлючЗначение.Ключ, КлючЗначение.Значение);
|
||||||
|
КонецЕсли;
|
||||||
КонецЦикла;
|
КонецЦикла;
|
||||||
|
|
||||||
МассивДанных.Добавить(Строка);
|
МассивДанных.Добавить(Строка);
|
||||||
|
|
||||||
// Чтение страховых взносов (из РАСЧЕТ, т.к. на листах сотрудников взносов нет)
|
// Данные сотрудников (скрытая таблица для связи)
|
||||||
СтрВзносов = ПрочитатьСтрокуВзносов(ЛистРасчет, Ном, ФИО, ИндексЗаголовков);
|
Если ЛистСотрудника <> Неопределено Тогда
|
||||||
|
ДанныеСотр = ПрочитатьДанныеСотрудника(ЛистСотрудника);
|
||||||
|
Иначе
|
||||||
|
ДанныеСотр = Новый Структура;
|
||||||
|
ДанныеСотр.Вставить("ФИО", ФИО);
|
||||||
|
ДанныеСотр.Вставить("ИНН", ?(ЛичныеДанные <> Неопределено, ЛичныеДанные.ИНН, ""));
|
||||||
|
ДанныеСотр.Вставить("СНИЛС", ?(ЛичныеДанные <> Неопределено, ЛичныеДанные.СНИЛС, ""));
|
||||||
|
ДанныеСотр.Вставить("ЛицевойСчетВБанке", "");
|
||||||
|
ДанныеСотр.Вставить("ВидЗанятости", "");
|
||||||
|
ДанныеСотр.Вставить("АдресРегистрации", "");
|
||||||
|
КонецЕсли;
|
||||||
|
ДанныеСотр.Вставить("Идентификатор", ИДСотрудника);
|
||||||
|
МассивСотрудников.Добавить(ДанныеСотр);
|
||||||
|
|
||||||
|
// Данные НДФЛ из блока внизу листа сотрудника
|
||||||
|
Если ЛистСотрудника <> Неопределено Тогда
|
||||||
|
ДанныеНДФЛ = ПрочитатьНДФЛСоЛистаСотрудника(ЛистСотрудника, ФИО);
|
||||||
|
Если ДанныеНДФЛ <> Неопределено Тогда
|
||||||
|
ДанныеНДФЛ.Вставить("ИдентификаторСотрудника", ИДСотрудника);
|
||||||
|
МассивНДФЛ.Добавить(ДанныеНДФЛ);
|
||||||
|
КонецЕсли;
|
||||||
|
КонецЕсли;
|
||||||
|
|
||||||
|
// Страховые взносы из листа "Расчет"
|
||||||
|
СтрВзносов = ПрочитатьСтрокуВзносов(ЛистРасчет, Ном, ФИО, ИндексЗаголовков);
|
||||||
Если СтрВзносов <> Неопределено Тогда
|
Если СтрВзносов <> Неопределено Тогда
|
||||||
|
СтрВзносов.Вставить("ИдентификаторСотрудника", ИДСотрудника);
|
||||||
МассивВзносов.Добавить(СтрВзносов);
|
МассивВзносов.Добавить(СтрВзносов);
|
||||||
КонецЕсли;
|
КонецЕсли;
|
||||||
|
|
||||||
Ном = Ном + 1;
|
Ном = Ном + 1;
|
||||||
КонецЦикла;
|
КонецЦикла;
|
||||||
|
|
||||||
// Этап 8: Закрытие Excel
|
|
||||||
СтатусЗагрузки = "Закрытие Excel...";
|
СтатусЗагрузки = "Закрытие Excel...";
|
||||||
Состояние("Закрытие Excel...", 95);
|
Состояние("Закрытие Excel...", 95);
|
||||||
ЗакрытьExcel(КонтекстExcel, ВременныйФайл);
|
ЗакрытьExcel(КонтекстExcel, ВременныйФайл);
|
||||||
|
|
||||||
// Этап 9: Передача на сервер
|
|
||||||
СтатусЗагрузки = "Передача данных на сервер...";
|
СтатусЗагрузки = "Передача данных на сервер...";
|
||||||
Состояние("Передача данных на сервер...", 98);
|
Состояние("Передача данных на сервер...", 98);
|
||||||
ЗаполнитьТаблицыНаСервере(МассивДанных, МассивВзносов);
|
ЗаполнитьТаблицыНаСервере(МассивДанных, МассивВзносов, МассивНДФЛ, МассивСотрудников);
|
||||||
|
|
||||||
// Этап 10: Обновление формы
|
|
||||||
Прогресс = 100;
|
Прогресс = 100;
|
||||||
СтатусЗагрузки = "Готово! Загружено: " + МассивДанных.Количество() + " сотрудников";
|
СтатусЗагрузки = "Готово! Загружено: " + МассивДанных.Количество() + " сотрудников";
|
||||||
Состояние("Готово! Загружено: " + МассивДанных.Количество() + " сотрудников", 100);
|
|
||||||
Сообщить(СтатусЗагрузки);
|
Сообщить(СтатусЗагрузки);
|
||||||
|
|
||||||
// Обновление формы
|
|
||||||
ОбновитьОтображениеДанных();
|
ОбновитьОтображениеДанных();
|
||||||
|
|
||||||
КонецПроцедуры
|
КонецПроцедуры
|
||||||
|
|
||||||
#КонецОбласти
|
#КонецОбласти
|
||||||
@@ -525,34 +643,43 @@
|
|||||||
|
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
// ДОМЕН: Серверная обработка данных
|
// ДОМЕН: Серверная обработка данных
|
||||||
// Ответственность: заполнение таблиц значений, запись в 1С
|
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
|
|
||||||
&НаСервере
|
&НаСервере
|
||||||
Процедура ИнициализироватьТаблицы()
|
Процедура ИнициализироватьТаблицы()
|
||||||
КонецПроцедуры
|
КонецПроцедуры
|
||||||
|
|
||||||
// Заполняет табличные части объекта из массивов структур.
|
|
||||||
// TabularSection не поддерживает РеквизитФормыВЗначение — работаем через Объект напрямую.
|
|
||||||
&НаСервере
|
&НаСервере
|
||||||
Процедура ЗаполнитьТаблицыНаСервере(МассивДанных, МассивВзносов)
|
Процедура ЗаполнитьТаблицыНаСервере(МассивДанных, МассивВзносов, МассивНДФЛ, МассивСотрудников)
|
||||||
// Очистка и заполнение ДанныеРасчетаЗП
|
// Таблица расчета ЗП
|
||||||
Объект.ДанныеРасчетаЗП.Очистить();
|
Объект.ДанныеРасчетаЗП.Очистить();
|
||||||
Для Каждого Эл Из МассивДанных Цикл
|
Для Каждого Эл Из МассивДанных Цикл
|
||||||
Строка = Объект.ДанныеРасчетаЗП.Добавить();
|
Строка = Объект.ДанныеРасчетаЗП.Добавить();
|
||||||
ЗаполнитьЗначенияСвойств(Строка, Эл);
|
ЗаполнитьЗначенияСвойств(Строка, Эл);
|
||||||
КонецЦикла;
|
КонецЦикла;
|
||||||
|
|
||||||
// Очистка и заполнение ДанныеСтраховыхВзносов
|
// Таблица страховых взносов
|
||||||
Объект.ДанныеСтраховыхВзносов.Очистить();
|
Объект.ДанныеСтраховыхВзносов.Очистить();
|
||||||
Для Каждого Эл Из МассивВзносов Цикл
|
Для Каждого Эл Из МассивВзносов Цикл
|
||||||
Строка = Объект.ДанныеСтраховыхВзносов.Добавить();
|
Строка = Объект.ДанныеСтраховыхВзносов.Добавить();
|
||||||
ЗаполнитьЗначенияСвойств(Строка, Эл);
|
ЗаполнитьЗначенияСвойств(Строка, Эл);
|
||||||
КонецЦикла;
|
КонецЦикла;
|
||||||
|
|
||||||
|
// Таблица НДФЛ
|
||||||
|
Объект.ДанныеНДФЛ.Очистить();
|
||||||
|
Для Каждого Эл Из МассивНДФЛ Цикл
|
||||||
|
Строка = Объект.ДанныеНДФЛ.Добавить();
|
||||||
|
ЗаполнитьЗначенияСвойств(Строка, Эл);
|
||||||
|
КонецЦикла;
|
||||||
|
|
||||||
|
// Таблица сотрудников (скрытая, для связи между ТЧ)
|
||||||
|
Объект.Сотрудники.Очистить();
|
||||||
|
Для Каждого Эл Из МассивСотрудников Цикл
|
||||||
|
Строка = Объект.Сотрудники.Добавить();
|
||||||
|
ЗаполнитьЗначенияСвойств(Строка, Эл);
|
||||||
|
КонецЦикла;
|
||||||
КонецПроцедуры
|
КонецПроцедуры
|
||||||
|
|
||||||
// Записывает данные в документы 1С.
|
|
||||||
// Работает напрямую с TabularSection через Объект.
|
|
||||||
&НаСервере
|
&НаСервере
|
||||||
Процедура ЗаписатьДанныеНаСервере()
|
Процедура ЗаписатьДанныеНаСервере()
|
||||||
ГодЗагрузки = ТекущаяДата().Год();
|
ГодЗагрузки = ТекущаяДата().Год();
|
||||||
@@ -561,6 +688,9 @@
|
|||||||
Если Объект.ДанныеСтраховыхВзносов.Количество() > 0 Тогда
|
Если Объект.ДанныеСтраховыхВзносов.Количество() > 0 Тогда
|
||||||
Объект.ЗаписатьДанныеСтраховыхВзносов(Объект.ДанныеСтраховыхВзносов, Период);
|
Объект.ЗаписатьДанныеСтраховыхВзносов(Объект.ДанныеСтраховыхВзносов, Период);
|
||||||
КонецЕсли;
|
КонецЕсли;
|
||||||
|
Если Объект.ДанныеНДФЛ.Количество() > 0 Тогда
|
||||||
|
Объект.ЗаписатьДанныеНДФЛ(Объект.ДанныеНДФЛ, Период);
|
||||||
|
КонецЕсли;
|
||||||
КонецПроцедуры
|
КонецПроцедуры
|
||||||
|
|
||||||
#КонецОбласти
|
#КонецОбласти
|
||||||
|
|||||||
Reference in New Issue
Block a user