2014-12-23 3 views
2

Кажется, у меня есть две строки проблемных кодов. Без них коды могут работать хорошо, с включенными в них, я получу ошибку времени выполнения «1004», определяемую приложением или объектно-ориентированную ошибку.VBA копирует ячейки с листа на новый с ошибкой 1004

Что я в принципе хочу сделать, это отправить команду с условиями из рабочей книги C, чтобы скопировать диапазон ячеек из рабочей книги А в рабочей книге B, мои коды, как показано ниже:

И смотрите, пожалуйста, две проблемные линии Я отметил. Это выглядело отлично для меня, но каким-то образом VBA не выполнит его. Может ли кто-нибудь объяснить мне, почему это так?

мне кажется, столкнуться с подобными проблемами, пока я баловаться с большим количеством книг, так что я предполагаю, что это общая проблема, я при работе с несколькими тетрадями и не ограничиваются только копируют клетки ...

Sub TrySaveAs() 

    Dim wkb0 As Workbook 
    Set wkb0 = ThisWorkbook 
    Dim wkb1 As Workbook 
    Dim wkb2 As Workbook 

    Dim i As Integer 
    i = 2 

    Do Until IsEmpty(wkb0.Worksheets("Sheet2").Cells(i, 1)) 

    Dim full_path As String 
    full_path = C:\something\something.xlsx 

    Set wkb1 = Workbooks.Open(Filename:=somename) 
    wkb1.SaveAs Filename:=full_path 

    Set wkb2 = Workbooks.Open(Filename:=someothername) 
    Dim last_row As Integer 
    last_row = wkb2.Worksheets("RAW").Range("A1").End(xlDown).Row 
    wkb2.Worksheets("RAW").Range(Cells(1, 1), Cells(last_row, 5)).Copy <--------problematic 
    wkb1.Worksheets("Sheet1").Range(Cells(1, 1), Cells(last_row, 5)).Paste <--------problematic 
    wkb2.Close SaveChanges:=False 

    wkb1.Close SaveChanges:=True 

    i = i + 1 

    Loop 

End Sub 
+1

Проверьте свой wkb2, чтобы увидеть, успешно ли он открывается, и если имя рабочей таблицы является правильным или существует/не скрыто. Кроме того, значение full_path необходимо "" – Alex

+0

Я думаю, что все в порядке. я просто перечеркнул их здесь, чтобы избежать осложнений ... –

ответ

1

Вы могли бы сделать

wkb2.Worksheets("RAW").Range(Cells(1, 1).Address & ":" & Cells(last_row, 5).Address).Copy

и

wkb1.Worksheets("Sheet1").Range(Cells(1, 1).Address & ":" & Cells(last_row, 5).Address).PasteSpecial

редактировать

Чтобы лучше понять, почему смотреть на это, с комментариями

Sub hello() 
Dim rr1 As Range 
Dim rr2, rr3 As Range 

Debug.Print Range(Worksheets(1).Cells(1, 1), Worksheets(1).Cells(3, 3)).Address(External:=False) 
Set rr1 = Range(Worksheets(1).Cells(1, 1), Worksheets(1).Cells(3, 3)) 
Debug.Print rr1.Parent.Name & "'!" & rr1.Address(External:=False) 
MsgBox rr1.Parent.Name & "'!" & rr1.Address(External:=False) 
'notice it says "Sheet1'!$A$1:$C$3 

Worksheets(2).Activate 
Set rr2 = Cells(1, 1) 'if we dont qualify Cells, with a range object, it defaults to cells of ActiveSheet 
Set rr3 = Cells(3, 3) 

Debug.Print Range(rr2, rr3).Parent.Name & "'!" & Range(rr2, rr3).Address(External:=False) 
MsgBox Range(rr2, rr3).Parent.Name & "'!" & Range(rr2, rr3).Address(External:=False) 
'notice it says "Sheet2'!$A$1:$C$3, because that is the current ActiveSheet 

Worksheets(3).Activate 
Set rr2 = Cells(1, 1) 'if we dont qualify Cells with a range object, it defaults to cells of ActiveSheet 
Set rr3 = Cells(3, 3) 
Debug.Print Range(rr2, rr3).Parent.Name & "'!" & Range(rr2, rr3).Address(External:=False) 
MsgBox Range(rr2, rr3).Parent.Name & "'!" & Range(rr2, rr3).Address(External:=False) 
'notice it says "Sheet3'!$A$1:$C$3, because that is the current ActiveSheet 

