2013-06-07 2 views
4

안녕하세요. VB에서 한 통합 문서에서 다른 통합 문서로 워크 시트를 복사하는 데 문제가 있습니다. 내가 가지고있는 코드는 새로운 통합 문서에서 잘 작동하지만 잠시 후 깨져서이 오류가 발생합니다. " '_Worksheet'개체의 '복사'메서드가 실패했습니다. 많은 사람들이 복사 할 때 통합 문서를 저장하고 다시 열 것을 제안했습니다. 나는 그것을 시도하고 여전히 작동하지 않았다. 나는 또한 이름이 정말로 길어질 지 여부를 확인했다. 복사하기 전에 워크 시트의 이름을 카운터에 설정했는데 여전히 버그가있다. 정말 혼란 스럽다. . 누군가가이 문제를 해결하기위한 방안을 알아 낸 수 있습니다 희망도 모두 통합 문서는 그들에 3 개 워크 시트를VBA에서 복사 워크 시트 복사 오류

'Copies all the worksheets from one workbook to another workbook 
'source_name is the Workbook's FullName 
'dest_name is the Workbook's FullName 
Function copyWorkbookToWorkbook(source_name As String, dest_name As String) As Boolean 
    Dim dest_wb As Workbook 
    Dim source_wb As Workbook 
    Dim dest_app As New Excel.Application 
    Dim source_app As New Excel.Application 
    Dim source_ws As Worksheets 
    Dim counter As Integer 
    Dim num_ws As Integer 
    Dim new_source As Boolean 
    Dim new_dest As Boolean 
    Dim ws As Worksheet 
    Dim regex As String 

    Application.ScreenUpdating = False 

    If source_name = "" Or dest_name = "" Then 
     MsgBox "Source and Target must both be selected!", vbCritical 
     copyWorkbookToWorkbook = False 
    ElseIf GetAttr(dest_name) = vbReadOnly Then 
     MsgBox "The target file is readonly and cannot be modified", vbCritical 
     copyWorkbookToWorkbook = False 
    Else 
     regex = "[^\\]*\.[^\\]*$" 'Gets only the filename 
     copyWorkbookToWorkbook = True 

     If (isWorkbookOpen(source_name)) Then 
      Set source_wb = Workbooks(regExp(source_name, regex, False, True)(0).Value) 
     Else 
      Set source_wb = source_app.Workbooks.Open(source_name) 
      new_source = True 
     End If 

     If (isWorkbookOpen(dest_name)) Then 
      Set dest_wb = Workbooks(regExp(dest_name, regex, False, True)(0).Value) 
     Else 
      Set dest_wb = dest_app.Workbooks.Open(dest_name) 
      new_dest = True 
     End If 

     'Clean the workbooks before copying the data 
     'Call cleanWorkbook(source_wb) 
     'Call cleanWorkbook(dest_wb) 

     'Copy each worksheet from source to target 

     counter = 0 
     source_wb.Activate 
     For Each ws In source_wb.Worksheets 
      MsgBox dest_wb.Worksheets.Count 
      ws.Copy After:=dest_wb.Worksheets(dest_wb.Worksheets.Count) 
      counter = counter + 1 
     Next ws 

     'Save and close any newly opened files 
     If (new_dest) Then 
      dest_wb.Application.DisplayAlerts = False 
      dest_wb.SaveAs Filename:=dest_name, ConflictResolution:=Excel.XlSaveConflictResolution.xlLocalSessionChanges 
      dest_wb.Application.CutCopyMode = False 
      dest_wb.Close 
     End If 
     If (new_source) Then 
      source_wb.Application.DisplayAlerts = False 
      source_wb.SaveAs Filename:=source_name, ConflictResolution:=Excel.XlSaveConflictResolution.xlLocalSessionChanges 
      source_wb.Close 
     End If 

     MsgBox counter & " worksheets have been cleaned and copied.", vbInformation + vbOKOnly 

    End If 

    'Cleanup 
    Set dest_wb = Nothing 
    Set source_wb = Nothing 
    Set dest_app = Nothing 
    Set source_app = Nothing 
    Set source_ws = Nothing 
    Set ws = Nothing 
End Function 

Function regExp(str As String, pattern As String, ignore_case As Boolean, glo As Boolean) As MatchCollection 
    Dim regex As New VBScript_RegExp_55.regExp 
    Dim matches As MatchCollection 

    regex.pattern = pattern 
    regex.IgnoreCase = ignore_case 
    regex.Global = glo 

    Set regExp = regex.Execute(str) 
End Function 

편집 :. 내가 "휴식 잠시 후이 통합 문서"를 의미하는 것은 내가 거기에이 코드를 실행할 수 있다는 것입니다 여러 번 (어쩌면 약 30 번). 결국이 오류가 나타납니다 "메서드 ''복사 ''_Worksheet '개체의"삭제 된 경우에도 dest_wb의 워크 시트. 복사 행을 가리 킵니다.

+0

실제로'dest_wb'를 초기화 하시겠습니까? – enderland

+0

예, 항상 초기화되어 있습니다. – Taztingo

+0

관련 코드를 모두 붙여 넣으십시오. 두 통합 문서를 초기화 할 때 코드가 작동합니다. 시트가 어떻게 든 보호됩니까? 또한 작동하지 않는 경우에 대한 설명이 도움이되지 않습니다. '잠시 후에 깨져서이 오류가 발생합니다.'무슨 뜻입니까? – enderland

답변

2

비슷한 문제가 '템플릿'파일에서 복사했습니다. 나는 그것이 당신의 시스템에 의존하는 복사 및 붙여 넣기의 일정한 횟수 후에 시작되는 기억 문제라고 생각한다.

