2015-01-22 2 views
0

Excel이 있습니다.Excel VBA에서 세 열의 계층 구조를 확인하는 방법

첫 번째 시트는 다음과 같습니다 : 두 개의 시트를 가지고있는 '관할 구역'세 개의 열이 :

국가 (열 B), 주 (열 C)와시 (열 D)을

이 시트 각 도시마다 단일 항목이 있습니다.

그러나 각 도시가 별도의 행에 나열되어 있기 때문에 어떤 도시가 속한 주 및 국가의 이름이 여러 행에 반복 될 수 있습니다. 예를 들어

:

U.S. --> New York --> Buffalo 

U.S. --> New York --> Manhattan 

(이 내 두 행이다)

나는 다른 시트를 가지고 : 시트 1을;

여기도 같은 세 개의 열이 있습니다. (및 다른 일부 20 개의 열)

이 세 개의 열은 '관할 구역'시트의 세 열로 검증됩니다. (만 몇 '관할 구역은'Sheet1의에 나와있는, 그 어떤 순서로 할 수 있으며 모든 국가를 위해 할 수 있습니다) 유효성 검사 규칙은

:

나라

를 들어

1) - 나라 이름은 단일 값이어야합니다.

- 관할 구역 시트의 '국가'열에있는 이름과 일치해야합니다.

- 단지 세미콜론 (세미콜론으로 그 값을 구분하기로 구분 된 하나 개 또는 여러 개의 값을 가질 수 나는 다른를 작성했습니다 - 케이스 가

(대문자/소문자)

2) 주 무시한다 코드가) 잘 작동

-이 셀의 항목도 할 수있다 '전체'

- 모든 국가 이름은 관할 시트의 '상태'열 아래에 나열된 상태와 일치해야합니다. (여러 항목이 나열된 경우 먼저 delimeter - semicolon을 기준으로 구분 한 다음 비교해야합니다.)

- 사례는 무시해야합니다 (대문자/소문자). 상태 이름 앞뒤의 여분의 공백을 제거해야합니다.

3)

도시

- 만

세미콜론

로 구분 된 하나 개 또는 여러 개의 값을 가질 수 있습니다 -이 셀의 항목은 '모든'도 될 수 있습니다.

- 모든 도시 이름은 관할 구역 시트의 '도시'열에 나열된 도시와 일치해야합니다.(여러 항목이 나열된 경우 먼저 delimeter - semicolon을 기준으로 구분 한 다음 비교해야합니다.)

- 사례는 무시해야합니다 (대문자/소문자). 상태 이름 앞뒤의 여분의 공백을 제거해야합니다.

개별 열의 유효성을 검사하는 코드를 작성했습니다.

하지만 충분하지 않습니다 .. !!!

너무 계층 구조를 검증해야합니다. !!

U.S. --> New York --> Buffalo 

U.S. --> New York --> Manhattan; Buffalo 

India --> Karnataka;Maharashtra --> All 

I 이러한 개별 열 다음과 유효성을 쓴 코드;

'******************************************************** 
'validate the 'Country' column in Sheet1, such that; It matches with one of the Country names and must exist 
'******************************************************** 

    'Get the last row 
    'Dim lastRow As Integer 
    LastRow = Sheets("Sheet1").UsedRange.Rows.Count 
    nLastRowSheet2 = Sheets("Jurisdictions").UsedRange.Rows.Count 

    Dim c As Range 

    'Turn screen updating off to speed up macro code. 
    'User won't be able to see what the macro is doing, but it will run faster. 
    Application.ScreenUpdating = False 

    For Each c In Worksheets("Sheet1").Range("B2:B" & LastRow) 
     Dim rngFnder As Range 
     On Error Resume Next 

      Set rngFnder = Sheets("Jurisdictions").Range("B2:B" & nLastRowSheet2).Find(c) 

      If rngFnder Is Nothing Then 
       c.Interior.Color = vbRed 
      End If 
     On Error GoTo 0 
    Next 


'******************************************************** 
'validate the 'State(multiples)' column in the Questions sheet, such that: 
'- State name matches with one of the state names or 
'- State name is set as 'All' 
'******************************************************** 

    Dim stString As String 
    Dim stArray() As String 

    'Get the last row 
    'Dim lastRow As Integer 
    'LastRow = Sheets("Sheet1").UsedRange.Rows.Count 
    'nLastRowSheet2 = Sheets("Jurisdictions").UsedRange.Rows.Count 

    'Dim c As Range 
    Dim d As Range 
    Dim e As Variant 

    For Each c In Worksheets("Sheet1").Range("C2:C" & LastRow) 
     stString = c 
     stArray() = Split(stString, ";") 
     For Each e In stArray() 
      e = Trim(e) 

      'Dim rngFnder As Range 
      On Error Resume Next 

       Set rngFnder = Sheets("Jurisdictions").Range("C2:C" & nLastRowSheet2).Find(e) 

       If rngFnder Is Nothing And c <> "All" Then 
        c.Interior.Color = vbRed 
       End If 

      On Error GoTo 0 
     Next 
    Next 

