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

Вход

Регистрация

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

 

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

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

Excel 2019
С ними как то спокойнее)))) хотя на скорость не повлияло никак после того как попробовал убрать
 
Ответить
СообщениеС ними как то спокойнее)))) хотя на скорость не повлияло никак после того как попробовал убрать

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

Excel 2019
Hugo, понял, прошагал еще раз по макросу по F8 и понял о чем вы говорите, но мои скудные знания о словарях и массивах к сожалению не позволят без помощи реализовать то что Вы предлагаете, хотя реально понимаю об ускорении в разы...
 
Ответить
СообщениеHugo, понял, прошагал еще раз по макросу по F8 и понял о чем вы говорите, но мои скудные знания о словарях и массивах к сожалению не позволят без помощи реализовать то что Вы предлагаете, хотя реально понимаю об ускорении в разы...

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

2019
Да тоже самое и делайте, только наоборот :)
Может на выходных покажу образец - сейчас уже поздно, завтра днём занят...


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

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

2010
Может на выходных покажу образец
:D
[vba]
Код
Sub МявМяв()
     Dim arr, arr1
     Dim i&, ii&
     arr = Sheets("БАЗА").Range("A1").CurrentRegion.Value
     arr1 = Sheets("Предоплата").Range("A1").CurrentRegion.Value
     With CreateObject("Scripting.Dictionary")
         For i = 2 To UBound(arr1)
             .Item(arr1(i, 3)) = i
         Next
         For i = UBound(arr) To 2 Step -1
             If .exists(arr(i, 7)) Then
                 If Len(arr(i, 8)) <> 1 Then
                     ii = .Item(arr(i, 7))
                     arr1(ii, 8) = arr(i, 12)
                     arr1(ii, 12) = arr(i, 16)
                     arr1(ii, 13) = arr(i, 17)
                     arr1(ii, 2) = arr(i, 6)
                     arr1(ii, 4) = arr(i, 8)
                     arr1(ii, 5) = arr(i, 9)
                 End If
                 .Remove (arr(i, 7))
             End If
             If .Count Then Else Exit For
         Next
     End With
     Sheets("Предоплата").Range("A1").CurrentRegion = arr1
End Sub
[/vba]


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

Сообщение отредактировал RAN - Суббота, 17.01.2015, 02:04
 
Ответить
Сообщение
Может на выходных покажу образец
:D
[vba]
Код
Sub МявМяв()
     Dim arr, arr1
     Dim i&, ii&
     arr = Sheets("БАЗА").Range("A1").CurrentRegion.Value
     arr1 = Sheets("Предоплата").Range("A1").CurrentRegion.Value
     With CreateObject("Scripting.Dictionary")
         For i = 2 To UBound(arr1)
             .Item(arr1(i, 3)) = i
         Next
         For i = UBound(arr) To 2 Step -1
             If .exists(arr(i, 7)) Then
                 If Len(arr(i, 8)) <> 1 Then
                     ii = .Item(arr(i, 7))
                     arr1(ii, 8) = arr(i, 12)
                     arr1(ii, 12) = arr(i, 16)
                     arr1(ii, 13) = arr(i, 17)
                     arr1(ii, 2) = arr(i, 6)
                     arr1(ii, 4) = arr(i, 8)
                     arr1(ii, 5) = arr(i, 9)
                 End If
                 .Remove (arr(i, 7))
             End If
             If .Count Then Else Exit For
         Next
     End With
     Sheets("Предоплата").Range("A1").CurrentRegion = arr1
End Sub
[/vba]

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

Excel 2019
Hugo, попробую сам поменять за завтра, но буду также благодарен и за Ваш вариант.
 
Ответить
СообщениеHugo, попробую сам поменять за завтра, но буду также благодарен и за Ваш вариант.

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

2010
поправил ошибку.


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

Автор - RAN
Дата добавления - 17.01.2015 в 02:13
krosav4ig Дата: Суббота, 17.01.2015, 03:55 | Сообщение № 27
Группа: Друзья
Ранг: Старожил
Сообщений: 2347
Репутация: 989 ±
Замечаний: 0% ±

