Visual Basic, .NET, ASP, VBScript
 

   
   
     

Форум - VBA

Страница: 1 |

 

  Вопрос: Помогите написать макрос в exel Добавлено: 20.04.07 12:01  

Автор вопроса:  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). Т.е. сверяем с содержимым из первой ячейки второй строки справочника. Потом второй ячейки второй строки, третьей ячейки второй строки и т.д. по всему справочнику.

Фу. Надеюсь, я достаточно подробно и ясно описал задачу.
Кто подскажет или поможет написать нечто подобно?

На самом деле, если такое возможно, то схему работы можно было бы усложнить некоторыми проверками и запросом с какой ячейки начать обрабатывать базу, например или при нескольких товаров в одной строчке добавлять дополнительную пустую строчку, но это уже слишком сложная работа, наверное и заморачиваться не стОит.

Ответить

  Ответы Всего ответов: 12  

Номер ответа: 1
Автор ответа:
 Черный ворон



Разработчик

ICQ: 342881585 

Вопросов: 32
Ответов: 256
 Профиль | | #1 Добавлено: 20.04.07 12:40
Вся база, грубо говоря, состоит из одного столбца. В каждой ячейке этого столбца имеется текстовая информация (товар, описание товара, его характеристики)

Так базы не делаются.
Вам проще написать программу с нуля (или заказать за деньги) где будет ПО ОТДЕЛЬНОСТИ наименование товара, его описание, характеристики и дт.
Макрос который Вы описали может выдавать ошибки, например:
КУР/Б
КУР/Б
Две одинаковых записи. но в первом случае – курицы бройлерные, а во втором – курвиметр б/у

Ответить

Номер ответа: 2
Автор ответа:
 Grozniy



Вопросов: 1
Ответов: 4
 Web-сайт: www.softopark.ru/
 Профиль | | #2
Добавлено: 20.04.07 15:19
Так базы не делаются.

К сожалению, именно такие базы мне и приходят (не я их составляю). Данный столбец идет как дополнительная информация. В целом же вся изначальная база имеет и много конкретных столбцов, которые я не беру в расчет.

Макрос который Вы описали может выдавать ошибки, например: ...

С этим, естественно, соглашусь, но... Справочник (лист2) буду составлять уже я сам. Поэтому, постараюсь учесть всевозможные колизии по этому поводу. К тому же одна база она как то ориентирована в одной области... Куры - это так... для примера :)

Ответить

Номер ответа: 3
Автор ответа:
 angrynews



Вопросов: 33
Ответов: 119
 Web-сайт: www.angrynews.ru
 Профиль | | #3
Добавлено: 20.04.07 15:22
Я мог бы ПОПРОБОВАТЬ вообще что-нить сделать, подобное я уже делал, но у тебя только куры или есть еще что-нить? Да и работать этот макросос будет ДОЛГО. Ну и сам понимаешь, если вообще от балды народ пишет, то может пройти неполное деление...

Ответить

Номер ответа: 4
Автор ответа:
 angrynews



Вопросов: 33
Ответов: 119
 Web-сайт: www.angrynews.ru
 Профиль | | #4
Добавлено: 20.04.07 15:26
присылай готовый файл с нужной для потрошения колонкой и описанием, что будем делать на cccatsmaster@rambler.ru
За результат не ручаюсь, но попробую :-)
Стоимость определишь сам (если все будет работать)

Ответить

Номер ответа: 5
Автор ответа:
 angrynews



Вопросов: 33
Ответов: 119
 Web-сайт: www.angrynews.ru
 Профиль | | #5
Добавлено: 20.04.07 15:26
Сорри адрес
catsmaster@rambler.ru

Ответить

Номер ответа: 6
Автор ответа:
 Grozniy



Вопросов: 1
Ответов: 4
 Web-сайт: www.softopark.ru/
 Профиль | | #6
Добавлено: 20.04.07 15:45
... у тебя только куры или есть еще что-нить?