'******************************************************** 
'validate the City(Multiples) column in the Questions sheet, such that: 
'- City name matches with one of the Cities or 
'- City name is set as 'All' 
'******************************************************** 

'Dim stString As String 
'Dim stArray() As String 

'Get the last row 
'Dim lastRow As Integer 
'LastRow = Sheets("Sheet1").UsedRange.Rows.Count 
'nLastRowSheet2 = Sheets("Jurisdictions").UsedRange.Rows.Count 

'Dim c As Range 
'Dim d As Range 
'Dim e As Variant 

For Each c In Worksheets("Sheet1").Range("D2:D" & LastRow) 
    stString = c 
    stArray() = Split(stString, ";") 
    For Each e In stArray() 
     e = Trim(e) 

     'Dim rngFnder As Range 
     On Error Resume Next 

      Set rngFnder = Sheets("Jurisdictions").Range("D2:D" & nLastRowSheet2).Find(e) 

      If rngFnder Is Nothing And c <> "All" Then 
       c.Interior.Color = vbRed 
      End If 

     On Error GoTo 0 
    Next 
Next 

위의 모든 코드를 단일 코드 모듈로 결합하려고 할 때 문제가 발생합니다. Excel vba의 초보자 인 것처럼 인접한 셀을 참조하는 방법을 모르겠습니다. 문자열을 연결하는 방법 ('State'및 'City'열에서는 여러 항목이있을 경우 세미콜론을 기준으로 해당 주/도시를 먼저 구분해야 함)을 세 가지 다른 열에서 비교하고 세 가지 열과 비교하십시오.

적절한 코드를 작성하는 데 도움을 줄 수 있습니까? NEW 정보를 기반으로

답변

1