워크 시트에 포함 된 내용에 따라 몇 가지 해결 방법이 있습니다. 많은 통합 문서를 반복 할 필요가 없었지만 다음 함수가 아무런 문제없이 효과적으로 동일한 작업을 수행한다는 것을 알았습니다.

한 가지 통합 문서에서 다른 통합 문서로 워크 시트를 복사 할 때마다 두 가지 새로운 Excel 인스턴스를 만드는 것이 도움이되지 않을 수도 있습니다. 왜 Excel의 인스턴스를 하나만 사용하면 Excel 인스턴스를 하나만 사용할 수 있습니까?

Sub CopyWorksheet(wsSource As Worksheet, sName As String, wsLocation As Worksheet, sLocation As String) 
    'Instead of straight copying we just add a temp worksheet and copy the cells. 
    Dim wsTemp As Worksheet 

    'The sLocation could be a boolean for before/after. whatever. 
    If sLocation = "After" Then 
     Set wsTemp = wsLocation.Parent.Worksheets.Add(, wsLocation) 
    ElseIf sLocation = "Before" Then 
     Set wsTemp = wsLocation.Parent.Worksheets.Add(wsLocation) 
    End If 

    'After the new worksheet is created 
    With wsTemp 
     .Name = sName       'Name it 
     .Activate        'Bring it to foreground for pasting 
     wsSource.Cells.Copy      'Copy all the cells in the original 
     .Paste         'Paste all the cells 
     .Cells(1, 1).Select      'Select the first cell so the whole sheet isn't selected 
    End With 
    Application.CutCopyMode = False 
End Sub 
+0

이 문제를 해결해 주셔서 감사합니다. 내가 Excel의 두 인스턴스를 열 때마다 계속 오류 1004가 발생했습니다. – Taztingo

+0

우수, 기쁘게 해결되었습니다. – CuberChase

1

예, 필자가 사용하는 일부 코드에서 똑같은 문제가 있습니다. 문제를 해결하기 위해 (필연적으로) 필요한 작업을 수행 할만큼 충분히 절박하지는 않았습니다.

문제는 this 기술 자료 문서에 설명되어 있습니다. 난 당신이 "저장 및 복사 할 때 통합 문서를 다시 열면"하지만 난 당신이 코드를 실행하기 전에 내가 어떤 표시되지 않기 때문에 것을하고있는 가정 있다고 말했다 있습니다

To resolve this problem, save and close the workbook periodically while the copy process is occurring

:이 기사는 제안 루프가 진행되는 동안 표시가 나타납니다. 그 자체가 될 것 루프 내부에 그 일을하는 한 가지 방법 :

초기 절차에

On Error Goto 

라인을함으로써 오류 처리를 구현; 다음

하단에서

Exit Function 
ErrorHandler: 

블록 퍼팅. 오류 처리기 자체에서 Err.Number가 1004인지 여부를 확인해야합니다. 그렇다면 원본 및 대상 통합 문서를 닫은 다음 두 개를 모두 열고 오류가 발생한 줄에서 다시 시작합니다. 오류 처리기에 대한 호출 수를 추적하고 무한 루프에 빠지지 않도록 특정 숫자를 포기하는 것이 좋습니다.

이것은 기본적으로 내 문제를 해결하기위한 아이디어 였지만 구현 시간은 절대로 필요하지 않았습니다. 나는 이것을 게시하기 전에 그것을 테스트했지만 파일은 사무실에 있으며 현재 그들에게 액세스 할 수 없습니다.

나는 그 길로 내려 가기로 결심했다면 어떻게 될지보고 싶습니다.

다른 옵션은 KB 문서에서 제안 된 것으로 n 회 반복 한 후에 책을 닫았다가 다시 열 수 있습니다. 그 문제는 광산이 32 또는 33 후에 실패하는 반면 100 번의 반복을 제안한다는 것입니다. (다른 것 중에서 시트의 크기에 의존하는 것 같습니다.) 또한 광산이 10 번 이후에 실패 할 때도 있습니다) 그리고이를 수정하는 유일한 방법은 Excel을 닫고 다시 여는 것입니다. (분명히 VBA 기반 코드에 대한 옵션이 많지 않습니다.)

+0

원래는 루프를 저장하고 닫고 열었습니다. 그것이 작동하지 않았기 때문에 나는 그것을 꺼냈다. (그것이 내 코드에없는 이유입니다. P) 나는 모든 것을 혼동하지 않도록 방금 그대로두고 주석 처리해야한다고 생각합니다. On Error Goto를 시험해 볼 것이지만, 루프에 넣는 것과 거의 같은 결과이므로 도움이되지 않을 것이라고 생각합니다. 좀 더 명확히하기 위해 Copy 문을 처음 실행할 때이 오류가 발생합니다. 거기에 디버그 문을 넣어 (내가 게시 한 코드에서 그것을 제거했다) – Taztingo

+0

처음 실행되는 시간은? 음, 흥미 롭다. 그것은 나에게있어서 새로운 것이다. 열기/닫기 루틴을 시도하는 것으로 돌아 가면 다른 것을 시도해 볼 수도 있습니다 (MSKB 코드에 있음을 알 수 있습니다). Nothing에 대한 참조를 모두 설정하고 다시 작성합니다. –

+0

흠도 그렇게 해봤고 작동하지 않는 것 같았습니다. 나는 우리가 같은 결과를 얻을 수 있도록 여기에 사용하고있는 파일을 업로드 할 수 있으면 좋겠다. – Taztingo

관련 문제