I want to output the Japanese written on the sheet as a UTF-8 text file. The current code also works, but this code export SJIS file.
Is the problem that I am getting it in range and outputting it?
Or is there something wrong with the SaveAs Filename code?
Set rng = Range("A1").CurrentRegion
Workbooks.Add
ActiveSheet.Cells.Select
Selection.NumberFormatLocal = "#"
rng.Copy ActiveSheet.Range("A1")
Rows(1).Delete
ActiveWorkbook.SaveAs Filename:=fPath & fName, FileFormat:=xlText, Local:=True
ActiveWindow.Close
Worksheets("sheetname").Select
Application.DisplayAlerts = True
Please, try the next code. It will not use Excel `SaveAs. It will build a string from the existing cells and save it in a different way:
Sub testExportUth8_NoBOM()
Dim sh As Worksheet, strTxt As String, strLine As String
Dim strName As String, arr, i As Long, j As Long, sep As String
Set sh = ActiveSheet
arr = sh.UsedRange.Value
sep = "," 'you can use here any needed separator
For i = 1 To UBound(arr)
For j = 1 To UBound(arr, 2)
strLine = strLine & arr(i, j) & sep
Next j
strLine = left(strLine, Len(strLine) - 1)
strTxt = strTxt & strLine & vbCrLf
strLine = ""
Next i
strName = ThisWorkbook.path & "\testUTF8_No_BOOM.txt" 'use here the name you want
WriteUTF8WithoutBOM strTxt, strName
End Sub
Private Function WriteUTF8WithoutBOM(strText As String, fileName As String)
Dim UTFStream As Object, BinaryStream As Object
With CreateObject("adodb.stream")
.Type = 2: .Mode = 3: .Charset = "UTF-8"
.LineSeparator = -1
.Open: .WriteText strText, 1
.Position = 3 'skip BOM' !!!
Set BinaryStream = CreateObject("adodb.stream")
BinaryStream.Type = 1
BinaryStream.Mode = 3
BinaryStream.Open
.CopyTo BinaryStream
.Flush
.Close
End With
BinaryStream.SaveToFile fileName, 2
BinaryStream.Flush
BinaryStream.Close
End Function
Please run it and send some feedback.
Related
I found a resource to find specific strings at the following link: https://www.excel-easy.com/vba/examples/read-data-from-text-file.html
How could I apply this to all the .txt files in a folder?
Sub READLINES()
Dim myFile As String, text As String, textline As String, posFood As Integer
'myFile = "C\FOLDER\TEST.txt"
myFile = Application.GetOpenFilename()
Open myFile For Input As #1
Do Until EOF(1)
Line Input #1, textline
text = text & textline
Loop
Close #1
posFood = InStr(text, "BACON")
Range("A1").Value = Mid(text, posFood + 7, 3) 'should return YUM
End Sub
I think your best bet is to import all data from all text files, into one single sheet, and then filter for the strings you want to find, and copy/paste those to another sheet.
Try the script below to import all data from all files.
Sub ImportCSVsWithReference()
'UpdatebyKutoolsforExcel20151214
Dim xSht As Worksheet
Dim xWb As Workbook
Dim xStrPath As String
Dim xFileDialog As FileDialog
Dim xFile As String
On Error GoTo ErrHandler
Set xFileDialog = Application.FileDialog(msoFileDialogFolderPicker)
xFileDialog.AllowMultiSelect = False
xFileDialog.Title = "Select a folder [Kutools for Excel]"
If xFileDialog.Show = -1 Then
xStrPath = xFileDialog.SelectedItems(1)
End If
If xStrPath = "" Then Exit Sub
Set xSht = ThisWorkbook.ActiveSheet
If MsgBox("Clear the existing sheet before importing?", vbYesNo, "Kutools for Excel") = vbYes Then xSht.UsedRange.Clear
Application.ScreenUpdating = False
xFile = Dir(xStrPath & "\" & "*.txt")
Do While xFile <> ""
Set xWb = Workbooks.Open(xStrPath & "\" & xFile)
Columns(1).Insert xlShiftToRight
Columns(1).SpecialCells(xlBlanks).Value = ActiveSheet.Name
ActiveSheet.UsedRange.Copy xSht.Range("A" & Rows.Count).End(xlUp).Offset(1)
xWb.Close False
xFile = Dir
Loop
Application.ScreenUpdating = True
Exit Sub
ErrHandler:
MsgBox "no files csv", , "Kutools for Excel"
End Sub
Then, run this.
Sub MoveData()
With Application
.ScreenUpdating = False
.EnableEvents = False
End With
Dim Rng As Range
Set Rng = Range([A1], Range("A" & Rows.Count).End(xlUp))
On Error Resume Next
With Rng
.AutoFilter , field:=1, Criteria1:="Book1"
.SpecialCells(xlCellTypeVisible).EntireRow.Copy Sheets("Sheet2").Range("A1")
.AutoFilter
End With
Application.EnableEvents = True
End Sub
I have below code which prints text from a column but open a text file many times instead of once. Please let me know what is the wrong.
When I run sub in Visual Basic debug mode, it open text file only once. But I am calling this macro after another macro and that time it is opening (same) text file many times.
Sub createdevtest()
Dim filename As String, lineText As String
Dim data As Range
Dim myrng As Range, i, j
' filename = ThisWorkbook.Path & "\textfile-" & Format(Now, "ddmmyy-hhmmss") & ".txt"
filename = ThisWorkbook.Path & "\devtest" & ".txt"
Open filename For Output As #1
Dim LastRow As Long
'Find the last non-blank cell in column A(1)
LastRow = Cells(Rows.count, 1).End(xlUp).Row
Range("B4:B" & LastRow).Select
Set myrng = Selection
For i = 1 To myrng.Rows.count
For j = 1 To myrng.Columns.count
lineText = IIf(j = 1, "", lineText & ",") & myrng.Cells(i, j)
Next j
Print #1, lineText
Next i
Close #1
Range("B4").Select
' open devtest
'Shell "explorer.exe" & " " & ThisWorkbook.Path, vbNormalFocus
filename = Shell("Notepad.exe " & filename, vbNormalFocus)
End Sub
Thanks #Luuklag. I had tried to figure out on my own but no success. After your comment, just went thru code again and got clue.
Below is the correct code where I have called one of the macro (devtest1) which contains above text file creation macro (createdevtest). Before correction I was calling macro in function instead of Sub, so it was looping again and opening txt file many times.
' macro to select folder and list files
Sub GetFileNames_devtest()
Set Folder = Application.FileDialog(msoFileDialogFolderPicker)
If Folder.Show <> -1 Then Exit Sub
xDir = Folder.SelectedItems(1)
Call ListFilesInFolder(xDir, True)
' call devtest: corrected to call macro at right place
devtest1
End Sub
Sub ListFilesInFolder(ByVal xFolderName As String, ByVal xIsSubfolders As Boolean)
Dim xFileSystemObject As Object
Dim xFolder As Object
Dim xSubFolder As Object
Dim xFile As Object
Dim rowIndex As Long
Set xFileSystemObject = CreateObject("Scripting.FileSystemObject")
Set xFolder = xFileSystemObject.GetFolder(xFolderName)
rowIndex = Application.ActiveSheet.Range("A65536").End(xlUp).Row + 1
For Each xFile In xFolder.Files
Application.ActiveSheet.Cells(rowIndex, 1).Formula = xFile.Name
rowIndex = rowIndex + 1
Next xFile
If xIsSubfolders Then
For Each xSubFolder In xFolder.SubFolders
ListFilesInFolder xSubFolder.Path, True
Next xSubFolder
End If
Set xFile = Nothing
Set xFolder = Nothing
Set xFileSystemObject = Nothing
'' Was calling wrongly macro here
End Sub
Function GetFileOwner(ByVal xPath As String, ByVal xName As String)
Dim xFolder As Object
Dim xFolderItem As Object
Dim xShell As Object
xName = StrConv(xName, vbUnicode)
xPath = StrConv(xPath, vbUnicode)
Set xShell = CreateObject("Shell.Application")
Set xFolder = xShell.Namespace(StrConv(xPath, vbFromUnicode))
If Not xFolder Is Nothing Then
Set xFolderItem = xFolder.ParseName(StrConv(xName, vbFromUnicode))
End If
If Not xFolderItem Is Nothing Then
GetFileOwner = xFolder.GetDetailsOf(xFolderItem, 8)
Else
GetFileOwner = ""
End If
Set xShell = Nothing
Set xFolder = Nothing
Set xFolderItem = Nothing
End Function
End Function
I wanted to know is there any way to work around this code so that I can import and export named ranges and their values from a workbook to and via .csv file format.
I can successfully import or export the named ranges of single cell. But I get error while exporting the multicell named ranges as they are arrays.
Code for exporting the named ranges to csv is this
Option Explicit
Sub ExportCSV()
Dim ws As Worksheet
Dim str1 As String
Dim i As Long
Dim FinalRow As Long
Set ws = Sheets("Export")
With ws
Application.ScreenUpdating = False
ws.Activate
ws.Range("A1").Select
Selection.ListNames
FinalRow = ws.Range("B9000").End(xlUp).Row
For i = 1 To FinalRow
Cells(i, "B") = Replace(Cells(i, "B"), "$", "")
Next i
Dim fileSaveName As Variant
fileSaveName = Application.GetSaveAsFilename( _
fileFilter:="Excel Files (*.csv), *.csv")
If fileSaveName <> False Then
'Code to save the file
ws.Copy
With ActiveWorkbook
.SaveAs Filename:=fileSaveName, FileFormat:=xlCSV, CreateBackup:=False
.Close False
End With
End If
ws.Cells.Clear
End With
Worksheets("Preferences").Activate
Range("A1").Select
Application.ScreenUpdating = True
MsgBox "Data Exported Successfully at " & vbNewLine & fileSaveName, vbInformation
End Sub
Code for importing named ranges and their values is this
Option Explicit
Sub impdata()
Dim MyCSV As Workbook
Dim MyCSVPath As String
Dim MyRange As Range
Dim MyCell As Range
Dim MyNextCell As Range
Dim MyNamedRange As Range
Dim ws As Worksheet
Dim FinalRow As Long
MyCSVPath = GetFile
If MyCSVPath <> "" Then
Set MyCSV = Workbooks.Open(MyCSVPath)
Application.ScreenUpdating = False
Set ws = Sheets(1)
FinalRow = ws.Range("B90000").End(xlUp).Row
Set MyRange = MyCSV.Worksheets(1).Range("B1" & ":B" & FinalRow)
ThisWorkbook.Activate
For Each MyCell In MyRange.Cells
'Get a reference to the named range.
Set MyNamedRange = Range(ThisWorkbook.Names(MyCell.Offset(, -1).Value))
'Find the next empty cell in the named range.
Set MyNextCell = MyNamedRange.Cells(MyNamedRange.Cells.Count).End(xlUp).Offset(1)
'If the next empty cell is above the named range, then set
'it to the first cell in the range.
If MyNextCell.Row < MyNamedRange.Cells(1).Row Then
Set MyNextCell = MyNamedRange.Cells(1)
End If
'Place the value in the range.
MyNextCell = MyCell.Value
Next MyCell
End If
MyCSV.Close False
Application.ScreenUpdating = True
End Sub
'---------------------------------------------------------------------------------------
' Procedure : GetFile
' Date : 23/10/2015
' Purpose : Returns the full file path of the selected file
' To Use : vFile = GetFile()
'---------------------------------------------------------------------------------------
Function GetFile(Optional startFolder As Variant = -1) As Variant
Dim fle As FileDialog
Dim vItem As Variant
Set fle = Application.FileDialog(msoFileDialogFilePicker)
With fle
.Title = "Select a File"
.AllowMultiSelect = False
.Filters.Add "Comma Separate Values", "*.CSV", 1
If startFolder = -1 Then
.InitialFileName = Application.DefaultFilePath
Else
If Right(startFolder, 1) <> "\" Then
.InitialFileName = startFolder & "\"
Else
.InitialFileName = startFolder
End If
End If
If .Show <> -1 Then GoTo NextCode
vItem = .SelectedItems(1)
End With
NextCode:
GetFile = vItem
Set fle = Nothing
End Function
Export Code
You've put With ws and didn't really use it your code, it'd be safer and also much more practical to do so! ;)
Here is the new export code, it will keep a master file listing your Named Ranges with the value if there is only one cell or the file name (placed in the folder "Save_as_CSV", so that you can find it to re-import it) if there is multiple cells :
Option Explicit
Sub ExportCSV()
Dim Ws As Worksheet, _
WsO As Worksheet, _
Str1 As String, _
i As Long, _
ShName As String, _
RgName As String, _
FileName As String, _
FileFullName As String, _
RgO As Range, _
FinalRow As Long, _
FileSaveName As Variant
Application.ScreenUpdating = False
Set Ws = Sheets("Export")
Set WsO = Sheets("OutPut")
With Ws
.Range("A1").ListNames
FinalRow = .Range("B" & .Rows.Count).End(xlUp).Row
For i = 1 To FinalRow
If InStr(1, .Cells(i, "B"), ":") Then
'NamedRange with Multiple cellS
ShName = Replace(Replace(Split(.Cells(i, "B"), "!")(0), "=", ""), "'", "")
RgName = Replace(Split(.Cells(i, "B"), "!")(1), "$", "")
Set RgO = ThisWorkbook.Sheets(ShName).Range(RgName)
WsO.Cells.Clear
WsO.Range("A1").Resize(RgO.Rows.Count, RgO.Columns.Count).Value = RgO.Value
FileName = .Cells(i, "A") & ".csv"
FileFullName = ThisWorkbook.Path & "\Save_as_CSV\" & FileName
'Code to save the file
WsO.Copy
With ActiveWorkbook
.SaveAs FileName:=FileFullName, FileFormat:=xlCSV, CreateBackup:=False
.Close False
End With
.Cells(i, "B") = FileName
Else
'NamedRange with only one cell
.Cells(i, "B") = Replace(.Cells(i, "B"), "$", "")
End If
Next i
FileSaveName = Application.GetSaveAsFilename(fileFilter:="Excel Files (*.csv), *.csv")
If FileSaveName <> False Then
'Code to save the file
.Copy
With ActiveWorkbook
.SaveAs FileName:=FileSaveName, FileFormat:=xlCSV, CreateBackup:=False
.Close False
End With
End If
.Cells.Clear
End With
Worksheets("Preferences").Range("A1").Select
Application.ScreenUpdating = True
MsgBox "Data Exported Successfully at " & vbNewLine & FileSaveName, vbInformation
End Sub
Import Code
MyNextCell = MyCell.Value (I think MyCell.Value is the address of the named range) should be :
MyNextCell.Resize(Range(MyCell.Value).Rows.Count, _
Range(MyCell.Value).Columns.Count).Value = _
Sheets(Names(MyCell.Value).RefersToRange.Parent.Name).Range(MyCell.Value).Value
If you work with CSV, this might be better Set MyCSV = Workbooks.Open(MyCSVPath, Local:=True) than Set MyCSV = Workbooks.Open(MyCSVPath)
If you want to add the data to what you already have (I tilted after that you must be trying only to update it), Set MyNextCell = MyNamedRange.Cells(MyNamedRange.Cells.Count).End(xlUp).Offset(1)
(will start at the end of the named range and go up, then Offset, so it'll give you the second line of the named range)
should be :
Set MyNextCell = MyNamedRange.Cells(MyNamedRange.Cells.Count).Offset(1)
I wanted to write a code for macro, that will load files from my local directory into excel sheet of Column say ("C"), the names on files should match names on Column ("B"). If any of the files doesn't find for the names given in column B it should skip that row of loading files and continues to next column. I'am difficulty in writing as I am new to VB. I tried somehow but, my script working to load files from directory and loading names. Please help!! thank you all,
Code:
Sub Insert_OLE_Object()
Dim mainWorkBook As Workbook
Set mainWorkBook = ActiveWorkbook
Set ActiveSheet = example1
Folderpath = "C:\Documents and Settings\my\Desktop\folder1"
Set fso = CreateObject("Scripting.FileSystemObject")
NoOfFiles = fso.GetFolder(Folderpath).Files.Count
Set listfiles = fso.GetFolder(Folderpath).Files
For Each fls In listfiles
Counter = Counter + 1
Range("B" & Counter).Value = fls.Name
strCompFilePath = Folderpath & "\" & Trim(fls.Name)
If strCompFilePath <> "" Then
Worksheets("Example1").OLEObjects.Add(Filename:=strCompFilePath, Link:=False, DisplayAsIcon:=True, IconIndex:=1, IconLabel:=strCompFilePath, Left:=20, Top:=40, Width:=150, Height:=10).Select
Sheets("example1").Activate
Sheets("example1").Range("C" & ((Counter - 1) * 3) + 1).Select
End If
Next
End Sub
Try this code:
Sub Insert_OLE_Object()
Dim ws As Worksheet
Dim rng As Range, c As Range
Dim strCompFilePath As String, Folderpath As String, fullpath As String
Dim obj As Object
Application.ScreenUpdating = False
'change to suit
Set ws = ThisWorkbook.Worksheets("Example1")
'change B1:B5 to suit
Set rng = ws.Range("B1:B5")
Folderpath = "C:\Documents and Settings\my\Desktop\folder1"
For Each c In rng
strCompFilePath = Dir(Folderpath & "\" & Trim(c.Value) & ".*")
'if file with this name found, embed it
If strCompFilePath <> "" Then
fullpath = Folderpath & "\" & strCompFilePath
Set obj = ws.OLEObjects.Add(Filename:=fullpath, Link:=False, _
DisplayAsIcon:=True, IconIndex:=1, _
IconLabel:=fullpath)
With obj
.Left = c.Offset(, 1).Left
.Top = c.Offset(, 1).Top
.Width = c.Offset(, 1).ColumnWidth
.Height = c.Offset(, 1).RowHeight
End With
End If
Next
Application.ScreenUpdating = True
End Sub
I have a macro 'macro1' that convert all *.xls files within a folder to *.csv. After converting them, I merge rows using the command prompt. The I convert the merged file into an xls using macro2. Everything is working fine but when a value is something like 123456789123456 the resulting csv value is something like 1234E+11. How to keep the number format between converted files?
here are my macros
macro1
Option Explicit
Sub ConvertToCSV()
Dim i As Long
Dim NumFiles As Long
Dim FileName As String
Dim FileNames() As String
FileName = Dir(ThisWorkbook.Path & "/*.xls")
NumFiles = 1
ReDim Preserve FileNames(1 To NumFiles)
FileNames(NumFiles) = FileName
Do While FileName <> ""
FileName = Dir()
If FileName <> "" Then
NumFiles = NumFiles + 1
ReDim Preserve FileNames(1 To NumFiles)
FileNames(NumFiles) = FileName
End If
Loop
Application.DisplayAlerts = False
For i = 1 To UBound(FileNames)
If FileNames(i) <> ThisWorkbook.Name Then
Workbooks.Open FileName:=ThisWorkbook.Path & "\" & FileNames(i)
ActiveWorkbook.SaveAs _
FileName:=Left(FileNames(i), Len(FileNames(i)) - 4) & ".csv", _
FileFormat:=xlCSV
ActiveWorkbook.Close
End If
Next i
Application.DisplayAlerts = True
End Sub
and the macro2
Sub FromCSVToXLS()
Dim myWB As Workbook, WB As Workbook
Dim L As Long, x As Long, i As Long
Dim v As Variant
Dim myPath
Dim myFile
Set myWB = ThisWorkbook
Application.ScreenUpdating = False
Sheets(1).Cells.ClearContents
myPath = "C:\Folder1\Folder2\" '<<< change path
myFile = "myFile.csv" '<<< change file name
Set WB = Workbooks.Open(myPath & myFile)
ActiveSheet.UsedRange.Copy myWB.Sheets(1).Range("A1")
ActiveWorkbook.Close False
L = myWB.Sheets(1).UsedRange.Rows.Count
For i = 1 To L
v = Split(Cells(i, 1), ",")
For x = 0 To UBound(v)
Cells(i, x + 1) = v(x)
Next x
Next i
Application.DisplayAlerts = False
ActiveWorkbook.SaveAs Filename:= "D:\data folder\1.xls"
Application.DisplayAlerts = True
myWB.Save
Application.ScreenUpdating = True
End Sub
PS: the command prompt is not altering the number format. VERIFIED!
Thank you
SOLVED!!
I did this:
Open the merged file
select the concerned column
right clic on the column
and I changed the format of all column's cells.