Всем привет! На просторах интернета нашел макрос, который переносит данные из книги в книгу. Немного его подправил под свои нужны и все казалось бы ничего, но столкнулся с такой проблемой - в книгах, из которых копирую данные, есть шапка из объединенных ячеек, ее в таком же формате макрос переносит и в итоговую книгу, а этого не надо. Надо наоборот - чтобы снял объединение, получившиеся пустые ячейки заполнил и уже это перенс в итоговую книгу. Не могу понять, что править в макросе, чтобы это сделать:
Option Explicit
Sub weeks_plans() Dim iBeginRange As Range, rCopy As Range, lCalc AsLong, lCol AsLong Dim oAwb AsString, sCopyAddress AsString, sSheetName AsString Dim lLastrow AsLong, lLastRowMyBook AsLong, li AsLong, iLastColumn AsInteger Dim wsSh As Worksheet, wsDataSheet As Worksheet, bPolyBooks AsBoolean, avFiles Dim wbAct As Workbook Dim bPasteValues AsBoolean, IsPasteSheetName AsBoolean
OnErrorResumeNext 'Выбираем диапазон выборки с книг 'Set iBeginRange = Application.InputBox("Выберите диапазон сбора данных." & vbCrLf & _ "1. При выборе только одной ячейки данные будут собраны со всех листов начиная с этой ячейки. " & _
vbCrLf & "2. При выделении нескольких ячеек данные будут собраны только с указанного диапазона всех листов.", Type:=8) 'для указания диапазона без диалогового окна: 'Set iBeginRange = Range("F24:AG30") 'диапазон указывается нужный Set iBeginRange = Union(Range("d3:Ae3"), Range("d7:Ae10"), Range("d26:Ae32"), Range("d44:Ae51"))
'Если диапазон не выбран - завершаем процедуру If iBeginRange IsNothingThen ExitSub EndIf 'Указываем имя листа 'Допустимо указывать в имени листа символы подставки ? и *. 'Если указать только * то данные будут собираться со всех листов
sSheetName = InputBox("Введите имя листа, с которого собирать данные(если не указан, то данные собираются со всех листов)", "Параметр") 'Если имя листа не указано - данные будут собраны со вех листов If sSheetName = ""Then
sSheetName = "*" EndIf 'добавлять ли имя листа в начало таблицы
IsPasteSheetName = (MsgBox("Вставлять имя листа первым столбцом?", vbQuestion + vbYesNo) = vbYes) OnErrorGoTo0 'Запрос - вставлять на результирующий лист все данные 'или только значения ячеек (без формул и форматов)
bPasteValues = (MsgBox("Вставлять только значения?", vbQuestion + vbYesNo) = vbYes) 'Запрос сбора данных с книг(если Нет - то сбор идет с активной книги) If MsgBox("Собрать данные с нескольких книг?", vbInformation + vbYesNo) = vbYes Then
avFiles = Application.GetOpenFilename("Excel files(*.xls*),*.xls*", , "Выбор файлов", , True) IfVarType(avFiles) = vbBoolean ThenExitSub
bPolyBooks = True
lCol = 0'1 Else
avFiles = Array(ThisWorkbook.FullName) EndIf If IsPasteSheetName Then
lCol = lCol + 1 EndIf 'отключаем обновление экрана, автопересчет формул и отслеживание событий 'для скорости выполнения кода и для избежания ошибок, если в книгах есть иные коды With Application
lCalc = .Calculation
.ScreenUpdating = False
.EnableEvents = False
.Calculation = xlManual EndWith 'создаем новый лист в книге для сбора 'Set wsDataSheet = ActiveWorkbook.Sheets.Add(After:=Sheets(Sheets.Count)) Set wsDataSheet = ActiveWorkbook.Sheets(4) 'если нужно сделать сбор данных на новый лист книги с кодом 'Set wsDataSheet = ThisWorkbook.Sheets.Add(After:=ThisWorkbook.Sheets(ThisWorkbook.Sheets.Count)) 'цикл по книгам For li = LBound(avFiles) ToUBound(avFiles) If bPolyBooks Then Set wbAct = Workbooks.Open(Filename:=avFiles(li)) Else Set wbAct = ThisWorkbook EndIf
oAwb = wbAct.Name 'цикл по листам For Each wsSh In wbAct.Sheets If wsSh.Name Like sSheetName AndNot wsSh.Visible = xlSheetHidden Then 'Если имя листа совпадает с именем листа, в который собираем данные 'и сбор идет только с активной книги - то переходим к следующему листу If wsSh.Name = wsDataSheet.Name And bPolyBooks = FalseThenGoTo NEXT_ With wsSh SelectCase iBeginRange.Count Case1'собираем данные начиная с указанной ячейки и до конца данных
lLastrow = .Cells(1, 1).SpecialCells(xlLastCell).Row
iLastColumn = .Cells.SpecialCells(xlLastCell).Column
sCopyAddress = .Range(.Cells(iBeginRange.Row, iBeginRange.Column), .Cells(lLastrow, iLastColumn)).Address CaseElse'собираем данные с фиксированного диапазона
sCopyAddress = iBeginRange.Address EndSelect
lLastRowMyBook = wsDataSheet.Cells.SpecialCells(xlLastCell).Row + 1 'определяем для копирования диапазон только заполненных данных на листе Set rCopy = Intersect(.Range(sCopyAddress).Parent.UsedRange, .Range(sCopyAddress)) 'вставляем имя книги, с которой собраны данные If lCol > 0Then If bPolyBooks Then
wsDataSheet.Cells(lLastRowMyBook, 1).Resize(rCopy.Rows.Count).Value = oAwb EndIf If IsPasteSheetName Then
wsDataSheet.Cells(lLastRowMyBook, lCol).Resize(rCopy.Rows.Count).Value = .Name EndIf EndIf ''если вставляем только значения If bPasteValues Then
rCopy.Copy
wsDataSheet.Cells(lLastRowMyBook, 1).Offset(, lCol).PasteSpecial xlPasteValues
wsDataSheet.Cells(lLastRowMyBook, 1).Offset(, lCol).PasteSpecial xlPasteFormats Else'если вставляем все данные ячеек(формулы, форматы и т.д.)
rCopy.Copy wsDataSheet.Cells(lLastRowMyBook, 1).Offset(, lCol) EndIf EndWith EndIf
NEXT_: Next wsSh If bPolyBooks Then
wbAct.Close False EndIf Next li With Application
.ScreenUpdating = True
.EnableEvents = True '.Calculation = lCalc
.Calculation = xlCalculationAutomatic EndWith EndSub
EndSub
Всем привет! На просторах интернета нашел макрос, который переносит данные из книги в книгу. Немного его подправил под свои нужны и все казалось бы ничего, но столкнулся с такой проблемой - в книгах, из которых копирую данные, есть шапка из объединенных ячеек, ее в таком же формате макрос переносит и в итоговую книгу, а этого не надо. Надо наоборот - чтобы снял объединение, получившиеся пустые ячейки заполнил и уже это перенс в итоговую книгу. Не могу понять, что править в макросе, чтобы это сделать:
Option Explicit
Sub weeks_plans() Dim iBeginRange As Range, rCopy As Range, lCalc AsLong, lCol AsLong Dim oAwb AsString, sCopyAddress AsString, sSheetName AsString Dim lLastrow AsLong, lLastRowMyBook AsLong, li AsLong, iLastColumn AsInteger Dim wsSh As Worksheet, wsDataSheet As Worksheet, bPolyBooks AsBoolean, avFiles Dim wbAct As Workbook Dim bPasteValues AsBoolean, IsPasteSheetName AsBoolean
OnErrorResumeNext 'Выбираем диапазон выборки с книг 'Set iBeginRange = Application.InputBox("Выберите диапазон сбора данных." & vbCrLf & _ "1. При выборе только одной ячейки данные будут собраны со всех листов начиная с этой ячейки. " & _
vbCrLf & "2. При выделении нескольких ячеек данные будут собраны только с указанного диапазона всех листов.", Type:=8) 'для указания диапазона без диалогового окна: 'Set iBeginRange = Range("F24:AG30") 'диапазон указывается нужный Set iBeginRange = Union(Range("d3:Ae3"), Range("d7:Ae10"), Range("d26:Ae32"), Range("d44:Ae51"))
'Если диапазон не выбран - завершаем процедуру If iBeginRange IsNothingThen ExitSub EndIf 'Указываем имя листа 'Допустимо указывать в имени листа символы подставки ? и *. 'Если указать только * то данные будут собираться со всех листов
sSheetName = InputBox("Введите имя листа, с которого собирать данные(если не указан, то данные собираются со всех листов)", "Параметр") 'Если имя листа не указано - данные будут собраны со вех листов If sSheetName = ""Then
sSheetName = "*" EndIf 'добавлять ли имя листа в начало таблицы
IsPasteSheetName = (MsgBox("Вставлять имя листа первым столбцом?", vbQuestion + vbYesNo) = vbYes) OnErrorGoTo0 'Запрос - вставлять на результирующий лист все данные 'или только значения ячеек (без формул и форматов)
bPasteValues = (MsgBox("Вставлять только значения?", vbQuestion + vbYesNo) = vbYes) 'Запрос сбора данных с книг(если Нет - то сбор идет с активной книги) If MsgBox("Собрать данные с нескольких книг?", vbInformation + vbYesNo) = vbYes Then
avFiles = Application.GetOpenFilename("Excel files(*.xls*),*.xls*", , "Выбор файлов", , True) IfVarType(avFiles) = vbBoolean ThenExitSub
bPolyBooks = True
lCol = 0'1 Else
avFiles = Array(ThisWorkbook.FullName) EndIf If IsPasteSheetName Then
lCol = lCol + 1 EndIf 'отключаем обновление экрана, автопересчет формул и отслеживание событий 'для скорости выполнения кода и для избежания ошибок, если в книгах есть иные коды With Application
lCalc = .Calculation
.ScreenUpdating = False
.EnableEvents = False
.Calculation = xlManual EndWith 'создаем новый лист в книге для сбора 'Set wsDataSheet = ActiveWorkbook.Sheets.Add(After:=Sheets(Sheets.Count)) Set wsDataSheet = ActiveWorkbook.Sheets(4) 'если нужно сделать сбор данных на новый лист книги с кодом 'Set wsDataSheet = ThisWorkbook.Sheets.Add(After:=ThisWorkbook.Sheets(ThisWorkbook.Sheets.Count)) 'цикл по книгам For li = LBound(avFiles) ToUBound(avFiles) If bPolyBooks Then Set wbAct = Workbooks.Open(Filename:=avFiles(li)) Else Set wbAct = ThisWorkbook EndIf
oAwb = wbAct.Name 'цикл по листам For Each wsSh In wbAct.Sheets If wsSh.Name Like sSheetName AndNot wsSh.Visible = xlSheetHidden Then 'Если имя листа совпадает с именем листа, в который собираем данные 'и сбор идет только с активной книги - то переходим к следующему листу If wsSh.Name = wsDataSheet.Name And bPolyBooks = FalseThenGoTo NEXT_ With wsSh SelectCase iBeginRange.Count Case1'собираем данные начиная с указанной ячейки и до конца данных
lLastrow = .Cells(1, 1).SpecialCells(xlLastCell).Row
iLastColumn = .Cells.SpecialCells(xlLastCell).Column
sCopyAddress = .Range(.Cells(iBeginRange.Row, iBeginRange.Column), .Cells(lLastrow, iLastColumn)).Address CaseElse'собираем данные с фиксированного диапазона
sCopyAddress = iBeginRange.Address EndSelect
lLastRowMyBook = wsDataSheet.Cells.SpecialCells(xlLastCell).Row + 1 'определяем для копирования диапазон только заполненных данных на листе Set rCopy = Intersect(.Range(sCopyAddress).Parent.UsedRange, .Range(sCopyAddress)) 'вставляем имя книги, с которой собраны данные If lCol > 0Then If bPolyBooks Then
wsDataSheet.Cells(lLastRowMyBook, 1).Resize(rCopy.Rows.Count).Value = oAwb EndIf If IsPasteSheetName Then
wsDataSheet.Cells(lLastRowMyBook, lCol).Resize(rCopy.Rows.Count).Value = .Name EndIf EndIf ''если вставляем только значения If bPasteValues Then
rCopy.Copy
wsDataSheet.Cells(lLastRowMyBook, 1).Offset(, lCol).PasteSpecial xlPasteValues
wsDataSheet.Cells(lLastRowMyBook, 1).Offset(, lCol).PasteSpecial xlPasteFormats Else'если вставляем все данные ячеек(формулы, форматы и т.д.)
rCopy.Copy wsDataSheet.Cells(lLastRowMyBook, 1).Offset(, lCol) EndIf EndWith EndIf
NEXT_: Next wsSh If bPolyBooks Then
wbAct.Close False EndIf Next li With Application
.ScreenUpdating = True
.EnableEvents = True '.Calculation = lCalc
.Calculation = xlCalculationAutomatic EndWith EndSub