VBA to export selected row values of excel to csv - vba

I have a requirement for VBA, wherein, If I select a cell in excel, it will export that entire row values to csv.
I have tried
Sub WriteCSVFile()
Dim My_filenumber As Integer
Dim logSTR As String
My_filenumber = FreeFile
logSTR = logSTR & Cells(1, "A").Value & " , "
logSTR = logSTR & Cells(2, "A").Value & " , "
logSTR = logSTR & Cells(3, "A").Value & " , "
logSTR = logSTR & Cells(4, "A").Value
Open "C:\Users\xxxxx\Desktop\Sample.csv" For Append As #My_filenumber
Print #My_filenumber, logSTR
Close #My_filenumber
End Sub
If the range selection can be made dynamic, it can solve the purpose.

Export Selection Rows to CSV
Sub ExportRowsToCSV()
Const FILE_PATH_RIGHT As String = "\Desktop\Sample.csv"
Const FIRST_CELL_ADDRESS As String = "A2"
Const ColDelimiter As String = "," ' or ";"
Const RowDelimiter As String = vbLf
If ActiveSheet Is Nothing Then Exit Sub ' no visible workbook open
If Not TypeOf ActiveSheet Is Worksheet Then Exit Sub ' not a worksheet
If Not TypeOf Selection Is Range Then Exit Sub ' not a range selected
Dim FilePath As String
FilePath = Environ("USERPROFILE") & FILE_PATH_RIGHT
' or:
'FilePath = Environ("OneDrive") & FILE_PATH_RIGHT
Dim drg As Range: Set drg = Selection
Dim ws As Worksheet: Set ws = drg.Worksheet
Dim srg As Range
With ws.UsedRange
Dim lCell As Range: Set lCell = .Cells(.Rows.Count, .Columns.Count)
Set srg = ws.Range(FIRST_CELL_ADDRESS, lCell)
End With
Dim rg As Range: Set rg = Intersect(srg, drg)
If rg Is Nothing Then Exit Sub
Set rg = Intersect(srg, rg.EntireRow)
If rg Is Nothing Then Exit Sub
Dim dLen As Long: dLen = Len(ColDelimiter)
Dim rString As String
Dim rrg As Range
Dim cell As Range
For Each rrg In rg.Rows
For Each cell In rrg.Cells
rString = rString & CStr(cell.Value) & ColDelimiter
Next cell
rString = Left(rString, Len(rString) - dLen) & RowDelimiter
Next rrg
rString = Left(rString, Len(rString) - Len(RowDelimiter))
Dim TextFile As Long: TextFile = FreeFile
Open FilePath For Append As #TextFile
Print #TextFile, rString
Close #TextFile
MsgBox "Row(s) exported.", vbInformation
End Sub

Here I got the code to copy the "values in the entire row where the cell is active" and paste to csv file.
'''
Sub xlRangeToCSVFile()
Dim myWB As Workbook
Dim rngToSave As Range
Dim fNum As Integer
Dim csvVal As String
Dim i As Integer
Set myWB = ThisWorkbook
csvVal = ""
fNum = FreeFile
Set rngToSave = Range("A" & ActiveCell.Row & ":J" & ActiveCell.Row)
Open "C:\Users\xxxxx\Desktop\Sample.csv" For Output As #fNum
i = 1
For j = 1 To rngToSave.Columns.Count
csvVal = csvVal & Chr(34) & rngToSave(i, j).Value & Chr(34) & ","
Next
Print #fNum, Left(csvVal, Len(csvVal) - 1)
csvVal = ""
Close #fnum
End Sub
'''

Related

VBA code:Save the fillter data to txt file

