Visual Basic, .NET, ASP, VBScript
 

   
   
     

Форум - VBA

Страница: 1 |

 

  Вопрос: Сравнение масивов Добавлено: 08.12.08 10:28  

Автор вопроса:  AngryBadger
Всем доброго времени суток!

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

Ответить

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

Номер ответа: 1
Автор ответа:
 Nytrogen



Вопросов: 18
Ответов: 186
 Профиль | | #1 Добавлено: 08.12.08 20:23
Как таковой функции, реализующей сравнение массивов, которое в Вашем случае правильно было бы назвать разностью, в VBA не существует. Я предлагаю вариант функции, основанной на использовании коллекции из уникальных элементов.
  1. Option Explicit
  2. Option Base 1
  3.  
  4. Function ArraysDifference(primArray As Variant, secondArray As Variant) As Variant
  5.   Dim newItems() As String           'конечный массив
  6.   Dim item As Variant                'текущий элемент
  7.   Dim tempItems As New Collection    'временная коллекция
  8.   Dim count As Integer               'счётчик элементов
  9.  
  10.   'заполняем коллекцию элементами первичного массива
  11.   For Each item In primArray
  12.     tempItems.Add item, item
  13.   Next item
  14.   'проходим по второму массиву и пытаемся добавить его элементы в коллекцию;
  15.   'если такой элемент уже добавлен в первом цикле, генерируется ошибка;
  16.   'если ошибки не произошло, добавляем новый элемент в конечный массив
  17.   count = 0
  18.   For Each item In secondArray
  19.     On Error Resume Next
  20.     tempItems.Add item, item
  21.     If Err = 0 Then
  22.       count = count + 1
  23.       ReDim Preserve newItems(count)
  24.       newItems(count) = item
  25.     End If
  26.     On Error GoTo 0
  27.   Next item
  28.   ArraysDifference = newItems
  29. End Function
  30.  
  31. Sub TestArrayDifference()
  32.   Dim array1, array2 As Variant
  33.   Dim newEmploy, escEmploy As Variant
  34.   'сотрудники в начале недели
  35.   array1 = Array("Дима", "Вася", "Петя", "Костя", "Паша")
  36.   'сотрудники в конце недели
  37.   array2 = Array("Лёха", "Игорь", "Петя", "Костя", "Боря")
  38.   'новые сотрудники
  39.   newEmploy = ArraysDifference(array1, array2)
  40.   'выбывшие сотрудники
  41.   escEmploy = ArraysDifference(array2, array1)
  42. End Sub

Ответить

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



Вопросов: 33
Ответов: 245
 Профиль | | #2 Добавлено: 09.12.08 10:00
Nytrogen, большое спасибо за ответ. А есть ли у тебя пример программного заполнения массива?

Ответить

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



Вопросов: 18
Ответов: 186
 Профиль | | #3 Добавлено: 09.12.08 16:36
Михаил: А есть ли у тебя пример программного заполнения массива?

Массив можно заполнять из разных источников: диапазонов, файлов, функций... Какой вариант Вас интересует?

Ответить

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



Вопросов: 33
Ответов: 245
 Профиль | | #4 Добавлено: 09.12.08 17:48
Наиболее удобно было бы заполнять из диапазона.

Ответить

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



Вопросов: 18
Ответов: 186
 Профиль | | #5 Добавлено: 09.12.08 20:13
Ну вот к примеру макрос, который заносит в массив значения из числового диапазона.

  1. Option Explicit
  2. Option Base 1
  3.  
  4. Sub RangeArray()
  5.   Dim theNumbers() As Integer 'массив
  6.   Dim theRange As Range 'диапазон
  7.   Dim item As Variant 'ячейка диапазона
  8.   Dim i As Integer 'счётчик
  9.  
  10.   'определяем диапазон
  11.   Set theRange = ThisWorkbook.Worksheets("Sheet1").Range("A1:A5")
  12.   'проходим по всем ячейкам и заносим их значения в массив
  13.   i = 0
  14.   For Each item In theRange
  15.     i = i + 1
  16.     ReDim Preserve theNumbers(i)
  17.     theNumbers(i) = CInt(item)
  18.     'и сразу выводим
  19.     Debug.Print theNumbers(i)
  20.   Next item
  21. End Sub

Ключевой здесь является строка
  1. ReDim Preserve theNumbers(i)

Оператор Redim Preserve переопределяет размерность массива, сохраняя все его элементы.



Возможен и более рациональный вариант, в котором размерность массива определяется непосредственно перед циклом:
  1. Option Explicit
  2. Option Base 1
  3.  
  4. Sub RangeArray()
  5.   Dim theNumbers() As Integer 'массив
  6.   Dim theRange As Range 'диапазон
  7.   Dim item As Variant 'ячейка диапазона
  8.   Dim i As Integer 'счётчик
  9.  
  10.   'определяем диапазон
  11.   Set theRange = ThisWorkbook.Worksheets("Sheet1").Range("A1:A5")
  12.   'задаём размерность от 1 до кол-ва ячеек в диапазоне
  13.   ReDim theNumbers(theRange.Cells.Count)
  14.   'проходим по всем ячейкам и заносим их значения в массив
  15.   i = 0
  16.   For Each item In theRange
  17.     i = i + 1
  18.     theNumbers(i) = CInt(item)
  19.     'и сразу выводим
  20.     Debug.Print theNumbers(i)
  21.   Next item
  22. End Sub

В этом случае оператор Preserve, сохраняющий элементы, нам уже не нужен, ибо вначале массив пустой.

Ответить

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



Вопросов: 0
Ответов: 159
 Профиль | | #6 Добавлено: 09.12.08 21:44
Наиболее удобно было бы заполнять из диапазона.

Вот любопытный способ:
  1. Dim ar() As Variant
  2. ar() = Range("A1:A10")
  3. Dim x As Integer
  4. For x = 1 To 10
  5.     Debug.Print ar(x, 1)
  6. Next


что интересно, LBound этого массива = 1, даже при Option Base 0

Ответить

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



Вопросов: 33
Ответов: 245
 Профиль | | #7 Добавлено: 10.12.08 13:26
Огромное всем Спасибо!

Ответить

Страница: 1 |

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



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