2014-10-17 3 views
2

두 개의 워크 시트가있는 Excel 통합 문서가 있습니다.표시/일치 보이는 셀만

Project ID Project Name 
1    Project 1 
2    Project 2 
3    Project 3 

두 번째는 프로젝트에 관한 의견 유지 : 다음과 같이 첫 번째 프로젝트의 목록을 보유하고

Project ID Comment 
1    First Comment 
1    Second Comment 
2    Third Comment 
3    Fourth Comment 
3    Five Comment 

내 목표는 프로젝트에 관한 의견을 표시하려면 코멘트 목록을 필터링하는 것입니다 그 나는 그들의 ID의 m 여부를 결정하여 현재 의견을 필터링 할 수 있어요

Project ID Comment 
1    First Comment 
1    Second Comment 

: 내가 프로젝트 2, 3, 코멘트 목록은 다음과 같이 걸러, 그래서 만약 표시됩니다 필드에 ID를 표시하고, 그렇다면 열 필터 만 적용하여 일치 항목을 표시합니다. 이 작업은 누군가 프로젝트를 삭제했지만 프로젝트와 관련된 주석을 삭제하지 않은 경우에 수행됩니다.

=IF(ISERROR(MATCH([@[Project ID]],ProjectWorksheet[Project ID], 0)), "No Match", "Match") 

내가 가진 문제는 내가 프로젝트를 필터링하는 경우, 그것은 Excel에서 그들이 대신 일치만을 보여주는 코멘트 필터에 의해 숨겨져있는 경우에도 모든 프로젝트에 대해 일치하기 때문에 프로젝트를 "표시"모든 의견을 표시한다는 것입니다.

나는 단지 표시된 프로젝트가 보여주는 코멘트가 필요합니다.

데이터 행이 숨겨져 있는지 여부에 따라 필드를 조인하는 다른 통합 문서의 매크로가 있지만 표시되는 프로젝트의 메모 만 볼 수 있도록이 방법론을 사용할 수 있습니다. 다음은 매크로입니다.

Function JoinAll(ByVal BaseValue, ByRef rng As Range, ByVal delim As String) 
Application.Volatile 
For Each a In rng 
If a = BaseValue And a.EntireRow.Hidden = False Then 
JoinAll = JoinAll & IIf(JoinAll = "", "", delim) & a(1, 7) 
End If 
Next a 
End Function 

가능한 경우 수식을 사용하고 싶습니다. 당신은 엑셀 2007 이상이, 두리스트가 적용된 필터 (자동 필터)가있는 경우

답변

1

편집 : 원래 질문을 다시 읽은 후, 나는 당신이 정말 필요로하는 것은 프로젝트 표에 숨겨지지하는 댓글 테이블에서 프로젝트 ID를의 목록입니다 생각합니다. 이를 끌어낼 수 있다면 관련 주석을 쉽게 검색 할 수 있습니다.

프로젝트 식별자가 인지 여부를 확인하기 위해 SUBTOTAL이라는 배열 수식을 사용하여 솔루션을 제공한다고 생각했습니다.나는 당신의 테이블 레이아웃보다는 좀 더 일반적인 워크 시트 셀 참조 스타일을 선택했으나, 필사하기가 어려워서는 안된다. 이것은 샘플 데이터 레이아웃입니다.

enter image description here

D8의 배열 수식은 다음과 같습니다 이 =IFERROR(INDEX($A$8:$A$99,SMALL(IFERROR(INDEX(ROW($1:$92)+NOT(SUBTOTAL(102,INDIRECT("A"&MATCH($A$8:$A$99,$A$1:$A$6,0))))*1E+99,,),1E+99),ROW(1:1))),"") 이것은 단순히 를 입력보다를 입력 + Shift를 Ctrl 키 +가 필요합니다. 올바르게 입력되면 필요에 따라 입력 할 수 있습니다.

E8의 표준 공식은 다음과 같습니다. =IF(LEN($D8),IFERROR(INDEX($B$8:$B$99,SMALL(INDEX(ROW($1:$92)+(($A$8:$A$99<>$D8)*1E+99),,),COUNTIF($D$8:$D8,$D8))),""),"") 필요에 따라 입력하십시오.

프로젝트 2 숨김 결과입니다.

enter image description here

나는 자신의 프로젝트는 좀 더 복잡 제공된 그러나 아마이 도움이 될 수 있습니다 샘플 데이터보다라고 생각한다. 사용자 목적에 맞게 필사하려면 ROW(1:92)인 위치가 워크 시트의 실제 행이 아닌B8:B99 내에 있어야합니다.

