2015-01-30 3 views
0

스크립트 섹션에 루프가 있으며 매우 느리게 실행됩니다. 이 문제를 개선하기위한 조언을 받기를 희망했습니다.VBA 2010 : 루프 속도를 높이는 코딩 방법에 대한 조언

데이터 쌍이 8 쌍 있습니다. 각 쌍은 Array (1 차원 및 일반적으로 400 개의 문자열 요소)와 일반적으로 약 2,000 개의 문자열 요소가있는 열로 구성됩니다. 데이터 세트의 각 쌍 내에서 배열의 각 요소를 열의 각 요소와 대조하여 일치 항목을 확인하려고합니다.

For i = 1 to 8 
    For j = 0 to 400 
     For k = 0 to 2000 
      If Cells(k,i) = myArray[1, then 2, then 3, etc.](j) then [action] 
     next K 
    next j 
next i 

나는 A의 첫번째 2000 세포에게 칼럼을 통해 400 번, 다음 열 B의 첫 번째 2000 개 세포를 400 배 등을 반복하고있어, 위를 수행하여 여기 내 접근 방식의 단순화 된 버전입니다. 이것은 매우 불필요하게 보이며 약 6 백 4 십만 개의 세포가 검사됩니다. 영원히 걸립니다. 나는 이것을 할 수있는 더 좋은 방법이 있고, 누군가가 나를 계몽하기를 바라고 있습니다.

필요한 경우 실제 코드를 보여주고 그 코드가 수행하는 모든 작업을 설명 할 수 있지만 다소 시간이 오래 걸립니다.

편집 : 여기 실제 코드가 있습니다. 그것은 또한 자격이있는 부울이있는 속을 찾고 있습니다. 이러한 조건이 충족되면 관련된 정수 값과 행 번호를 사용합니다. 모든 정수 값을 합하고 그 정수를 그 합으로 바꿉니다. 이 작업은 모든 고유 한 이름에 대해 수행 한 다음 (표시되지 않음) 나머지 7 개의 데이터 세트에 대해이 작업을 반복합니다.

For i = 0 To j - 1 'starts with the first unique element and searches for dupes... 
     v = 0 'initial qty value 
     r = 0 'initial number of rows with dupes 
     For k = 2 To WULastRow 'go though each cell in the first column 
      If Cells(k, colPair + 2) = True And Cells(k, colPair).Text = uniqueNames(i) Then '...if one is found and the row's boolean is true... 
       v = v + Cells(k, colPair + 1).Value '...sum it's qty with previous dupes qty's... 
       r = r + 1 'increment number of dupes found 
       ReDim Preserve rngMatch(r - 1) 'increase the size of the array that will hold the row numbers of the dupes. 
       rngMatch(r - 1) = k '...and input dupe's row number to said array. 
      End If 
     Next k 

     k = 0 

     'if 1 or more duplicate is found for the given unique item name is found... 
     If r > 1 Then 
      k = 0 
      For k = 0 To r - 1 
       Cells(rngMatch(k), colPair + 1).Value = v '...input the summed quantity in their qty cells... 
      Next k 
     End If 
    Next i 'then regardless, move on to the name unique name and repeat this process. 
+0

[동작]은 무엇인가요? –

+0

[조치]가 조금 관련되어 있습니다. 나열된 간단한 코드를 조금 지나치면 2000 개의 이름의 각 열 A와 함께 2000 개의 정수 B 열과 2000 개의 부울 C 열이 나옵니다. A 열에서 중복이 발견되고 해당 행의 부울이 참인 경우, [action]은 B 열의 정수를 가져 와서이 고유 배열 항목의 다른 모든 정수와 합산합니다. dupe가 C 열에 "true"와 함께 발견 된 경우 해당 추가에 관련된 각 정수를 결과 합계로 바꿉니다. 그게 도움이 되니? – AnthonyJS

+0

_ _ "관련된 각 정수를 바꿉니다"_는 루프의 크기가 아니라 시간을 의미합니다. –

답변

2

큰 오버 헤드를 사용하면 셀에 액세스 할 때마다 (I, J)

당신은 다음의 경우, 다음 루프 변형이 배열로 배열의 데이터를 얻을 수있는 하나의 문을 사용하여이를 방지 할 필요가있다 다시 넣어주세요 : 데모 코드는 여기

Option Base 1 
dim vArr as variant 
varr=Range("A1").resize(Lastrow,LastCol).Value2 
for j=1 to LastRow 
for k=1 to LastCol 
if vArr(j,k) .... then Varr(j,k)= ... 
next k 
next j 
Range("A1").resize(Lastrow,LastCol)=Varr 
+0

오, 매우 흥미 롭습니다. 그래서 2 차원 배열입니까? 나는 이것을 시험 할 것이다 (직장에서의 월요일에, 지금 나는 집으로 돌아갈 것이다 haha). 고마워요! – AnthonyJS

1

당신이해야 할 일은 변수를 순서에 따라 (가장 낮은 것부터 가장 높은 것 등) 순서를 바꾸기위한 일종의 변수 순서화 휴리스틱을 구현하는 것입니다.

하나의 배열 a = [1,8,16] (최소로 정렬 됨)과 다른 배열 b = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16] (다시 정렬 됨)이있는 경우 각 검색 반복이 마지막 검색의 끝 위치에서 발생한다는 규칙을 소개 할 수 있습니다 .

index = 0 
for i in a: 
    for j in range(index, len(b)): 
     if a == b: 
      do something 
      index = j 

이것이 효과적으로 수행하는 것은 당신이 반복적으로 더 작은 공간을 당신이 값과 일치 할 때마다 검색 할 수 있습니다 : 여기에 내가 무엇을 의미하는지에 대한 몇 가지 의사입니다. 다행히도 이것은 의미가 있습니다 - 행렬을 b 변수 순서로 적용하는 것은 어려울 수 있습니다.

+0

사실, 빠른 정렬 알고리즘이라는 것을 사용할 수 있다고 생각합니다. 원래의 포스터에는 문제를 빨리 해결할 수있는 유용한 컴퓨터 과학 알고리즘이 필요할 수도 있습니다. – Bobort

+0

@Kyle Booth, 네, 이것이 내가 찾고있는 것입니다. 중복이 발견되면 정의에 따라 다음 uniqueName() 요소에 대한 중복이 없으므로 다음 반복마다 자동으로 무시되어야합니다. 나는 어려움이 배열을 주문하는데 있다고 생각한다. (그것은 모든 이점이 그것에서 오는 곳이다). 데이터 집합을 정렬하면 나머지 데이터 집합을 조작합니다. 이것은 확실히 좋은 출발점이며, 나는 bobort가 언급 한 "빠른 정렬 알고리즘"을 점검 할 것입니다. 고마워요! – AnthonyJS

+0

괜찮습니다. 행운을 빌어 요. –

관련 문제