2016-09-19 6 views
0

속도 문제가 있습니다. (긴 게시물에 대한 사과 ...). Windows 용 Excel 2013 및 2016을 사용하고 있습니다.SUMPRODUCT 및 COUNTIFS를 사용하는 Excel VBA - 속도 문제

저는 200,000 개의 셀 테이블 (1000 행 x 200 열)에서 10,000+ 계산을 수행하는 통합 문서를 가지고 있습니다.

각 계산은 정수 (예 : 필터링 된 행 수) 또는 더 일반적으로 백분율 (예 : 필터링 된 행의 합계를 행 값 합으로 나눈 값)을 반환합니다. 위에서 설명하면

=IF($B6=0, 
    0, 
    SUMPRODUCT(COUNTIFS(
    Data[CompanyName], 
    CompanyName, 
    Data[CurrentYear], 
    TeamYear, 
    INDIRECT(VLOOKUP(TeamYear&"R2",RealProgress,2,FALSE)), 
    "<>"&"", 
    Data[High Stage], 
    NonDom[NonDom] 
    )) 
    /$B6 
) 

:

  1. 쌍 데이터 [회사 명] 및 회사 명 테이블과의 열되는 계산의 구조의 라인을 따라 상기 SUMPRODUCT(COUNTIFS()) 아이디어의 변형 인 첫 번째 필터의 조건 값입니다.
  2. 데이터 [Current Year]와 TeamYear 쌍은 위와 같으며 두 번째 필터를 구성합니다.
  3. 세 번째 쌍은 중간 테이블을 조회하고 컬럼의 이름을 반환은, 조건 ("<>"&"")는 '비어 있지'이다, 즉
  4. 마지막으로이 칼럼에 값이있는 모든 행을 반환, 네 번째 쌍은 위의 3과 유사하지만 값 집합과 일치하는 값 집합을 반환합니다.
  5. 마지막으로 4 개의 필터는 AND 문과 함께 결합됩니다. 모든 계산에서 동일한 원칙이 SUMPRODUCT(COUNTIFS())을 사용하여 적용된다는 점에 유의해야합니다. 그러나이 주제에는 많은 변형이 있습니다. 현재 전체 통합 문서를 더 느리게 계산하지 않고 선택한 범위의 시트에서 계산을 사용하면 약 30-40 초 정도의 계산 속도가 산출됩니다. 계산이 항상 수행되지 않으므로 나쁘지 않고 견딜 수 있습니다.

불행하게도이 모델은 확장되어 이제는 1,000 행이 아닌 20,000 개의 행에 접근 할 수 있습니다. 계산 성능은 행 또는 셀 수에 직접 연결되므로 성능이 크게 떨어질 것으로 예상됩니다!

명백한 해결 방법은 배열을 사용하여 메모리에 보관 된 배열을 셀의 수식에 이상적으로 전달하고 필터의 조건 (룩업 필터도 배열 임)과 함께 처리하는 것입니다.

대체 솔루션 [2]은 배열을 사용하여 UDF를 작성하지만 UDF가 기본 Excel 기능보다 훨씬 느리다는 의견을 인터넷을 통해 읽는 것입니다.

두 질문 :

  1. 솔루션 [1] 가능하고,이 일을하는 가장 좋은 방법, 그리고 만약 그렇다면 어떻게 내가 그것을 만들 것입니까?
  2. 해결책 [1]이 가능하지 않거나 최선의 방법이 아닌 경우 누구에게 더 빠른 해결책 [2]이 현재 솔루션과 비교 될 수 있는지에 대한 의견이 있습니까?
  3. 더 좋은 해결책이 있습니까? Power BI Desktop, PowerPivot 및 PowerQuery에 대해 알고 있습니다. 그러나 Excel 이외의 사용자가 사용하기위한 상용 응용 프로그램이므로 현재 Excel 그리드 형태의 행과 열로 표시해야합니다.

읽어 주셔서 감사합니다.

부록 : Worksheet.Activate 이벤트의 각 시트에 대해 배열 계산을 실행하고 시간이 절약되는지 확인해 보겠습니다.

+1

IMO이 질문은 불가능에 좋은 답변을 제공합니다. * 도움이 될만한 것들이 너무 많습니다. 그러나 더 많은 정보와 선호하는 통합 문서의 사본이 없으면 말하기 란 불가능합니다. 예를 들어, 피벗 테이블이 좋은 해결책이 될 수 있습니다. VLOOKUP을 이진 검색 버전 또는 INDEX 및 MATCH로 대체하면 도움이 될 수 있습니다. UDF는 일부 처리를 단락시킬 수있는 경우 수식보다 빠를 수 있습니다. 소스 데이터에서 마지막 조건을 TRUE/FALSE 수식으로 변환하면 도움이 될 수 있습니다. 내가 말했듯이, 너무 많은 옵션. ;) – Rory

+0

감사합니다. Rory. VLOOKUP보다는 INDEX MATCH를 시도했지만 속도가 느립니다. 나는 또한 '2 VLOOKUP'솔루션을 시도했지만 - 그 중 하나가 작동하지 않았다. 출력에 가까운 컨트롤과 좋은 형식 지정이 필요하므로 피벗은 대답이 아닙니다. 나는 TRUE/FALSE 아이디어에 대해 생각할 것입니다 ... 흥미로운 것 같습니다! 다른 사람들을 위해, 특정 솔루션이 내게로 내려와 주셔서 감사합니다 일반적인 포인터와 조언을 찾고 있습니다! – WithnailsHoliday

+0

내가 말했듯이, 너무 많은 가능성 ... 성능 문제에 대한 절대적인 치료법은 거의 없다. FastExcel에 투자하여 병목 현상이 어디에 있는지 정확하게 파악할 수 있습니다. (간접적 인 것은 분명히 문제를 돕지 않을 것입니다.) – Rory

답변

0

데이터를 배열에 쓰는 것이 일반적으로 속도를 높이려는 경우 좋습니다. 다음과 같이 완료 :

Dim myTable As ListObject 
Dim myArray As Variant 

'Set path for Table variable 
    Set myTable = ActiveSheet.ListObjects("Table1") 

'Create Array List from Table 
    myArray = myTable.DataBodyRange 

(Source)