배열 처리는 검사 할 행의 수에 크게 의존합니다. 또한 INDIRECT 함수는 변동성이있는 것으로 간주되어 통합 문서의 내용이 변경 될 때마다 다시 계산되므로 큰 데이터 블록에 대한 계산 지연이 예상됩니다.

나는 당신이 참조하고 다운로드 할 수 있도록 OneDrive here에 샘플 견본 통합 문서를 제공하고 있습니다. 문제가 발생하면 의견을 다시 게시하십시오.

Remove_Comments_from_Hidden_Projects.xlsx

+0

Project ID를 기준으로 "Third Comment"가 표시되어서는 안됩니까? – Kode

+0

@Kode - OP의 질문을 처음으로 완전히 포착하지 않았고 의견을 거꾸로 가져 오는 아이디어를 얻었습니다. 필자는 제안 된 솔루션을 실제 문제를 더욱 밀접하게 다루는 배열 수식으로 다시 작성했습니다. – Jeeped

+0

우리가 더 가까워지고 있을지 모릅니다.나는 두 장만 가지고 있는데 하나는 프로젝트 용이고 다른 하나는 주석 용이다. 프로젝트 시트의 보이는 프로젝트로 필터링 할 주석 시트 만 있습니다. 저는 당신의 모범이 세 개의 "장"을 가지고 있다고 믿습니다. 여기까지 모든 도움을 감사하십시오! – Kode

1

사실, 자동 필터 사용하여 할 수있는 멋진 방법이 있습니다 : 그것은 파업 경우

Sub FilterChildFromParent(ByRef wksParent As Worksheet, _ 
    ByRef wksChild As Worksheet) 

    Dim i As Integer    ' Loop counter 
    Dim fltSaved As Filter   ' Var to save Filter on first column 
    Dim sFilterTLC As String  ' Address of Filter Top Left Corner 

    If wksParent.AutoFilterMode = True Then 
     Set fltSaved = wksParent.AutoFilter.Filters(1) ' Save Filter on 1st col 
    End If 

    ' Expand filter if needed 
    If wksParent.AutoFilter.Range.Address <> wksParent.UsedRange.Address Then 
     ExpandFilterRange wksParent, wksParent.AutoFilter.Range(1) 
     Set wksParent.AutoFilter.Filters(1) = fltSaved 
    End If 

    ' Now apply filter to Child 
    If wksChild.AutoFilterMode = False Then 
     sFilterTLC = "A1" 
    Else 
     sFilterTLC = wksChild.AutoFilter.Range(1).Address 
    End If 
    ExpandFilterRange wksChild, wksChild.Range(sFilterTLC) 
    If Not (fltSaved Is Nothing) Then     ' If any filter applied 
     If fltSaved.On Then 
     ReDim filterArray(fltSaved.Count) 
      If fltSaved.Count > 1 Then 
       For i = 1 To fltSaved.Count 
        filterArray(i) = fltSaved.Criteria1(i) 
       Next i 
      Else 
       filterArray(1) = fltSaved.Criteria1 
      End If 
      If fltSaved.Operator Then 
       wksChild.AutoFilter.Range.AutoFilter 1, filterArray(), _ 
        fltSaved.Operator, fltSaved.Criteria2 
      Else 
       wksChild.AutoFilter.Range.AutoFilter 1, filterArray() 
      End If 
     Else 
      wksChild.AutoFilter.ShowAllData 
     End If 
    End If 

End Sub 

Sub ExpandFilterRange(ByRef wks As Worksheet, ByRef rngTLC As Range) 
Dim rngFilterPoss As Range  ' Possible filtered cells 
' Range from Top Left Corner of Filter to Bottom Right of worksheet 
Set rngFilterPoss = Range(rngTLC, wks.Cells(wks.Rows.Count, wks.Columns.Count)) 
wks.AutoFilterMode = False  ' Turn off Filter 
Intersect(rngFilterPoss, wks.UsedRange).AutoFilter  ' Re-apply filter 
End Sub 
+0

는, 내가 것을 시도 EntireRow.Hidden = 거짓 – Kode

1

여기에 다른 접근 방식의은 관심. 이 코드를 두 번째 워크 시트 (자동으로 업데이트하려는 워크 시트)에 놓습니다. 워크 시트로 전환 할 때마다이 코드가 실행됩니다.

  • 변경 한 에서 설정 FirstSheet = ActiveWorkbook.Sheets ("1") 제 1 시트의 이름.
  • 두 번째 시트를 두 번째 시트 라인과 동일한 방법으로 업데이트하십시오.

Here's a good page on AutoFilter VBA. 혹시 궁금한 점이 있으면 알려주세요.

