Домашняя страница Undo Do New Save Карта сайта Обратная связь Поиск по форуму
МИР MS EXCEL - Гость.xls

Вход

Регистрация

Напомнить пароль

 

= Мир MS Excel/Сравнение двух листов, подстановка данных (массив/словарь) - Мир MS Excel

Старая форма входа
  • Страница 1 из 2
  • 1
  • 2
  • »
Модератор форума: китин, _Boroda_  
Мир MS Excel » Вопросы и решения » Вопросы по VBA » Сравнение двух листов, подстановка данных (массив/словарь) (Макросы/Sub)
Сравнение двух листов, подстановка данных (массив/словарь)
DJ_Marker_MC Дата: Пятница, 16.01.2015, 18:38 | Сообщение № 1
Группа: Друзья
Ранг: Ветеран
Сообщений: 991
Репутация: 213 ±
Замечаний: 0% ±

Excel 2019
Друзья, приходится обратиться сегодня уже второй раз за помощью.
Имеется файл в котором два листа, второй лист "Предоплата" это небольшая часть листа БАЗА
Сам файл большой и обычный цикл выполняется долго, имеется такой вот цикл:

[vba]
Код
Private Sub CommandButton1_Click()
Dim f As String
Application.ScreenUpdating = False
Application.Calculation = xlManual

lAntR = Sheets("Предоплата").Cells.Find(What:="*", SearchOrder:=xlByRows, SearchDirection:=xlPrevious).Row
lAntRB = Sheets("БАЗА").Cells.Find(What:="*", SearchOrder:=xlByRows, SearchDirection:=xlPrevious).Row

For p = 2 To lAntR
f = Sheets("Предоплата").Cells(p, 3).Value
      For I = lAntRB To 2 Step -1
          s = Sheets("БАЗА").Cells(I, 7).Value
          If f = s And Sheets("БАЗА").Cells(I, 8).Value <> " " Then
          Sheets("Предоплата").Cells(p, 2).Value = Sheets("БАЗА").Cells(I, 6).Value 'клиент
          Sheets("Предоплата").Cells(p, 4).Value = Sheets("БАЗА").Cells(I, 8).Value 'РН
          Sheets("Предоплата").Cells(p, 5).Value = Sheets("БАЗА").Cells(I, 9).Value 'Дата окончания
          Sheets("Предоплата").Cells(p, 8).Value = Sheets("БАЗА").Cells(I, 12).Value 'Сумма
          Sheets("Предоплата").Cells(p, 12).Value = Sheets("БАЗА").Cells(I, 16).Value 'прим
          Sheets("Предоплата").Cells(p, 13).Value = Sheets("БАЗА").Cells(I, 17).Value 'прим1
          Exit For
          End If
      Next I
Next p
Application.Calculation = xlAutomatic
Application.ScreenUpdating = False
End Sub
[/vba]

На основном файле выполняется 20-30 минут
Прошу помощи в его адаптации через словарь или массивы.
Поиск происходит по столбцу СФ

Если простыми словами, то ищет поочередно на листе Предоплаты сверху вниз СФ и подставляет определенные данные с листа база, но с конца, при условии что на листе база у данной СФ есть РН, если РН не заполнено, то пропускаем.

Заранее спасибо.
К сообщению приложен файл: primer.xlsm (30.8 Kb)
 
Ответить
СообщениеДрузья, приходится обратиться сегодня уже второй раз за помощью.
Имеется файл в котором два листа, второй лист "Предоплата" это небольшая часть листа БАЗА
Сам файл большой и обычный цикл выполняется долго, имеется такой вот цикл:

[vba]
Код
Private Sub CommandButton1_Click()
Dim f As String
Application.ScreenUpdating = False
Application.Calculation = xlManual

lAntR = Sheets("Предоплата").Cells.Find(What:="*", SearchOrder:=xlByRows, SearchDirection:=xlPrevious).Row
lAntRB = Sheets("БАЗА").Cells.Find(What:="*", SearchOrder:=xlByRows, SearchDirection:=xlPrevious).Row