VBA code: help me with, I want to save the fillter data to txt file.
Sub Intemp()
Dim arr, i As Long
Dim FPath As String
FPath = ThisWorkbook.Path & "\" & "text" & ".txt"
Application.CutCopyMode = False
arr = Sheet5.Range("B1:C" & [B100000].End(xlUp).Row)
Open FPath For Output As #1
For i = 1 To UBound(arr)
Print #1, arr(i, 1) & vbTab & arr(i, 2)
Next i
Close #1
End Sub
If you want to assign your filtered values to an array, an easy way to do that would be to use advanced filtering and filter into another area of the worksheet and assign your values there.
But a simple approach that will get you started is to just loop your rows in your range, if the row is hidden, then move on - otherwise, print the data to your text document.
Dim rng As Range, r As Long
Set rng = Sheet5.Range("B1:C" & [B100000].End(xlUp).Row)
Dim FPath As String
FPath = ThisWorkbook.Path & "\" & "text" & ".txt"
Application.CutCopyMode = False
Open FPath For Output As #1
With Sheet5
For r = rng.Row To rng.Rows.Count + rng.Row - 1
If Not .Rows(r).Hidden Then
Print #1, .Cells(r, 1) & vbTab & .Cells(r, 2)
End If
Next
End With
Close #1

Save copy of workbook as new xlsm, runtime error 1004

I'm trying to save a copy of the workbook as a new .xlsm file via the following code:
SaveAs FileName:=StrPadHoofdDocument & "\Docs\" & "\n\" & ".xlsm", FileFormat:=xlOpenXMLWorkbookMacroEnabled, CreateBackup:=False
I get the following error: "runtime error 1004: method of object SaveAs of object_Workbook failed"
I've read a lot of other topics with the same kind of problem but I just can't quite solve it. Hope you guys can help!
full code:
Sub motivatieFormOpmaken()
Const StBestand = "Stambestand.xlsm"
Const motivatie = "Template motivatieformulier opstapregeling.xlsx"
Dim wbMotivTemp As Workbook
Dim wsMotiv As Worksheet
Dim PathOnly, mot, FileOnly As String
Dim StrPadSourcenaam As String
Set wbMotivTemp = ThisWorkbook
Set wsMotiv = ActiveSheet
StrHoofdDocument = ActiveWorkbook.Name
StrPadHoofdDocument = ActiveWorkbook.Path
StrPadSourcenaam = StrPadHoofdDocument & "\" & c_SourceDump
If Not FileThere(StrPadSourcenaam) Then
MsgBox "Document " & StrPadSourcenaam & " is niet gevonden."
Exit Sub
End If
Application.ScreenUpdating = False
Workbooks.Open FileName:=StrPadSourcenaam
Application.Run "Stambestand.xlsm!unhiderowsandcolumns"
Worksheets("stambestand").Activate
iLaatsteKolom = Worksheets("stambestand").Cells.SpecialCells(xlLastCell).Column
iLaatsteRij = Worksheets("stambestand").Cells.SpecialCells(xlLastCell).row
VulKolomNr
If KolomControle = False Then Exit Sub
Aantalregels = AantalZichtbareRows
Dim rng As Range
Dim row As Range
Dim StrFileName As String
'If Aantalregels > 1 Then
Set rng = Selection.SpecialCells(xlCellTypeVisible)
For Each row In rng.Rows
iRijnummer = row.row
If iRijnummer > 1 Then
'Windows(c_SourceDump).Activate
wsMotiv.Range("motiv_cid") = Cells(iRijnummer, iKolomnrCorpID).Text
wsMotiv.Range("motiv_naam") = Cells(iRijnummer, iKolomnrNaam).Text
wsMotiv.Range("motiv_ldg") = Cells(iRijnummer, iKolomnrHuidigeLeidingGevende).Text
n = naamOpmaken
wbMotivTemp.Activate
ActiveWorkbook.SaveAs FileName:=StrPadHoofdDocument & "\Docs\" & "\n\" & ".xlsm", FileFormat:=xlOpenXMLWorkbookMacroEnabled, CreateBackup:=False
End If
Next row
End Sub
Function naamOpmaken() As String
Dim rng As Range
Dim row As Range
Set rng = Selection.SpecialCells(xlCellTypeVisible)
iRijnummer = rng.row
If iRijnummer > 1 Then
s = Cells(iRijnummer, iKolomnrNaam).Text
Dim Position As Long, Length As Long
Dim n As String
Position = InStrRev(s, " ")
Length = Len(s)
n = Right(s, Length - Position)
End If
naamOpmaken = n
End Function
Change this part:
FileName:=StrPadHoofdDocument & "\Docs\" & "\n\" & ".xlsm",
With this:
FileName:=StrPadHoofdDocument & "\Docs\" & n & ".xlsm",
As you see, the problem is that you are using twice \\. Furthermore, n is a variable and it is passed as string. In future similar cases, print the problematic string and examine it closely, with code like this:
Debug.Print StrPadHoofdDocument & "\Docs\" & "\n\" & ".xlsm"
Debug.Print StrPadHoofdDocument & "\Docs\" & n & ".xlsm"
The errors would be visible then.

