Автор вопроса: Grozniy | Web-сайт:www.softopark.ru/
Частенько приходится работать с базами данных в Exel. Вся база, грубо говоря, состоит из одного столбца. В каждой ячейке этого столбца имеется текстовая информация (товар, описание товара, его характеристики). Необходимо выделить в отдельный столбец наименование товара, в другой столбец характеристику1, в третий характеристику2 и т.д. Все это не трудно сделать стандартными функциями, НО! Заполняли этот столбец разные люди и как кому вздумается. Кто напишет КУРЫ БРОЙЛЕРНЫЕ, кто КУРИЦА_БРОЙЛЕРНАЯ, кто КУРЫ-БРОЙЛЕР, КУРЫ/БР... В общем, как попало. Мало того, в одной ячейке может оказаться несколько товаров! Количество строк может достигать 30 000! В общем, вручную (с помощью написания стандартных функций) разбивка занимает ОГРОМНОЕ количество времени!
Может быть кто поможет написать макрос? К сожалению, у меня нет необходимых знаний :(
Как я представляю себе работу макроса (если, конечно можно такое написать!):
1. На листе 1 находится столбец с данными по товарам;
2. На листе 2 можно составить некий справочник совпадений. Например,
КУРЫ БРОЙ | КУРЫ/БРОЙ | КУРЫ_БРОЙ | КУРЫ-БРОЙ | КУРЫ, БРОЙ и т.д. (это одна строчка по одному товару. Знаком | я отделил каждую ячейку)
ХЛОПОК100% | ХЛОПОК-100% | ХЛОПОК_100 | ХЛОП100 | ХЛОП_100% и т.д. (это вторая строчка по другому товару)
и т.д.
Количество вариантов написания одного товара может достигать до 32. Количество самих товаров (строчек в справочнике) до 300! Справочник составляется вручную.
3. Алгоритм макроса представляется примерно такой:
3.1 Берем содержимое из первой ячейки первой строки справочника (лист2) и пытаемся найти совпадение с содержимым в первой ячейки первой строки базы данных (лист1). Если совпадение есть, то во вторую ячейку первой строки (лист1) копируем содержимое последней ячейки первой строки из справочника (лист2). В справочнике (лист2) последний (или какой то определенный) столбец будет обозначать Истинное значение (наименование) товара. Например КУРЫ БРОЙЛЕРЫ. Т.е. Найдя совпадение КУРЫ БРОЙ мы все же напишем КУРЫ БРОЙЛЕРЫ. Далее переходим сразу к пункту 4.1
Если совпадения не нашли, то переходим к пункту 3.2
3.2 Берем содержимое из второй ячейки первой строки справочника (лист2) и пытаемся найти совпадение с содержимым в первой же ячейки первой строки базы данных (лист1). Т.е. ищем теперь КУРЫ/БРОЙ. Если совпадение есть, то в третью ячейку первой строки (лист1) копируем содержимое последней ячейки первой строки из справочника (лист2). Т.е. пишем тоже КУРЫ БРОЙЛЕРЫ. Далее переходим сразу к пункту 4.1
Если совпадения не нашли, то переходим к пункту 3.3
3.3 Берем содержимое из третьей ячейки первой строки справочника (лист2) и проделываем тоже самое с первой же ячейкой первой строки базы данных. И так до тех пор, пока не проверим все возможные словосочетания КУР... (думаю максимум можно задать 32. Хотя, можно сделать некоторую проверку... Например, если очередная ячейка в справочнике пуста, то считаем, что всевозможные варианты написания названия данного товара исчерпаны).
Итак. В первой ячейке базы данных мы проверили наличие первого товара.
Переходим ко второй ячейке базы данных.
4.1 Берем содержимое из первой ячейки первой строки справочника (лист2) и пытаемся найти совпадение с содержимым в первой ячейки второй строки базы данных (лист1). Если совпадение есть, то во вторую ячейку второй строки (лист1) копируем содержимое последней ячейки первой строки из справочника (лист2). В справочнике (лист2) последний (или какой то определенный) столбец будет обозначать Истинное значение (наименование) товара. Далее переходим сразу к пункту 5.1
Если совпадения не нашли, то переходим к пункту 4.2
4.2 Аналогично проверяем второй вариант написания КУРЕЙ в первой ячейке второй строки базы данных.
5.1 Проверяем всевозможные варианты написания товара1 (КУРЕЙ в моем примере) в первой ячейке третьей строки базы данных. И т.д. до конца базы данных. Напомню, что база данных состоит только из одного столбца! Т.е. сама база, конечно не из одного столбца. Есть другие столбцы с другими данными, но обрабатываем только один столбец.
Проверив весь столбец на наличие первого товара мы снова переходим к первой ячейке первой строки базы данных и начинаем проверять присутствие совпадений названия второго товара из справочника (лист2). Т.е. сверяем с содержимым из первой ячейки второй строки справочника. Потом второй ячейки второй строки, третьей ячейки второй строки и т.д. по всему справочнику.
Фу. Надеюсь, я достаточно подробно и ясно описал задачу.
Кто подскажет или поможет написать нечто подобно?
На самом деле, если такое возможно, то схему работы можно было бы усложнить некоторыми проверками и запросом с какой ячейки начать обрабатывать базу, например или при нескольких товаров в одной строчке добавлять дополнительную пустую строчку, но это уже слишком сложная работа, наверное и заморачиваться не стОит.
Вся база, грубо говоря, состоит из одного столбца. В каждой ячейке этого столбца имеется текстовая информация (товар, описание товара, его характеристики)
Так базы не делаются.
Вам проще написать программу с нуля (или заказать за деньги) где будет ПО ОТДЕЛЬНОСТИ наименование товара, его описание, характеристики и дт.
Макрос который Вы описали может выдавать ошибки, например:
КУР/Б
КУР/Б
Две одинаковых записи. но в первом случае – курицы бройлерные, а во втором – курвиметр б/у
К сожалению, именно такие базы мне и приходят (не я их составляю). Данный столбец идет как дополнительная информация. В целом же вся изначальная база имеет и много конкретных столбцов, которые я не беру в расчет.
Макрос который Вы описали может выдавать ошибки, например: ...
С этим, естественно, соглашусь, но... Справочник (лист2) буду составлять уже я сам. Поэтому, постараюсь учесть всевозможные колизии по этому поводу. К тому же одна база она как то ориентирована в одной области... Куры - это так... для примера
Я мог бы ПОПРОБОВАТЬ вообще что-нить сделать, подобное я уже делал, но у тебя только куры или есть еще что-нить? Да и работать этот макросос будет ДОЛГО. Ну и сам понимаешь, если вообще от балды народ пишет, то может пройти неполное деление...
присылай готовый файл с нужной для потрошения колонкой и описанием, что будем делать на cccatsmaster@rambler.ru
За результат не ручаюсь, но попробую
Стоимость определишь сам (если все будет работать)
Grozniy, у меня есть вариант решения Вашей задачи. Еще актуально?
(Решение несколько иное, чем Вы описывали... но может быть тоже подойдет... Что-то типа "в процеессе обработки используются ранее определенные подстановки"...)
Пока актуально.
Вообще, пытаюсь пока сам написать что ни будь. Думаю это не так сложно. Главное, правильно составить алгоритм!
А что у Вас за решение? "Что-то типа "в процеессе обработки используются ранее определенные подстановки"". Это как? искуственный интелект что ли?
Ну, интеллект-неинтеллект... но если одну подстановку Вы определили, то она будет обрабатываться именно так и дальше, но уже автоматически.
Это процедура для обчыного модуля:
Public ish As Range, sta As Range, fla As Boolean
Public Sub a_WordsToStandard()
'программа пройдет по столбцу и попытается преобразовать названия в стандартизованные
Dim cc As Range, inslo As Long, wdict As Range
On Error Resume Next
fla = True
If ish Is Nothing Then
Set ish = Application.InputBox(Prompt:="Выдели область исходных слов", Type:=8)
If ish Is Nothing Then Exit Sub
Set ish = ish.Columns(1)
Set sta = Application.InputBox(Prompt:="Выдели столбец для стандартизованных слов", Type:=8)
If sta Is Nothing Then Exit Sub
Set sta = sta.Columns(1).EntireColumn
End If
For Each cc In ish.Cells
If sta.Cells(cc.Row, 1).Value = "" Then
inslo = WorksheetFunction.Match(cc.Value, ish, 0)
If inslo > 0 And Err.Number = 0 And inslo <> cc.Row Then
Application.EnableEvents = False
sta.Cells(cc.Row, 1).Value = sta.Cells(inslo, 1).Value
Application.EnableEvents = True
Else
Application.StatusBar = "Введите стандартное значение для слова: " & cc.Value
Application.OnTime Now() + TimeSerial(0, 0, 10), "StaClear"
sta.Cells(cc.Row, 1).Select
Exit Sub
End If
End If
Next cc
End Sub
Private Sub staClear()
Application.StatusBar = False
End Sub
А это в модуль листа:
Private Sub Worksheet_Change(ByVal Target As Range)
If fla Then
fla = False
If MsgBox("Продолжим?", vbYesNo) = vbYes Then
Call a_WordsToStandard
End If
End If
End Sub
1. Запуск - Alt-F8 - выбрать макрос a_WordsToStandard - Выполнить. (Хотите улучшать - улучшайте, как хотите.)
2. Программа спросит указать область исходных слов и столбец стандартизованных (куда должны быть вписаны стандартизованные слова/фразы)
3. Курсор остановится на очередном "пока неопределенном" поле стандартизованных значений
4. В место остановки курсора нужно ввести стандартизованное значение для соответствующего слова.
ЗДЕСЬ ВАЖНО!: можно ввести нужное слово/фразу, но можно нажать Alt+СтрелкаВниз - выпадет список уже введенных стандатизованных значений отсортированных по алфавиту - это может помочь в заполнении
5. После ввода нужного стандартизованного значения программа продолжит автоматически заполнять следующие стандартизованные значения, пока не столкнется со значением, страндартизвованное значение которого пока неопределено.
6. Программа будет предлагать продолжать свою работу, пока все ячейки исходных значений не будут просмотренны (а их стандартизованные значения не будут определены)
7. Если необходимо отказаться от продолжения работы, то это можно сделать. Следующий запуск программы возобновит обработку с первого неопределенного стандартизованного значения.
Таким образом, получился какбы самообучаемый словарь стандартизации исходных названий.
Это решение можно взять за основу (но оно не подойдет без доработок), если у Вас постоянно появляются все новые и новые файлы/списки... Это решение будет работать лучше и лучше, если список слов, требующих обработки, будет добавляться в конец уже существующего и уже обработанного списка.
Да, это немного не то, что мне хотелось бы.
Базы как правило разнородные. И каждый раз придется "учить" макрос с нуля.
Даже если взять одну тему, то две базы еще как то можно совместить (допустим, 25 и 30 тыс записей), а третья уже не поместится - строк не хватает.
Со справочником было бы намного проще. На его составление потратить какое то время, а потом можно будет использовать хоть сотню раз.
В предложенное мной решение без проблем можно добавить ведение и справочка тоже... потребуются только команды открытия этого справочка (а если процедура обработки будет размещена в книге справочка, то и этого может не потребоваться), добавление в справочник новых решений по ходу обработки и сохранение справочника по завершению работы.