Имя: Пароль:
1C
1С v8
убрать дубли в строках при выгрузке в exсel
,
0 Slaifer
 
13.09.22
10:39
Всем привет, написал обработку чтобы выгружало в CVS, конфигурация ЗУП (8.3.20.1789)
По сотрудникам выгружается информация и иногда дублируются строки, если сотрудник например два раза устраивался на работу и увольнялся.
Пример:
Сидоров Роман Николаевич,Сидоров,Роман,Николаевич,ООО "Ромашка",Столовая,Кассир,001-111-222 33,03.05.2005,29.12.2021,п. 5 ч. 1 ст. 77,Увольнение
Иванов Иван Иванович,Иванов,Иван,Иванович,ООО "Ромашка"Столовая,Повар,001-111-222 33,30.12.2021,,п. 5 ч. 1 ст. 77,Увольнение
Иванов Иван Иванович,Иванов,Иван,Иванович,ООО "Ромашка",Столовая,Повар,001-111-222 33,31.05.2016,29.12.2021,п. 5 ч. 1 ст. 77,Увольнение
Петров Петр Петрович,Петров,Петр,Петрович,ООО "Ромашка",Столовая,Официант,001-111-222 33,30.12.2021,,п. 5 ч. 1 ст. 77,Увольнение
Петров Петр Петрович,Петров,Петр,Петрович,ООО "Ромашка",Столовая,Официант,001-111-222 33,26.12.2019,29.12.2021,п. 5 ч. 1 ст. 77,Увольнение

Подскажите как при одинаковом ФИО убирать ПЕРВУЮ строку, а вторую оставлять (я отсортирую чтобы первая была последняя запись о сотруднике)

КОД:
Дата = ТекущаяДата();
   ДатаВНазвании = Лев(Строка(Дата),10);
  
   ИспользуемыйРазделитель = ",";
  
   ФайлCSV="\\server\1c\ZUP_" + ДатаВНазвании + ".csv";
  

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

       ТекстCSV1 = "Full_Name,Surname,First_Name,Patronymic,Organization,Division,Position,Snils,Date_Of_Admission,Date_Of_Dismissal,Reason_For_Dismissal,Employee_Status";
       ТекстCSV = ТекстCSV + СтрокаТЗ.ФизическоеЛицо + ИспользуемыйРазделитель + СтрокаТЗ.ФизическоеЛицоФамилия + ИспользуемыйРазделитель + СтрокаТЗ.ФизическоеЛицоИмя
       + ИспользуемыйРазделитель + СтрокаТЗ.ФизическоеЛицоОтчество + ИспользуемыйРазделитель + СтрокаТЗ.ГоловнаяОрганизация
       + ИспользуемыйРазделитель + СтрокаТЗ.Подразделение + ИспользуемыйРазделитель + СтрокаТЗ.Должность
       + ИспользуемыйРазделитель + СтрокаТЗ.ФизическоеЛицоСтраховойНомерПФР + ИспользуемыйРазделитель + Лев(Строка(СтрокаТЗ.ДатаПриема),10) + ИспользуемыйРазделитель
       + Лев(Формат(СтрокаТЗ.ДатаУвольнения, "ггггММддЧЧмм"),10) + ИспользуемыйРазделитель + СтрокаТЗ.СтатьяТКРФ + ИспользуемыйРазделитель + СтрокаТЗ.Состояние + Символы.ПС;
        КонецЕсли;
   КонецЦикла;

   КодANSI = КодировкаТекста.ANSI;
   ТекстовыйФайлЗапись = Новый ЗаписьТекста(ФайлCSV, КодANSI); // Создание файла CSV
   ТекстовыйФайлЗапись.ЗаписатьСтроку(ТекстCSV1);
   ТекстовыйФайлЗапись.ЗаписатьСтроку(ТекстCSV); // Запись информации в файл
   ТекстовыйФайлЗапись.Закрыть(); // Обязательно закрываем, иначе зависает в процессе
1 Ryzeman
 
13.09.22
10:43
Простой алгоритм - пронумеровать строки. Сделать выборку в ВТ - фамилия и максимум от номера строки. Связать полученную ВТ с нужными тебе данными.
На более сложные и красивые алгоритмы мне лень думать и мне за это не заплатят)
2 Slaifer
 
13.09.22
10:45
Логически я тоже понимаю, как сделать, а вот именно написать не смог. И как переделать код не понимаю
3 Garykom
 
