2014-10-21 2 views
-1

다양한 프로젝트에 대한 정보를 저장하는 데이터베이스 테이블이 있습니다. 다음과 같이 보입니다.다른 열 값을 순환하는 가장 빠른 방법

Project ID | Field | Truth Value 
dog  | 1a | True 
dog  | 1b | True 
dog  | 1c | False 
cat  | 1a | True 
cat  | 1b | True 
cat  | 1c | False 

내가 원하는 것은 이러한 프로젝트를 순환 할 수 있습니다. 나는 두 가지 아이디어를 가지고 있는데, 나는 그다지 효율적이지 않다. 각 프로젝트는 3 개 필드가 있다는 사실을 사용하고 단지에 사용되는 행 번호 3을 추가로 뭔가를 둘째 값이 나머지 사용하거나 다음

Columns("B:B").AutoFilter 
Range("B:B").AutoFilter Field:=1, Criteria1:="1a", Operator:=xlFilterValues 

을 그리고 : 첫 번째 아이디어는 다음과 같이 필터를 사용하는 것입니다 Project Name을 잡아라.

실제로 진실 값은 다른 페이지의 체크 상자와 일치하므로 프로젝트가 더 복잡하므로이 모든 작업을 더 쉽게 수행 할 수있는 방법이 있는지를 아는 것이 중요합니다.
컨텍스트에 넣으려면 아이디어는 다른 페이지에서 하나는 프로젝트 사이를 쓸어 넘겨 둘 수 있고 어느 상자가 각 상자에 체크되어 있는지 보거나 편집 할 수 있습니다.

+0

사이클링중인 데이터의 크기는 어느 정도입니까? – JNevill

답변

1

또 다른 가능한 답변입니다. 좀 더 복잡하지만 매우 빠릅니다. ADODB를 사용하여 엑셀 워크 시트를 데이터베이스 인 것처럼 쿼리 할 수 ​​있습니다. 각 개별 프로젝트에 대해 "TRUE"진리 값 또는 일부 비슷한 데이터 가능성을 얻으려면이 방법이 유용 할 것입니다. (그것은 단어, 사기꾼이다).

Sub LoopDistinctProjects() 

    'Variables 
    Dim objConn As Object 
    Dim rs As Object 
    Dim strFileName As String, strSQL As String, strConn As String 
    Dim wsTable As Worksheet 

    'Sheet with the data 
    Set wsTable = ThisWorkbook.Sheets("Sheet1") 

    'Make a new file with _tmp appended to it in same folder 
    strFileName = ThisWorkbook.Path & "/" & ThisWorkbook.Name 
    strFileName = Replace(strFileName, ".xls", "_tmp.xls") 
    ThisWorkbook.SaveCopyAs strFileName 

    'Fancy ADODB stuff.. essentially open up that copy we just saves as if it were a database 
    Set objConn = CreateObject("ADODB.Connection") 
    strConn = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & strFileName & ";Extended Properties=""Excel 12.0 Xml;HDR=YES;""" 
    objConn.Open strConn 

    'This is the sql string we will use to query the excel/database. The field names are the names in Row 1 of the sheet 
    strSQL = "SELECT [Project] FROM [" & wsTable.Name & "$] WHERE [Project] IS NOT NULL GROUP BY [Project];" 

    'Fancy ADODB stuff to apply that SQL statement to the excel/database 
    Set rs = CreateObject("ADODB.Recordset") 
    rs.Open strSQL, objConn 

    'move to the first record (it's already there... probably) 
    rs.Movefirst 

    Do While Not rs.EOF 
     Debug.Print rs.Fields("Project").Value '<----That's a distinct project right there. 
     rs.movenext 
    Loop 

    'close it up 
    rs.Close 
    objConn.Close 

    'Remove that tmp workbook 
    Kill strFileName 

End Sub 

높은 수준이은 다음 ACE OLEDB 공급자를 사용하여 워크 시트에 대한 데이터베이스 연결을 열 ADODB를 사용하여, 같은 폴더에 워크 시트의 복사본을 만듭니다.

