Как перенести первые 10 цифр из наименования контрагента в комментарий и удалить их из наименования в 1С 8.3?

Программист 1С v8.3 (Управляемые формы) 1C:Бухгалтерия Бухгалтерский учет
← На главную

При работе с базами данных 1С часто возникает необходимость в массовой корректировке данных. Одной из таких задач может быть перенос части информации из одного реквизита объекта в другой, а затем удаление этой части из исходного реквизита. Рассмотрим подробнее ситуацию, когда нам требуется выделить первые десять цифр из наименования контрагента, переместить их в поле «Комментарий» и после этого убрать из самого наименования. Эта операция особенно актуальна, если в наименование контрагента изначально вносился номер лицевого счета или иной цифровой идентификатор, который должен храниться отдельно.

Мы разберем комплексное решение этой задачи, которое включает использование стандартных механизмов платформы 1С:Предприятие 8.3, а также покажем различные подходы к программной реализации логики проверки и преобразования строк.

Основное решение: Использование стандартной обработки "Групповое изменение реквизитов"

Для массового изменения данных в 1С 8.3 наиболее эффективным и безопасным способом является использование стандартной обработки "Групповое изменение реквизитов". Эта обработка позволяет нам выполнить произвольный алгоритм для выбранных элементов справочника или документа, что значительно упрощает процесс и минимизирует риски ошибок по сравнению с ручной корректировкой или прямыми изменениями в конфигураторе. Давайте посмотрим, как настроить эту обработку для нашей задачи.

  1. Открытие обработки: Перейдем в раздел Администрирование, затем Обслуживание и выберем пункт Корректировка данных. Здесь мы найдем ссылку на "Групповое изменение реквизитов".
  2. Выбор типа объектов: В открывшейся форме в поле "Изменять" выберем тип объектов, с которыми будем работать. В нашем случае это "Справочники.Контрагенты". После выбора, нажмите кнопку "Добавить элементы", чтобы выбрать конкретных контрагентов или настроить отбор.
  3. Настройка отбора элементов: Для выполнения операции только для необходимых контрагентов, установим отбор. Например, если лицевые счета встречаются только у физических лиц, мы можем установить отбор по полю "Юридическое/физическое лицо = Физическое лицо". Также можно использовать отбор по дате создания или другим критериям, чтобы ограничить круг обрабатываемых объектов.
  4. Активация произвольного алгоритма: После выбора элементов, установим флажок "Выполнить произвольный алгоритм". Это откроет текстовое поле, куда мы сможем ввести наш код на встроенном языке 1С.
  5. Ввод алгоритма: В текстовое поле вставим разработанный нами алгоритм, который будет выполняться для каждого выбранного контрагента. Мы подробно разберем его далее.
  6. Запуск обработки: После ввода кода и установки всех необходимых отборов, нажмем кнопку "Изменить реквизиты". Обработка последовательно применит наш алгоритм ко всем выбранным объектам.

Этот подход гарантирует, что все изменения будут внесены корректно, с соблюдением всех правил работы с объектами 1С (запись, проведение и т.д.), что существенно снижает риск повреждения данных.

Подробный анализ алгоритма переноса данных

Теперь давайте сосредоточимся на программном коде, который мы вставим в поле "Выполнить произвольный алгоритм" обработки "Групповое изменение реквизитов". Этот код будет выполняться для каждого объекта Объект (в нашем случае, для каждого контрагента), выбранного в обработке.


ПервыеДесятьСимволовНаименования = Лев(Объект.Наименование, 10);
Если СтрДлина(ПервыеДесятьСимволовНаименования) = 10 И СтрРазделить(ПервыеДесятьСимволовНаименования,"0123456789",Ложь).Количество = 0 Тогда
    Объект.Комментарий = ПервыеДесятьСимволовНаименования;
    Объект.Наименование = СокрЛ(Сред(Объект.Наименование, 11));
    Объект.НаименованиеПолное = СокрЛ(Сред(Объект.НаименованиеПолное, 11));
КонецЕсли;