Private Sub Worksheet_Activate() 
    Dim FirstSheet As Worksheet 
    Dim SecondSheet As Worksheet 
    Dim Header As Range 

    Set FirstSheet = ActiveWorkbook.Sheets("1") 
    Set Header = FirstSheet.Range("A1") 
    Set SecondSheet = ActiveWorkbook.Sheets("2") 

    'Detect whether Autofilter is active, turn on if not 
    If SecondSheet.AutoFilterMode Then 
     'Detect whether a filter is active, clear if so 
     If SecondSheet.FilterMode Then SecondSheet.ShowAllData 
    Else 
     SecondSheet.UsedRange.AutoFilter 
    End If 

    'Grab filter criteria of FirstSheet 
    With Header.Parent.AutoFilter 
     With .Filters(Header.Column - .Range.Column + 1) 
      If Not .On Then Exit Sub 
      'Update SecondSheet to match FirstSheet 
      If .Operator = xlAnd Then 
       SecondSheet.UsedRange.AutoFilter 1, .Criteria1, xlAnd, .Criteria2 
      ElseIf .Operator = xlOr Then 
       SecondSheet.UsedRange.AutoFilter 1, .Criteria1, xlOr, .Criteria2 
      ElseIf .Operator = xlFilterValues Then 
       SecondSheet.UsedRange.AutoFilter 1, .Criteria1, xlFilterValues 
      Else 
       SecondSheet.UsedRange.AutoFilter 1, .Criteria1 
      End If 
     End With 
    End With 
End Sub 
+0

를 찾는 기능을 가지고 더 나은/적은 코드이지만, SecondSheet에 난처. UsedRange.AutoFilter – Kode

+0

기괴한, 그것은 내 프로토 타입에 완벽하게 작동합니다. 이 시트에 대해 자동 필터가 꺼져 있으면 해당 라인에 도달합니다. 어떤 오류가 발생 했습니까? –

+0

"Autofilter 메서드 또는 Range 클래스가 실패했습니다." 어떤 식 으로든이 공식에 VBA를 사용할 수는 없습니까? Excel에 이러한 단점이 있습니다. – Kode

1

난 당신이 사용하는 엑셀 Forumlas을 수행 할 알고, 문제가되지 않으나, 당신은 그냥 루프와 시트를 구축 세 번째 시트 "보고서"를 고려하는 것이 좋습니다. 버튼을 삽입하고이 코드에 지정하면 주석 시트를 전혀 사용하지 않고 원하는 결과를 얻을 수 있습니다. 이 방법으로 쿼리 보고서가 더 필요합니다.

Worksheet에 적용되는 필터 이벤트를 캡처하는 좋은 방법이 없으므로 Worksheet_change가 아닌 다른 필터를 사용하려고하면 댓글 시트에 불필요한 새로 고침이 발생합니다. 이벤트. .. 또한, 만약 당신이, 당신은 어쨌든 VB에서 무릎 깊은 것입니다. 따라서 "보고서"시트를 삽입하고 하루 만 부르는 것이 좋습니다. 코멘트 시트와 일치시키기 위해 헤더 행 만 있으면됩니다. 내 필터에만 표시 필드의 선택을 제외하고 작동하기 때문에

Sub VisibleReport() 

Dim lastProjectRow As Integer 
Dim lastCommentRow As Integer 
Dim pRow As Integer 
Dim cRow As Integer 
Dim rRow As Integer 

'Clear the previous reports run on "Reports" 
Sheets("Reports").Range("A2:B65000").Clear 

'Get the last row of the Projects and Comments Sheets 
lastProjectRow = Sheets("Projects").Range("A65536").End(xlUp).Row 
lastCommentRow = Sheets("Comments").Range("A65536").End(xlUp).Row 

'Set the ReportRow to start on 2 
rRow = 2 

'Begin Looping through the rows on the Projects Sheet 

For pRow = 2 To lastProjectRow 

    If Sheets("Projects").Rows(pRow).Hidden = False Then 

     'Set the TempID to the current row's projectID 
     tempID = Sheets("Projects").Cells(pRow, 1) 

     For cRow = 2 To lastCommentRow 
      'Check to see if the Project ID matches on the Comment Sheet, and if so, copy A & B of that Row to Report. 
      If (Sheets("Comments").Cells(cRow, 1) = tempID) Then 
       Sheets("Reports").Cells(rRow, 1) = Sheets("Comments").Cells(cRow, 1) 
       Sheets("Reports").Cells(rRow, 2) = Sheets("Comments").Cells(cRow, 2) 

       'increment the Row on the Report Sheet. 
       rRow = rRow + 1 
      End If 
     Next cRow 
    End If 

Next pRow 

'Set the Focus on the Report Sheet. 
Sheets("Reports").Activate 
Range("A1").Select 

End Sub 
관련 문제