For p = 2 To lAntR
f = Sheets("Предоплата").Cells(p, 3).Value
      For I = lAntRB To 2 Step -1
          s = Sheets("БАЗА").Cells(I, 7).Value
          If f = s And Sheets("БАЗА").Cells(I, 8).Value <> " " Then
          Sheets("Предоплата").Cells(p, 2).Value = Sheets("БАЗА").Cells(I, 6).Value 'клиент
          Sheets("Предоплата").Cells(p, 4).Value = Sheets("БАЗА").Cells(I, 8).Value 'РН
          Sheets("Предоплата").Cells(p, 5).Value = Sheets("БАЗА").Cells(I, 9).Value 'Дата окончания
          Sheets("Предоплата").Cells(p, 8).Value = Sheets("БАЗА").Cells(I, 12).Value 'Сумма
          Sheets("Предоплата").Cells(p, 12).Value = Sheets("БАЗА").Cells(I, 16).Value 'прим
          Sheets("Предоплата").Cells(p, 13).Value = Sheets("БАЗА").Cells(I, 17).Value 'прим1
          Exit For
          End If
      Next I
Next p
Application.Calculation = xlAutomatic
Application.ScreenUpdating = False
End Sub
[/vba]

На основном файле выполняется 20-30 минут
Прошу помощи в его адаптации через словарь или массивы.
Поиск происходит по столбцу СФ

Если простыми словами, то ищет поочередно на листе Предоплаты сверху вниз СФ и подставляет определенные данные с листа база, но с конца, при условии что на листе база у данной СФ есть РН, если РН не заполнено, то пропускаем.

Заранее спасибо.

Автор - DJ_Marker_MC
Дата добавления - 16.01.2015 в 18:38
RAN Дата: Пятница, 16.01.2015, 21:02 | Сообщение № 2
Группа: Друзья
Ранг: Экселист
Сообщений: 5660
Репутация: 1163 ±
Замечаний: 0% ±

2010
[vba]
Код
Sub Мяв()
       Dim arr, arr1
       Dim i&, ii&
       arr = Sheets("БАЗА").Range("A1").CurrentRegion.Value
       arr1 = Sheets("Предоплата").Range("A1").CurrentRegion.Value
       For i = UBound(arr1) To 2 Step -1
           For ii = 1 To UBound(arr)
               If arr1(i, 3) = arr(ii, 7) Then
                   If Len(arr(ii, 8)) Then ' правка
                       arr1(i, 8) = arr(ii, 12)
                       arr1(i, 12) = arr(ii, 16)
                       arr1(i, 13) = arr(ii, 17)
                       arr1(i, 2) = arr(ii, 6)
                       arr1(i, 4) = arr(ii, 8)
                       arr1(i, 5) = arr(ii, 9)
                   End If
                   Exit For
               End If
           Next
       Next
       Sheets("Предоплата").Range("A1").CurrentRegion = arr1
End Sub
[/vba]


Быть или не быть, вот в чем загвоздка!

Сообщение отредактировал RAN - Суббота, 17.01.2015, 00:10
 
Ответить
Сообщение[vba]
Код
Sub Мяв()
       Dim arr, arr1
       Dim i&, ii&
       arr = Sheets("БАЗА").Range("A1").CurrentRegion.Value
       arr1 = Sheets("Предоплата").Range("A1").CurrentRegion.Value
       For i = UBound(arr1) To 2 Step -1
           For ii = 1 To UBound(arr)
               If arr1(i, 3) = arr(ii, 7) Then
                   If Len(arr(ii, 8)) Then ' правка
                       arr1(i, 8) = arr(ii, 12)
                       arr1(i, 12) = arr(ii, 16)
                       arr1(i, 13) = arr(ii, 17)
                       arr1(i, 2) = arr(ii, 6)
                       arr1(i, 4) = arr(ii, 8)
                       arr1(i, 5) = arr(ii, 9)
                   End If
                   Exit For
               End If
           Next
       Next
       Sheets("Предоплата").Range("A1").CurrentRegion = arr1
End Sub
[/vba]

Автор - RAN
Дата добавления - 16.01.2015 в 21:02
Karataev Дата: Пятница, 16.01.2015, 21:02 | Сообщение № 3
Группа: Проверенные
Ранг: Старожил
Сообщений: 1334
Репутация: 533 ±
Замечаний: 0% ±

