Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Microsoft Office и VBA программирование > Microsoft Office Excel
Регистрация

Восстановить пароль

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 16.02.2010, 15:40   #1
Nekota
Пользователь
 
Регистрация: 16.02.2010
Сообщений: 12
По умолчанию Выборка данных в листе А по параметру 1 из листа Б

Добрый день.
Есть проблема следующего вида - у меня есть 2 прайс листа (один мой другой поставщика), в каждом из прайсов есть колонки "артикул" и "наличие". Нужно что бы по артикулу из моего прайса делался поиск в прайсе поставщика. Если в прайсе поставщика есть такой артикул, то проверяется наличие товара. Если товар есть хоть на одном из складов, то в моём прайсе в ячейке этого товара ставится пометка "наличие", если товара нету, то ставится пометка "заказ".
Прайсы формате 2007 Exel.
Сам уже лет 5 на VB не писал - не помню уже ничего. Буду благодарен, как и за готовые решения, так и за советы по решению данной проблемы.
Заранее спасибо.
Вложения
Тип файла: rar 123.rar (2.21 Мб, 15 просмотров)
Nekota вне форума Ответить с цитированием
Старый 16.02.2010, 15:56   #2
Dophin
Форумчанин
 
Аватар для Dophin
 
Регистрация: 13.01.2010
Сообщений: 410
По умолчанию

не нашел ни на одном листе колонок "наличие".

счетз(смещ(индекс(поискпоз())))

формулами так наверно можно)

Последний раз редактировалось Dophin; 16.02.2010 в 15:59.
Dophin вне форума Ответить с цитированием
Старый 16.02.2010, 15:59   #3
Nekota
Пользователь
 
Регистрация: 16.02.2010
Сообщений: 12
По умолчанию

В листе "мой прайс" это столбец T, а с листом "прайс поставщика" я немного ошибся... Там нет такого столбца, там наличием являются столбцы C, D, E, F и G

Последний раз редактировалось Nekota; 16.02.2010 в 16:16.
Nekota вне форума Ответить с цитированием
Старый 16.02.2010, 16:07   #4
Maxx
Форумчанин
 
Аватар для Maxx
 
Регистрация: 29.10.2008
Сообщений: 294
По умолчанию

Цитата:
В листе "мой прайс" это столбец S
На сколько я понял - это столбец T.

То, что вы просите сделать не сложно. Однако, это конечно не мое дело, прежде чем это делать, Вам следует привести Ваш прайс в порядок
Например столбцы B и C начиная со строки 5255, ячейка D5263, да и еще много чего непонятного.

Последний раз редактировалось Maxx; 16.02.2010 в 16:10.
Maxx вне форума Ответить с цитированием
Старый 16.02.2010, 16:09   #5
EducatedFool
Программист VBA
СуперМодератор
 
Аватар для EducatedFool
 
Регистрация: 13.07.2008
Сообщений: 6,858
По умолчанию

Кривой у Вас прайс какой-то...
До 5254-й строки артикулы находятся в столбце С, а ниже - уже в столбце В.
Макросу это вряд ли понравится...


Вот Вам готовый макрос:

Код:
Sub ОсновнойМакрос()
    Dim sh1 As Worksheet: Set sh1 = Sheets("Мой прайс")
    Dim sh2 As Worksheet: Set sh2 = Sheets("Прайс поставщика")
    Dim cell As Range, ra As Range: Application.ScreenUpdating = False

    Set ra = sh1.Range(sh1.[c2], Range("c" & Rows.Count).End(xlUp))    ' обрабатываемый диапазон ячеек
    n = ra.SpecialCells(xlCellTypeConstants).Count    ' для статистики в строке состояния

    For Each cell In ra.SpecialCells(xlCellTypeConstants).Cells    ' перебираем все непустые
        i = i + 1: If i Mod 50 = 0 Then Application.StatusBar = _
                      "Обрабатывается строка " & cell.Row & "     (ячейка " & i & " из " & n & ")"

        ' в столбец 20 пишем результат проверки
        cell.EntireRow.Cells(20) = _
        IIf(ЕстьТакойТовар(cell, sh2.UsedRange.Columns(1)), "наличие", "заказ")
    Next cell
    Application.StatusBar = False
End Sub

Function ЕстьТакойТовар(ByVal Артикул As String, ДиапазонПоиска As Range) As Boolean
    On Error Resume Next: Err.Clear
    x = ДиапазонПоиска.Find(Артикул).Next.Next.Resize(, 4).Find("*").Address
    ЕстьТакойТовар = Err = 0
End Function
Выполняется он, конечно, долго - порядка 10-15 секунд, но, чтобы сделать быстрее, придётся значительно усложнять алгоритм.

PS: Все артикулы предварительно я поместил в 3-й столбец
В строке состояния Excel отображается ход обработки.

См. пример в файле:



(добавлено)
В макросе, который в примере файла, небольшая ошибка - не заметил, что в файле поставщика 5 складов, а не 4.
Замените в строке
x = ДиапазонПоиска.Find(Артикул).Next.N ext.Resize(, 4).Find("*").Address
4 на 5

Последний раз редактировалось EducatedFool; 16.02.2010 в 16:13.
EducatedFool вне форума Ответить с цитированием
Старый 16.02.2010, 16:11   #6
Nekota
Пользователь
 
Регистрация: 16.02.2010
Сообщений: 12
По умолчанию

