Добрый день! Возникла необходимость добавления примечаний с использованием макроса (связывается по артикулу). Помогите, пожалуйста, с решением такой задачи: во вложенном файле нужно макросом на лист "АНАЛИТ" в ячейки M:M (с листа "Магазин №1", ячейки H:H), U:U (с листа "Магазин №2", ячейки H:H), AC:AC (с листа "Магазин №4", ячейки H:H), AK:AK (с листа "Магазин №6", ячейки H:H) подтягивать примечания.
Добрый день! Возникла необходимость добавления примечаний с использованием макроса (связывается по артикулу). Помогите, пожалуйста, с решением такой задачи: во вложенном файле нужно макросом на лист "АНАЛИТ" в ячейки M:M (с листа "Магазин №1", ячейки H:H), U:U (с листа "Магазин №2", ячейки H:H), AC:AC (с листа "Магазин №4", ячейки H:H), AK:AK (с листа "Магазин №6", ячейки H:H) подтягивать примечания.Inna13Kr
К сожалению, тема, о которой Вы пишете, уже закрыта, а макрос, предложенный в ней, не работает в моем файле: примечания проставляются на листах Магазин №1, Магазин №2, Магазин №4 и Магазин №6, а в рабочий лист АНАЛИТ почему-то не подтягиваются.
К сожалению, тема, о которой Вы пишете, уже закрыта, а макрос, предложенный в ней, не работает в моем файле: примечания проставляются на листах Магазин №1, Магазин №2, Магазин №4 и Магазин №6, а в рабочий лист АНАЛИТ почему-то не подтягиваются. Inna13Kr
Сообщение отредактировал Inna13Kr - Понедельник, 29.12.2014, 18:51
Sub Примечание() LastCell = Cells(Rows.Count, 4).End(xlUp).Row magazin = Array("Магазин №1", "Магазин №2", "Магазин №4", "Магазин №6") For j = 13 To 37 Step 8 Set sh = Sheets(magazin(m)) LastCell2 = sh.Cells(Rows.Count, 3).End(xlUp).Row For i = 10 To LastCell SKU = Cells(i, 2) toComm = "" For k = 2 To LastCell2 If sh.Cells(k, 1) = SKU Then toComm = sh.Cells(k, 8).Value: Exit For Next k If Not Cells(i, j).Comment Is Nothing Then Cells(i, j).ClearComments If toComm <> "" Then Cells(i, j).NoteText Text:=toComm Cells(i, j).Comment.Shape.TextFrame.AutoSize = True End If Next i m = m + 1 Next j End Sub
[/vba]
Тестируйте.
[vba]
Код
Sub Примечание() LastCell = Cells(Rows.Count, 4).End(xlUp).Row magazin = Array("Магазин №1", "Магазин №2", "Магазин №4", "Магазин №6") For j = 13 To 37 Step 8 Set sh = Sheets(magazin(m)) LastCell2 = sh.Cells(Rows.Count, 3).End(xlUp).Row For i = 10 To LastCell SKU = Cells(i, 2) toComm = "" For k = 2 To LastCell2 If sh.Cells(k, 1) = SKU Then toComm = sh.Cells(k, 8).Value: Exit For Next k If Not Cells(i, j).Comment Is Nothing Then Cells(i, j).ClearComments If toComm <> "" Then Cells(i, j).NoteText Text:=toComm Cells(i, j).Comment.Shape.TextFrame.AutoSize = True End If Next i m = m + 1 Next j End Sub
Leanna, спасибо. Макрос работает, только виснет (подтягивает инфу около 2-3 мин)... В чем может быть проблема, не подскажете? ЕЩЕ ИНТЕРЕСУЕТ ВОПРОС: как можно прописать аналогичный макрос с использованием функции VLookup?
Leanna, спасибо. Макрос работает, только виснет (подтягивает инфу около 2-3 мин)... В чем может быть проблема, не подскажете? ЕЩЕ ИНТЕРЕСУЕТ ВОПРОС: как можно прописать аналогичный макрос с использованием функции VLookup?Inna13Kr
Сообщение отредактировал Inna13Kr - Вторник, 30.12.2014, 14:15
Перевела в массив обращения, попробуйте, должно быть побыстрее, если будет долго сделаю c Vlookup. (ps не уверена что vlookup убыстрит) [vba]
Код
Sub Примечание() Dim key1, result1, SKU LastCell = Cells(Rows.Count, 4).End(xlUp).Row magazin = Array("Магазин №1", "Магазин №2", "Магазин №4", "Магазин №6") For j = 13 To 37 Step 8 Set sh = Sheets(magazin(m)) LastCell2 = sh.Cells(Rows.Count, 3).End(xlUp).Row key1 = sh.Range("A2:A" & LastCell2).Value result1 = sh.Range("H2:H" & LastCell2).Value SKU = [B1].Resize(LastCell, 1).Value For i = 10 To LastCell toComm = "" For k = 1 To UBound(key1) If key1(k, 1) * 1 = SKU(i, 1) * 1 Then toComm = result1(k, 1): Exit For Next k If toComm = "" And Not Cells(i, j).Comment Is Nothing Then Cells(i, j).ClearComments If toComm <> "" Then Cells(i, j).NoteText Text:=toComm Cells(i, j).Comment.Shape.TextFrame.AutoSize = True End If Next i m = m + 1 Next j End Sub
[/vba]
Перевела в массив обращения, попробуйте, должно быть побыстрее, если будет долго сделаю c Vlookup. (ps не уверена что vlookup убыстрит) [vba]
Код
Sub Примечание() Dim key1, result1, SKU LastCell = Cells(Rows.Count, 4).End(xlUp).Row magazin = Array("Магазин №1", "Магазин №2", "Магазин №4", "Магазин №6") For j = 13 To 37 Step 8 Set sh = Sheets(magazin(m)) LastCell2 = sh.Cells(Rows.Count, 3).End(xlUp).Row key1 = sh.Range("A2:A" & LastCell2).Value result1 = sh.Range("H2:H" & LastCell2).Value SKU = [B1].Resize(LastCell, 1).Value For i = 10 To LastCell toComm = "" For k = 1 To UBound(key1) If key1(k, 1) * 1 = SKU(i, 1) * 1 Then toComm = result1(k, 1): Exit For Next k If toComm = "" And Not Cells(i, j).Comment Is Nothing Then Cells(i, j).ClearComments If toComm <> "" Then Cells(i, j).NoteText Text:=toComm Cells(i, j).Comment.Shape.TextFrame.AutoSize = True End If Next i m = m + 1 Next j End Sub
А это с VLookup, скажите какой побыстрее отрабатывает [vba]
Код
Sub Примечание() Dim key1, result1, SKU LastCell = Cells(Rows.Count, 4).End(xlUp).Row magazin = Array("Магазин №1", "Магазин №2", "Магазин №4", "Магазин №6") For j = 13 To 37 Step 8 Set sh = Sheets(magazin(m)) LastCell2 = sh.Cells(Rows.Count, 3).End(xlUp).Row key1 = sh.Range("A2:H" & LastCell2).Value SKU = [B1].Resize(LastCell, 1).Value For i = 10 To LastCell On Error Resume Next toComm = Trim(Application.WorksheetFunction.VLookup(SKU(i, 1) * 1, key1, 8, 0)) If Err <> 0 Then toComm = "" If toComm <> "" Then Cells(i, j).NoteText Text:=toComm Cells(i, j).Comment.Shape.TextFrame.AutoSize = True End If If toComm = "" And Not Cells(i, j).Comment Is Nothing Then Cells(i, j).ClearComments On Error GoTo 0 Next i m = m + 1 Next j End Sub
[/vba]
А это с VLookup, скажите какой побыстрее отрабатывает [vba]
Код
Sub Примечание() Dim key1, result1, SKU LastCell = Cells(Rows.Count, 4).End(xlUp).Row magazin = Array("Магазин №1", "Магазин №2", "Магазин №4", "Магазин №6") For j = 13 To 37 Step 8 Set sh = Sheets(magazin(m)) LastCell2 = sh.Cells(Rows.Count, 3).End(xlUp).Row key1 = sh.Range("A2:H" & LastCell2).Value SKU = [B1].Resize(LastCell, 1).Value For i = 10 To LastCell On Error Resume Next toComm = Trim(Application.WorksheetFunction.VLookup(SKU(i, 1) * 1, key1, 8, 0)) If Err <> 0 Then toComm = "" If toComm <> "" Then Cells(i, j).NoteText Text:=toComm Cells(i, j).Comment.Shape.TextFrame.AutoSize = True End If If toComm = "" And Not Cells(i, j).Comment Is Nothing Then Cells(i, j).ClearComments On Error GoTo 0 Next i m = m + 1 Next j End Sub
Leanna, при использовании 2-ого и 3-го вариантов- все равно подвисает. Возможно, много строк- 4000? При запуске последнего выдает ошибку "Type mismatch (Error 13)", нажимаю End-проставляются примечания только в столбце М.
Leanna, при использовании 2-ого и 3-го вариантов- все равно подвисает. Возможно, много строк- 4000? При запуске последнего выдает ошибку "Type mismatch (Error 13)", нажимаю End-проставляются примечания только в столбце М.Inna13Kr
Сообщение отредактировал Inna13Kr - Вторник, 30.12.2014, 17:43
Работа с ячейками - всегда долго. А работа с примечаниями - это работа с ячейками, и даже хуже... Поэтому быстро не будет. Может быть можно к массивам ещё и словарь привлечь (не вникал, может и не можно...) - но всё равно это ускорит на пару секунд, что на минуте работы с примечаниями не скажется.
P.S. Посмотрел - можно словарь привлечь: запоминаем в словаре адреса ячеек для ключей артикул-лист, затем циклом по данным-массивам листов если находим необходимость писать комментарий - пишем по адресу из словаря. Предварительно можно молча стереть скопом все примечания - так быстрее. Если конечно это нужно по задаче.
Работа с ячейками - всегда долго. А работа с примечаниями - это работа с ячейками, и даже хуже... Поэтому быстро не будет. Может быть можно к массивам ещё и словарь привлечь (не вникал, может и не можно...) - но всё равно это ускорит на пару секунд, что на минуте работы с примечаниями не скажется.
P.S. Посмотрел - можно словарь привлечь: запоминаем в словаре адреса ячеек для ключей артикул-лист, затем циклом по данным-массивам листов если находим необходимость писать комментарий - пишем по адресу из словаря. Предварительно можно молча стереть скопом все примечания - так быстрее. Если конечно это нужно по задаче.Hugo
Технически не очень поняла про словари >>"запоминаем в словаре адреса ячеек для ключей артикул-лист" цикл по массиву(?) где записываем адреса(которых в массиве нет, а ячейки лишний раз трогать не хотим) в item, артикул-лист key(?). Получается адреса будут вида 5 строка 6 колонка, т.е. потом это надо сплитовать, так же как и артикул-лист >>затем циклом по данным-массивам листов если находим необходимость писать комментарий - пишем по адресу из словаря Не поняла. В целом для меня темный лес, зачем нужен адрес из словаря? есть же циклы i по строкам и j по столбцам главной табл.- вот и есть адрес, без этих циклов же все равно не обойтись (?) - перебор по артикулам-столбцам=магазинам.
Не понимаю как именно можно сделать то о чем вы говорите, перебор столбцов и строк мне понятен, а как словари сюда прикручиваются и оптимизируют - нет. Я вижу только лишние циклы - по загону данных в словарь и лишние сплиты что бы считать данные со словаря, что если не замедляет, то запутывает. Если поясните буду благодарна. "За" оптимизацию)) Честно хочу понять как можно ускориться за счет словарей.
Про скопом стирание примечаний согласна.
Технически не очень поняла про словари >>"запоминаем в словаре адреса ячеек для ключей артикул-лист" цикл по массиву(?) где записываем адреса(которых в массиве нет, а ячейки лишний раз трогать не хотим) в item, артикул-лист key(?). Получается адреса будут вида 5 строка 6 колонка, т.е. потом это надо сплитовать, так же как и артикул-лист >>затем циклом по данным-массивам листов если находим необходимость писать комментарий - пишем по адресу из словаря Не поняла. В целом для меня темный лес, зачем нужен адрес из словаря? есть же циклы i по строкам и j по столбцам главной табл.- вот и есть адрес, без этих циклов же все равно не обойтись (?) - перебор по артикулам-столбцам=магазинам.
Не понимаю как именно можно сделать то о чем вы говорите, перебор столбцов и строк мне понятен, а как словари сюда прикручиваются и оптимизируют - нет. Я вижу только лишние циклы - по загону данных в словарь и лишние сплиты что бы считать данные со словаря, что если не замедляет, то запутывает. Если поясните буду благодарна. "За" оптимизацию)) Честно хочу понять как можно ускориться за счет словарей.Leanna
Лучше день потерять, потом за пять минут долететь!
Сделал пример на словаре - даже получилось чуть медленнее , хотя в общем одинаково, если отключить отключения в коде Но кажется что код как раз понятнее.
[vba]
Код
Option Explicit
Sub tt() Dim tm!: tm = Timer Dim adr, magazin, a(), h(), i&, ii&, lc&, el, s$ adr = Array("M", "U", "AC", "AK") magazin = Array("Магазин №1", "Магазин №2", "Магазин №4", "Магазин №6")
With Sheets("АНАЛИТ") lc = .Cells(.Rows.Count, 3).End(xlUp).Row a = .Range("B10:B" & lc).Value .Range("M10:AK" & lc).ClearComments End With
With CreateObject("scripting.dictionary") 'заполняем словарь адресами ячеек артикул/магазин For i = 1 To UBound(a) For ii = 0 To UBound(adr) .Item(a(i, 1) & "|" & magazin(ii)) = adr(ii) & i + 9 Next Next
For Each el In magazin 'цикл по листам With Sheets(el) lc = .Cells(.Rows.Count, 1).End(xlUp).Row a = .Range("A2:A" & lc).Value h = .Range("H2:H" & lc).Value End With For i = 1 To UBound(a) 'цикл по данным листа If Len(h(i, 1)) Then 'если есть что писать в примечание s = .Item(a(i, 1) & "|" & el) 'извлекаем адрес With Sheets("АНАЛИТ").Range(s) 'пишем примечание .NoteText Text:=h(i, 1) .Comment.Shape.TextFrame.AutoSize = True End With End If Next Next
[/vba] Вообще переменная s не нужна - без неё шевелится чуть быстрее. Но код чуть непонятнее.
Сделал пример на словаре - даже получилось чуть медленнее , хотя в общем одинаково, если отключить отключения в коде Но кажется что код как раз понятнее.
[vba]
Код
Option Explicit
Sub tt() Dim tm!: tm = Timer Dim adr, magazin, a(), h(), i&, ii&, lc&, el, s$ adr = Array("M", "U", "AC", "AK") magazin = Array("Магазин №1", "Магазин №2", "Магазин №4", "Магазин №6")
With Sheets("АНАЛИТ") lc = .Cells(.Rows.Count, 3).End(xlUp).Row a = .Range("B10:B" & lc).Value .Range("M10:AK" & lc).ClearComments End With
With CreateObject("scripting.dictionary") 'заполняем словарь адресами ячеек артикул/магазин For i = 1 To UBound(a) For ii = 0 To UBound(adr) .Item(a(i, 1) & "|" & magazin(ii)) = adr(ii) & i + 9 Next Next
For Each el In magazin 'цикл по листам With Sheets(el) lc = .Cells(.Rows.Count, 1).End(xlUp).Row a = .Range("A2:A" & lc).Value h = .Range("H2:H" & lc).Value End With For i = 1 To UBound(a) 'цикл по данным листа If Len(h(i, 1)) Then 'если есть что писать в примечание s = .Item(a(i, 1) & "|" & el) 'извлекаем адрес With Sheets("АНАЛИТ").Range(s) 'пишем примечание .NoteText Text:=h(i, 1) .Comment.Shape.TextFrame.AutoSize = True End With End If Next Next
Hugo, спасибо за мастер класс "как ещё можно"! Особенно если бы колонки куда вставляются примечания были бы с неравным шагом, то именно так как у вас было бы лучше делать.
Hugo, спасибо за мастер класс "как ещё можно"! Особенно если бы колонки куда вставляются примечания были бы с неравным шагом, то именно так как у вас было бы лучше делать.Leanna
Лучше день потерять, потом за пять минут долететь!
Если эти столбцы вообще изначально непонятно где - то их можно сперва в коде определить (поиском или циклом, не важно), занести буквы в коллекцию или словарь, перекинуть в массив, ну или сразу в массив. Вообще тут по задаче видно что листы и эти столбцы всегда изначально известно где и какие (тем более что их наименования неодинаковы) - т.е. когда добавится лист магазина - то соответственно появится и его диапазон на сводном листе. Поэтому я это в коде прописал явно, как впрочем это сделала и Leanna.
Если эти столбцы вообще изначально непонятно где - то их можно сперва в коде определить (поиском или циклом, не важно), занести буквы в коллекцию или словарь, перекинуть в массив, ну или сразу в массив. Вообще тут по задаче видно что листы и эти столбцы всегда изначально известно где и какие (тем более что их наименования неодинаковы) - т.е. когда добавится лист магазина - то соответственно появится и его диапазон на сводном листе. Поэтому я это в коде прописал явно, как впрочем это сделала и Leanna.Hugo