On Error GoTo theError 
Debug.Print Worksheets(1).Range(rr1, rr2).Address 
MsgBox Worksheets(1).Range(rr1, rr2).Address 
theError: Debug.Print "Error because ranges rr1 and rr2 are cells of Worksheet(3), not Worksheet(1)" 

Debug.Print Range(Cells(1, 1), Cells(3, 3)).Parent.Name & "'!" & _ 
Range(Cells(1, 1), Cells(3, 3)).Address(External:=False) 
MsgBox Range(Cells(1, 1), Cells(3, 3)).Parent.Name & "'!" & _ 
Range(Cells(1, 1), Cells(3, 3)).Address(External:=False) 
'notice it says "Sheet3'!$A$1:$C$3, because that is the current ActiveSheet 
'Moral of story you cannot do Worksheets(1).range(cells(a,b),cells(c,d)) because 
'cannot guarantee Cells refer to Worksheet(1) 


'If you really want to refer to unqualified Cells, one way is to mimic the Excel 
'range syntax by grabbing the cell address 
Debug.Print Worksheets(1).Range(Cells(1, 1).Address & ":" & Cells(3, 3).Address).Parent.Name & "'!" & _ 
Worksheets(1).Range(Cells(1, 1).Address & ":" & Cells(3, 3).Address).Address(External:=False) 

MsgBox Worksheets(1).Range(Cells(1, 1).Address & ":" & Cells(3, 3).Address).Parent.Name & "'!" & _ 
Worksheets(1).Range(Cells(1, 1).Address & ":" & Cells(3, 3).Address).Address(External:=False) 

End Sub 
+0

Удивительно, что это сработало! Но можете ли вы любезно сказать мне, почему мой код не работал именно тогда, чтобы я мог узнать причину и избежать ее в следующий раз? –

+0

И еще один лишний вопрос ... Я пробую ваш код, но с помощью Paste вместо PasteSpecial, у меня будет ошибка 438, почему я должен использовать PasteSpecial в этом случае? –

+0

@BoscoTsin спасибо. Рад, что это сработало для вас. 'Paste' работает по-разному. Он работает в сочетании с буфером обмена, а также использует выбранные диапазоны (именно поэтому вы видите его, если вы записали макрос). Поскольку вы копируете диапазон с помощью метода «Копировать», выбора диапазона нет (выбор чего-либо в VBA бесперспективно демонический, и вы должны * почти * никогда не «выбирать» что-либо). 'PasteSpecial' - это метод« Range ». Поэтому (обычно) работает нормально, но это действительно отдельный вопрос. –

-1

Попробуйте

wkb2.Worksheets("RAW").Range(Cells(1, 1), Cells(last_row, 5)).Copy destination:= _ 
wkb1.Worksheets("Sheet1").Range(Cells(1, 1), Cells(last_row, 5)) 

Я думаю .Paste Вставляет содержимое буфера обмена в указанный диапазон

+0

Привет, Барри, я просто попробовал свой код, но он не работает. Ошибка 1004. Есть идеи по этому поводу? –

1

Вы нанесли скрытую ссылку на ActiveSheet. Неквалифицированный вызов Range, которому передается строка или неквалифицированная ссылка на Cells по умолчанию Activesheet.Range и ActiveSheet.Cells. Так что ваша первая линия проблематичной становится

wkb2.Worksheets("RAW").Range(ActiveSheet.Cells(1, 1), ActiveSheet.Cells(last_row, 5)).Copy 

И это выдаст ошибку, если ActiveSheet.Cells(1, 1) не в wkb2.Worksheets("RAW").

Правильный способ сделать это, так что это не без ошибок, чтобы поставить ссылку на лист вызова Cells, а не призыв к Range:

Range(wkb2.Worksheets("RAW").Cells(1, 1), _ 
    wkb2.Worksheets("RAW").Cells(last_row, 5)).Copy 

В связи с @ Ответ Русана Какса: Cells(1, 1).Address по умолчанию - ActiveSheet.Cells(1, 1).Address, который становится строкой A1. И звонок

wkb2.Worksheets("RAW").Range("A1:...").Copy 

действительный синтаксис.

+0

спасибо Degustaf, что ваша версия работает и для меня. вы имеете в виду его действительный синтаксис и как-то работаете над кодом @Rusan Kax, но теоретически не слишком правильно, потому что область, о которой я упоминал, не совсем то же самое, на которое я хочу ссылаться, но это диапазон адресов, который мне так или иначе нужен ... я понимаю это правильно? –

Смежные вопросы