2014-12-08 4 views
0

하나의 문서 k 열에서 고유 한 값을 다른 통합 문서의 광고 열에 쓰려고합니다. 문자열로 희미 할 때 오버플로 오류가 발생합니다. 어둡게 할 때 오류 1004가 발생합니다. 응용 프로그램 정의 또는 개체 정의 오류입니다. CarID가 <> 셀 (i + 1, 11) 인 라인 모두. 루프를 사용할 때까지 사용하지 않더라도 exit를 사용합니다. 읽기 열에 약 10 개의 인스턴스에 대해 동일한 데이터가 포함되므로 해당 부분이 필요합니다. 정확하게는 아니지만 모든 값에 대해 변경됩니다. 처음 3 개의 값에 대해 코드가 제대로 작동하면 멈추고 오류가 발생합니다. 나는 값을 a로 변경하려고 시도했다. 비. 동일한 문제가 발생합니다.겉으로보기에 아무 이유없이 VBA 오버플로

Sub PrintCarID() 

Dim ABC_App As Excel.Application 
Dim carPath As String 
Dim carWBook As Excel.Workbook 
Dim MigrationDocument As Excel.Workbook 

Dim CarID As String 
Dim i As Long 
Dim n As Integer 
i = 0 
n = 1 

Set MigrationDocument = ActiveWorkbook  'activeworkbook is the document we need to print in 
carPath = Cells(ActiveCell.Row, 29).Value 'the path and filename for the read document 
Set carWBook = Workbooks.Open(carPath) 
Set ABC_App = carWBook.Parent 
ABC_App.Visible = True 


Do 
carWBook.Activate 
Do 
i = i + 1 
CarID = Cells(i, 11).Value 


Loop Until CarID <> Cells(i + 1, 11) 

MigrationDocument.Activate 
Cells(n, 30).Value = CarID 
n = n + 1 

Loop Until CarID = "" 

End Sub 
+1

열 11에서 최종 값을 이동하면 첫 번째 빈 행에서 'CarID'를 설정합니다. 그런 다음 비어 있지 않은 행을 찾을 때까지 반복합니다. 문자열'i'는 정수로 취급되어 32768에서 오버플로되는 것 같습니다. 긴'i'의 경우, 존재하지 않는 행에 액세스하려고하면 오류가 발생합니다. 최대 행 수는 사용중인 Excel 버전에 따라 다릅니다. 코드를 시험해보고 실패 할 때'i'의 값을 말해주십시오. 제 이론이 맞다면 수정 된 버전의 코드로 답을 게시 할 것입니다. –

+0

원본 데이터에 머리글 행이있는 경우 사전 또는 고급 필터 만 사용할 수 있습니다. – Rory

+0

당신이 맞았을 때 토니의 가치는 32767 (문자열 일 경우)입니다. 나는 코드가 중재 루프에 carID = ""면 exit를 추가하도록 수정했습니다. 그러나 심지어 코드는 여전히 문서의 첫 번째 3 개의 고유 한 값만 인쇄합니다. –

답변

0

당신은 첫 번째 세 개의 고유 한 값을 얻을 말 : 주셔서 감사합니다 도움을, 여기에 코드입니다. 나는 그 문제를 복제 할 수 없다. 내 코드를 시험해보고 문제가 해결되는지 확인하십시오. 그렇지 않다면 나는 당신의 데이터의 본질을 잘못 이해했다고 가정 할 수 있습니다. 내 테스트 데이터의 이미지를 게시합니다. 내 데이터가 귀하의 데이터와 다른 점을 알려 주셔야합니다.

Rory의 의견은 적절한 고급 기술이 있음을 나타냅니다. 코드를 많이 변경했지만 이러한 고급 기술은 사용하지 않았습니다. 나는 너에게 생각할 것을 충분히 주었다. 내 모든 포인트와 모든 나의 변화에 ​​대한 이유를 숙지하십시오. 그러면 다음 단계로 나아갈 준비가 될 것입니다.

일반 포인트

Workbooks.Open 엑셀의 현재 사본에서 새 통합 문서를 엽니 다. 당신은 필요하지 않습니다 :의 ActiveCell에서 값을 선택하는 것이 필요하고 적절한, 또는를 기준으로 할 때

Dim ABC_App As Excel.Application 

Set ABC_App = carWBook.Parent 
ABC_App.Visible = True 

은 시간이 있습니다. 이게 그 중 하나라고 확신합니까? 사용자가 커서를 놓은 행의 열 29 열에 원본 통합 문서의 이름을 저장해야합니까? 그들은 이전 워크 북의 이름을 잊어 버리고 떠날 것입니까? 원본 통합 문서 이름을 가져 오는 가장 신뢰할 수있는 방법인지 확인하십시오.

원본 워크 시트가 열려있는 상태에서 원본 통합 문서가 저장되었다고 가정합니다. 이게 사실일까요?

나는 With 문장을 사용했습니다. 이것은 정확한 접근 99 %의 시간이 될 것입니다. 이 경우에 올바른 접근법인지 알 수 있습니다.


