나눔터  
  HOME > 나눔터 > 묻고답하기 > 엑셀
엑셀
엑셀에 대한 질문과 답변을 올려주세요. 단, 취지에 맞지 않는 글은 운영자가 삭제합니다.
 "000 님, 도와주세요", "부탁 드립니다.", "급합니다!" 등과 같이 막연한 제목을 달지 말아주세요.
[필독] 빠르고 정확한 답변을 얻는 16가지 Tip !
[필독] 저작권법 개정에 따른 이용안내
작성자:  

 조삿갓 (choga21)

추천:  2
파일:     조회:  5498
제목:   [RE]VBA로 피벗테이블 필터 변경하기
     
  * 아래줄에 질문을 작성하세요 >>

안녕하세요. 오늘 처음 VBA를 사용해봅니다.
피벗테이블의 목록을 피벗 필터나 슬라이서로 변경하지 않고, 첨부와 같이 별도의 입력창(c3)에 입력한 조건으로 또는 두개의 조건으로 필터가 자동 조정되게 할 수 있게 VBA로 만들수 있을까요? 초보라서 어떻게 해야하는지 잘 모르겠습니다.  Object error나 End with without End라는 에러가 발생합니다ㅠㅠ 도움 부탁드립니다.
==============[영님 글에 대한 답변입니다]==============

 * 아래줄에 질문을 작성하세요 >>

안녕하세요. 오늘 처음 VBA를 사용해봅니다.
피벗테이블의 목록을 피벗 필터나 슬라이서로 변경하지 않고, 첨부와 같이 별도의 입력창(c3)에 입력한 조건으로 또는 두개의 조건으로 필터가 자동 조정되게 할 수 있게 VBA로 만들수 있을까요? 초보라서 어떻게 해야하는지 잘 모르겠습니다.  Object error나 End with without End라는 에러가 발생합니다ㅠㅠ 도움 부탁드립니다.
==============[영님 글에 대한 답변입니다]==============

End with without End 오류의 원인
---------------------------------
 For 문을 썼으면 반드시 그 짝인 Next 명령이 있어야 합니다.
 그리고 With 문과 End With 문을 연결한 루프와
 For 문과 Next문을 연결한 루프는 서로 교차하면 안됩니다.
 두 번째 For 문이 Next 짝을 만나기 전에
 End With가 나왔기 때문입니다.
 이 End With는 두번째 For 루프 안에서만 With 짝을 찾으려고 합니다.
 그걸 못 찾았다는 뜻이지요.

 사실은 다음에 설명하는 이유로,
 질문자께서 시도하신 것처럼 두 차례의 For 루프로 해결하려는 방식은
 엄청난 시간을 소요하므로 좋은 방법이 아닙니다.

=====================================
개체 오류 원인
-------------------------------------
여러 가지 실수를 범하셨네요.

1. B열의 PivotField 이름이 "Edwards Job Title"가 아니고
   " Job Title"입니다.

2. Visible 속성의 철자를 Visable 로 틀리게 쓰셨네요.

=====================================
구문 오류
-------------------------------------
     If .PivotItems(i) = sItem1 Then .PivotItems(i).Visible = True
 ifElse:     .PivotItems(i).Visable = False

이렇게 쓰면, .PivotItems(i) = sItem1이 거짓일 때
   .PivotItems(i).Visable = False 명령이 실행될 것 같지요?
천만의 말씀입니다.
ifElse: 는 단지 레이블로 해석될 뿐입니다.
두 번째 명령은 무조건 실행되어 버립니다.
즉, 첫번째 If Then 명령을 무용지물로 만들어 버리지요.

올바른 구문은

     If .PivotItems(i) = sItem1 Then .PivotItems(i).Visible = True Else .PivotItems(i).Visable = False

와 같이 한 줄로 쭈욱 써 주거나 또는

     If .PivotItems(i) = sItem1 Then
         .PivotItems(i).Visible = True
     Else
         .PivotItems(i).Visable = False
     End If

와 같이 줄을 구분해서 써 주어야 합니다. 더 깔끔한 방법은
.PivotItems(i) = sItem1 이라는 조건식 자체가 True 또는 False 값을 갖게 되므로

    .PivotItems(i).Visible = .PivotItems(i) = sItem1

과 같이 한 줄만 써도 된답니다.

===============================================
PivotItems의 Visible 속성을 조작할 때 제약 조건
-----------------------------------------------
실제 실험해 본 바에 의하면
VB 코드로 PivotItems의 Visible 속성을 조작할 경우
어느 순간에든지 모든 PivotItems의 Visible 속성이 False로 되어 버리면 안되고
그들 중에 최소한 어느 하나는 True인 것이 있어야 합니다.
이걸 위반하면 400 오류가 발생하더군요.

아마 그래서 질문자께서도 두 개의 For 루프를 설계하고
모든 PivotItems의 Visible 속성을 True로 만든 후에
두 번째 For 루프에서 .PivotItems(i) = sItem1 조건에 따라
Visible 속성을 조작하겠다고 시도하신 듯 합니다.

그런데, 실제로 PivotItems의 개수가 무려 1654개가 되다 보니
이런 방법으로 하면 엄청난 시간이 소요됩니다.

======================
문제 해결
----------------------
Sub Macro1()

Dim sItem1 As String

Application.ScreenUpdating = False
sItem1 = Cells(3, 3)
With ActiveSheet.PivotTables("PivotTable1").PivotFields(" Job Title")
  .PivotItems(sItem1).Visible = True
   ' 먼저 Cells(3, 3)에서 선택된 PivotItems 에 대해서만 Visible = True

  For i = 1 To .PivotItems.Count
        If .PivotItems(i) <> sItem1 Then .PivotItems(i).Visible = False
  Next i  '다음 For루프를 돌면서 선택되지 않은 것은 모두 Visible = False
 
End With
Application.ScreenUpdating = True

End Sub

이렇게 해도 1654 바퀴를 돌려면 시간이 한참 걸리네요.


=============================
F열: "HR LINK Job Family "
-----------------------------
F열의 PivotField 이름은 "HR LINK Job Family "네요.
낚시하는 법을 열심히 알려드렸으니
복습 삼아서 해결해 보시기 바랍니다.
 
[불량 게시물 신고]  
조삿갓님,

자세한 설명 감사합니다. 이렇게나 오류가 많은 지 몰랐었네요. 알려주신 내용과 구문오류(여백포함)해서 열심히 연습해보고 있습니다. 기초이해없이 따라하려니 어렵지만 잘 되면 다시 한 번 올리도록 하겠습니다. 감사합니다.
02-12 (16:27)
삭제 ■신고
        
  

작성일 : 2018-02-10(22:07)
최종수정일 : 2018-02-10(22:07)
 


 ◎ 관련글

  제 목   작성자   날짜
VBA로 피벗테이블 필터 변경하기 2018-02-09
[RE]VBA로 피벗테이블 필터 변경하기 조삿갓 2018-02-10