Excel 2007,2010,2013
может немного не в тему, но все-таки предложу вариант с Power Query, авось где-нить пригодится. Данные для запроса берутся из двух именованных диапазонов.
К сообщению приложен файл: 5573520.xlsm (45.0 Kb)


email:krosav4ig26@gmail.com WMR R207627035142 WMZ Z821145374535 ЯД 410012026478460
 
Ответить
Сообщениеможет немного не в тему, но все-таки предложу вариант с Power Query, авось где-нить пригодится. Данные для запроса берутся из двух именованных диапазонов.

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

Excel 2019
RAN, похоже
[vba]
Код
.Remove (arr(i, 7))
[/vba]
должна быть строчкой выше.
 
Ответить
СообщениеRAN, похоже
[vba]
Код
.Remove (arr(i, 7))
[/vba]
должна быть строчкой выше.

Автор - DJ_Marker_MC
Дата добавления - 17.01.2015 в 03:58
Karataev Дата: Суббота, 17.01.2015, 09:15 | Сообщение № 29
Группа: Проверенные
Ранг: Старожил
Сообщений: 1334
Репутация: 533 ±
Замечаний: 0% ±

Excel
не обратил внимание,что у автора снизу вверх было движение.
изменил в двух местах:1)решил брать со второй строки в массив arrBase,чтобы путаницы не было:т.к. в одном месте с первой строки было, а в другом- со второй;2)изменил,чтобы в словарь записывались только последние данные.
[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("A2:Q" & lLastRow).Value
     Set dicBase = CreateObject("Scripting.Dictionary"): dicBase.CompareMode = 1
     For i = UBound(arrBase) To 1 Step -1
         If CStr(arrBase(i, 8)) <> " " Then
             If dicBase.Exists(CStr(arrBase(i, 7))) = False Then
                 dicBase.Add CStr(arrBase(i, 7)), i
             End If
         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]
CStr -используется от всяких непредвиденных ситуаций. например, если сравниваемые данные могут быть двух видов: в виде текста и в виде числа. текст и число не сравниваются.
 
Ответить
Сообщениене обратил внимание,что у автора снизу вверх было движение.
изменил в двух местах:1)решил брать со второй строки в массив arrBase,чтобы путаницы не было:т.к. в одном месте с первой строки было, а в другом- со второй;2)изменил,чтобы в словарь записывались только последние данные.
[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("A2:Q" & lLastRow).Value
     Set dicBase = CreateObject("Scripting.Dictionary"): dicBase.CompareMode = 1
     For i = UBound(arrBase) To 1 Step -1
         If CStr(arrBase(i, 8)) <> " " Then
             If dicBase.Exists(CStr(arrBase(i, 7))) = False Then
                 dicBase.Add CStr(arrBase(i, 7)), i
             End If
         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]
CStr -используется от всяких непредвиденных ситуаций. например, если сравниваемые данные могут быть двух видов: в виде текста и в виде числа. текст и число не сравниваются.

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

2010
должна быть строчкой выше.

Ты уж определись, что тебе надо. :)
Сейчас
у данной СФ есть РН, если РН не заполнено, то пропускаем.

если перенести выше, поиск будет продолжен до заполненного РН.


Быть или не быть, вот в чем загвоздка!
 
Ответить
Сообщение
должна быть строчкой выше.

Ты уж определись, что тебе надо. :)
Сейчас
у данной СФ есть РН, если РН не заполнено, то пропускаем.

если перенести выше, поиск будет продолжен до заполненного РН.

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

Excel 2019
RAN, нут, так все правильно)))
если СФ с листа предоплата равно СФ с листа БАЗА и у проверяемой на листе БАЗА СФ есть РН то берем данные с этой строки и переносим в эту же СФ на лист предоплата.
Если СФ совпадают, а РН на листе БАЗА отсутствует, то шагаем выше по листу База в поисках такого же СФ у которого есть РН)))