гуру
13.09.22
10:46
(0) >,ООО "Ромашка",Столовая,Официант,

у тебя формат CSV кривой
4 Kassern
 
13.09.22
10:46
(1) есть еще проще вариант, создать переменную до цикла, хранить там сотрудника, либо несколько полей. В цикле сравнивать эту переменную с сотрудником из ТЗ, если такой есть, значить продолжить. В цикле присвоить этой переменной сотрудника.
5 Kassern
 
13.09.22
10:46
Для более красивого в запросе ->см. (1) =)
6 vicof
 
13.09.22
10:49
Еще проще и логичней использовать КадровыйУчет.КадровыеДанныеСотрудников
7 Fish
 
13.09.22
10:49
(5) Зачем (1), кода ему нужна последняя запись по дате?
8 Ryzeman
 
13.09.22
10:49
(2) Что именно у тебя не получается или что именно ты не знаешь? Для нумерации - АВТОНОМЕРЗАПИСИ(). Для (4) вообще базовых знаний должно хватить. Что такое соединение вроде понимаешь, если сам писал
9 Slaifer
 
13.09.22
10:49
(4) ИЗначально так пытался сделать, передал в переменную физическое лицо, а как обойти именно чтоб отбрасывал запись не понял
10 Garykom
 
гуру
13.09.22
10:50
(0) Запрос портянка не надо так
Сделай два или более запросов
Первым получаешь данные-поля по которым дубли и банально ВЫБРАТЬ РАЗЛИЧНЫЕ
Затем таблицу без дублей дозаполняешь через ЛЕВОЕ СОЕДИНЕНИЕ нужными данными
11 Garykom
 
гуру
13.09.22
10:52
(10)+ Гы. Походу так и было в запросе пока кто то кривыми лапками туда не влез...
12 Fish
 
13.09.22
10:58
(9) Не надо так делать. Отбирай сразу запросом только нужные записи, без дублей.
13 Kassern
 
13.09.22
11:03
(7) Как думаете, что проще - научить новичка писать грамотный запрос, который отберет правильно данные, или же в цикле срезать лишнее по условию? Скорее всего, здесь не идет речи про миллионы строк (ТСа бы к тому вряд ли допустили).
Сам запрос даже не смотрел, возможно там можно просто срезать лишние строчки, я лишь описал общий случай.
14 Kassern
 
13.09.22
11:07
(9) Общий случай такой
Сотрудник="";

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

Если ТекСтрока.Сотрудник=Сотрудник Тогда
Продолжить;
КонецЕсли;
.....
Сотрудник=ТекСтрока.Сотрудник;
КонецЦикла

В этом случае у вас будет обходиться лишь первая строчка с каждым сотрудником.
15 Fish
 
13.09.22
11:09
(13) Думаю, проще сразу объяснить, как правильно, чтобы потом не объяснять, почему ты в прошлый раз советовал одно, а потом стал советовать другое и называть предыдущий совет быдлокодом :))
16 Kassern
 
13.09.22
11:12
(15) Надеюсь у вас получится объяснить. После ночного охотника у меня стали опускаться руки)
17 Fish
 
13.09.22
11:13
(16) А не надо растрачивать силы на Ливингстара. Он необучаем.
18 Fish
 
13.09.22
11:14
+(17) Либо это корпоративный ник в каком-нибудь франче для новичков :)
19 Kassern
 
13.09.22
11:15
Ну и мышление же должно быть кодерское, как в цикле обойти правильно, как из большой выборки создать несколько документов в одном цикле и т.д.
20 Kassern
 
13.09.22
11:15
(18) это вряд ли. Ну не могут быть несколько людей такими, у него свой почерк)
21 piter3
 
13.09.22
11:15
(19) Не должно никому)
22 Fish
 
13.09.22
11:17
(19) Чем меньше логики в обходе выборки, тем лучше. И с методологической точки зрения, в большинстве задач, в выборке уже должно быть отсечено всё лишнее, а не отсекаться в цикле.
23 gul_Sayan
 
13.09.22
12:27
(0) Если нужно последние актуальные данные то лучше в качестве ведущей таблицы использовать интервальные регистры там где дата окончания последний год 1с (ну не помню точно чтото типа 31.12.3999) В ЗУП 3.1. использовать срез последних дурной тон, как минимум после временных перемещений в них остаются не верные данные.