How to open all files in the folder (xls and csv format files) - VBA

I have written code for consolidate the data from multiple workbook to one workbook and the code only opening the xls format files but some files have csv format in the folder. how to open csv and xls files in the folder? Any suggestion it would appreciated
Option Explicit
Sub ImportGroups()
Dim fPATH As String, fNAME As String
Dim LR As Long, LastRow As Long
Dim wb2, wb1 As Workbook, ofs As Worksheet
Set ofs = ThisWorkbook.Sheets("Sheet3")
fPATH = "C:\Users\ashokkumar.d\Desktop\MFI\"
fNAME = Dir(fPATH & "*.xls") 'get the first filename in fpath
Do While Len(fNAME) > 0
Set wb1 = Workbooks.Open(fPATH & fNAME) 'open the file
LastRow = ofs.Range("B" & Rows.Count).End(xlUp).Row
ofs.Range("B" & LastRow).Offset(1, -1).Value = fNAME
Sheets("Input").Range("C8:J12").Copy
ofs.Range("B" & LastRow).Offset(1, 0).PasteSpecial xlPasteValues
wb1.Close False 'close data workbook
fNAME = Dir 'get the next filename
Loop
LR = ofs.Range("C" & Rows.Count).End(xlUp).Row
ofs.Range("E2:I" & LR).Select
Selection.NumberFormat = "0.00%"
Application.ScreenUpdating = True
ofs.Range("A1:Z" & LR).Select
With Selection
WrapText = True
End With
End Sub
Just like this:
fNAME = Dir(fPATH & "*") 'get the first filename in fpath
Do While Len(fNAME) > 0
dim ext as string, p as integer
p = inStrRev(fName, ".")
ext = ucase(mid(fName, p+1))
if ext = "CSV" or ext = "XLS" or ext = "XLSX" or ext = "XLST" then
Set wb1 = Workbooks.Open(fPATH & fNAME) 'open the file
...
end if
You can get all Files in the Folder and check then if the file is an CSV or xlsx File. And then Open it like you did.
Option Explicit
Sub ImportGroups()
Dim fPATH As String, fNAME As String
Dim LR As Long, LastRow As Long
Dim wb2, wb1 As Workbook, ofs As Worksheet
Set ofs = ThisWorkbook.Sheets("Sheet3")
fPATH = "C:\Users\ashokkumar.d\Desktop\MFI\"
fNAME = Dir(fPATH & "*.*") 'get the first filename in fpath
Do While Len(fNAME) > 0
If Right(fNAME, 4) = "xlsx" Or Right(fNAME, 4) = ".csv" Then
Set wb1 = Workbooks.Open(fPATH & fNAME) 'open the file
LastRow = ofs.Range("B" & Rows.Count).End(xlUp).Row
ofs.Range("B" & LastRow).Offset(1, -1).Value = fNAME
Sheets("Input").Range("C8:J12").Copy
ofs.Range("B" & LastRow).Offset(1, 0).PasteSpecial xlPasteValues
wb1.Close False 'close data workbook
fNAME = Dir 'get the next filename
end if
Loop
LR = ofs.Range("C" & Rows.Count).End(xlUp).Row
ofs.Range("E2:I" & LR).Select
Selection.NumberFormat = "0.00%"
Application.ScreenUpdating = True
ofs.Range("A1:Z" & LR).Select
With Selection
WrapText = True
End With
End Sub