Excel
[vba]
Код
Private Sub CommandButton1_Click()
      Dim arrPred(), arrBase(), dicBase As Object
      Dim lLastRow As Long
      Dim i As Long, r As Long
      Application.ScreenUpdating = False
      Application.Calculation = xlManual

      lLastRow = Sheets("Предоплата").Cells.Find(What:="*", SearchOrder:=xlByRows, SearchDirection:=xlPrevious).Row
      arrPred() = Sheets("Предоплата").Range("A2:M" & lLastRow).Value
      lLastRow = Sheets("БАЗА").Cells.Find(What:="*", SearchOrder:=xlByRows, SearchDirection:=xlPrevious).Row
      arrBase() = Sheets("БАЗА").Range("A1:Q" & lLastRow).Value
      Set dicBase = CreateObject("Scripting.Dictionary"): dicBase.CompareMode = 1
      For i = 2 To UBound(arrBase)
          If CStr(arrBase(i, 8)) <> " " Then
              dicBase.Add CStr(arrBase(i, 7)), i
          End If
      Next
        
      For i = 1 To UBound(arrPred)
          If dicBase.Exists(CStr(arrPred(i, 3))) = False Then
              GoTo metka
          End If
          r = dicBase.Item(CStr(arrPred(i, 3)))
          arrPred(i, 2) = arrBase(r, 6) 'клиент
          arrPred(i, 4) = arrBase(r, 8) 'РН
          arrPred(i, 5) = arrBase(r, 9) 'Дата окончания
          arrPred(i, 8) = arrBase(r, 12) 'Сумма
          arrPred(i, 12) = arrBase(r, 16) 'прим
          arrPred(i, 13) = arrBase(r, 17) 'прим1
metka:
      Next i
      Sheets("Предоплата").Range("A2").Resize(UBound(arrPred), UBound(arrPred, 2)).Value = arrPred()
      Application.Calculation = xlAutomatic
      Application.ScreenUpdating = False
End Sub
[/vba]


Сообщение отредактировал Karataev - Пятница, 16.01.2015, 21:05
 
Ответить
Сообщение[vba]
Код
Private Sub CommandButton1_Click()
      Dim arrPred(), arrBase(), dicBase As Object
      Dim lLastRow As Long
      Dim i As Long, r As Long
      Application.ScreenUpdating = False
      Application.Calculation = xlManual

      lLastRow = Sheets("Предоплата").Cells.Find(What:="*", SearchOrder:=xlByRows, SearchDirection:=xlPrevious).Row
      arrPred() = Sheets("Предоплата").Range("A2:M" & lLastRow).Value
      lLastRow = Sheets("БАЗА").Cells.Find(What:="*", SearchOrder:=xlByRows, SearchDirection:=xlPrevious).Row
      arrBase() = Sheets("БАЗА").Range("A1:Q" & lLastRow).Value
      Set dicBase = CreateObject("Scripting.Dictionary"): dicBase.CompareMode = 1
      For i = 2 To UBound(arrBase)
          If CStr(arrBase(i, 8)) <> " " Then
              dicBase.Add CStr(arrBase(i, 7)), i
          End If
      Next
        
      For i = 1 To UBound(arrPred)
          If dicBase.Exists(CStr(arrPred(i, 3))) = False Then
              GoTo metka
          End If
          r = dicBase.Item(CStr(arrPred(i, 3)))
          arrPred(i, 2) = arrBase(r, 6) 'клиент
          arrPred(i, 4) = arrBase(r, 8) 'РН
          arrPred(i, 5) = arrBase(r, 9) 'Дата окончания
          arrPred(i, 8) = arrBase(r, 12) 'Сумма
          arrPred(i, 12) = arrBase(r, 16) 'прим
          arrPred(i, 13) = arrBase(r, 17) 'прим1
metka:
      Next i
      Sheets("Предоплата").Range("A2").Resize(UBound(arrPred), UBound(arrPred, 2)).Value = arrPred()
      Application.Calculation = xlAutomatic
      Application.ScreenUpdating = False
End Sub
[/vba]

Автор - Karataev
Дата добавления - 16.01.2015 в 21:02
alex77755 Дата: Пятница, 16.01.2015, 21:09 | Сообщение № 4
Группа: Проверенные
Ранг: Обитатель
Сообщений: 362
Репутация: 64 ±
Замечаний: 0% ±

[vba]
Код
= False  
              GoTo metka

metka:
[/vba]
лишние. Их можно просто стереть, а на место metka: перенести End If


Могу помочь в VB6, VBA
Alex77755@mail.ru
 
Ответить
Сообщение[vba]
Код
= False  
              GoTo metka

metka:
[/vba]
лишние. Их можно просто стереть, а на место metka: перенести End If