나는 코드에 대한 또 다른 개정 조항을 만들었습니다. 변수 이름이 섞여서 이전 편집이 계획대로 작동하지 않았습니다. (부수적으로 이것은 쉽게 식별 할 수있는 변수 이름을 사용하는 것이 중요한 이유를 보여 주며 변수 c 또는 e을 호출하면 독자를 혼동시킬 수 있습니다.

아직 all 상태로 필요한 것을 완전히 이해하지 못했습니다. 이 부분이 제대로 작동하는지 확인한 다음 all 상황을 해결할 수 있습니다.

Dim LastRow As Long 
Dim nLastRowSheet2 As Long 
Dim rngFnder As Range 
Dim strFndAddress As String 
Dim stArray() As String 
Dim c As Range 
LastRow = Sheets("Sheet1").Cells(Rows.Count, 2).End(xlUp).Row 
nLastRowSheet2 = Sheets("Jurisdictions").Cells(Rows.Count, 2).End(xlUp).Row 

For Each c In Worksheets("Sheet1").Range("D2:D" & LastRow) 
    stString = c 
    stArray() = Split(stString, ";") 
    For Each e In stArray() 
     e = Trim(e) 

     strFndAddress = "" 
     On Error Resume Next 

      Set rngFnder = Sheets("Jurisdictions").Range("D2:D" & nLastRowSheet2).Find(e) 

      If rngFnder Is Nothing And c <> "All" Then 
       c.Interior.Color = vbRed 

      Else 
       strFndAddress = rngFnder.Address 
       Do 
        If c.Offset(, -1) = rngFnder.Offset(, -1) And c.Offset(, -2) = rngFnder.Offset(, -2) Then 
         strFndAddress = "" 
         Exit Do 
        Else 

         Set rngFnder = Sheets("Jurisdictions").Range("D2:D" & nLastRowSheet2).FindNext(rngFnder) 

        End If 
       Loop While Not rngFnder Is Nothing And rngFnder.Address <> strFndAddress 
      End If 

      If rngFnder.Address = strFndAddress Then 
       c.Interior.Color = vbRed 
      End If 
     On Error GoTo 0 
     Set c = Nothing 
     strFndAddress = "" 
    Next 
Next 
+0

방금 ​​코드를 다시 편집했습니다. . 무한 루프를 제거하려면이 새 코드를 시도하십시오. 잘못된 위치에 내 검사 변수가 있습니다. – user3561813

0

편집 : 일치하는 항목을 찾을 때까지 나는 아래의 코드를 수정했습니다

는 관할 범위를 반복 계속합니다. 그렇지 않으면 빨간색으로 표시됩니다.

Dim LastRow As Long 
Dim nLastRowSheet2 As Long 
Dim rngFnder As Range 
Dim strFndAddress As String 
Dim stArray() As String 
LastRow = Sheets("Sheet1").Cells(Rows.Count, 2).End(xlUp).Row 
nLastRowSheet2 = Sheets("Jurisdictions").Cells(Rows.Count, 2).End(xlUp).Row 

For Each c In Worksheets("Sheet1").Range("D2:D" & LastRow) 
    stString = c 
    stArray() = Split(stString, ";") 
    For Each e In stArray() 
     e = Trim(e) 

     strFndAddress = "" 
     On Error Resume Next 

      Set rngFnder = Sheets("Jurisdictions").Range("D2:D" & nLastRowSheet2).Find(e) 

      If rngFnder Is Nothing And c <> "All" Then 
       c.Interior.Color = vbRed 

      Else 
       Do 
        If c.Offset(, -1) = rngFnder.Offset(, -1) And c.Offset(, -2) = rngFnder.Offset(, -2) Then 
         Exit Do 
        Else 
         strFndAddress = c.Address 
         Set c = Sheets("Jurisdictions").Range("D2:D" & nLastRowSheet2).FindNext(c) 

        End If 
       Loop While Not c Is Nothing And c.Address <> strFndAddress 
      End If 

      If c.Address = strFndAddress Then 
       c.Interior.Color = vbRed 
      End If 
     On Error GoTo 0 
    Next 
Next 

계층 구조의 역순으로 처리하면 가장 쉽게 처리 할 수 ​​있습니다. 앞에서 언급했듯이 Jurisdictions 워크 시트에서는 국가와 주 모두가 반복되지만 도시는 고유합니다. 그래서 우리는 도시를 먼저 검색해야합니다. 도시가 발견되면 도시와 주가 일치하는지 확인할 수 있습니다. 샘플 코드 항목은 다음과 같습니다. 작동하는지 알려주세요. (Rows_to_Move, Columns_to_Move)에 기초하여 다른 하나 개의 범위에서

For Each c In Worksheets("Sheet1").Range("D2:D" & LastRow) 
    stString = c 
    stArray() = Split(stString, ";") 
    For Each e In stArray() 
     e = Trim(e) 

     'Dim rngFnder As Range 
     On Error Resume Next 

      Set rngFnder = Sheets("Jurisdictions").Range("D2:D" & nLastRowSheet2).Find(e) 

      If rngFnder Is Nothing And c <> "All" Then 
       c.Interior.Color = vbRed 
     Else 
     If c.Offset(,-1) = rngFnder.Offset(,-1) AND c.Offset(,-2) = rngFnder.Offset(,-2) then 
      'Do Nothing, or enter code if they all match 
     Else 
      c.Interior.Color = vbRed 
     End if 
      End If 

     On Error GoTo 0 
    Next 
Next 

Offset있어서 이동한다. 코드에서 변수 C이 왼쪽에있는 셀을 1 개 확인하고 발견 된 범위의 왼쪽에있는 셀을 Jurisdictions (비교 상태)으로 비교 한 다음 왼쪽에있는 셀 2 개를 반복했습니다. 모두 일치하면 코드는 아무 것도하지 않습니다. 그렇지 않으면 셀이 빨간색으로 강조 표시됩니다.

후속 질문을 알려주세요.

+0

감사합니다. 톤 선생님; 이 코드는 잘 작동합니다. 단지 하나의 도전이 있습니다 : 이 코드는 'Sheet1'의 레코드를 '관할 구역'시트의 레코드와 비교합니다. 그들의 첫 번째 발생과 함께. 도시 이름에 'Santa Cruz'라고 말하면 '관할 구역'시트의 셀 구조를 첫 번째 발생과 만 비교합니다. 첫 번째 발생이 잘못된 경우; 셀 내부 색상이 빨간색으로 변경됩니다. 비교를 위해 'Sheet1'에서 다음 레코드를 가져옵니다. 다른 주/국가에 같은 이름의 여러 도시가 있습니다. – Avidan

+0

다른 요구 사항으로 코드를 수정하려고했습니다. 요구 사항 (1) '도시'에 '모두'라는 레코드가있는 경우 상태는 아무거나 될 수 있지만 다음 계층 구조는 정확해야합니다. 그건 (국가 -> 상태 -> 모두) 올바른해야합니다. ('관할 구역'에는 8000+ (여전히 증가하고있는) 기록이 있으므로 '모든'사례를 추가 할 수는 없습니다.) 또 다른 사항은 그 것입니다. 여러 상태가 'state'셀 (또는 값이 'All') 아래에 나열되면 도시의 인접 셀에 'All'값만 있어야합니다. 이 코드를 추가 할 위치를 이해하지 못했습니다. ( – Avidan

+0

편집 된 코드 블록을 확인하고 도움이되는지 알려주십시오. – user3561813

관련 문제