Разберем каждую строку этого алгоритма, чтобы полностью понять его логику и функциональность.

  1. Извлечение первых десяти символов: ПервыеДесятьСимволовНаименования = Лев(Объект.Наименование, 10);

    Здесь мы используем функцию Лев(), которая возвращает подстроку заданной длины с начала строки. Мы извлекаем первые 10 символов из поля Наименование текущего объекта контрагента и сохраняем их в переменную ПервыеДесятьСимволовНаименования. Это предположение о том, что лицевой счет всегда находится в начале наименования и имеет длину в 10 символов.

  2. Проверка на то, что первые символы являются исключительно цифрами:
    
    Если СтрДлина(ПервыеДесятьСимволовНаименования) = 10 И СтрРазделить(ПервыеДесятьСимволовНаименования,"0123456789",Ложь).Количество = 0 Тогда
    

    Это ключевой момент алгоритма, обеспечивающий надежность операции. Мы используем два условия:

    • СтрДлина(ПервыеДесятьСимволовНаименования) = 10: Первое условие проверяет, что извлеченная подстрока действительно имеет длину 10 символов. Это важно, если наименование может быть короче 10 символов, и мы хотим избежать ошибок.
    • СтрРазделить(ПервыеДесятьСимволовНаименования,"0123456789",Ложь).Количество = 0: Второе условие является наиболее надежным способом проверки того, что строка состоит исключительно из цифр.
      • Функция СтрРазделить() разбивает исходную строку (ПервыеДесятьСимволовНаименования) на части по символам-разделителям.
      • В качестве разделителей мы передаем строку "0123456789", которая содержит все возможные цифры.
      • Параметр Ложь указывает, что пустые части не должны игнорироваться.
      • Если строка ПервыеДесятьСимволовНаименования содержит только цифры, то функция СтрРазделить() не сможет найти ни одного символа, который *не* является разделителем (т.е. не является цифрой). В этом случае она вернет массив, содержащий только одну пустую строку (если исходная строка не пустая) или будет вести себя специфически. Более надежная интерпретация в данном контексте: если *все* символы являются разделителями, то "неразделимые" части отсутствуют, и количество элементов в результирующем массиве будет равно 0, что говорит нам о том, что строка состоит только из символов, переданных в качестве разделителей. На практике, этот подход очень хорошо работает для проверки на "только цифры". Если бы строка содержала хотя бы один нецифровой символ (например, "123456789А"), то СтрРазделить() создала бы как минимум одну часть, содержащую этот нецифровой символ, и .Количество было бы больше нуля.
  3. Присвоение значения полю "Комментарий": Объект.Комментарий = ПервыеДесятьСимволовНаименования;

    Если оба условия выполняются, то есть первые десять символов присутствуют и являются только цифрами, мы присваиваем это значение полю Комментарий текущего контрагента.

  4. Удаление лицевого счета из наименования: Объект.Наименование = СокрЛ(Сред(Объект.Наименование, 11));

    Здесь мы изменяем исходное поле Наименование.

    • Сред(Объект.Наименование, 11): Функция Сред() возвращает подстроку, начиная с указанной позиции и до конца строки. В данном случае мы берем все символы, начиная с 11-й позиции (то есть пропускаем первые 10 символов - наш лицевой счет).
    • СокрЛ(...): Функция СокрЛ() удаляет пробелы в начале и конце строки. Это важно, чтобы после удаления лицевого счета не осталось лишних начальных пробелов в наименовании.
  5. Удаление лицевого счета из полного наименования: Объект.НаименованиеПолное = СокрЛ(Сред(Объект.НаименованиеПолное, 11));

    Аналогично, мы выполняем те же действия для поля НаименованиеПолное, если оно также содержит лицевой счет и требует корректировки. Это обеспечивает консистентность данных.

После выполнения этого алгоритма для каждого отобранного контрагента, лицевые счета будут перенесены в комментарии, а наименования будут очищены от этих цифровых префиксов.

Альтернативные методы проверки строки на числовые символы

Хотя метод с СтрРазделить() является очень надежным для проверки на "только цифры", существуют и другие подходы, которые могут быть рассмотрены или использованы в других контекстах. Мы рассмотрим несколько из них.

Проверка с использованием функции Число()

Один из очевидных способов проверить, является ли строка числом, это попытаться преобразовать её в число с помощью функции Число(). Если преобразование успешно, то строка содержит число. Однако, этот метод имеет свои нюансы, если нам нужно убедиться, что строка состоит исключительно из цифр без других символов (например, пробелов или знаков).


ПервыеДесятьСимволовНаименования = Лев(Объект.Наименование, 10);
ПервыеДесятьСимволовНаименованияЯвляютсяЧислом = Ложь;
Попытка
    // Пытаемся преобразовать строку в число
    а = Число(ПервыеДесятьСимволовНаименования);
    ПервыеДесятьСимволовНаименованияЯвляютсяЧислом = Истина;
Исключение
    // Если преобразование не удалось, значит строка не является числом
    // (или содержит нечисловые символы, которые Число() не может обработать)
КонецПопытки;

Если ПервыеДесятьСимволовНаименованияЯвляютсяЧислом Тогда
    // Здесь можем выполнить перенос и удаление
    Объект.Комментарий = ПервыеДесятьСимволовНаименования;
    Объект.Наименование = СокрЛ(Сред(Объект.Наименование, 11));
    Объект.НаименованиеПолное = СокрЛ(Сред(Объект.НаименованиеПолное, 11));
КонецЕсли;

