I'm writing a VBA code which supposed to delete the data on a selected excel sheet, open a dialog box for text file selection, and then import the data from that text file to the same exact sheet I've deleted the data from. So far I can only open the text file into a new workbook but can't open it to the same sheet I've deleted the data from.
Here's what I came with so far, will appreciate your help:
Dim Filt As String
Dim FilterIndex As Integer
Dim Title As String
Dim FileName As Variant
Filt = "Cst Files (*.prn),*.prn"
Title = "Select a cst File to Import"
FileName = Application.GetOpenFilename(FileFilter:=Filt, Title:=Title)
If FileName = False Then
MsgBox "No File Was Selected"
Exit Sub
End If
With Application.ActiveSheet
Cells.Select
Selection.QueryTable.Delete
Selection.ClearContents
End With
Workbooks.Open FileName
There are many ways you can import Text file to the current sheet. Here are three (including the method that you are using above)
Using a QueryTable
Open the text file in memory and then write to the current sheet and finally applying Text To Columns if required.
If you want to use the method that you are currently using then after you open the text file in a new workbook, simply copy it over to the current sheet using Cells.Copy
Using a QueryTable
Here is a simple macro that I recorded. Please amend it to suit your needs.
Sub Sample()
With ActiveSheet.QueryTables.Add(Connection:= _
"TEXT;C:\Sample.txt", Destination:=Range("$A$1") _
)
.Name = "Sample"
.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)
.TextFileTrailingMinusNumbers = True
.Refresh BackgroundQuery:=False
End With
End Sub
Open the text file in memory
Sub Sample()
Dim MyData As String, strData() As String
Open "C:\Sample.txt" For Binary As #1
MyData = Space$(LOF(1))
Get #1, , MyData
Close #1
strData() = Split(MyData, vbCrLf)
End Sub
Once you have the data in the array you can export it to the current sheet.
Using the method that you are already using
Sub Sample()
Dim wbI As Workbook, wbO As Workbook
Dim wsI As Worksheet
Set wbI = ThisWorkbook
Set wsI = wbI.Sheets("Sheet1") '<~~ Sheet where you want to import
Set wbO = Workbooks.Open("C:\Sample.txt")
wbO.Sheets(1).Cells.Copy wsI.Cells
wbO.Close SaveChanges:=False
End Sub
FOLLOWUP
You can use the Application.GetOpenFilename to choose the relevant file. For example...
Sub Sample()
Dim Ret
Ret = Application.GetOpenFilename("Prn Files (*.prn), *.prn")
If Ret <> False Then
With ActiveSheet.QueryTables.Add(Connection:= _
"TEXT;" & Ret, Destination:=Range("$A$1"))
'~~> Rest of the code
End With
End If
End Sub
you can write
.WorkbookConnection.Delete
after
.Refresh BackgroundQuery:=False
this will delete text file external connection.
I think my answer to my own question here is the simplest solution to what you are trying to do:
Select the cell where the first line of text from the file should be.
Use the Data/Get External Data/From File dialog to select the text file to import.
Format the imported text as required.
In the Import Data dialog that opens, click on Properties...
Uncheck the Prompt for file name on refresh box.
Whenever the external file changes, click the Data/Get External Data/Refresh All button.
Note: in your case, you should probably want to skip step #5.
Related
I developed a macro using VBA in excel to split large text files in to smaller ones, but I need those splited files to be splited in to excel type files instead of text files, currently they are being converted back to text files can anyone help on what can I do so those files are directly converted to excel instead of text ?
Appreciate it, Neyrivan Silva.
I'm not sure what your end game is, but this should help you get started.
Private Declare Function SetCurrentDirectoryA Lib _
"kernel32" (ByVal lpPathName As String) As Long
Public Function ChDirNet(szPath As String) As Boolean
'based on Rob Bovey's code
Dim lReturn As Long
lReturn = SetCurrentDirectoryA(szPath)
ChDirNet = CBool(lReturn <> 0)
End Function
Sub Get_TXT_Files()
'For Excel 2000 and higher
Dim Fnum As Long
Dim mysheet As Worksheet
Dim basebook As Workbook
Dim TxtFileNames As Variant
Dim QTable As QueryTable
Dim SaveDriveDir As String
Dim ExistFolder As Boolean
'Save the current dir
SaveDriveDir = CurDir
'You can change the start folder if you want for
'GetOpenFilename,you can use a network or local folder.
'For example ChDirNet("C:\Users\Ron\test")
'It now use Excel's Default File Path
ExistFolder = ChDirNet("C:\your_path_here\")
If ExistFolder = False Then
MsgBox "Error changing folder"
Exit Sub
End If
TxtFileNames = Application.GetOpenFilename _
(filefilter:="TXT Files (*.txt), *.txt", MultiSelect:=True)
If IsArray(TxtFileNames) Then
On Error GoTo CleanUp
With Application
.ScreenUpdating = False
.EnableEvents = False
End With
'Add workbook with one sheet
Set basebook = Workbooks.Add(xlWBATWorksheet)
'Loop through the array with txt files
For Fnum = LBound(TxtFileNames) To UBound(TxtFileNames)
'Add a new worksheet for the name of the txt file
Set mysheet = Worksheets.Add(After:=basebook. _
Sheets(basebook.Sheets.Count))
On Error Resume Next
mysheet.Name = Right(TxtFileNames(Fnum), Len(TxtFileNames(Fnum)) - _
InStrRev(TxtFileNames(Fnum), "\", , 1))
On Error GoTo 0
With ActiveSheet.QueryTables.Add(Connection:= _
"TEXT;" & TxtFileNames(Fnum), Destination:=Range("A1"))
.TextFilePlatform = xlWindows
.TextFileStartRow = 1
'This example use xlDelimited
'See a example for xlFixedWidth below the macro
.TextFileParseType = xlDelimited
'Set your Delimiter to true
.TextFileTabDelimiter = True
.TextFileSemicolonDelimiter = False
.TextFileCommaDelimiter = False
.TextFileSpaceDelimiter = False
'Set the format for each column if you want (Default = General)
'For example Array(1, 9, 1) to skip the second column
.TextFileColumnDataTypes = Array(1, 9, 1)
'xlGeneralFormat General 1
'xlTextFormat Text 2
'xlMDYFormat Month-Day-Year 3
'xlDMYFormat Day-Month-Year 4
'xlYMDFormat Year-Month-Day 5
'xlMYDFormat Month-Year-Day 6
'xlDYMFormat Day-Year-Month 7
'xlYDMFormat Year-Day-Month 8
'xlSkipColumn Skip 9
' Get the data from the txt file
.Refresh BackgroundQuery:=False
End With
ActiveSheet.QueryTables(1).Delete
Next Fnum
'Delete the first sheet of basebook
On Error Resume Next
Application.DisplayAlerts = False
basebook.Worksheets(1).Delete
Application.DisplayAlerts = True
On Error GoTo 0
CleanUp:
ChDirNet SaveDriveDir
With Application
.ScreenUpdating = True
.EnableEvents = True
End With
End If
End Sub
I currently have this code for importing multiple .csv files, where if the file name matches an existing sheet in my excel file, then the content will be automatically pasted into it. And if not in creates a tab with the exact same name.
I was wondering if by any chance could I replace the QueryTables command used to import the data from a .csv file and use something similar for .xlsx files.
Thank you
PS: it would be to modify mainly te importCSV part. For now I won’t be needing anymore csv formats.
It was just to explain the logic of the importing method. I need something to allow me to import data coming from multiple xlsx into the corresponding Tab in my master excel. Thankss!
Sub CopyCSVfiles()
Dim naming As Object
Dim xlsheet As Worksheet
Dim qt As QueryTable
Dim txtfilesToOpen As Variant, txtfile As Variant
Application.ScreenUpdating = False
Set Name = CreateObject("Scripting.FileSystemObject")
txtfilesToOpen = Application.GetOpenFilename _
(FileFilter:="Text Files (*.csv), *.csv", _
MultiSelect:=True, Title:="Text Files to Open")
For Each txtfile In txtfilesToOpen
' Here we find if there is an already existing worksheet
For Each xlsheet In ThisWorkbook.Worksheets
If xlsheet.Name = Replace(naming.GetFileName(txtfile), ".csv", "") Then
xlsheet.Activate
GoTo ImportCSV
End If
Next xlsheet
' CREATES A NEW WORKSHEET IF NOT FOUND
Set xlsheet = ThisWorkbook.Worksheets.Add( _
After:=ThisWorkbook.Sheets(ThisWorkbook.Sheets.Count))
xlsheet.Name = Replace(naming.GetFileName(txtfile), ".csv", "")
xlsheet.Activate
GoTo ImportCSV
ImportCSV:
' DELETE EXISTING DATA
ActiveSheet.Range("A:Z").EntireColumn.Delete xlShiftToLeft
' IMPORT DATA FROM TEXT FILE
With ActiveSheet.QueryTables.Add(Connection:="TEXT;" & txtfile, _
Destination:=ActiveSheet.Cells(1, 1))
.TextFileParseType = xlDelimited
.TextFileConsecutiveDelimiter = False
.TextFileTabDelimiter = False
.TextFileSemicolonDelimiter = False
.TextFileCommaDelimiter = False
.TextFileSpaceDelimiter = False
.TextFileOtherDelimiter = "|"
.Refresh BackgroundQuery:=False
End With
For Each qt In ActiveSheet.QueryTables
qt.Delete
Next qt
Next txtfile
Application.ScreenUpdating = True
MsgBox "Successfully imported text files!", vbInformation, "SUCCESSFUL IMPORT"
Set naming = Nothing
End Sub
For copy the information from a CSV file and put it in an Excel Worksheet, directly from VBA, you can take advantage of this project. If you don't know how to start with the utility, read the installation instructions.
Replace the following code:
With ActiveSheet.QueryTables.Add(Connection:="TEXT;" & txtfile, _
Destination:=ActiveSheet.Cells(1, 1))
.TextFileParseType = xlDelimited
.TextFileConsecutiveDelimiter = False
.TextFileTabDelimiter = False
.TextFileSemicolonDelimiter = False
.TextFileCommaDelimiter = False
.TextFileSpaceDelimiter = False
.TextFileOtherDelimiter = "|"
.Refresh BackgroundQuery:=False
End With
For Each qt In ActiveSheet.QueryTables
qt.Delete
Next qt
with a call to this procedure:
Sub ImportCSVRecords(filePathAndName As String, OutputSheet As String, OutputRange As String)
Dim CSVix As CSVinterface
Set CSVix = New CSVinterface 'Create new instance
Call CSVix.OpenConnection(filePathAndName) 'Open a physical connection to the CSV file
Call CSVix.ImportFromCSV 'Import data
Call CSVix.DumpToSheet(WBookName:=ThisWorkbook.Name, SheetName:=OutputSheet, rngName:=OutputRange) 'Dumps the data to the current Workbook's OutputSheet starting at named OutputRange.
Set CSVix = Nothing 'Terminate the current instance
End Sub
I create a CSV BOM exported from CREO. I have a command button on my master worksheet, which will import the CSV to a new worksheet and name the worksheet with the CSV file name.
The issue is the import won't add the date to a new worksheet, instead it will open a new workbook.
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
Dim ws As Worksheet 'variable that will contain the new sheet
Dim help_name() As String 'helper string array that will contain the full path of your file
help_name = Split(fStr, "\") 'populating the variable with the full path, each '\' creates a new item
Set ws = ThisWorkbook.Sheets.Add 'adding a new sheet to your workbook
ws.Name = Replace(help_name(UBound(help_name)), ".bom", "", , , vbTextCompare) 'naming the new sheet with the name of the file and removing the '.bom'
'ubound returns the highest position of the array, which is always name of the file
With ThisWorkbook.Sheets("Sheet2").QueryTables.Add(Connection:= _
"TEXT;" & fStr, Destination:=ThisWorkbook.Sheets("Sheet2").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
'ActiveWorkbook.Save
End With
End Sub
I created code to import the CSV to 'Sheet2' however I would like this added as a new worksheet and then that worksheet renamed to the file name without .BOM at the end.
I hope this helps :-)
if you paste it before the with statement and then replace the 'ThisWorkbook.Sheets("Sheet2")' with 'ws' in the with statement, I believe it should do what you need.
Dim ws As Worksheet 'variable that will contain the new sheet
Dim help_name() As String 'helper string array that will contain the full path of your file
help_name = Split(fstr, "\") 'populating the variable with the full path, each '\' creates a new item
Set ws = ThisWorkbook.Sheets.Add 'adding a new sheet to your workbook
'Original not reliable option 'ws.Name = Replace(help_name(UBound(help_name)), ".bom", "", , , vbTextCompare) 'naming the new sheet with the name of the file and removing the '.bom'
'ubound returns the highest position of the array, which is always name of the file
ws.Name = Left(help_name(UBound(help_name)), InStr(1, help_name(UBound(help_name)), ".bom", vbTextCompare) - 1) 'updated hopefully more reliable option of naming the sheet
wondering if you can help out with a VBA issue. I pieced together the following without really knowing what I was doing:
Sub Import_Raw_Stripe_data()
Dim fileDialog As fileDialog
Dim strPathFile As String
Dim strFileName As String
Dim strPath As String
Dim dialogTitle As String
Dim Tworkbook As Workbook
Dim Sworkbook As Workbook
dialogueTitle = "Select File to Import"
Set fileDialogue = Application.fileDialog(msoFileDialogFilePicker)
With fileDialogue
.InitialFileName = "L:\Downloads"
.AllowMultiSelect = False
.Filters.Clear
.Title = dialogueTitle
If .Show = False Then
MsgBox "No file selected."
Exit Sub
End If
strPathFile = .SelectedItems(1)
End With
Set Sworkbook = Workbooks.Open(fileName:=strPathFile)
Set Tworkbook = ThisWorkbook
End Sub
Which, as far as I can tell opens a file dialog in excel, allows a user to choose a document and then opens it.
What I would like to do is the following:
1) Open a file dialogue and select a .csv file to import data from (complete?) into a .xlsm master file (with multiple sheets).
2) Select certain columns from the .csv (column A, Q, R and S in this case), copy them and import them into the second sheet of the master excel file entitled "Raw Stripe Data".
Any help in the matter would be greatly appreciated.
Update: I managed to find the following code:
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("Stripe Raw Data").QueryTables.Add(Connection:= _
"TEXT;" & fStr, Destination:=ThisWorkbook.Sheets("Stripe Raw 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
ActiveWorkbook.Save
End With
End Sub
This works great - but is there anyway to have it not override the data already imported? (for example, if i use it twice, the second import overrides the first).
ThisWorkbook.Sheets("Stripe Raw Data").Range("$A$1") specifies where the imported data is written to, that is the first cell of the sheet Stripe Raw Data.
Adapt this to your liking if you want the next import at another location.
As mentioned in the comments, you could change load_csv() to take the output destination as a parameter. If you also change it from Sub to Function, you can return the number of rows imported:
Function load_csv(rngDestination As Range) As Long
'...
With ThisWorkbook.Sheets("Stripe Raw Data").QueryTables.Add(Connection:= _
"TEXT;" & fStr, Destination:=rng)
'...
.Refresh BackgroundQuery:=False
load_csv = .ResultRange.Rows.Count
'...
End Function
Now you can repeatedly call load_csv and provide it with the range where the output should begin for example:
Dim rngOutput As Range
Dim lngRows As Long
Set rngOutput = ThisWorkbook.Sheets("Stripe Raw Data").Range("$A$1")
lngRows = load_csv(rngOutput) ' load first file
lngRows = lngRows + load_csv(rngOutput.Offset(lngRows)) ' load second file
lngRows = lngRows + load_csv(rngOutput.Offset(lngRows)) ' load third file
lngRows = lngRows + load_csv(rngOutput.Offset(lngRows)) ' load fourth file
There is still much room for improvement:
Removing duplicate headers
Creating a loop instead of explicitly calling load_csv four times
Better control for the user to select files (multiselect)
Disconnecting the imported data from the QueryTable to reduce dependencies even after the import
Not importing in ThisWorkbook but afterwards saving ActiveWorkbook - they may not always be the same
...
But that's not part of this question. After all, all you wanted to know was:
is there anyway to have it not override the data already imported?
I hope I could sufficiently answer this with the above.
Text file looks like below
a, John, "2014-2", ...
d, Will, "2016-7" , ...
I want to put element a in row 1, col 1, John in row 1 col 2, d in cell row 2, col 1, etc. Please help. Thanks. below are the code I have
Sub Importdata()
Open "C:\Users\apple\desktop\12345.txt" For Input As #1
r = 0
Do Until EOF(1)
Line Input #1, Data
ActiveCell.Offset(r, 0) = Data
r = r + 1
Loop
Close #1
End Sub
You can split each line using Split and , as delimiter
Try this it works fine:
Option Explicit
Sub Importdata()
Dim cet
Dim r As Long
Dim Data
Dim wk AS worksheet
Set wk = sheet1
Open "C:\Users\apple\desktop\12345.txt" For Input As #1
r = 1
Do Until EOF(1)
Line Input #1, Data
cet = Split(Data, ",")
if len(join(cet)) > 0 then
wk.Cells(r, 1) = cet(0)
wk.Cells(r, 2) = cet(1)
ENd if
r = r + 1
Loop
Close #1
End Sub
You could use the QueryTables property, importing and parsing the lines in one step. Easiest method is to do this using the Macro Recorder (Using the Data ► Get External Data ► From Text option from the Excel menu), then tweak to suit. In Excel, that would bring up the Text Import wizard, but you can also do it in VBA. Below is an example where I browse for the file, but you can easily hard-code it as you have in your original macro. Also note that I have explicitly declared the workbook and worksheets; you can easily change this if you wish.
EDIT Minor tweaks added for clarification
Option Explicit
Sub ImportData()
Dim sMyFile As Variant
Dim WS As Worksheet, WB As Workbook
Set WB = ThisWorkbook
Set WS = WB.Worksheets("sheet1")
sMyFile = Application.GetOpenFilename("Text Files(*.txt), *.txt")
If sMyFile <> False Then
With WS.QueryTables.Add(Connection:= _
"TEXT;" & sMyFile, _
Destination:=WS.Range("$A$1"))
.Name = "TestText"
.FieldNames = True
.RowNumbers = False
.FillAdjacentFormulas = False
.PreserveFormatting = True
.RefreshOnFileOpen = False
.RefreshStyle = xlInsertDeleteCells
.SavePassword = False
.SaveData = True
.AdjustColumnWidth = True
.RefreshPeriod = 0
.TextFilePromptOnRefresh = False
.TextFilePlatform = xlWindows
.TextFileStartRow = 1
.TextFileParseType = xlDelimited
.TextFileTextQualifier = xlTextQualifierDoubleQuote
.TextFileConsecutiveDelimiter = False
.TextFileTabDelimiter = True
.TextFileSemicolonDelimiter = False
.TextFileCommaDelimiter = True
.TextFileSpaceDelimiter = False
.TextFileColumnDataTypes = Array(1, 1, 1, 1)
.TextFileTrailingMinusNumbers = True
.Refresh BackgroundQuery:=False
End With
End If
End Sub