Может быть все что угодно! Автомобили, мебель, шины, алкоголь, стройматериалы...

Да и работать этот макросос будет ДОЛГО

Да пусть хоть сутками работает! :) Вручную делать намного дольше будет!

... может пройти неполное деление

Это тоже понятно. Кое что придется все же вручную проделать. К тому же это только часть разбора. В целом, все намного сложнее!

Ответить

Номер ответа: 7
Автор ответа:
 angrynews



Вопросов: 33
Ответов: 119
 Web-сайт: www.angrynews.ru
 Профиль | | #7
Добавлено: 20.04.07 16:14
Вот и опиши полностью,что ты хочешь видеть. И сам пример пришли

Ответить

Номер ответа: 8
Автор ответа:
 GenyaA



Вопросов: 0
Ответов: 185
 Web-сайт: www.genyaa.nm.ru
 Профиль | | #8
Добавлено: 21.04.07 00:17
Grozniy, у меня есть вариант решения Вашей задачи. Еще актуально?

(Решение несколько иное, чем Вы описывали... но может быть тоже подойдет... Что-то типа "в процеессе обработки используются ранее определенные подстановки"...)

Ответить

Номер ответа: 9
Автор ответа:
 Grozniy



Вопросов: 1
Ответов: 4
 Web-сайт: www.softopark.ru/
 Профиль | | #9
Добавлено: 21.04.07 19:56
Пока актуально.
Вообще, пытаюсь пока сам написать что ни будь. Думаю это не так сложно. Главное, правильно составить алгоритм! :)
А что у Вас за решение? "Что-то типа "в процеессе обработки используются ранее определенные подстановки"". Это как? искуственный интелект что ли?

Ответить

Номер ответа: 10
Автор ответа:
 GenyaA



Вопросов: 0
Ответов: 185
 Web-сайт: www.genyaa.nm.ru
 Профиль | | #10
Добавлено: 21.04.07 20:18
Ну, интеллект-неинтеллект... но если одну подстановку Вы определили, то она будет обрабатываться именно так и дальше, но уже автоматически.

Это процедура для обчыного модуля:

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. Если необходимо отказаться от продолжения работы, то это можно сделать. Следующий запуск программы возобновит обработку с первого неопределенного стандартизованного значения.

Таким образом, получился какбы самообучаемый словарь стандартизации исходных названий.

Это решение можно взять за основу (но оно не подойдет без доработок), если у Вас постоянно появляются все новые и новые файлы/списки... Это решение будет работать лучше и лучше, если список слов, требующих обработки, будет добавляться в конец уже существующего и уже обработанного списка.

Ответить

Номер ответа: 11
Автор ответа:
 Grozniy



Вопросов: 1
Ответов: 4
 Web-сайт: www.softopark.ru/
 Профиль | | #11
Добавлено: 26.04.07 10:16
Да, это немного не то, что мне хотелось бы.
Базы как правило разнородные. И каждый раз придется "учить" макрос с нуля.
Даже если взять одну тему, то две базы еще как то можно совместить (допустим, 25 и 30 тыс записей), а третья уже не поместится - строк не хватает.
Со справочником было бы намного проще. На его составление потратить какое то время, а потом можно будет использовать хоть сотню раз.

Ответить

Номер ответа: 12
Автор ответа:
 GenyaA



Вопросов: 0
Ответов: 185
 Web-сайт: www.genyaa.nm.ru
 Профиль | | #12
Добавлено: 26.04.07 11:05
В предложенное мной решение без проблем можно добавить ведение и справочка тоже... потребуются только команды открытия этого справочка (а если процедура обработки будет размещена в книге справочка, то и этого может не потребоваться), добавление в справочник новых решений по ходу обработки и сохранение справочника по завершению работы.

Ответить

Страница: 1 |

Поиск по форуму



© Copyright 2002-2011 VBNet.RU | Пишите нам