Автор - alex77755
Дата добавления - 16.01.2015 в 21:09
alex77755 Дата: Пятница, 16.01.2015, 21:15 | Сообщение № 5
Группа: Проверенные
Ранг: Обитатель
Сообщений: 362
Репутация: 64 ±
Замечаний: 0% ±

[vba]
Код
dicBase.Add CStr(arrBase(i, 7)), i
[/vba]
можно записать так
[vba]
Код
dicBase(CStr(arrBase(i, 7))= i
[/vba]
и соответственно считывать
[vba]
Код
r = dicBase(CStr(arrPred(i, 3)))
[/vba]
При такой записи можно просматривать значение Item наведением мышки в пошаговом режиме


Могу помочь в VB6, VBA
Alex77755@mail.ru
 
Ответить
Сообщение[vba]
Код
dicBase.Add CStr(arrBase(i, 7)), i
[/vba]
можно записать так
[vba]
Код
dicBase(CStr(arrBase(i, 7))= i
[/vba]
и соответственно считывать
[vba]
Код
r = dicBase(CStr(arrPred(i, 3)))
[/vba]
При такой записи можно просматривать значение Item наведением мышки в пошаговом режиме

Автор - alex77755
Дата добавления - 16.01.2015 в 21:15
Karataev Дата: Пятница, 16.01.2015, 21:48 | Сообщение № 6
Группа: Проверенные
Ранг: Старожил
Сообщений: 1334
Репутация: 533 ±
Замечаний: 0% ±

Excel
alex77755, я специально все так сделал. может быть использовать ваши замечания для ускорения макроса.
я сделал,чтобы было удобно работать с кодом.
 
Ответить
Сообщениеalex77755, я специально все так сделал. может быть использовать ваши замечания для ускорения макроса.
я сделал,чтобы было удобно работать с кодом.

Автор - Karataev
Дата добавления - 16.01.2015 в 21:48
DJ_Marker_MC Дата: Пятница, 16.01.2015, 23:23 | Сообщение № 7
Группа: Друзья
Ранг: Ветеран
Сообщений: 991
Репутация: 213 ±
Замечаний: 0% ±

Excel 2019
Коллеги, спасибо за помощь. Нету пока времени потестить более тщательно, но на скорую руку проверив на живом файле, макрос предложенный Karataev срабатывает в разы быстрее и отрабатывает правильно. но при исправлении alexx77755 в посте 5, если не исправить это, то почему то стопорит и выдает ошибку.
Андрей, твой макрос я еще покручу поверчу но уже вижу что предложенный тобой вариант не проверяет наличие РН на листе БАЗА столбец H (восьмой) и отрабатывает намного медленнее.
Но однозначно с этим всем уже добью до конца. Но насколько понял, то со словарем все же намного шустрее.
Всем огромное спасибо
 
Ответить
СообщениеКоллеги, спасибо за помощь. Нету пока времени потестить более тщательно, но на скорую руку проверив на живом файле, макрос предложенный Karataev срабатывает в разы быстрее и отрабатывает правильно. но при исправлении alexx77755 в посте 5, если не исправить это, то почему то стопорит и выдает ошибку.
Андрей, твой макрос я еще покручу поверчу но уже вижу что предложенный тобой вариант не проверяет наличие РН на листе БАЗА столбец H (восьмой) и отрабатывает намного медленнее.
Но однозначно с этим всем уже добью до конца. Но насколько понял, то со словарем все же намного шустрее.
Всем огромное спасибо

Автор - DJ_Marker_MC
Дата добавления - 16.01.2015 в 23:23
RAN Дата: Пятница, 16.01.2015, 23:52 | Сообщение № 8
Группа: Друзья
Ранг: Экселист
Сообщений: 5660
Репутация: 1163 ±
Замечаний: 0% ±

2010
Проверяет, но цифирьку поменять забыл. Поправляю.


Быть или не быть, вот в чем загвоздка!
 
Ответить
СообщениеПроверяет, но цифирьку поменять забыл. Поправляю.

Автор - RAN
Дата добавления - 16.01.2015 в 23:52
DJ_Marker_MC Дата: Суббота, 17.01.2015, 00:31 | Сообщение № 9
Группа: Друзья
Ранг: Ветеран
Сообщений: 991
Репутация: 213 ±
Замечаний: 0% ±

Excel 2019
Все равно немного не так))) ты не в том цикле Step -1 сделал и проверку на РН тоже не так подправил)))
Вообщем вот так итоговый код твой выглядит и правильно отрабатывает:

[vba]
Код
Private Sub CommandButton1_Click()
     Dim arr, arr1
     Dim i&, ii&
     arr = Sheets("БАЗА").Range("A1").CurrentRegion.Value
     arr1 = Sheets("Предоплата").Range("A1").CurrentRegion.Value
     For i = 2 To UBound(arr1)
         For ii = UBound(arr) To 2 Step -1
             If arr1(i, 3) = arr(ii, 7) Then
                 If Len(arr(ii, 8)) <> 1 Then ' правка
                     arr1(i, 8) = arr(ii, 12)
                     arr1(i, 12) = arr(ii, 16)
                     arr1(i, 13) = arr(ii, 17)
                     arr1(i, 2) = arr(ii, 6)
                     arr1(i, 4) = arr(ii, 8)
                     arr1(i, 5) = arr(ii, 9)
                 End If
                 Exit For
             End If
         Next
     Next
     Sheets("Предоплата").Range("A1").CurrentRegion = arr1
End Sub
[/vba]
 
Ответить
СообщениеВсе равно немного не так))) ты не в том цикле Step -1 сделал и проверку на РН тоже не так подправил)))
Вообщем вот так итоговый код твой выглядит и правильно отрабатывает:

[vba]
Код
Private Sub CommandButton1_Click()
     Dim arr, arr1
     Dim i&, ii&
     arr = Sheets("БАЗА").Range("A1").CurrentRegion.Value
     arr1 = Sheets("Предоплата").Range("A1").CurrentRegion.Value
     For i = 2 To UBound(arr1)
         For ii = UBound(arr) To 2 Step -1
             If arr1(i, 3) = arr(ii, 7) Then
                 If Len(arr(ii, 8)) <> 1 Then ' правка
                     arr1(i, 8) = arr(ii, 12)
                     arr1(i, 12) = arr(ii, 16)
                     arr1(i, 13) = arr(ii, 17)
                     arr1(i, 2) = arr(ii, 6)
                     arr1(i, 4) = arr(ii, 8)
                     arr1(i, 5) = arr(ii, 9)
                 End If
                 Exit For
             End If
         Next
     Next
     Sheets("Предоплата").Range("A1").CurrentRegion = arr1
End Sub
[/vba]

Автор - DJ_Marker_MC
Дата добавления - 17.01.2015 в 00:31
Hugo Дата: Суббота, 17.01.2015, 00:35 | Сообщение № 10
Группа: Друзья
Ранг: Участник клуба
Сообщений: 3255
Репутация: 707 ±
Замечаний: 0% ±

2019
Т.к. база всегда больше предоплаты - может быть быстрее будет делать наоборот: загнать в словарь индексы предоплаты, затем идти проверкой по базе, попутно считая не пора ли проверку прекращать.
А идти по базе можно и снизу вверх - если нужные скорее всего внизу.


excel@nxt.ru
webmoney: E265281470651 Z422237915069
 
Ответить
СообщениеТ.к. база всегда больше предоплаты - может быть быстрее будет делать наоборот: загнать в словарь индексы предоплаты, затем идти проверкой по базе, попутно считая не пора ли проверку прекращать.
А идти по базе можно и снизу вверх - если нужные скорее всего внизу.

Автор - Hugo
Дата добавления - 17.01.2015 в 00:35
RAN Дата: Суббота, 17.01.2015, 00:41 | Сообщение № 11
Группа: Друзья
Ранг: Экселист
Сообщений: 5660
Репутация: 1163 ±
Замечаний: 0% ±

