8.х Удаление двойников из справочника "контрагенты"

Тема в разделе "Общие вопросы "1С:Предприятие 8"", создана пользователем ILDARIAN, 17 ноя 2013.

  1. TopicStarter Overlay
    ILDARIAN
    Offline

    ILDARIAN Опытный в 1С

    Регистрация:
    6 янв 2013
    Сообщения:
    131
    Симпатии:
    1
    Баллы:
    29
    Добрый день!

    база самописная.

    Такая задача: нужно сравнить каждый элемент справочника "Контрагенты" со всеми остальными элементами по полю "Телефон". Из списка контрагентов с одинаковым наименованием, оставить тот, у которого заполнено больше реквизитов, а остальные пометить на удаление.

    написал такой запрос, он по идеи должен выдавать список контрагентов которые нужно удалить

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





    выдает ошибку:

    {Справочник.ОбщиеКонтрагенты.Форма.ФормаСписка1.Форма(66)}: Ошибка при вызове метода контекста (Выполнить)
    Результат = Запрос.Выполнить();
    по причине:
    {(16, 5)}: Недопустимое поле для группировки "Телефон"
    <<?>>Телефон
  2. nickpugachev
    Offline

    nickpugachev Профессионал в 1С Команда форума

    Регистрация:
    28 май 2012
    Сообщения:
    3.266
    Симпатии:
    131
    Баллы:
    104
    у вас реквизит Телефон имеет неограниченную длину, по таким полям нельзя группировку делать в запросе

    попробуйте ВЫРАЗИТЬ(ОбщиеКонтрагенты.Телефон КАК Строка(200))
    и в блоке ВЫБРАТЬ и в блоке СГРУППИРОВАТЬ ПО запросов
  3. TopicStarter Overlay
    ILDARIAN
    Offline

    ILDARIAN Опытный в 1С

    Регистрация:
    6 янв 2013
    Сообщения:
    131
    Симпатии:
    1
    Баллы:
    29
    Спасибо большое, я просто поставил реквизиту длину ограниченную.
  4. TopicStarter Overlay
    ILDARIAN
    Offline

    ILDARIAN Опытный в 1С

    Регистрация:
    6 янв 2013
    Сообщения:
    131
    Симпатии:
    1
    Баллы:
    29
    Появилась новая проблема: нужно чтобы при сравнении контрагентов запрос "не обращал внимания" на скобки дефисы и пр. и опускал первые 2 цифры телефона, если они равняются "0" или "8". Тесть если номер телефона допустим 8(099)-123-45-67, то нужно чтобы он брал только 991234567 и сравнивал по этому номеру. Так реально сделать ?
  5. nickpugachev
    Offline

    nickpugachev Профессионал в 1С Команда форума

    Регистрация:
    28 май 2012
    Сообщения:
    3.266
    Симпатии:
    131
    Баллы:
    104
    нет, это уже не в запросе
  6. TopicStarter Overlay
    ILDARIAN
    Offline

    ILDARIAN Опытный в 1С

    Регистрация:
    6 янв 2013
    Сообщения:
    131
    Симпатии:
    1
    Баллы:
    29
    ну запрос сейчас выдает двойников по телефону, где поле с телефоном идентичное. после запроса это делать бесмысленно

    в запросе это можно прописать, или только за пределами запроса ?
  7. nickpugachev
    Offline

    nickpugachev Профессионал в 1С Команда форума

    Регистрация:
    28 май 2012
    Сообщения:
    3.266
    Симпатии:
    131
    Баллы:
    104
    все, что касается поиска и замены символов в строках, делается за пределами запроса
  8. TopicStarter Overlay
    ILDARIAN
    Offline

    ILDARIAN Опытный в 1С

    Регистрация:
    6 янв 2013
    Сообщения:
    131
    Симпатии:
    1
    Баллы:
    29
    Идея такая: нужно перебрать всех контрагентов и сконвертировать номера телефона согласно шаблону, записать их в отдельную таблицу, потом в этой таблице найти двойников и пометить на удаление контрагентов в справочнике. Проблема в том что я не знаю как это написать в коде
  9. vartanet
    Offline

    vartanet Опытный в 1С Команда форума

    Регистрация:
    16 ноя 2010
    Сообщения:
    2.698
    Симпатии:
    15
    Баллы:
    29
    так сходу - жесть задачка... это если брать регистр сведений КонтактныеДанные..

    телефоны могут быть городские (без 495), с добавочными номерами (доб 140, ext 221), с разными городскими кодами (095, 8132), 2 номера телефона в одной строке (даже не разделены запятыми), если номеров несколько, то первый может быть указан с кодом города, а последующие без кода... то есть тупо убрать все, что не число. и обкусить определенное количество цифр не проканает.

    какого типа реквизит Телефон? какие значения он может принимать?
  10. nickpugachev
    Offline

    nickpugachev Профессионал в 1С Команда форума

    Регистрация:
    28 май 2012
    Сообщения:
    3.266
    Симпатии:
    131
    Баллы:
    104
    суда по первому вопросу база кривосамописная, так что тут совсем все плохо
  11. TopicStarter Overlay
    ILDARIAN
    Offline

    ILDARIAN Опытный в 1С

    Регистрация:
    6 янв 2013
    Сообщения:
    131
    Симпатии:
    1
    Баллы:
    29
    телефон типа "Строка"
  12. TopicStarter Overlay
    ILDARIAN
    Offline

    ILDARIAN Опытный в 1С

    Регистрация:
    6 янв 2013
    Сообщения:
    131
    Симпатии:
    1
    Баллы:
    29
    номер имеет максимум 9 цифр, иногда 7. Если он не входит в данный диапазон, значит это не правильный номер. Нужно в каждом номере убрать все кроме цифр, и выбрать первые 7 цифр. Далее сравнивать. В случае если номеров больше одного, то таких контрагентов просто нужно пропускать.

    То есть берем первые 7 цифр с каждого номера, записываем в массив. Далее сравниваем все элементы этого массива со всеми остальными его элементами. Если находятся 2 одинаковых номера, помечаем их на удаление.

    Напишите примерный код, кто может.
  13. vartanet
    Offline

    vartanet Опытный в 1С Команда форума

    Регистрация:
    16 ноя 2010
    Сообщения:
    2.698
    Симпатии:
    15
    Баллы:
    29
    ща накалякаю..
  14. TopicStarter Overlay
    ILDARIAN
    Offline

    ILDARIAN Опытный в 1С

    Регистрация:
    6 янв 2013
    Сообщения:
    131
    Симпатии:
    1
    Баллы:
    29
    Идеально оно, конешно, не будет находить всех двойников, но все же упростит работу

    о и ещё, если номер начинается на 0 или 80, то эти цифры нужно удалять вместе с не циферными символами

    ещё если номер начинается на +380 то тройку тоже нужно убрать
  15. vartanet
    Offline

    vartanet Опытный в 1С Команда форума

    Регистрация:
    16 ноя 2010
    Сообщения:
    2.698
    Симпатии:
    15
    Баллы:
    29
    Код:
    Функция ПолучитьТелефонКонтрагента(ТекСтрока)
    НоваяСтрока = "";
    Для Сч=1 По СтрДлина(ТекСтрока) Цикл
    
    ТекСимвол = Сред(ТекСтрока, Сч, 1);
    
    Если ТекСимвол="1"
    ИЛИ ТекСимвол="2"
    ИЛИ ТекСимвол="3"
    ИЛИ ТекСимвол="4"
    ИЛИ ТекСимвол="5"
    ИЛИ ТекСимвол="6"
    ИЛИ ТекСимвол="7"
    ИЛИ ТекСимвол="8"
    ИЛИ ТекСимвол="9"
    ИЛИ ТекСимвол="0"
    Тогда
    НоваяСтрока = НоваяСтрока + ТекСимвол;
    КонецЕсли;
    
    КонецЦикла;
    
    возврат НоваяСтрока;
    КонецФункции // ПолучитьТелефонКонтрагента()
    
    Процедура КнопкаВыполнитьНажатие(Кнопка)
    
    // получим все телефоны ввсех контрагентов
    Запрос = Новый Запрос;
    Запрос.Текст =
    "ВЫБРАТЬ
    | КонтактнаяИнформация.Объект,
    | КонтактнаяИнформация.Представление
    |ИЗ
    | РегистрСведений.КонтактнаяИнформация КАК КонтактнаяИнформация
    |ГДЕ
    | КонтактнаяИнформация.Тип = &Тип
    | И КонтактнаяИнформация.Вид = &Вид";
    Запрос.УстановитьПараметр("Тип", Перечисления.ТипыКонтактнойИнформации.Телефон);
    Запрос.УстановитьПараметр("Вид", Справочники.ВидыКонтактнойИнформации.ТелефонКонтрагента);
    Таблица = Запрос.Выполнить().Выгрузить();
    
    // в каждом телефоне оставляем только цифры
    Для каждого СтрокаТаблицы Из Таблица Цикл
    
    СтрокаТаблицы.Представление = ПолучитьТелефонКонтрагента(СтрокаТаблицы.Представление);
    
    КонецЦикла;
    
    КонецПроцедуры
    
    в итоге получили таблицу числовых номеров..

    дальше эту таблицу можешь кинуть в скд и получить группировку по номеру телефона с подсчетом различных контрагентов..
  16. TopicStarter Overlay
    ILDARIAN
    Offline

    ILDARIAN Опытный в 1С

    Регистрация:
    6 янв 2013
    Сообщения:
    131
    Симпатии:
    1
    Баллы:
    29
    немного переделать нужно будет, у меня нету регистра с контактно информацией.
    -------------
    А можно просто вытянуть все номера телефонов из справочника, сделать их по шаблону и записать в регистр сведений. Потом запросом из этого регистра получить их и сравнить между собой, ну и удалять по ссылке контрагентов ?
  17. vartanet
    Offline

    vartanet Опытный в 1С Команда форума

    Регистрация:
    16 ноя 2010
    Сообщения:
    2.698
    Симпатии:
    15
    Баллы:
    29
    можете сразу в справочнике поменять - зачем городить какой-то отдельный регистр.. потом по этому же справочнику запрос сделать..

    опять же, думаю надо вручную решать кто из контрагентов должен остаться, а кого пометить на удаление..
  18. TopicStarter Overlay
    ILDARIAN
    Offline

    ILDARIAN Опытный в 1С

    Регистрация:
    6 янв 2013
    Сообщения:
    131
    Симпатии:
    1
    Баллы:
    29
    Они и будут удалятся вручную, просто если пометить всех двойников, то список, который нужно перебрать станет в разы меньше
  19. TopicStarter Overlay
    ILDARIAN
    Offline

    ILDARIAN Опытный в 1С

    Регистрация:
    6 янв 2013
    Сообщения:
    131
    Симпатии:
    1
    Баллы:
    29
    Код:
    Функция ПолучитьТелефонКонтрагента(ТекСтрока)
    
    
    
    НоваяСтрока = "";
    
    Для Сч=1 По СтрДлина(ТекСтрока) Цикл
    
    ТекСимвол = Сред(ТекСтрока, Сч, 1);
    
    Если ТекСимвол = "1"
    ИЛИ ТекСимвол = "2"
    ИЛИ ТекСимвол = "3"
    ИЛИ ТекСимвол = "4"
    ИЛИ ТекСимвол = "5"
    ИЛИ ТекСимвол = "6"
    ИЛИ ТекСимвол = "7"
    ИЛИ ТекСимвол = "8"
    ИЛИ ТекСимвол = "9"
    ИЛИ ТекСимвол = "0"
    Тогда
    НоваяСтрока = НоваяСтрока + ТекСимвол;
    КонецЕсли;
    
    КонецЦикла;
    
    возврат НоваяСтрока;
    
    КонецФункции
    
    
    Процедура КнопкаВыполнитьНажатие(Кнопка)
    
    
    ТекЭлемент = Справочники.ОбщиеКонтрагенты.Выбрать();
    Пока ТекЭлемент.Следующий()Цикл
    ТекЭлемент.Телефон = ПолучитьТелефонКонтрагента(ТекЭлемент.Телефон);
    ТекЭлемент.записать();
    КонецЦикла;
    
    КонецПроцедуры
    
    я решил преобразовать все номера и записать их в справочник, а потом уже делать сверку и удалять, только ругается при выполнении:
    {Обработка.КонвертироватьНомераСправочника.Форма.Форма.Форма(39)}: Поле объекта недоступно для записи (Телефон)
    ТекЭлемент.Телефон = ПолучитьТелефонКонтрагента(ТекЭлемент.Телефон);
  20. TopicStarter Overlay
    ILDARIAN
    Offline

    ILDARIAN Опытный в 1С

    Регистрация:
    6 янв 2013
    Сообщения:
    131
    Симпатии:
    1
    Баллы:
    29
    Подскажите как записать полученный циферный номер в реквизит "телефон" ?

Поделиться этой страницей