Preciso consolidar 3 arquivos .XLSM.
Cada arquivo tem 3 planilhas, MAS, preciso pegar apenas a Primeira planilha.
Todos os arquivos possuem a mesma estrutura.
A partir do segundo arquivo não pode vir o cabeçalho, ou seja, a primeira linha não deve ser importada.
O código abaixo funciona bem e faz quase todo o processo. Porém, ele importa todas as planilhas de cada arquivo e ainda também importa a primeira linha de todas planilhas.
Desde já agradeço aos que puderem ajudar.
Célio
Public Sub ConsolidateSheets()
Dim Wb1 As Workbook
Dim Wb2 As Workbook
Dim ws1 As Worksheet
Dim ws2 As Worksheet
Dim ws3 As Worksheet
Dim rng1 As Range
Dim rng2 As Range
Dim rng3 As Range
Dim rngArea As Range
Dim lrowSpace As Long
Dim lSht As Long
Dim lngCalc As Long
Dim lngRow As Long
Dim lngCol As Long
Dim X()
Dim bProcessFolder As Boolean
Dim bNewSheet As Boolean
Dim StrPrefix
Dim strFileName As String
Dim strFolderName As String
'Declaração Variant necessária para o objeto Shell para usar o diretório padrão
Dim strDefaultFolder As Variant
bProcessFolder = (MsgBox("Processa um único diretório (SIM)," & vbNewLine & "or single file (NÃO)", vbYesNo, "Escopo da Aplicação: Diretório ou Arquivo Simples") = vbYes)
bNewSheet = (MsgBox("Extrai todos os dados para uma única planilha (SIM)," & vbNewLine & "Ou um arquivo destino para cada planilha de origem (NÃO)", vbYesNo, "Formato de saída: Planilha única ou planilha por planilha") = vbYes)
If Not bProcessFolder Then
If Not bNewSheet Then
MsgBox "Não há muito sentido em criar uma réplica exata de seu arquivo de origem :)"
Exit Sub
End If
End If
'Coloque o diretório padrão aqui se necessário
strDefaultFolder = "\tcerj96TCERJ_TSUM1 - CONTROLE CONTÍNUO - CICLO 1CONTROLE PROCESSOS POR CCM"
'Se o usuário estiver copiando todas as planilhas para uma planilha única então a linha de espaçamento
'para distinguir entre diferentes planihas pode ser colocada aqui
lrowSpace = 0
If bProcessFolder Then
strFolderName = BrowseForFolder(strDefaultFolder)
'Procura por xls, xlsx, xlsm files
strFileName = Dir(strFolderName & "*.xls*")
Else
strFileName = Application _
.GetOpenFilename("Selecione os arquivos (*.xls*), *.xls*")
End If
Set Wb1 = Workbooks.Add(1)
Set ws1 = Wb1.Sheets(1)
If Not bNewSheet Then ws1.Range("A1:K1") = Array("workbook name", "worksheet count")
'Desliga Atualização de tela, Eventos, Alertas e colocar o modo de cálculo para manual
With Application
.DisplayAlerts = False
.EnableEvents = False
.ScreenUpdating = False
lngCalc = .Calculation
.Calculation = xlCalculationManual
End With
'Coloca o caminha fora do loop
StrPrefix = strFolderName & IIf(bProcessFolder, "", vbNullString)
Do While Len(strFileName) > 0
'Providencia o status do progresso ao usuário
Application.StatusBar = Left("Processing " & strFolderName & "" & strFileName, 255)
'Abre cada pasta de trabalho no diretório de interesse
Set Wb2 = Workbooks.Open(StrPrefix & strFileName)
If Not bNewSheet Then
'Adiciona um resumo à primeira planilha
ws1.Cells(Rows.Count, "A").End(xlUp).Offset(1, 0) = Wb2.Name
ws1.Cells(Rows.Count, "A").End(xlUp).Offset(0, 1) = Wb2.Sheets.Count
End If
For Each ws2 In Wb2.Sheets
'If ws2.Name = "Processos" Then
If bNewSheet Then
'Todos os dados para uma única planilha
'Pula a importação dos dados da planilha se a planilha de origem estiver vazia
Set rng2 = ws2.Cells.Find("*", ws2.[a1], xlValues, , xlByRows, xlPrevious)
If Not rng2 Is Nothing Then
Set rng1 = ws1.Cells.Find("*", ws1.[a1], xlValues, , xlByRows, xlPrevious)
'Encontra a primeira linha em branco na planilha destino
If Not rng1 Is Nothing Then
Set rng3 = ws2.Range(ws2.UsedRange.Cells(1), ws2.Cells(rng2.Row, "A"))
'Certifica que a área da linha na planilha destino não será excedida
If rng3.Rows.Count + rng1.Row < Rows.Count Then
'Copia os dados do intervalo usado de cada planilha de origem para a primeira linha em branco
' da planilha destino, usando o endereço inicial da coluna da planilha de origem sendo copiada
ws2.UsedRange.Copy ws1.Cells(rng1.Row + 1 + lrowSpace, ws2.UsedRange.Cells(1).Column)
Else
MsgBox "Tamanho da planilha consolidada excedido. Processo interrompido" & vbNewLine & _
"sheet: " & ws2.Name & vbNewLine & "of" & vbNewLine & "workbook: " & Wb2.Name
Wb2.Close False
Exit Do
End If
'Colore a primeira qualquer linha de espaçamento
If lrowSpace <> 0 Then ws1.Rows(rng1.Row + 1).Interior.Color = vbGreen
Else
'Planilha destino está vazia então copia para a primeira linha
ws2.UsedRange.Copy ws1.Cells(1, ws2.UsedRange.Cells(1).Column)
End If
End If
Else
'Nova planilha para cada planilha de origem
ws2.Copy after:=Wb1.Sheets(Wb1.Sheets.Count)
'Remove qualquer link na planilha destino
'With Wb1.Sheets(Wb1.Sheets.Count).Cells
'.Copy
'.PasteSpecial xlPasteValues
'End With
On Error Resume Next
Wb1.Sheets(Wb1.Sheets.Count).Name = ws2.Name
'Nome da planilha já existe na pasta de trabalho destino
If Err.Number <> 0 Then
'Adiciona um número ao nome da planilha até obter um nome único
Do
lSht = lSht + 1
Set ws3 = Wb1.Sheets(ws2.Name & " " & lSht)
Loop While Not ws3 Is Nothing
lSht = 0
End If
On Error GoTo 0
End If
'End If
Next ws2
'Fecha a pasta de trabalho aberta
Wb2.Close False
'Checa se necessário forçar uma saída do laço DO se processando um arquivo único
If bProcessFolder = False Then Exit Do
strFileName = Dir
Loop
'Remove qualquer link se o usuário usou uma planilha destino
If bNewSheet Then
With ws1.UsedRange
.Copy
.Cells(1).PasteSpecial xlPasteValuesAndNumberFormats
.Cells(1).Activate
ws1.Range("A1:k1").Font.Bold = True
ws1.Columns.AutoFit
End With
Else
'Formata a planilha resumo se o usuário criou planilhas separadas
ws1.Activate
ws1.Range("A1:k1").Font.Bold = True
ws1.Columns.AutoFit
End If
With Application
.CutCopyMode = False
.DisplayAlerts = True
.EnableEvents = True
.ScreenUpdating = True
.Calculation = lngCalc
.StatusBar = vbNullString
End With
End Sub
Function BrowseForFolder(Optional OpenAt As Variant) As Variant
'From Ken Puls as used in his vbaexpress.com article
'http://www.vbaexpress.com/kb/getarticle.php?kb_id=284
Dim ShellApp As Object
'Cria uma janela de navegador de arquivo no diretório padrão
Set ShellApp = CreateObject("Shell.Application"). _
BrowseForFolder(0, "Please choose a folder", 0, OpenAt)
'Coloca o diretório para o padrão selecionado. (Em caso de erro cancela)
On Error Resume Next
BrowseForFolder = ShellApp.self.Path
On Error GoTo 0
'Destroi a aplicação Shell
Set ShellApp = Nothing
'Checa por entradas inválidas e não entradas e envia para o Manipulador de Erro se encontrado
'Seleções válidas pode começar com L: (Em que L é a letra) ou
'\ (com em \nomedoservidornomearquivo. Todos os outros serão inválidos
Select Case Mid(BrowseForFolder, 2, 1)
Case Is = ":"
If Left(BrowseForFolder, 1) = ":" Then GoTo Invalid
Case Is = ""
If Not Left(BrowseForFolder, 1) = "" Then GoTo Invalid
Case Else
GoTo Invalid
End Select
Exit Function
Invalid:
'Se foi determinado que a seleção é inválida, coloque pra Falso
BrowseForFolder = False
End Function
Postado : 01/07/2016 12:06 pm