Недостатки этого метода: Функция Число() может успешно преобразовать строки, которые содержат только цифры, но также она может обрабатывать строки с пробелами (например, " 123 ") или знаками пунктуации, которые она умеет игнорировать или интерпретировать (например, "123.45"). Если нам критически важно, чтобы строка состояла строго из цифр и ничего более, метод с СтрРазделить() будет более точным.

Использование регулярных выражений

Начиная с версии платформы 1С:Предприятие 8.3.23, появилась встроенная поддержка регулярных выражений. Это мощный инструмент для работы со строками, позволяющий проверять их на соответствие сложным шаблонам. Если ваша платформа поддерживает эту версию или выше, вы можете использовать регулярные выражения для более элегантной и гибкой проверки.


ПервыеДесятьСимволовНаименования = Лев(Объект.Наименование, 10);

// Проверяем, состоит ли строка из 10 цифр
Если СтрНайтиПоРегулярномуВыражению(ПервыеДесятьСимволовНаименования, "^[0-9]{10}$") > 0 Тогда
    // Алгоритм переноса
    Объект.Комментарий = ПервыеДесятьСимволовНаименования;
    Объект.Наименование = СокрЛ(Сред(Объект.Наименование, 11));
    Объект.НаименованиеПолное = СокрЛ(Сред(Объект.НаименованиеПолное, 11));
КонецЕсли;

Объяснение регулярного выражения "^[0-9]{10}$":

Таким образом, всё выражение "^[0-9]{10}$" означает "строка должна начинаться с 10 цифр и заканчиваться этими 10 цифрами, не содержа других символов". Это делает проверку очень точной. Если лицевой счет находится в начале наименования, а за ним может следовать что угодно, можно использовать "^[0-9]{10}.*", где .* означает "любое количество любых символов после 10 цифр".

Использование запросов для отбора данных

В некоторых случаях, если нам нужно выполнить сложный отбор контрагентов на основе шаблона в наименовании, мы можем использовать запросы. Запросы 1С обладают мощными возможностями для выборки данных и могут включать строковые функции и оператор ПОДОБНО для поиска по шаблону. Однако, важно помнить, что запрос сам по себе лишь *выбирает* данные, а для их *изменения* всё равно потребуется программный код, который будет выполняться для каждого выбранного элемента.

Приведем пример запроса, который может выбрать контрагентов, у которых наименование начинается с 10 цифр и при этом поле "Комментарий" пустое:


ВЫБРАТЬ
    Контрагенты.Ссылка КАК Ссылка,
    СОКРЛП(ПОДСТРОКА(Контрагенты.Наименование, 11, 10000)) КАК НовоеНаименование,
    ПОДСТРОКА(Контрагенты.Наименование, 1, 10) КАК НовыйКомментарий
ИЗ
    Справочник.Контрагенты КАК Контрагенты
ГДЕ
    Контрагенты.Наименование ПОДОБНО "[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]%"
    И Выразить(Контрагенты.Комментарий КАК Строка(1)) = ""

Объяснение запроса:

Использование такого запроса в сочетании с обработкой "Групповое изменение реквизитов" (где запрос может быть использован для формирования списка изменяемых объектов) позволяет очень точно отобрать необходимые элементы для последующей программной обработки.

Рекомендации по безопасности и производительности

При выполнении массовых операций с данными всегда важно соблюдать осторожность и учитывать потенциальное влияние на производительность системы.

  1. Резервное копирование: Перед началом любых массовых изменений обязательно создайте полную резервную копию базы данных. Это ваша страховка на случай непредвиденных ошибок или некорректных результатов.
  2. Тестирование на копии: Всегда сначала тестируйте алгоритм на тестовой или архивной копии рабочей базы данных. Только после того, как вы убедитесь в корректности работы, приступайте к выполнению в рабочей базе.
  3. Ограничение выборки: Если в базе данных очень много контрагентов, старайтесь максимально сузить круг обрабатываемых объектов с помощью отборов в "Групповом изменении реквизитов". Это сократит время выполнения и снизит нагрузку на систему.
  4. Пакетная обработка: "Групповое изменение реквизитов" уже является формой пакетной обработки. При написании собственных обработок для больших объемов данных рассмотрите возможность использования транзакций и коммитов через определенное количество объектов, чтобы не перегружать СУБД.
  5. Индексы: Убедитесь, что поля, используемые в отборах запросов (например, Наименование, Юридическое/физическое лицо), проиндексированы в базе данных. Это существенно ускоряет выборку данных.
  6. Использование БСП: Если в вашей конфигурации используется Библиотека стандартных подсистем (БСП), проверьте наличие готовых функций для работы со строками, например, для проверки на наличие только цифр. В БСП часто есть оптимизированные и протестированные решения для типовых задач.

Внимательное следование этим рекомендациям поможет вам выполнить задачу переноса данных безопасно и эффективно, сохраняя целостность и производительность вашей информационной системы 1С.

← На главную