워크 시트를 활성화하지 마십시오. 특히 Excel에서 새 워크 시트를 활성화 할 때마다 화면이 다시 표시되기 때문에 Application.ScreenUpdating = False을 생략하면 느린 명령입니다.


당신은 현재 셀의 행의 열 (29)에서 값을 얻을 즉시 Worksbooks.Open 성명에서 그것을 사용할 수 있습니다. 값이 null이 아니며 액세스 할 수있는 통합 문서의 경로와 이름인지 확인하지 않습니다. 가능한 많은 오류를 확인하는 습관을 가지므로 강조 표시된 VBA 문과 VBA 인터프리터의 불분명 한 오류 메시지가 아닌 이해하기 쉬운 오류 메시지와 우아한 종료를 사용자에게 제공 할 수 있습니다. in 같은


피 이름.이 매크로를 작성하는 동안 in이 무엇인지 기억할 것입니다. 6 개월에서 12 개월 사이에이 매크로를 업데이트해야 할 때 기억하십니까? 나는 RowSrcCrntRowDestCrnt과 같은 이름을 사용합니다. 나는 당신에게 나의 명명 체계를 좋아하지 않고, 당신 자신의 체계를 가지라고 요청하고있다. 저는 몇 년 전에 쓴 매크로로 돌아가서 모든 변수가 무엇인지 알 수 있습니다. 이전 매크로를 업데이트해야하는 경우 시간 절약 효과가 있습니다.


내가 같은 11, 29 및 30 오늘 매직 넘버를 부르는 피, 데이터 열 (11)에 확인하지만 당신은 새로운 열이 추가되지 않는다는 것을 확신합니다. 워크 시트 재배치 후에 매크로를 업데이트하더라도 작업은 악몽이 될 수 있습니다. 상수를 사용하면 문장을 입력하는 데 조금 시간이 걸리지 만 의미있는 이름을 사용하면 무언가가 변경 될 때 많은 시간을 절약 할 수 있습니다. 종종 상수 값을 업데이트하는 것만으로도 충분합니다.

매크로가 포함 된 통합 문서 내에서 워크 시트의 내 버전은 매크로하기 전에 다음과 같습니다

이 실행 내 테스트 데이터 및 코드 :

The name of the workbook to be opened

워크 시트의 내 버전에서 데이터가 포함 된 통합 문서는 다음과 같습니다.

The source data

매크로가 포함 된 통합 문서 내에서 워크 시트의 363,210

내 버전은 매크로를 실행 한 후 다음과 같습니다

The unquie names within the destination worksheet

위의 이미지는 코드에 대한 이해를 일치합니다.

내 코드는 다음과 같습니다. 나는 모든 변화를 설명했다. 이러한 변경 중 일부는 현재 요구 사항에 부적절 할 수 있습니다. 내 변경 사항은 대부분 정확한 시간이 될 것이지만 현재 정확한지 알 수 있습니다. 내 코드로 일해라. 필요하다면 질문으로 다시 돌아 오지만, 당신이 스스로 변화를 이해할 수 있으면 더 빨리 개발할 수 있습니다. 행운을 빕니다.