그 다음이 ("프로젝트"를 가정 위로 상단에 설정 한 워크 시트에서 별개의 프로젝트 이름을 가져올 필드 이름/열 머리글을 간단한 쿼리 SELECT [Project] FROM [" & wsTable.Name & "$] WHERE [Project] IS NOT NULL GROUP BY [Project];를 쓴다.

그것은 레코드와 열립니다 그 쿼리는 VBE에서 immediate 만 창을 쓰는 결과 (당신이 원하는 무엇이든 할 주시기 바랍니다).

은 그 다음 연결을 닫고 시트를 삭제합니다.

을 말했듯을 통해 루프 이것은 좀 더 복잡하지만, 당신이 뭔가를 좋아할 필요가 있다면 뚜렷하게 구별하는 것보다 이것은 탐험 할 수있는 탄탄한 길입니다. 그리고 비록 여러분이 별개의 것으로 생각된다고해도, 코드 오버 헤드의 트레이드 오프에 신경 쓰지 않는다면 그렇게 나쁘지 않습니다.

+0

이것은 매우 흥미로운 것 같습니다. 비록 내가 아직 사용하지 않더라도 이것을 유용하게 표시 할 것이다. ADODB에 대해 알기위한 좋은 링크가 있습니까? 고마워요 – quantum285

+0

머리 꼭대기에서 나는 아무것도 모르지만 ADODB는 어디에서나 사용되어 인터넷에 많은 도움이됩니다. 일반적으로 쿼리를 실행하거나 저장 프로 시저 등을 실행하기 위해 데이터베이스에 연결하는 데 사용되지만 여기서는 Excel을 전통적인 RDBMS로 전환하는 데 사용됩니다. 그것을 사용하면 vlookup을 사용하여 다시 생각하게 할 것입니다. 레퍼런스를 추가하는 것이 좋습니다 : Tools> References를 선택하고 "Microsoft ActiveX Data Objects 2.8"을 선택하십시오. 그렇게하면 코드를 작성하는 도우미 텍스트가 생깁니다. 이 예제에서 런타임에 바인딩을 사용 했으므로 참조가 필요하지 않습니다. – JNevill

0

한 번에 세 가지를 통해 루프, 당신은 for 루프를 사용할 수 있습니다 : 이것은 어떤로 할 수있는 좋은 방법처럼 보인다

Sub test() 
    Dim intRow as integer 
    Dim strProject as string 

    For intRow = 1 to 500 step 3 '1 is starting row, 500 is ending 
     strProject = Sheet1.Range("B" & intRow).value 
    Next intRow 
End Sub 

. 필터에 포함되지 않은 행만 숨기므로 자동 필터 아이디어가 작동하는지 확신 할 수 없으므로 행을 반복하면 여전히 모든 것을 얻을 수 있습니다. 각 프로젝트에 대해 때로는보다 많거나 적은 세 줄이있는 경우에 당신은 모든 행 및 테스트를 통해 루프는 확실이 다르다 만들 수 있습니다 :

Sub test() 
    Dim intRow as integer 
    Dim strProject as string 

    For intRow = 1 to 500 '1 is starting row, 500 is ending 
     if strProject <> Sheet1.Range("B" & intRow).value 
      strProject = Sheet1.Range("B" & intRow).value 
     End if 
    Next intRow 
End Sub 

는 모든 행을 반복하고 테스트해야하기 때문에이 느려집니다.

+0

답장을 보내 주셔서 감사합니다.하지만 루프를 사용하여 코드를 작성하는 방법을 알고 있습니다. 필자가 작성한 내용을 간소화해야만하기 때문에 코드를 작성하지 않았습니다. 표시되는 행의 범위를 순환하기 때문에 자동 필터 메서드도 작동합니다.내가 이것을 요구하는 것이 더 효율적이거나 매끄러운 방법이 있다면 묻습니다. 그리고 네, 항상 각 프로젝트에 대해 동일한 양의 필드가 있으므로 아마 "every x rows method"를 사용하는 것이 좋습니다. – quantum285

관련 문제