Excel VBA trouble looping through sheets and calling subroutine - vba

My subroutine works fine when I run it on individual sheets, but I've had a lot of problems getting it to run on each individual sheet. The Subroutine is a simple query of an online CSV database, but it only executes 25 times on the first sheet. can't figure out for the life of me why this is.
I was able to do calculations through this same loop, but could not get it to run a subroutine on each sheet.
Sub Datacollection()
Dim ws As Worksheet
For Each ws In Worksheets
ws.Application.Run "Gethistory"
Next ws
End Sub
Sub Gethistory()
Dim Target As Variant
Dim Name As Variant
'
Set Target = Range("B1")
Set Name = Range("B2")
With ActiveSheet.QueryTables.Add(Connection:= _
"Text;" & Target, _
Destination:=Range("$A$3"))
.Name = Name
.FieldNames = True
.RowNumbers = False
.FillAdjacentFormulas = False
.PreserveFormatting = True
.RefreshOnFileOpen = False
.RefreshStyle = xlOverwriteCells
.SavePassword = False
.SaveData = True
.AdjustColumnWidth = True
.RefreshPeriod = 0
.TextFilePromptOnRefresh = False
.TextFilePlatform = 437
.TextFileStartRow = 1
.TextFileParseType = xlDelimited
.TextFileTextQualifier = xlTextQualifierDoubleQuote
.TextFileConsecutiveDelimiter = True
.TextFileTabDelimiter = True
.TextFileSemicolonDelimiter = False
.TextFileCommaDelimiter = True
.TextFileSpaceDelimiter = True
.TextFileColumnDataTypes = Array(1, 1, 1, 1, 1, 1, 1, 1, 1)
.TextFileTrailingMinusNumbers = True
.Refresh BackgroundQuery:=False
End With
End Sub

Gather the worksheet to be processed in your primary loop and pass that to the getHistory sub as a parameter.
Option Explicit
Sub dataCollection()
Dim w As Long
For w = 1 To Worksheets.Count
getHistory Worksheets(w)
Next w
End Sub
Sub getHistory(ws As Worksheet)
Dim trgt As Range, nm As Range
With ws
Set trgt = .Range("B1")
Set nm = .Range("B2")
With .QueryTables.Add(Connection:= _
"Text;" & trgt.Value, _
Destination:=.Range("$A$3"))
.Name = nm.Value
.FieldNames = True
.RowNumbers = False
.FillAdjacentFormulas = False
.PreserveFormatting = True
.RefreshOnFileOpen = False
.RefreshStyle = xlOverwriteCells
.SavePassword = False
.SaveData = True
.AdjustColumnWidth = True
.RefreshPeriod = 0
.TextFilePromptOnRefresh = False
.TextFilePlatform = 437
.TextFileStartRow = 1
.TextFileParseType = xlDelimited
.TextFileTextQualifier = xlTextQualifierDoubleQuote
.TextFileConsecutiveDelimiter = True
.TextFileTabDelimiter = True
.TextFileSemicolonDelimiter = False
.TextFileCommaDelimiter = True
.TextFileSpaceDelimiter = True
.TextFileColumnDataTypes = Array(1, 1, 1, 1, 1, 1, 1, 1, 1)
.TextFileTrailingMinusNumbers = True
.Refresh BackgroundQuery:=False
End With
End With
End Sub
If you do this repeatedly, you will end up with a lot of connections that could interfere in the general workbook efficiency as well as future getHistory runs. You might want to delete the connections as you create them or only use a refresh method to maintain the data.

Related

Import variable path CSV directly into table