2010
Если говорить о скорострельности, в макросе Karataev, есть несколько строк, смысл которых в контексте макроса - замедлить его работу.
Это отключение/ включение обновления экрана и пересчета, а также многократное преобразование текста в текст
[vba]
Код
CStr(arrBase(i, 7)
[/vba]

И очень странное условие проверки
[vba]
Код
Cells(I, 8).Value <> " "     оно же  CStr(arrBase(i, 8)) <> " "
[/vba]

данных нет только в случае, если в ячейке пробел :D


Быть или не быть, вот в чем загвоздка!
 
Ответить
СообщениеЕсли говорить о скорострельности, в макросе Karataev, есть несколько строк, смысл которых в контексте макроса - замедлить его работу.
Это отключение/ включение обновления экрана и пересчета, а также многократное преобразование текста в текст
[vba]
Код
CStr(arrBase(i, 7)
[/vba]

И очень странное условие проверки
[vba]
Код
Cells(I, 8).Value <> " "     оно же  CStr(arrBase(i, 8)) <> " "
[/vba]

данных нет только в случае, если в ячейке пробел :D

Автор - RAN
Дата добавления - 17.01.2015 в 00:41
RAN Дата: Суббота, 17.01.2015, 00:48 | Сообщение № 12
Группа: Друзья
Ранг: Экселист
Сообщений: 5660
Репутация: 1163 ±
Замечаний: 0% ±

2010
и проверку на РН тоже не так подправил

Цитата DJ_Marker_MC, 16.01.2015 в 18:38,
РН не заполнено


Странная логика? Если в ячейке есть 1 символ, она не заполнена, а если пусто, или 2 символа - заполнена.


Быть или не быть, вот в чем загвоздка!
 
Ответить
Сообщение
и проверку на РН тоже не так подправил

Цитата DJ_Marker_MC, 16.01.2015 в 18:38,
РН не заполнено


Странная логика? Если в ячейке есть 1 символ, она не заполнена, а если пусто, или 2 символа - заполнена.

Автор - RAN
Дата добавления - 17.01.2015 в 00:48
DJ_Marker_MC Дата: Суббота, 17.01.2015, 00:51 | Сообщение № 13
Группа: Друзья
Ранг: Ветеран
Сообщений: 991
Репутация: 213 ±
Замечаний: 0% ±

Excel 2019
То что в макросе Karataev нужно покопаться, это я понимаю, но в тоже время только что провел замер по времени:
Твое предложение сработало за 17,6сек, у Karataev за 9,3сек.

Параллельно пока писал начало сообщения, успел убрать в коде CStr, макрос без этого отработал за 9,25 (так что видимо не очень влияет, но и правильно замечено походу и не нужно)

up:
Странная логика?

Тут мой косяк, забыл что 1с выгружает не пустоту, а 1 пробел, хотя в своем изначальном коде так и ищу " "
 
Ответить
СообщениеТо что в макросе Karataev нужно покопаться, это я понимаю, но в тоже время только что провел замер по времени:
Твое предложение сработало за 17,6сек, у Karataev за 9,3сек.

Параллельно пока писал начало сообщения, успел убрать в коде CStr, макрос без этого отработал за 9,25 (так что видимо не очень влияет, но и правильно замечено походу и не нужно)

up:
Странная логика?

Тут мой косяк, забыл что 1с выгружает не пустоту, а 1 пробел, хотя в своем изначальном коде так и ищу " "

Автор - DJ_Marker_MC
Дата добавления - 17.01.2015 в 00:51
RAN Дата: Суббота, 17.01.2015, 00:56 | Сообщение № 14
Группа: Друзья
Ранг: Экселист
Сообщений: 5660
Репутация: 1163 ±
Замечаний: 0% ±

2010
А в чем великий смысл прохода снизу? Никак в толк не возьму.


Быть или не быть, вот в чем загвоздка!
 
Ответить
СообщениеА в чем великий смысл прохода снизу? Никак в толк не возьму.

Автор - RAN
Дата добавления - 17.01.2015 в 00:56
DJ_Marker_MC Дата: Суббота, 17.01.2015, 01:01 | Сообщение № 15
Группа: Друзья
Ранг: Ветеран
Сообщений: 991
Репутация: 213 ±
Замечаний: 0% ±

Excel 2019
RAN, в том что в базе один и тот же счет СФ повторяется неоднократно, а брать нужно последний.
 
Ответить
СообщениеRAN, в том что в базе один и тот же счет СФ повторяется неоднократно, а брать нужно последний.

Автор - DJ_Marker_MC
Дата добавления - 17.01.2015 в 01:01
Hugo Дата: Суббота, 17.01.2015, 01:13 | Сообщение № 16
Группа: Друзья
Ранг: Участник клуба
Сообщений: 3255
Репутация: 707 ±
Замечаний: 0% ±

2019
Если брать нужно последний, то со словарём так и нужно делать, как я описал - предоплаты в словарь, затем по базе вверх, как нашли - копируем и выкидываем из словаря. Как набрали количество - финиш, далее базу шерстить смысла нет, незачем время тратить.


excel@nxt.ru
webmoney: E265281470651 Z422237915069
 
Ответить
СообщениеЕсли брать нужно последний, то со словарём так и нужно делать, как я описал - предоплаты в словарь, затем по базе вверх, как нашли - копируем и выкидываем из словаря. Как набрали количество - финиш, далее базу шерстить смысла нет, незачем время тратить.

Автор - Hugo
Дата добавления - 17.01.2015 в 01:13
RAN Дата: Суббота, 17.01.2015, 01:14 | Сообщение № 17
Группа: Друзья
Ранг: Экселист
Сообщений: 5660
Репутация: 1163 ±
Замечаний: 0% ±

2010
счет СФ повторяется неоднократно

Счет может быть, но в паре с датой нет.
А если вдруг такое случится, то вылетит ошибка на строке
[vba]
Код
dicBase.Add CStr(arrBase(i, 7)), i
[/vba]
Если учесть №5, то ошибки не будет.


Быть или не быть, вот в чем загвоздка!
 
Ответить
Сообщение
счет СФ повторяется неоднократно

Счет может быть, но в паре с датой нет.
А если вдруг такое случится, то вылетит ошибка на строке
[vba]
Код
dicBase.Add CStr(arrBase(i, 7)), i
[/vba]
Если учесть №5, то ошибки не будет.

Автор - RAN
Дата добавления - 17.01.2015 в 01:14
DJ_Marker_MC Дата: Суббота, 17.01.2015, 01:21 | Сообщение № 18
Группа: Друзья
Ранг: Ветеран
Сообщений: 991
Репутация: 213 ±
Замечаний: 0% ±

Excel 2019
RAN, все верно, при такой записи она как раз и вылетела.
но если учесть предложение alex и записать эту строчку вот так
[vba]
Код
dicBase(arrBase(i, 7)) = i
[/vba]
То все хорошо.

Hugo, а разве в макросе Karataev он не именно это делает?
Вообщем пока что код Karataev принимает с учетом все правок такой вид:
[vba]
Код
Private Sub CommandButton2_Click()
     Dim arrPred(), arrBase(), dicBase As Object
     Dim lLastRow As Long
     Dim i As Long, r As Long
     Application.ScreenUpdating = False
     Application.Calculation = xlManual
     t = Timer
      
     lLastRow = Sheets("Предоплата").Cells.Find(What:="*", SearchOrder:=xlByRows, SearchDirection:=xlPrevious).Row
     arrPred() = Sheets("Предоплата").Range("A2:M" & lLastRow).Value
     lLastRow = Sheets("БАЗА").Cells.Find(What:="*", SearchOrder:=xlByRows, SearchDirection:=xlPrevious).Row
     arrBase() = Sheets("БАЗА").Range("A1:Q" & lLastRow).Value
      
     Set dicBase = CreateObject("Scripting.Dictionary"): dicBase.CompareMode = 1
     For i = 2 To UBound(arrBase)
         If arrBase(i, 8) <> " " Then
             dicBase(arrBase(i, 7)) = i
         End If
     Next
          
     For i = 1 To UBound(arrPred)
         If dicBase.Exists(arrPred(i, 3)) Then
             r = dicBase(arrPred(i, 3))
             arrPred(i, 2) = arrBase(r, 6) 'клиент
             arrPred(i, 4) = arrBase(r, 8) 'РН
             arrPred(i, 5) = arrBase(r, 9) 'Дата окончания
             arrPred(i, 8) = arrBase(r, 12) 'Сумма
             arrPred(i, 12) = arrBase(r, 16) 'прим
             arrPred(i, 13) = arrBase(r, 17) 'прим1
         End If
     Next i
      
     Sheets("Предоплата").Range("A2").Resize(UBound(arrPred), UBound(arrPred, 2)).Value = arrPred()
      
     Application.Calculation = xlAutomatic
     Application.ScreenUpdating = False
      
     MsgBox "Время выполнения" & Timer - t & " сек.", vbInformation
End Sub
[/vba]
 
Ответить
СообщениеRAN, все верно, при такой записи она как раз и вылетела.
но если учесть предложение alex и записать эту строчку вот так
[vba]
Код
dicBase(arrBase(i, 7)) = i
[/vba]
То все хорошо.

Hugo, а разве в макросе Karataev он не именно это делает?
Вообщем пока что код Karataev принимает с учетом все правок такой вид:
[vba]
Код
Private Sub CommandButton2_Click()
     Dim arrPred(), arrBase(), dicBase As Object
     Dim lLastRow As Long
     Dim i As Long, r As Long
     Application.ScreenUpdating = False
     Application.Calculation = xlManual
     t = Timer
      
     lLastRow = Sheets("Предоплата").Cells.Find(What:="*", SearchOrder:=xlByRows, SearchDirection:=xlPrevious).Row
     arrPred() = Sheets("Предоплата").Range("A2:M" & lLastRow).Value
     lLastRow = Sheets("БАЗА").Cells.Find(What:="*", SearchOrder:=xlByRows, SearchDirection:=xlPrevious).Row
     arrBase() = Sheets("БАЗА").Range("A1:Q" & lLastRow).Value
      
     Set dicBase = CreateObject("Scripting.Dictionary"): dicBase.CompareMode = 1
     For i = 2 To UBound(arrBase)
         If arrBase(i, 8) <> " " Then
             dicBase(arrBase(i, 7)) = i
         End If
     Next
          
     For i = 1 To UBound(arrPred)
         If dicBase.Exists(arrPred(i, 3)) Then
             r = dicBase(arrPred(i, 3))
             arrPred(i, 2) = arrBase(r, 6) 'клиент
             arrPred(i, 4) = arrBase(r, 8) 'РН
             arrPred(i, 5) = arrBase(r, 9) 'Дата окончания
             arrPred(i, 8) = arrBase(r, 12) 'Сумма
             arrPred(i, 12) = arrBase(r, 16) 'прим
             arrPred(i, 13) = arrBase(r, 17) 'прим1
         End If
     Next i
      
     Sheets("Предоплата").Range("A2").Resize(UBound(arrPred), UBound(arrPred, 2)).Value = arrPred()
      
     Application.Calculation = xlAutomatic
     Application.ScreenUpdating = False
      
     MsgBox "Время выполнения" & Timer - t & " сек.", vbInformation
End Sub
[/vba]

Автор - DJ_Marker_MC
Дата добавления - 17.01.2015 в 01:21
RAN Дата: Суббота, 17.01.2015, 01:32 | Сообщение № 19
Группа: Друзья
Ранг: Экселист
Сообщений: 5660
Репутация: 1163 ±
Замечаний: 0% ±

2010
А это зачем в коде?
[vba]
Код
    Application.ScreenUpdating = False
     Application.Calculation = xlManual
[/vba]
Ты же не с ячейками работаешь, и кучу книг не открываешь. В массив забрал, обработал, выгрузил.
А уж 1 раз экран по любому обновиться, да и файл пересчитается при нужде.


Быть или не быть, вот в чем загвоздка!
 
Ответить
СообщениеА это зачем в коде?
[vba]
Код
    Application.ScreenUpdating = False
     Application.Calculation = xlManual
[/vba]
Ты же не с ячейками работаешь, и кучу книг не открываешь. В массив забрал, обработал, выгрузил.
А уж 1 раз экран по любому обновиться, да и файл пересчитается при нужде.

Автор - RAN
Дата добавления - 17.01.2015 в 01:32
Hugo Дата: Суббота, 17.01.2015, 01:38 | Сообщение № 20
Группа: Друзья
Ранг: Участник клуба
Сообщений: 3255
Репутация: 707 ±
Замечаний: 0% ±

2019
Hugo, а разве в макросе Karataev он не именно это делает?

Что именно это?
В этом макросе все диапазоны просматриваются сверху вниз, и там в словаре запоминается позиция данных (всех, и ненужных тоже) в базе, затем данные извлекаются в предоплату.


excel@nxt.ru
webmoney: E265281470651 Z422237915069


Сообщение отредактировал Hugo - Суббота, 17.01.2015, 01:54
 
Ответить
Сообщение
Hugo, а разве в макросе Karataev он не именно это делает?

Что именно это?
В этом макросе все диапазоны просматриваются сверху вниз, и там в словаре запоминается позиция данных (всех, и ненужных тоже) в базе, затем данные извлекаются в предоплату.

Автор - Hugo
Дата добавления - 17.01.2015 в 01:38
Мир MS Excel » Вопросы и решения » Вопросы по VBA » Сравнение двух листов, подстановка данных (массив/словарь) (Макросы/Sub)
  • Страница 1 из 2
  • 1
  • 2
  • »
Поиск:

Яндекс.Метрика Яндекс цитирования
© 2010-2024 · Дизайн: MichaelCH · Хостинг от uCoz · При использовании материалов сайта, ссылка на www.excelworld.ru обязательна!