Страницы: 1
RSS
vba: сохранение нескольких листов в новую книгу
 
Уважаемые форумчане! Честно искала в форуме, находила, но не смогла переделать найденный код под свои нужды. Проблема такая: в книге много скрытых листов, надо сохранить в новую книгу несколько листов таким образом, чтобы копировались только значения ячеек и элементов управления на листе и пользователь мог только смотреть и распечатывать содержимое (словно картинкой листы копировались).  
Нашла в инете код для одного листа, но при копировании часть текста теряется, плюс не знаю, как вставить в процедуру еще несколько листов:  
Sub SaveSheet()  
Dim ActiveSht As Worksheet  
Dim NewWb As Workbook  
   Set ActiveSht = ActiveSheet  
   Set NewWb = Workbooks.Add  
   ActiveSht.Copy Before:=Workbooks(NewWb.Name).Sheets(1)  
   With ActiveSheet.UsedRange  
       .Value = .Value  
   End With  
   ActiveWorkbook.SaveAs Filename:="C:\" & ActiveSht.Name  
   MsgBox "Лист скопирован в новую книгу и сохранён!", , ""  
End Sub  
 
Помогите, пожалуйста!
 
Чтобы текст не терялся: вместо UsedRange попробуйте Cells  
А чтобы несколько листов, обращайтесь к ним по имени, или по номеру и копируйте по очереди. Можно макрорекордером: выделить несколько листов и скопировать в новую книгу.
Я сам - дурнее всякого примера! ...
 
{quote}{login=KuklP}{date=30.03.2010 06:05}{thema=}{post}Чтобы текст не терялся: вместо UsedRange попробуйте Cells  
А чтобы несколько листов, обращайтесь к ним по имени, или по номеру и копируйте по очереди. Можно макрорекордером: выделить несколько листов и скопировать в новую книгу.{/post}{/quote}  
 
Замена UsedRange на Cells безнадежно вешает компьютер :(
 
Sub SaveSheet()  
Dim ActiveSht As Worksheet  
Dim NewWb As Workbook  
Sheets(Array("Лист1", "Лист2", "Лист3")).Copy ' Здесь указываете имена нужных листов, в т.ч. и скрытых.  
Set NewWb = ActiveWorkbook  
For Each ActiveSht In NewWb.Worksheets  
 ActiveSht.Visible = True ' делаем скрытые листы видимыми в новой книге.  
 With ActiveSht.UsedRange  
   .Value = .Value  
 End With  
Next  
NewWb.SaveAs Filename:="C:\" & "Лист3.xls" ' листов стало много - какое имя нужно давать для книги не знаю.  
End Sub  
 
Про текст:  
нужен пример как именно потерялся текст.  
созханите одил лист руками (без потери текста) и один лист макросом. Прикрепите сюда (не забывая про правила формума).
Bite my shiny metal ass!      
 
{quote}{login=Лузер™}{date=31.03.2010 10:04}{thema=}{post}Sub SaveSheet()  
Dim ActiveSht As Worksheet  
Dim NewWb As Workbook  
Sheets(Array("Лист1", "Лист2", "Лист3")).Copy ' Здесь указываете имена нужных листов, в т.ч. и скрытых.  
Set NewWb = ActiveWorkbook  
For Each ActiveSht In NewWb.Worksheets  
 ActiveSht.Visible = True ' делаем скрытые листы видимыми в новой книге.  
 With ActiveSht.UsedRange  
   .Value = .Value  
 End With  
Next  
NewWb.SaveAs Filename:="C:\" & "Лист3.xls" ' листов стало много - какое имя нужно давать для книги не знаю.  
End Sub  
 
Про текст:  
нужен пример как именно потерялся текст.  
созханите одил лист руками (без потери текста) и один лист макросом. Прикрепите сюда (не забывая про правила формума).{/post}{/quote}  
Копирование не удается. Выскакивает ошибка (см. вложение) в строке  
"Sheets(Array("З_СМБ", "П_СМБ", "П_СМБ")).Copy ' Здесь указываете имена нужных листов, в т.ч. и скрытых."
 
Так вот Вам и ответ почему текст обрезается.  
счас поправим :)
Bite my shiny metal ass!      
 
{quote}{login=Лузер™}{date=31.03.2010 11:23}{thema=}{post}Так вот Вам и ответ почему текст обрезается.  
счас поправим :){/post}{/quote}  
 