How can I open and define two Excel files in VBA?

As a part of a bigger macro, and need to open and define two workbooks and sheets (I am aware of that I define my worksheets as Variant, I need this for future operations). I get a mistake when I try to set value to SheetRI. What can it be?
Sub compareQRTsAll()
Dim ActiveWb As Workbook
Dim ActiveSh As Worksheet
Dim SheetFasit As Variant
Dim SheetRI As Variant
Dim FolderFasit As String
Dim FileFasit As String
Dim FolderRI As String
Dim FileRI As String
Dim WbFasit As Workbook
Dim WbRI As Workbook
Dim WbFasitPath As String
Dim strRangeToCheck As String
Dim nShFasit As Integer
Dim nShRI As Integer
Dim iRow As Long
Dim iCol As Long
Dim i As Integer
Dim j As Integer
i = 2
j = 6
Set ActiveWb = ActiveWorkbook
Set ActiveSh = ActiveWb.Worksheets(1)
strRangeToCheck = "A1:AAA1000"
ActiveSh.Range("A2:D10000").Clear
FolderFasit = ActiveSh.Range("J6")
FolderRI = ActiveSh.Range("J7")
Do While ActiveSh.Cells(j, 8) <> ""
FileFasit = Dir(FolderFasit & "\*" & ActiveSh.Cells(j, 8) & "*.xls*")
Set WbFasit = Workbooks.Open(Filename:=FolderFasit & "\" & FileFasit)
SheetFasit = WbFasit.Worksheets(1).Range(strRangeToCheck)
nShFasit = WbFasit.Sheets.Count
FileRI = Dir(FolderRI & "\*" & ActiveSh.Cells(j, 8) & "*.xls*")
Set WbRI = Workbooks.Open(Filename:=FolderRI & "\" & FileRI)
SheetRI = WbRI.Worksheets(1).Range(strRangeToCheck) '<-------------THIS DOESN'T WORK
nShRI = WbRI.Sheets.Count
If nShFasit <> nShRI Then
MsgBox "QRT " & ActiveSh.Cells(j, 8) & " has different number of sheets in fasit and in RI. Further check will not be performed"
ElseIf nShFasit = nShRI And nShFasit = 1 Then
For iRow = LBound(SheetFasit, 1) To UBound(SheetFasit, 1)
For iCol = LBound(SheetFasit, 2) To UBound(SheetFasit, 2)
If SheetFasit(iRow, iCol) = SheetRI(iRow, iCol) Then
' Do nothing.
Else
ActiveSh.Cells(i, 1) = "Check row " & iRow & ", column " & iCol & " in " & ActiveSh.Cells(j, 8)
ActiveSh.Cells(i, 2) = SheetFasit(iRow, iCol)
ActiveSh.Cells(i, 3) = SheetRI(iRow, iCol)
i = i + 1
End If
Next iCol
Next iRow
End If
'close workbooks
Dim wb As Workbook
For Each wb In Workbooks
If Not wb Is ActiveWb Then
wb.Close SaveChanges:=False
End If
Next wb
j = j + 1
Loop
End Sub
The problem was in range strRangeToCheck = "A1:AAA1000". Some of my files are saved as .xls, and there is no AAA column on Excel 2003.
Dim FolderRI As String
Dim FileRI As String
Dim WbFasit As Workbook
Dim WbRI As Workbook
Dim WbFasitPath As String
Dim strRangeToCheck As String
Dim nShFasit As Integer
Dim nShRI As Integer
Dim iRow As Long
Dim iCol As Long
Dim i As Integer
Dim j As Integer
i = 2
j = 6
Set ActiveWb = ActiveWorkbook
Set ActiveSh = ActiveWb.Worksheets(1)
strRangeToCheck = "A1:IV1000"
ActiveSh.Range("A2:D10000").Clear
' If you know the data will only be in a smaller range, reduce the size of the ranges above.
'FolderFasit = InputBox("Enter path to the forder with correct QRTs")
'FolderRI = InputBox("Enter path to the forder with QRTs from RI")
FolderFasit = ActiveSh.Range("J6")
FolderRI = ActiveSh.Range("J7")
Do While ActiveSh.Cells(j, 8) <> ""
FileFasit = Dir(FolderFasit & "\*" & ActiveSh.Cells(j, 8) & "*.xls*")
Set WbFasit = Workbooks.Open(Filename:=FolderFasit & "\" & FileFasit)
SheetFasit = WbFasit.Worksheets(1).Range(strRangeToCheck)
nShFasit = WbFasit.Sheets.Count
FileRI = Dir(FolderRI & "\*" & ActiveSh.Cells(j, 8) & "*.xls*")
Set WbRI = Workbooks.Open(Filename:=FolderRI & "\" & FileRI)
Debug.Print FileRI
SheetRI = WbRI.Worksheets(1).Range(strRangeToCheck)
nShRI = WbRI.Sheets.Count
If nShFasit <> nShRI Then
MsgBox "QRT " & ActiveSh.Cells(j, 8) & " has different number of sheets in fasit and in RI. Further check will not be performed"
ElseIf nShFasit = nShRI And nShFasit = 1 Then
For iRow = LBound(SheetFasit, 1) To UBound(SheetFasit, 1)
For iCol = LBound(SheetFasit, 2) To UBound(SheetFasit, 2)
If SheetFasit(iRow, iCol) = SheetRI(iRow, iCol) Then
' Do nothing.
Else
ActiveSh.Cells(i, 1) = "Check row " & iRow & ", column " & iCol & " in " & ActiveSh.Cells(j, 8)
ActiveSh.Cells(i, 2) = SheetFasit(iRow, iCol)
ActiveSh.Cells(i, 3) = SheetRI(iRow, iCol)
i = i + 1
End If
Next iCol
Next iRow
End If
'close workbooks
Dim wb As Workbook
For Each wb In Workbooks
If Not wb Is ActiveWb Then
wb.Close SaveChanges:=False
End If
Next wb
j = j + 1
Loop
End Sub

Automatically Generate CSVs based on cell data

I have the following code which generates a csv file.
Sub WriteCSVFile()
Dim My_filenumber As Integer
Dim logSTR As String
My_filenumber = FreeFile
logSTR = logSTR & Cells(1, "A").Value & " , "
logSTR = logSTR & Cells(2, "A").Value & " , "
logSTR = logSTR & Cells(3, "A").Value & " , "
logSTR = logSTR & Cells(4, "A").Value
Open "D:\BIG DATA\VBA\Sample.csv" For Append As #My_filenumber
Print #My_filenumber, logSTR
Close #My_filenumber
End Sub
This just pulls the top 4 values from the sheets and puts them in a CSV, I now need to modify it to do 2 things, one generate multiple CSVs one for each unique value in column A and then pull values from column B based on column A.
For example:-
Column A contains set A, set B, set C - Set A has 3 tables in column B and I want this to be copied across to the new CSV but I want this to happen for all the sets automatically.
Any help would be greatly appreciated, even a point to another answer?
I am assuming that you want to Print the contents of each Table to the associated Set.
Sub WriteCSVFile2()
Const RootPath As String = "C:\Data Files\Sample_"
Const KillOldFiles As Boolean = True
Dim My_filenumber As Integer
Dim FileName As String
Dim rw As Range
Dim tbls As Collection
Dim tbl As ListObject
Set tbls = getAllTables
My_filenumber = FreeFile
If KillOldFiles Then
For Each rw In Sheet1.ListObjects("SourceTable").DataBodyRange.Rows
FileName = RootPath & rw.Cells(1, 1) & ".csv"
If Len(Dir(FileName)) Then Kill FileName
Next
End If
For Each rw In Sheet1.ListObjects("SourceTable").DataBodyRange.Rows
FileName = RootPath & rw.Cells(1, 1) & ".csv"
Debug.Print FileName
On Error Resume Next
Set tbl = tbls.Item(rw.Cells(1, 2))
If Not tbl Is Nothing Then
Open FileName For Append As #My_filenumber
Print #My_filenumber, getDataBodyRangeCSV(tbl)
Close #My_filenumber
End If
Set tbl = Nothing
On Error GoTo 0
Next
End Sub
Function getDataBodyRangeCSV(tbl As ListObject) As String
Dim c As Range, rw As Range
Dim tr As String, result As String
For Each rw In tbl.DataBodyRange.Rows
For Each c In rw.Cells
tr = tr & c.value & ","
Next
result = result & Left(tr, Len(tr) - 1) & vbCrLf
tr = ""
Next
getDataBodyRangeCSV = Left(result, Len(result) - 1)
End Function
Function getAllTables() As Collection
Dim lists As Collection
Dim tbl As ListObject
Dim ws As Worksheet
Set lists = New Collection
For Each ws In ThisWorkbook.Worksheets
For Each tbl In ws.ListObjects
On Error Resume Next
lists.Add tbl, tbl.Name
On Error GoTo 0
Next
Next
Set getAllTables = lists
End Function
Update: You don't need the more complex example but I am going to leave it. It may be helpful to future viewers.
Cahnge these variables
SouceWorkSheet: The name of the worksheet that your list is on
KillOldFiles: Do you want to delete the old files
arColumns = Array(1, 2, 9, 10): Add the column numbers that you want to export to this array. You just nned to use WriteCSVFile3.
Sub WriteCSVFile3()
Const SouceWorkSheet As String = "Source"
Const RootPath As String = "C:\Data Files\Sample_"
Const KillOldFiles As Boolean = True
Dim My_filenumber As Integer
Dim FileName As String, tr As String
Dim lastRow As Long, x As Long, y
Dim arColumns As Variant
arColumns = Array(1, 2, 9, 10)
My_filenumber = FreeFile
With Worksheets(SouceWorkSheet)
lastRow = .Range("A" & Rows.Count).End(xlUp).Row
If KillOldFiles Then
For x = 2 To lastRow
FileName = RootPath & .Cells(x, 1) & ".csv"
If Len(Dir(FileName)) Then Kill FileName
Next
End If
For x = 2 To lastRow
FileName = RootPath & .Cells(x, 1) & ".csv"
Open FileName For Append As #My_filenumber
For y = 0 To UBound(arColumns)
tr = tr & .Cells(x, arColumns(y)).value & ","
Next
Print #My_filenumber, Left(tr, Len(tr) - 1)
Close #My_filenumber
tr = ""
Next
End With
End Sub
Can't you use something like this ?
Dim OutputFileNum As Integer
OutputFileNum = FreeFile
Open "file.csv" For Output Lock Write As #OutputFileNum
Print #OutputFileNum, "Field1" & "," & "Field2"
SheetValues = Sheets("Sheet1").Range("A1:H9").Value
Dim LineValues() As Variant
ReDim LineValues(1 To 2)
For RowNum = 1 To 9
For ColNum = 1 To 2
LineValues(ColNum) = SheetValues(RowNum, ColNum)
Next
Line = Join(LineValues, ",")
Print #OutputFileNum, Line
Next
Close OutputFileNum