I am trying to import data from CSV file "User Roles Entitlements" into my current sheet (current sheet tab name is also "User Roles Entitlements"), which is working perfectly fine if it being imported to cell A1. However, if I try to a table, the code does not work. I know it is a minor tweak, however, I am unable to figure it out.
Note: My file is in the same folder and I am using a variable path import VBA Code.
My code is as follows:
Dim path As String
path = CreateObject("Scripting.FileSystemObject").GetAbsolutePathName(ThisWorkbook.path)
Sheets("User Roles Entitlements").Select
Range("A1").Select
With ActiveSheet.QueryTables.Add(Connection:="TEXT;" & path & "\User Roles Entitlements.csv", Destination:=Range("A1"))
.Name = "positions_1"
.FieldNames = True
.RowNumbers = False
.FillAdjacentFormulas = False
.PreserveFormatting = True
.RefreshOnFileOpen = False
.RefreshStyle = xlInsertDeleteCells
.SaveData = True
.AdjustColumnWidth = True
.RefreshPeriod = 0
.TextFilePromptOnRefresh = False
.TextFilePlatform = 857
.TextFileStartRow = 1
.TextFileParseType = xlDelimited
.TextFileTextQualifier = xlTextQualifierDoubleQuote
.TextFileConsecutiveDelimiter = False
.TextFileTabDelimiter = False
.TextFileSemicolonDelimiter = False
.TextFileCommaDelimiter = True
.TextFileSpaceDelimiter = False
.TextFileColumnDataTypes = Array(1, 1, 1, 1, 1)
.TextFileTrailingMinusNumbers = True
.Refresh BackgroundQuery:=False
End With
End Sub
Would appreciate if I could get help with this.
Are you okay if the data connection is lost after you import? In other words, will you need to dynamically refresh the table from the CSV file after you bring it in?
If the answer is no, then you can simply convert the range to a ListObject (table) after the fact.
For ease (so you don't have to figure out the range later), you can capture the range from the QueryTable object before you clobber it.
Sub CsvInsert()
Dim sh As Worksheet
Dim qt As QueryTable
Dim r As Range
Set sh = Sheets("User Roles Entitlements")
Set qt = sh.QueryTables.Add(Connection:="TEXT;" & path & _
"\User Roles Entitlements.csv", Destination:=Range("A1"))
With qt
.Name = "positions_1"
.FieldNames = True
.RowNumbers = False
.FillAdjacentFormulas = False
.PreserveFormatting = True
.RefreshOnFileOpen = False
.RefreshStyle = xlInsertDeleteCells
.SaveData = True
.AdjustColumnWidth = True
.RefreshPeriod = 0
.TextFilePromptOnRefresh = False
.TextFilePlatform = 857
.TextFileStartRow = 1
.TextFileParseType = xlDelimited
.TextFileTextQualifier = xlTextQualifierDoubleQuote
.TextFileConsecutiveDelimiter = False
.TextFileTabDelimiter = False
.TextFileSemicolonDelimiter = False
.TextFileCommaDelimiter = True
.TextFileSpaceDelimiter = False
.TextFileColumnDataTypes = Array(1, 1, 1, 1, 1)
.TextFileTrailingMinusNumbers = True
.Refresh BackgroundQuery:=False
End With
Then convert the querytable to a range and create a table over the range:
Set r = qt.ResultRange
sh.QueryTables("positions_1").Delete
sh.ListObjects.Add(xlSrcRange, r).Name = "positions_1"
End Sub

Importing CSV to another worksheet

I need to import my data into another Excel sheet instead of active worksheet.
I have 2 sheets the UI and the DATA_List. My button is in the UI. I want to import the csv file to data_list sheet.
Sub btnImport_Click()
Dim slect As String
Set r = Range("A" & Cells(Rows.Count, "A").End(xlUp).Row + 1)
With Application.FileDialog(msoFileDialogFilePicker)
.Show
If .SelectedItems.Count = 0 Then
MsgBox "Cancel Selected"
Exit Sub
End If
slect = .SelectedItems(1)
End With
With ThisWorkbook.Sheets("UI").QueryTables.Add(Connection:= _
"TEXT;" & slect, Destination:=r)
.Name = "Data"
.FieldNames = True
.RowNumbers = False
.FillAdjacentFormulas = False
.PreserveFormatting = True
.RefreshOnFileOpen = False
.RefreshStyle = xlInsertDeleteCells
.SavePassword = False
.SaveData = True
.AdjustColumnWidth = True
.RefreshPeriod = 0
.TextFilePromptOnRefresh = False
.TextFilePlatform = 437
.TextFileStartRow = 1
.TextFileParseType = xlDelimited
.TextFileTextQualifier = xlTextQualifierDoubleQuote
.TextFileConsecutiveDelimiter = False
.TextFileTabDelimiter = False
.TextFileSemicolonDelimiter = False
.TextFileCommaDelimiter = True
.TextFileSpaceDelimiter = False
.TextFileColumnDataTypes = Array(1)
.TextFileTrailingMinusNumbers = True
.Refresh BackgroundQuery:=False
End With
Change the first line to
Set r = Worksheets("data_list").Range("A1")
You will also need to change the line
With ThisWorkbook.Sheets("UI").QueryTables.Add(Connection:= _
"TEXT;" & slect, Destination:=r)
To
With ThisWorkbook.Sheets("data_list").QueryTables.Add(Connection:= _
"TEXT;" & slect, Destination:=r)

Import multiple CSV files into master excel spreadsheet and append the data to previous imports

I have a script that imports a .csv file into worksheet "Data"
After the first import all following ones appear to the right of the previous imports and not added onto the bottom (last row).
I think the issue involves this area of the script:
Destination:=ThisWorkbook.Sheets("Data").Range("$A$1"))
Sub load_csv()
Dim fStr As String
With Application.FileDialog(msoFileDialogFilePicker)
.Show
If .SelectedItems.Count = 0 Then
MsgBox "Cancel Selected"
Exit Sub
End If
'fStr is the file path and name of the file you selected.
fStr = .SelectedItems(1)
End With
With ThisWorkbook.Sheets("Data").QueryTables.Add(Connection:= _
"TEXT;" & fStr, Destination:=ThisWorkbook.Sheets("Data").Range("$A$1"))
.Name = "CAPTURE"
.FieldNames = True
.RowNumbers = False
.FillAdjacentFormulas = False
.PreserveFormatting = True
.RefreshOnFileOpen = False
.RefreshStyle = xlInsertDeleteCells
.SavePassword = False
.SaveData = True
.AdjustColumnWidth = True
.RefreshPeriod = 0
.TextFilePromptOnRefresh = False
.TextFilePlatform = 437
.TextFileStartRow = 1
.TextFileParseType = xlDelimited
.TextFileTextQualifier = xlTextQualifierDoubleQuote
.TextFileConsecutiveDelimiter = False
.TextFileTabDelimiter = True
.TextFileSemicolonDelimiter = False
.TextFileCommaDelimiter = True
.TextFileSpaceDelimiter = False
.TextFileColumnDataTypes = Array(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1)
.TextFileTrailingMinusNumbers = True
.Refresh BackgroundQuery:=False
End With
End Sub
You need to examine the destination to see what the next unused cell is.
With ThisWorkbook.Sheets("Data")
.QueryTables.Add(Connection:= _
..., Destination:=.Cells(Rows.Count, "A").End(xlUp).Offset(1, 0)
'lots of other stuff
End With
You can rereference the ThisWorkbook.Sheets("Data") repeatedly but using a With ... End With statement is easier.

VBA importing CSV file to OjbExcel

I've been trying to generate an excel by feeding it a .Csv file in VBA.
We are using a inhouse business program that uses vba so I have to reference to objExcel.
This:
Function load_csv()
Dim objExcel
Dim objWorkbook
Dim baseSheet
Set objExcel = CreateObject("Excel.Application")
Set objWorkbook = objExcel.workbooks.Add()
Set baseSheet = objWorkbook.worksheets(1)
With objExcel.ThisWorkbook.Sheets("Data").QueryTables.Add(Connection:="TEXT;FILENAME.csv", Destination:=Range("$A$1"))
.Name = "CAPTURE"
.fieldNames = True
.RowNumbers = False
.FillAdjacentFormulas = False
.PreserveFormatting = True
.RefreshOnFileOpen = False
.RefreshStyle = xlInsertDeleteCells
.SavePassword = False
.SaveData = True
.AdjustColumnWidth = True
.RefreshPeriod = 0
.TextFilePromptOnRefresh = False
.TextFilePlatform = 437
.TextFileStartRow = 1
.TextFileParseType = xlDelimited
.TextFileTextQualifier = xlTextQualifierDoubleQuote
.TextFileConsecutiveDelimiter = False
.TextFileTabDelimiter = True
.TextFileSemicolonDelimiter = False
.TextFileCommaDelimiter = True
.TextFileSpaceDelimiter = False
.TextFileColumnDataTypes = Array(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1)
.TextFileTrailingMinusNumbers = True
.Refresh BackgroundQuery:=False
End With
objExcel.ActiveWorkbook.SaveAs
Set objExcel = Nothing
Set objWorkbook = Nothing
Set baseSheet = Nothing
End Function
Gives me an application defined or object defined error.
What am I doing wrong?
Thank you for your time.
This will be closer. You will still need to define all Excel constants such as xlInsertDeleteCells though. You can find their values in the VB editor Object Browser (press F2) in Excel. You should also provide the full path to the CSV file.
Function load_csv()
Const xlInsertDeleteCells = 1
Const xlDelimited = 1
Const xlTextQualifierDoubleQuote = 1
Dim objExcel As Object
Dim objWorkbook As Object
Dim baseSheet As Object
Set objExcel = CreateObject("Excel.Application")
Set objWorkbook = objExcel.workbooks.Add()
Set baseSheet = objWorkbook.worksheets(1)
With baseSheet.QueryTables.Add(Connection:="TEXT;FILENAME.csv", _
Destination:=baseSheet.Range("$A$1"))
.Name = "CAPTURE"
.fieldNames = True
.RowNumbers = False
.FillAdjacentFormulas = False
.PreserveFormatting = True
.RefreshOnFileOpen = False
.RefreshStyle = xlInsertDeleteCells
.SavePassword = False
.SaveData = True
.AdjustColumnWidth = True
.RefreshPeriod = 0
.TextFilePromptOnRefresh = False
.TextFilePlatform = 437
.TextFileStartRow = 1
.TextFileParseType = xlDelimited
.TextFileTextQualifier = xlTextQualifierDoubleQuote
.TextFileConsecutiveDelimiter = False
.TextFileTabDelimiter = True
.TextFileSemicolonDelimiter = False
.TextFileCommaDelimiter = True
.TextFileSpaceDelimiter = False
.TextFileColumnDataTypes = Array(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1)
.TextFileTrailingMinusNumbers = True
.Refresh BackgroundQuery:=False
End With
objWorkbook.SaveAs "C:\Temp.xlsx" '<<<< needs a path
objWorkbook.Close False
Set objExcel = Nothing
End Function

Importing Files Into Excel - Skip if not Found

This is my first question here, I have a macro to import .txt files "Semicolon" delimited into Excel. Each file is name specific, and each file is imported in a new sheet. But if one of theses files doesn't exists, the macro Fails. I want to add an "On Erro" to handle these cases, if the file doesn't exists, skip it. Heres the code:
Sub Importar_Dep()
Dim Caminho As String
Caminho = Sheets("DADOS").Cells(5, 8).Value
Sheets("DEP").Select
With ActiveSheet.QueryTables.Add(Connection:= _
"TEXT;" & Caminho, _
Destination:=Range("$A$1"))
.Name = "RECONQUISTA_DEP_0"
.FieldNames = True
.RowNumbers = False
.FillAdjacentFormulas = False
.PreserveFormatting = True
.RefreshOnFileOpen = False
.RefreshStyle = xlInsertDeleteCells
.SavePassword = False
.SaveData = True
.AdjustColumnWidth = True
.RefreshPeriod = 0
.TextFilePromptOnRefresh = False
.TextFilePlatform = 850
.TextFileStartRow = 1
.TextFileParseType = xlDelimited
.TextFileTextQualifier = xlTextQualifierDoubleQuote
.TextFileConsecutiveDelimiter = False
.TextFileTabDelimiter = False
.TextFileSemicolonDelimiter = True
.TextFileCommaDelimiter = False
.TextFileSpaceDelimiter = False
.TextFileColumnDataTypes = Array(1, 1, 1, 1, 1, 1, 1, 1)
.TextFileTrailingMinusNumbers = True
.Refresh BackgroundQuery:=False
End With
End Sub
Here is your code with the check if the file exist:
Sub Importar_Dep()
Dim Caminho As String
Caminho = Sheets("DADOS").Cells(5, 8).Value
Sheets("DEP").Select
'+++++ Added block to check if file exists +++++
Dim FS
Set FS = CreateObject("Scripting.FileSystemObject")
Dim TextFile_FullPath As String
'The textfile_fullPath should be like:
TextFile_FullPath = "C:\Users\Username\Desktop\" & _
RECONQUISTA_DEP_0 & _
".txt"
If FS.FileExists(TextFile_FullPath) Then
'++++++++++++++++++++++++++++++++++++++++++++++++
With ActiveSheet.QueryTables.Add(Connection:= _
"TEXT;" & Caminho, _
Destination:=Range("$A$1"))
.Name = "RECONQUISTA_DEP_0"
.FieldNames = True
.RowNumbers = False
.FillAdjacentFormulas = False
.PreserveFormatting = True
.RefreshOnFileOpen = False
.RefreshStyle = xlInsertDeleteCells
.SavePassword = False
.SaveData = True
.AdjustColumnWidth = True
.RefreshPeriod = 0
.TextFilePromptOnRefresh = False
.TextFilePlatform = 850
.TextFileStartRow = 1
.TextFileParseType = xlDelimited
.TextFileTextQualifier = xlTextQualifierDoubleQuote
.TextFileConsecutiveDelimiter = False
.TextFileTabDelimiter = False
.TextFileSemicolonDelimiter = True
.TextFileCommaDelimiter = False
.TextFileSpaceDelimiter = False
.TextFileColumnDataTypes = Array(1, 1, 1, 1, 1, 1, 1, 1)
.TextFileTrailingMinusNumbers = True
.Refresh BackgroundQuery:=False
End With
End If
End Sub
Like in your comment, if you want to run through all files that have a certain name in common (a filter), you can use this code. The above modifications have then became useless because with this you don't have to check if file exists anymore since it will just go through all existing files. You could have to check if the folder exists though:
Sub RunThroughAllFiles()
Dim Caminho As String
Caminho = Sheets("DADOS").Cells(5, 8).Value
Sheets("DEP").Select
Dim FS
Set FS = CreateObject("Scripting.FileSystemObject")
Dim Filter As String: Filter = "RECONQUISTA_DEP_*.txt"
Dim dirTmp As String
If FS.FolderExists(Caminho) Then
dirTmp = Dir(Caminho & "\" & Filter)
Do While Len(dirTmp) > 0
Call Importar_Dep(Caminho & "\" & dirTmp, _
Left(dirTmp, InStrRev(dirTmp, ".") - 1))
dirTmp = Dir
Loop
Else
MsgBox "Folder """ & Caminho & """ does not exists", vbExclamation
End If
End Sub
Sub Importar_Dep(iFullFilePath As String, iFileNameWithoutExtension)
With ActiveSheet.QueryTables.Add(Connection:= _
"TEXT;" & iFullFilePath, _
Destination:=Range("$A$1"))
.Name = iFileNameWithoutExtension
.FieldNames = True
.RowNumbers = False
.FillAdjacentFormulas = False
.PreserveFormatting = True
.RefreshOnFileOpen = False
.RefreshStyle = xlInsertDeleteCells
.SavePassword = False
.SaveData = True
.AdjustColumnWidth = True
.RefreshPeriod = 0
.TextFilePromptOnRefresh = False
.TextFilePlatform = 850
.TextFileStartRow = 1
.TextFileParseType = xlDelimited
.TextFileTextQualifier = xlTextQualifierDoubleQuote
.TextFileConsecutiveDelimiter = False
.TextFileTabDelimiter = False
.TextFileSemicolonDelimiter = True
.TextFileCommaDelimiter = False
.TextFileSpaceDelimiter = False
.TextFileColumnDataTypes = Array(1, 1, 1, 1, 1, 1, 1, 1)
.TextFileTrailingMinusNumbers = True
.Refresh BackgroundQuery:=False
End With
End Sub
For more information see Dir, FileExists and FolderExists
Here:
Sub Abrir_PORT()
Dim Caminho As String
Caminho = Sheets("DADOS").Cells(5, 5).Value
Sheets("PORT").Select
Dim FS
Set FS = CreateObject("Scripting.FileSystemObject")
Dim Filter As String: Filter = "ATENTO_TLMKT_REC*.txt"
Dim dirTmp As String
If FS.FolderExists(Caminho) Then
dirTmp = Dir(Caminho & "\" & Filter)
Do While Len(dirTmp) > 0
Call Importar_PORT(Caminho & "\" & dirTmp, _
Left(dirTmp, InStrRev(dirTmp, ".") - 1))
dirTmp = Dir
Loop
End If
End Sub
Sub Importar_PORT(iFullFilePath As String, iFileNameWithoutExtension)
With ActiveSheet.QueryTables.Add(Connection:= _
"TEXT;" & iFullFilePath, _
Destination:=Range("$A$1"))
.Name = iFileNameWithoutExtension
.FieldNames = True
.RowNumbers = False
.FillAdjacentFormulas = False
.PreserveFormatting = True
.RefreshOnFileOpen = False
.RefreshStyle = xlInsertDeleteCells
.SavePassword = False
.SaveData = True
.AdjustColumnWidth = True
.RefreshPeriod = 0
.TextFilePromptOnRefresh = False
.TextFilePlatform = 850
.TextFileStartRow = 1
.TextFileParseType = xlDelimited
.TextFileTextQualifier = xlTextQualifierDoubleQuote
.TextFileConsecutiveDelimiter = False
.TextFileTabDelimiter = False
.TextFileSemicolonDelimiter = True
.TextFileCommaDelimiter = False
.TextFileSpaceDelimiter = False
.TextFileColumnDataTypes = Array(1, 1, 1, 1, 1, 1, 1, 1)
.TextFileTrailingMinusNumbers = True
.Refresh BackgroundQuery:=False
iRow = 2
Do While Sheets("PORT").Cells(iRow, 1) <> ""
If Cells(iRow, 2) = IsNumber Then
Else
Rows(iRow).Select
Selection.EntireRow.Delete
iRow = iRow - 1
contagem = contagem + 1
End If
iRow = iRow + 1
Loop
End With
End Sub