Я делаю поиск по артикулу:
Код:
    Range("A10").Select
    ActiveCell.FormulaR1C1 = "0132658"
    Sheets("Прайс поставщика").Select
    Cells.Find(What:="0132658", After:=ActiveCell, LookIn:=xlFormulas, _
        LookAt:=xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, _
        MatchCase:=False, SearchFormat:=False).Activate
Это сделать было не сложно, но далее я выпал в ступор по 2м причинам:
1.) Строка
Код:
Range("A10").Select
делает поиск только по артикулу забитому в строке 10 столбца А. А надо получить поиск по всем имеющимся артикулам.
2.) Итогом данного действа является, то что я нахожу строку данного артикула в "прайсе поставщика". Как сделать чтобы делалась проверка на наличие наличия товара (простите за тавтологию) только в найденой строке.

учитывая что поиск делался по А10, то пишем вT10 (там наличие в моём прайсе) либо nal (если есть), либо zak (если нет)... Вот как-то так...

Последний раз редактировалось Nekota; 16.02.2010 в 16:15.
Nekota вне форума Ответить с цитированием
Старый 16.02.2010, 16:15   #7
Nekota
Пользователь
 
Регистрация: 16.02.2010
Сообщений: 12
По умолчанию

EducatedFool, кривой, а делать приходится в нём=( тока в С находится наш внутренний артикул=) а артикул по которому надо искать находится в А... и забит он только до 2166 и то не везде... За пример спасибо сейчас попробую.

Maxx, прошу прощения - ошибся...
Nekota вне форума Ответить с цитированием
Старый 16.02.2010, 16:40   #8
Maxx
Форумчанин
 
Аватар для Maxx
 
Регистрация: 29.10.2008
Сообщений: 294
По умолчанию

To EducatedFool:
не первый раз вижу у Вас такую конструкцию
x = ДиапазонПоиска.Find(Артикул).Next.N ext.Resize(, 4).Find("*").Address
Можно в двух словах пояснить, как это работает?
Maxx вне форума Ответить с цитированием
Старый 16.02.2010, 16:46   #9
Nekota
Пользователь
 
Регистрация: 16.02.2010
Сообщений: 12
По умолчанию

EducatedFool, Спасибо большое=) Всё шикарно работает.
есть 2 вопроса:
1.) Можно ли сделать так чтобы он строчки в которых артикула нету пропускал?
2.) Напишите пожалуйста что что значит в скрипте=) очень уж интересно=)
По всей видимости придётся теперь частенько писать скрипты, а постоянно просить на форуме не хотелось бы...
Nekota вне форума Ответить с цитированием
Старый 16.02.2010, 17:05   #10
EducatedFool
Программист VBA
СуперМодератор
 
Аватар для EducatedFool
 
Регистрация: 13.07.2008
Сообщений: 6,858
По умолчанию

Цитата:
Можно ли сделать так чтобы он строчки в которых артикула нету пропускал?
А разве макрос работает как-то иначе???



Цитата:
Напишите пожалуйста что что значит в скрипте=) очень уж интересно=)
Мне самому интересно)) Сам с трудом понимаю, как это работает

Единственное, что, на мой взгляд, нуждается в комментариях, так это функция
Код:
Function ЕстьТакойТовар(ByVal Артикул As String, ДиапазонПоиска As Range) As Boolean
    On Error Resume Next: Err.Clear
    x = ДиапазонПоиска.Find(Артикул).Next.Next.Resize(, 4).Find("*").Address
    ЕстьТакойТовар = Err = 0
End Function
Эта функция получает в качестве параметров Артикул для поиска, и диапазон, в котором следует искать этот артикул.
Диапазон для поиска - это sh2.UsedRange.Columns(1)
То есть первый столбец ИСПОЛЬЗУЕМОЙ области листа sh2 = Sheets("Прайс поставщика")
В данном примере, это ячейки a4:a13309 листа Прайс поставщика

Что делает функция? Она пытается выполнить последовательность действий по поиску, после чего проверяет, вызвали ли эти действия ошибку.
Если в ходе поиска произошла ошибка (любая) - Err <> 0 - артикул не найден, и функция возвращает FALSE
Если ошибок не возникло, то возвращается TRUE (артикул найден)

Как производится поиск:
В диапазоне a4:a13309 ищется ячейка, содержащая артикул ДиапазонПоиска.Find(Артикул)
от этой найденной ячейки отступаем вправо на 2 ячейки .Next.Next
расширяем выделение на 5 ячеек .Resize(, 5)
и в этих ячейках (на пересечении строки с найденным артикулом и 5 столбцов-складов) ищем что-нибудь (любой символ) .Find("*")

Если все эти действия отработали без ошибок - значит, товар найден в прайсе, и присутствует хотя бы на одном из складов.
EducatedFool вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Замена листа с сохранением его имени на другом листе akd2009 Microsoft Office Excel 2 03.02.2010 15:52
Разворачивание/сворачивание данных на защищенном листе Wespe Microsoft Office Excel 12 02.02.2010 12:11
Перенос данных из строк в массив на другом листе akd2009 Microsoft Office Excel 2 15.12.2009 15:58
Помогите пожалуйста с решением поставленной задачи (Выборка товара из прайс-листа) DimonPS Microsoft Office Excel 4 12.11.2009 10:51
Фильтрация данных на втором листе по данным на первом ppl Microsoft Office Excel 3 13.08.2008 14:07