И кстати тест на скорость показал что этот макрос самый крутой)))) - 0,5 - 0,8 сек.
 
Ответить
СообщениеRAN, нут, так все правильно)))
если СФ с листа предоплата равно СФ с листа БАЗА и у проверяемой на листе БАЗА СФ есть РН то берем данные с этой строки и переносим в эту же СФ на лист предоплата.
Если СФ совпадают, а РН на листе БАЗА отсутствует, то шагаем выше по листу База в поисках такого же СФ у которого есть РН)))

И кстати тест на скорость показал что этот макрос самый крутой)))) - 0,5 - 0,8 сек.

Автор - DJ_Marker_MC
Дата добавления - 17.01.2015 в 12:07
alex77755 Дата: Суббота, 17.01.2015, 12:11 | Сообщение № 32
Группа: Проверенные
Ранг: Обитатель
Сообщений: 362
Репутация: 64 ±
Замечаний: 0% ±

но при исправлении alexx77755 в посте 5, если не исправить это, то почему то стопорит и выдает ошибку.

Возможно где-то что-то не так. Вот что я имел в виду полный код

[vba]
Код
Private Sub Comma()
      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 Len(arrBase(i, 8)) <> 0 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
End Sub
[/vba]


Могу помочь в VB6, VBA
Alex77755@mail.ru


Сообщение отредактировал alex77755 - Суббота, 17.01.2015, 12:28
 
Ответить
Сообщение
но при исправлении alexx77755 в посте 5, если не исправить это, то почему то стопорит и выдает ошибку.

Возможно где-то что-то не так. Вот что я имел в виду полный код

[vba]
Код
Private Sub Comma()
      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 Len(arrBase(i, 8)) <> 0 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
End Sub
[/vba]

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

Цитата
изменил,чтобы в словарь записывались только последние данные.

А при проходе сверху вниз без проверки наличия ключа в словаре так и будет: в словаре будет последняя запись
[vba]
Код
        If Len(arrBase(i, 8)) <> 0 Then
              dicBase(arrBase(i, 7)) = i
         End If
[/vba]


Могу помочь в VB6, VBA
Alex77755@mail.ru
 
Ответить
Сообщение
Цитата
изменил,чтобы в словарь записывались только последние данные.

А при проходе сверху вниз без проверки наличия ключа в словаре так и будет: в словаре будет последняя запись
[vba]
Код
        If Len(arrBase(i, 8)) <> 0 Then
              dicBase(arrBase(i, 7)) = i
         End If
[/vba]

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

Excel 2019
alex77755, работает правильно, но по скорости выходит 9 сек, по сравнению с макросом Андрея 0,8сек разница существенная. Так что на нем и остановлюсь.
Всем спасибо, тема в полностью раскрыта и благодаря разным примерам буду осваивать работу с массивами и словарями (ответ самому себе: "давно уже пора лодарь :D " )
 
Ответить
Сообщениеalex77755, работает правильно, но по скорости выходит 9 сек, по сравнению с макросом Андрея 0,8сек разница существенная. Так что на нем и остановлюсь.
Всем спасибо, тема в полностью раскрыта и благодаря разным примерам буду осваивать работу с массивами и словарями (ответ самому себе: "давно уже пора лодарь :D " )

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

2019
Думаю вариант Андрея выигрывает именно потому, что не просматривает всю огромную базу, а только пока найдёт все соответствия в последних записях.
И спасибо что нашёл ночью эти 4 минуты (или полчаса...) :) Меня уже конкретно ломило...


excel@nxt.ru
webmoney: E265281470651 Z422237915069
 
Ответить
СообщениеДумаю вариант Андрея выигрывает именно потому, что не просматривает всю огромную базу, а только пока найдёт все соответствия в последних записях.
И спасибо что нашёл ночью эти 4 минуты (или полчаса...) :) Меня уже конкретно ломило...

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

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