Option Explicit 
Sub PrintCarID() 

    ' * I name my constant and variables using a sequence of keywords. 
    ' * The first keyword identifies the type of information. For example: 
    ' Wsht for worksheet, Wbk for workbook, Row for row, Col for column and 
    ' Rng for range. 
    ' * Each subsequent keyword narrows the constant or variable down until 
    ' I hsve a name that is unique within the macro or project. 
    ' * If I have more than one workbook, the keyword following Wbk will identify 
    ' the workbook. I know nothing about your workbooks and worksheets so have 
    ' named them Source and Destination and have used keywords Src and Dest. 
    ' * This is my system which you may not like. If you do not like mine, 
    ' invent your own. Naming your constants and variables makes large macro 
    ' much easier to follow particularly if you return to one after 6 or 12 
    ' months. 

    ' * 11 and 30 in your code are what I call magic numbers. You say "Abracadabra!" 
    ' and good (or bad) things happen but you do not know why. Replacing 11 and 30 
    ' with names makes the code easier to understand and easier to maintain. 
    Const ColSrcId As Long = 11 
    Const ColDestId As Long = 30 

    ' * I do not like using the cell that was active when the macro was called 
    ' unless this is important to how the user controls the macro. Switch 
    ' back to your approach if necessary. 
    Const RngWbkSrcName As String = "AC1" 

    ' Chamge these values if you add header rows 
    Const RowSrcDataFirst As Long = 1 
    Const RowDestDataFirst As Long = 1 

    ' * You use the active worksheet in the workbook containing the macro and the 
    ' worksheet active when the source worksheet was saved. This may be 
    ' necessary for your macro but I have coded on the assumption it is not. 
    ' Switch back to ActiveWorkbook if necessary. Better replace "Destination" 
    ' and "Source" with your names. 
    Const WshtDestName As String = "Destination" 
    Const WshtSrcName As String = "Source" 

    Dim CarIdLast As String 
    Dim Path As String 
    Dim RowDestCrnt As Long 
    Dim RowSrcCrnt As Long 
    Dim RowSrcLast As Long 
    Dim WbkDest As Workbook 
    Dim WbkSrc As Workbook 
    Dim WbkSrcName As String 
    Dim WshtDest As Worksheet 
    Dim WshtSrc As Worksheet 

    ' * ThisWorkbook explicitly identifies the workbook containing the macro 
    ' It is possible to execute a macro in a non-active workbook so ActiveWorkbook 
    ' is not necessarily the workbook containing the macro 
    Set WbkDest = ThisWorkbook  ' The workbook containing the macro 

    With WbkDest 

    Set WshtDest = Worksheets(WshtDestName) 

    With WshtDest 

     ' * carPath may be a meaningful name for you but I have used my own naming 
     ' convention. If "car" is meaningful, I would use a name like WbkCarName 
     ' or WbkCarPath. 
     WbkSrcName = .Range(RngWbkSrcName).Value 

    End With 
    End With 

    If WbkSrcName = "" Then 
    Call MsgBox("The name of the source workbook is missing.", vbOKOnly) 
    Exit Sub 
    End If 

    ' * I like to place all linked workbooks and files in the same folder 
    ' since this makes it easier to handle them. With your approach the 
    ' user has to include the full path within the workbook name. With 
    ' my approach the user only has to include specify the file name. 
    Path = WbkDest.Path & "\" 

    ' * Check the path and file exists. I could check the path exists first 
    ' but I doubt that would provide much extra help to the user 
    If Dir$(Path & WbkSrcName) = "" Then 
    Call MsgBox("I cannot find """ & Path & WbkSrcName & """.", vbOKOnly) 
    Exit Sub 
    End If 

    ' * I have checked the file exists but the open may still fail because, 
    ' for example, I may not have read permission. There is little I can 
    ' do to avoid such errors. Te statements around the Workbook.Open 
    ' switch off normal error processing so I can issue my own error 
    ' message rather than have the VBA halt on the Workbook.Open statement. 
    Err.Clear 
    On Error Resume Next 
    Set WbkSrc = Workbooks.Open(Path & WbkSrcName) 
    On Error GoTo 0 
    If Err.Number <> 0 Then 
    Call MsgBox("My attempt to open """ & Path & WbkSrcName & """failed. " & _ 
       "The reason I have been given is: " & Err.Description, vbOKOnly) 
    Exit Sub 
    End If 

    ' * You step the source row number then check it but output to the destination 
    ' row then step. I like to be consistent unless there is good reason not to 
    ' be consistent. I step afterwards for both rows. 
    ' * You do not allow for header rows. This may be correct at the moment but 
    ' will it always be correct. I allow for header rows to be added easily 
    ' by making the first data row a constant 
    RowDestCrnt = RowDestDataFirst 

    CarIdLast = ""  ' No last Car Id 

    With WbkSrc 

    ' * If I was particularly careful, I would check a worksheet with name 
    ' WshtSrcName exists before trying this statement. 
    Set WshtSrc = Worksheets(WshtSrcName) 

    With WshtSrc 

     ' * This gets the last used row in column ColSrcId. This allows me to 
     ' use a For-Loop which I find clearer. 
     RowSrcLast = .Cells(Rows.Count, ColSrcId).End(xlUp).Row 

     For RowSrcCrnt = RowSrcDataFirst To RowSrcLast 
     If CarIdLast <> .Cells(RowSrcCrnt, ColSrcId).Value Then 
      ' * New value for CarId 
      If CarIdLast <> "" Then 
      ' * Have a value to copy to the destination worksheet 
      WshtDest.Cells(RowDestCrnt, ColDestId).Value = CarIdLast 
      RowDestCrnt = RowDestCrnt + 1 
      End If 
      CarIdLast = .Cells(RowSrcCrnt, ColSrcId).Value 
     End If 
     Next 
     ' * Output final value 
     If CarIdLast <> "" Then 
     ' * Have a value to copy to the destination worksheet 
     WshtDest.Cells(RowDestCrnt, ColDestId).Value = CarIdLast 
     RowDestCrnt = RowDestCrnt + 1 
     End If 

    End With 

    ' * Close the source workbook without saving any changes. There should not 
    ' be any changes but best to be safe. Without SaveChanges the user will 
    ' be asked if changes are to be saved. 
    .Close SaveChanges:=False 

    End With 

End Sub 
+0

토니를 사용하여 코드를 테스트 한 결과 더 자세하고 광범위하며 준비가 된 대답은 없었습니다. 코드를 읽고 있는데 익숙하지 않은 일부 키워드가 표시되지만 지금 당장 이에 따라 잡기 때문에 코드가 명확하고 명확 해집니다. 나는 당신의 명명 규칙과 팁을 매우 좋아합니다. 이것은 나와 같은 초보자를 도우미의 완벽한 대답이자 완벽한 태도입니다. 너에게 정말 감사 해. –

+0

내 대답이 도움이 된 것을 기쁘게 생각합니다. 상단의 개요 체크를 클릭하여 답변을 수락하십시오. –

관련 문제