Текст, который обрезался, вырезала из ячеек и вставила в textbox`ы. Теперь при выполнении макроса копирования появляется ошибка  
" `1004` Метод Copy из класса Sheets завершен неверно"  
все в той же строке  
"Sheets(Array("Заявление_СМБ", "Полис_СМБ", "Перечень_СМБ")).Copy ' Здесь указываете имена нужных листов, в т.ч. и скрытых."
 
Боюсь, без примера все же не обойтись.
Bite my shiny metal ass!      
 
{quote}{login=Лузер™}{date=31.03.2010 12:58}{thema=}{post}Боюсь, без примера все же не обойтись.{/post}{/quote}  
 
Похоже, что проблемы с копированием возникают из-за защищенности книги.  
Тем не менее, копирование не работает так, как хотелось бы. Во вложении пример с Вашим кодом.  
А хотелось бы, чтоб по нажатию кнопки "Скопировать листы" происходило копирование только указанных листов - они скрыты в исходном файле, но должны быть видимыми в новой книге.
 
Уважаемые форумчане! Подскажите, пожалуйста, как решить описанную в теме ситуацию!!
 
Переименуйте макрос Copy в Copy1 соответственно и ссылку на него в кнопке.
Я сам - дурнее всякого примера! ...
 
Сначала делайте все листы видимыми в исходной книге. Копируете нужные в новую книгу, а исходную закрываете не сохраняя.
Я сам - дурнее всякого примера! ...
 
Sub Copy1()  ' не используйте зарезервированные имена. Придумайте свое имя макроса.  
Dim ActiveSht As Worksheet  
Dim NewWb As Workbook  
Set NewWb = Workbooks.Add  
For Each ActiveSht In ThisWorkbook.Sheets(Array("Лист11", "Лист21", "Лист31"))  ' не используйте стандартные имена листов или будет ошибка.  
 NewWb.Worksheets.Add.Name = ActiveSht.Name  
 With ActiveSht.UsedRange  
   .Copy  
   ActiveSheet.Range(.Address).PasteSpecial Paste:=xlPasteValues  
   ActiveSheet.Range(.Address).PasteSpecial Paste:=xlPasteFormats  
   ActiveSheet.Range(.Address).PasteSpecial Paste:=xlPasteColumnWidths  
 End With  
Next  
NewWb.SaveAs Filename:="C:\" & "Копия.xls"  ' листов стало много - какое имя нужно давать для книги не знаю.  
MsgBox "Формы документов перенесены в новую книгу и сохранены.", , ""  
End Sub
Bite my shiny metal ass!      
 
Ув. Лузер™, вот на этой строке:  
For Each ActiveSht In ThisWorkbook.Sheets(Array("Лист11", "Лист21", "Лист31"))    
Вылетает в Дебаг - Subscript out of range. Мой вариант работает:  
Sub Copy1()  
Dim ActiveSht As Worksheet  
Dim NewWb As Workbook  
For Each ActiveSht In ThisWorkbook.Worksheets  
ActiveSht.Visible = True ' делаем скрытые листы видимыми в исходной книге.  
Next  
 
Sheets(Array("Лист1", "Лист2", "Лист3")).Copy ' Здесь указываете имена нужных листов  
Set NewWb = ActiveWorkbook  
For Each ActiveSht In NewWb.Worksheets  
With ActiveSht.UsedRange  
.Value = .Value  
End With  
Next  
NewWb.SaveAs Filename:="C:\" & "Копия.xls" ' листов стало много - какое имя нужно давать для книги не знаю.  
MsgBox "Формы документов перенесены в новую книгу и сохранены.", , ""  
ThisWorkbook.Close SaveChanges:=False  
End Sub
Я сам - дурнее всякого примера! ...
 
{quote}{login=KuklP}{date=01.04.2010 05:42}{thema=}{post}Ув. Лузер™, вот на этой строке:  
For Each ActiveSht In ThisWorkbook.Sheets(Array("Лист11", "Лист21", "Лист31"))    
Вылетает в Дебаг - Subscript out of range. Мой вариант работает:  
{/post}{/quote}А листы с такими именами есть? Или так и остались "Лист1", "Лист2", "Лист3"?  
Потом, я не претендую на эксклюзив и работоспособность Вашего варианта не оспариваю.    
Только копирует ли он ячейки с >255 символами? - У топикстартера проблема не только со скрытыми листами. Но и с потерей части текста.  
А нужно ли закрывать исходную книгу? А вдруг в ней остались несохраненые изменения?
Bite my shiny metal ass!      
 
{quote}{login=Лузер™}{date=01.04.2010 05:54}{thema=Re: }{post}{quote}{login=KuklP}{date=01.04.2010 05:42}{thema=}{post}Ув. Лузер™, вот на этой строке:  
For Each ActiveSht In ThisWorkbook.Sheets(Array("Лист11", "Лист21", "Лист31"))    
Вылетает в Дебаг - Subscript out of range. Мой вариант работает:  
{/post}{/quote}А листы с такими именами есть? Или так и остались "Лист1", "Лист2", "Лист3"?  
Потом, я не претендую на эксклюзив и работоспособность Вашего варианта не оспариваю.    
Только копирует ли он ячейки с >255 символами? - У топикстартера проблема не только со скрытыми листами. Но и с потерей части текста.  
А нужно ли закрывать исходную книгу? А вдруг в ней остались несохраненые изменения?{/post}{/quote}  
Копировать можно и по вашему(при этом две строки, формат и ширина отпадают) в новой книге. А сохранение данных - проблема топикстартера. Хотя можно и программно. Одна строка: ActiveWorkbook.Save  
После Dimов. И я вообще-то не об оспаривании писал. Программы Вы пишете блестяще! Просто Черная Дыра(или я неправильно перевел Black__Hole?) нуждается в более... Нет, не так. Не стоит ее перенапрягать. Спасибо, хоть пример выложила. Если бы сделала это 29 числа - давно бы проблема ушла. Но вот прикол - мы тут стараемся, перед работой, после, а она только изредка заглядывает. Может так ей нужно?
Я сам - дурнее всякого примера! ...
 
Я понимаю, что сохранить легко. Но если не нужно сохранять? Или наоборот нужно - мы не знаем. Лишнее сохранение/закрытие накладывает ненужные ограничения на функциональность кода.  
 
Про "при этом две строки, формат и ширина отпадают" не понял.  
 
Про топикстартера - может она чаще не может. Я вот последнее время раз в пять меньше на форуме провожу.
Bite my shiny metal ass!      
 
{quote}{login=Лузер™}{date=01.04.2010 10:05}{thema=}{post}  
Про "при этом две строки, формат и ширина отпадают" не понял.  
{/post}{/quote}  
Если скопированы листы целиком то на них уже и формат и ширина, высота, возможно объединенные ячейки и Бог знает что еще - все уже есть. Остается только формулы и ссылки преобразовать в значения. Поэтому мне больше нравится вариант с копированием листов целиком.
Я сам - дурнее всякого примера! ...
 
Уважаемые KuklP и Лузер™! Спасибо Вам за то, что оказываете посильную помощь - я искренне Вам признательна!  
KuklP, Вы правы: я профан в vba, тем более, в сравнении с корифеями форума. Ну а незнание синтаксиса порой приводит к возникновению сложностей даже в решении незначительных задач. Однако с помощью этого форума vba перестал быть загадкой и, я надеюсь, достаточно скоро станет полноценным инструментом в руках даже Черной__Дыры.  
Ответы на данную тему приходили не так скоро, как хотелось бы и я пыталась найти иные варианты решения (и на других форумах в том числе). В итоге пришла к такому решению (здесь выложен истинный, а не адаптированный для выкладки примера код):  
 
Sub SaveSheet_SMB()  
ThisWorkbook.Unprotect ("XXX")  
   Dim wsSh As Worksheet  
   Dim NewWb As Workbook, asArr(), li As Long  
   Application.ScreenUpdating = False  
   For Each wsSh In Sheets(Array("П_СМБ", "З_СМБ", "Пер_СМБ"))  
       If wsSh.Visible <> -1 Then ReDim Preserve asArr(li): asArr(li) = wsSh.Name: li = li + 1: wsSh.Visible = xlSheetVisible  
   Next wsSh  
   Sheets(Array("П_СМБ", "З_СМБ", "Пер_СМБ")).Copy  
   Set NewWb = ActiveWorkbook  
   For Each wsSh In NewWb.Worksheets  
       With wsSh  
           .Visible = True  
           .UsedRange.Value = .UsedRange.Value  
       End With  
   Next  
 
   For li = LBound(asArr) To UBound(asArr)  
       ThisWorkbook.Sheets(asArr(li)).Visible = xlSheetVeryHidden  
   Next li  
   NewWb.SaveAs Filename:=ActiveWorkbook.Path & "Копия.xls"  
   Application.ScreenUpdating = True  
   MsgBox "Формы документов перенесены в новую книгу и сохранены.", , ""  
End Sub  
 
Однако снова возникли вопросы:  
1. Можно ли сохранить копируемые (а на самом деле - перемещаемые) листы в исходной книге иным способом или это возможно только с помощью закрытия исходной книги без сохранения?  
2. Есть ли способ защитить новосозданную книгу и ее листы таким образом, чтобы пользователю были недоступны никакие изменения, словно лист сохранился как картинка в pdf-формате?
 
1. Попробуйте все же мой код от 01.04.2010, 13:41  
2. Да можно. Можно защитить листы.  
Вставьте в мой код перед Next строчку:  
ActiveSheet.Protect Password:="12345"  
Помните, что защита не стойкая. На форуме неоднократно это обсуждалось.  
Может и сохранить листы в пдф? Наберите в поиск напечатать в pdf  
 
Кстати, мой код от 31.03.2010, 10:04 не работал из-за того, что все листы были скрытые. Достаточно один сделать видимым, как все копируются. Т.е. сначала  
Sheets("П_СМБ").Visible = True  
затем весь код  
и в конце скрываем  
ThisWorkbook.Sheets("П_СМБ").Visible = xlSheetVeryHidden  
 
все циклы и массивы не нужны.
Bite my shiny metal ass!      
 
Или так:  
Sub SaveSheet_SMB()  
ThisWorkbook.Unprotect ("XXX")  
Dim wsSh As Worksheet  
Dim NewWb As Workbook, asArr(), li As Long  
Application.ScreenUpdating = False  
For Each wsSh In Sheets(Array("П_СМБ", "З_СМБ", "Пер_СМБ"))  
If wsSh.Visible <> -1 Then ReDim Preserve asArr(li): asArr(li) = wsSh.Name: li = li + 1: wsSh.Visible = xlSheetVisible  
Next wsSh  
Sheets(Array("П_СМБ", "З_СМБ", "Пер_СМБ")).Copy  
Set NewWb = ActiveWorkbook  
For Each wsSh In NewWb.Worksheets  
With wsSh.UsedRange  
.Copy  
wsSh.Range(.Address).PasteSpecial Paste:=xlPasteValues 'Вот эта строка от Лузер™  
End With  
Next  
 
For li = LBound(asArr) To UBound(asArr)  
ThisWorkbook.Sheets(asArr(li)).Visible = xlSheetVeryHidden  
Next li  
NewWb.SaveAs Filename:=ActiveWorkbook.Path & "Копия.xls"  
Application.ScreenUpdating = True  
MsgBox "Формы документов перенесены в новую книгу и сохранены.", , ""  
End Sub  
У меня работает.  
По поводу сохранения в PDF ссылаюсь на пост Лузер™.
Я сам - дурнее всякого примера! ...
 
Еше перед End Sub:  
ThisWorkbook.Protect ("XXX")
Я сам - дурнее всякого примера! ...
 
А если сохранить новый файл с названием из определенной ячейки оригинального файла?  
 
Sub SaveSheet_SMB()  
Sheets("Учет").Range("$B$2") = Sheets("1").Range("B2")  
Dim wsSh As Worksheet  
Dim NewWb As Workbook, asArr(), li As Long  
Application.ScreenUpdating = False  
For Each wsSh In Sheets(Array("1", "2"))  
If wsSh.Visible <> -1 Then ReDim Preserve asArr(li): asArr(li) = wsSh.Name: li = li + 1: wsSh.Visible = xlSheetVisible  
Next wsSh  
Sheets(Array("1", "2")).Copy  
Set NewWb = ActiveWorkbook  
For Each wsSh In NewWb.Worksheets  
With wsSh.UsedRange  
.Copy  
wsSh.Range(.Address).PasteSpecial Paste:=xlPasteValues 'Вот эта строка от Лузер™  
End With  
Next  
 
 
NewWb.SaveAs Filename:=Replace(ThisWorkbook.FullName, ThisWorkbook.Name, "1_2 ") & Sheets("Учет").Range("B2")& ".xls"  
For li = LBound(asArr) To UBound(asArr)  
ThisWorkbook.Sheets(asArr(li)).Visible = xlSheetVeryHidden  
Next li  
Application.ScreenUpdating = True  
MsgBox "Формы документов перенесены в новую книгу и сохранены.", , ""  
 
Sheets(Array("1", "2")).Select  
Sheets("1").Activate  
ActiveWindow.SelectedSheets.PrintPreview  
'Selection.PrintOut Copies:=1, Collate:=True  
ThisWorkbook.Save  
ThisWorkbook.Close  
End Sub  
 
Отчего игнорируется & Sheets("Учет").Range("B2")& ".xls" ?  
Помогите как нибудь.
Страницы: 1
Читают тему
Наверх