word vba text replacing between arrays - vba

I'm trying to populate on array from a CSV file that has spaces between the words and a second one that I'm trying to populate after I have replaced all the spaces with hyphens.
So the contents of array1 looks like this "Hi there" and the contents of array2 looks like this "Hi-there".
I've tried using the replace(text, old, new) but I'm coming across problems. In a standalone macro with no other subs, it works. If there are any other subs it doesn't, throwing up and error saying "wrong number of arguments or invalid property assignment"
This is the code I've got:
Private Sub import_csv()
Dim file_name As String
Dim fnum As Integer
Dim whole_file As String
Dim lines As Variant
Dim one_line As Variant
Dim num_rows As Long
Dim num_cols As Long
Dim the_array() As String
Dim imported_array() As String
Dim txt As String
Dim R As Long
Dim C As Long
file_name = "test.csv"
'load the file
fnum = FreeFile
Open file_name For Input As fnum
whole_file = Input$(LOF(fnum), #fnum)
Close fnum
'Break the file into lines
lines = Split(whole_file, vbCrLf)
'Dimension the array
num_rows = UBound(lines)
one_line = Split(lines(0), ",")
num_cols = UBound(one_line)
ReDim the_array(num_rows, num_cols)
ReDim imported_array(num_rows, num_cols)
'Copy the data into the arrays
For R = 0 To num_rows
If Len(lines(R)) > 0 Then
one_line = Split(lines(R), ",")
For C = 0 To num_cols
imported_array(R, C) = one_line(C)
txt = one_line(C)
txt = replace(txt, " ", "-") '<----- problem line
the_array(R, C) = txt
Next C
End If
Next R
End Sub

Sorry, but this sounds totally weird to me. You are trying to use Word to do a find/replace in a CSV file? Is that it? Why would you even do that? Here is a typical find/replace in a Word document.
Sub FindAndReplaceFirstStoryOfEachType()
Dim rngStory As Range
For Each rngStory In ActiveDocument.StoryRanges
With rngStory.Find
.Text = "find text"
.Replacement.Text = "I'm found"
.Wrap = wdFindContinue
.Execute Replace:=wdReplaceAll
End With
Next rngStory
End Sub
That's updating things in the body of a Word document. Now, if you want to do a find/replace in a data file, whether it is a CSV, TXT, or Excel file, you should probably use Excel for this kind of task.
Sub Update_CSV()
Open "C:\test.csv" For Input As #1
c0 = Input(LOF(1), #1)
Close #1
Open "C:\test.csv" For Output As #1
Print #1, Replace(c0, "OLD TEXT", "NEW TEXT")
Close #1
End Sub

Related

VBA - How can you pull Cyrillic text into Powerpoint Label from .TXT File

I am making a random word generator for use in my Global Studies class for a game with the Cyrillic alphabet. I found a VBA setup for PowerPoint 2016 to pull random words from a text file. The problem is, it won't show the Cyrillic. I have tried changing the encoding in the VBA Tools. I have made sure to try different encoding settings for the .txt file, but I can't seem to get actually Cyrillic letters in the label.
The VBA code that I'm using is:
Public myArray, Word1
Sub OnSlideShowPageChange(ByVal SSW As SlideShowWindow)
If SSW.View.CurrentShowPosition = 2 Then
Randomize
Label1.Caption = ""
Dim path
path = ActivePresentation.path & "\words.txt"
Open path For Input As #1
filecontent = Input(LOF(1), #1)
Close #1
myArray = Split(filecontent, vbCrLf)
End If
End Sub
Private Sub CommandButton1_Click()
Word1 = Int((UBound(myArray)) * Rnd)
Label1.Caption = myArray(Word1)
End Sub
Private Sub Label1_Click()
End Sub
Try reading a line at a time from the file rather than using LOF:
Function FileToString(sFileName as string) as String
Dim FileNum As Integer
Dim sBuf As String
Dim sTemp as String
FileToString = False ' by default
If ExistFile(sFileName ) Then
FileNum = FreeFile
sTemp = ""
Open sFileName For Input As FileNum
While Not EOF(FileNum)
Line Input #FileNum, sBuf
sTemp= sTemp & sBuf & vbCrLf
Wend
Close FileNum
FileToString = sTemp
End Function

using excel vba read and edit text file into excel sheet

i would like to extract data from text file into excel worksheet.
my text file format is not the same for each line.
so for each line read, the first data would go input into the 1st excel column, and the next data to go into the 2nd excel column(same row) which is 2 or more blank spaces away from the 1st data. This goes on until all the text file data in that line are input into different columns of the same row.
text file:
data1 (space) data2 (space,space,space) data3 (space,space) data4
excel:
column 1 | column 2 | column 3
data1 data2 | data3 | data4
i do not know how to identify the spaces in each line to be written to excel sheet, pls advise, below is my code:
Sub test()
Dim ReadData, myFile As String
myFile = Application.GetOpenFilename()
Open myFile For Input As #1
Do Until EOF(1)
Line Input #1, ReadData
Loop
End Sub
While David's Solution works fine, here is another way to go about it.
Like David's my solution assumes that each data piece is not broken. This solution also assumes that each new row (that has data) will be placed in the Sheet1 row after the prior row
You need to use the Split() function to separate the pieces of data into their respective Strings.
Then, only using the strings with actual characters (i.e. no spaces or blank lines), you Trim the strings to remove spaces before or after your data(s)
Once all this has occurred, you are left with desired elements in an array which you populate the columns with.
Sub test()
'variables
Dim ReadData, myFile As String
Dim i As Integer
Dim j As Integer
Dim k As Integer
Dim s As Variant
Dim stringTemp1() As String
Dim stringTemp2() As Variant
i = 1
'get fileName
myFile = Application.GetOpenFilename()
Open myFile For Input As #1
Do Until EOF(1)
Line Input #1, ReadData
'check to make sure line is not empty
If Not ReadData = "" Then
'split row into array of strings
stringTemp1 = Split(ReadData, " ")
'remove any string elements that are blank
j = 0
ReDim stringTemp2(j)
For Each s In stringTemp1
If Not IsSpace(s) Then
ReDim Preserve stringTemp2(j)
stringTemp2(j) = s
j = j + 1
End If
Next s
'remove excess spaces from each element when adding to cell
For k = 0 To UBound(stringTemp2)
Worksheets("Sheet1").Cells(i, k + 1).Value = Trim(stringTemp2(k))
Next k
i = i + 1
Erase stringTemp2
Erase stringTemp1
End If
Loop
Close #1
End Sub
This external function was to check if an element in stringTemp1 contained data or not
Function IsSpace(ByVal tempString As String) As Boolean
IsSpace = False
If tempString = "" Then
IsSpace = True
End If
End Function
Assuming that each element of "data" does not internally contain spaces (e.g., your data is non-breaking, such as "John" or 1234 but not like "John Smith", or "1234 Main Street") then this is what I would do.
Use the Split function to convert each line to an array. Then you can iterate the array in each column.
Sub test()
Dim ReadData As String
Dim myFile As String
Dim nextCol as Integer
myFile = Application.GetOpenFilename()
Open myFile For Input As #1
Do Until EOF(1)
nextcol = nextCol + 1
Line Input #1, ReadData
Call WriteLineToColumn(ReadData, nextCol)
Loop
End Sub
Now that will call a procedure like this which splits each line (ReadData) and puts it in to the column numbered nextCol:
Sub WriteLineToColumn(s As String, col as Integer)
'Converts the string of data to an array
'iterates the array and puts non-empty elements in to successive rows within Column(col)
Dim r as Long 'row counter
Dim dataElement as Variant
Dim i as Long
For i = lBound(Split(s, " ")) to UBound(Split(s, " "))
dataElement = Trim(Split(s)(i))
If Not dataelement = vbNullString Then
r = r + 1
Range(r, col).Value = dataElement
End If
Next
End Sub
NOTE ALSO that a declaration of Dim ReadData, myFile as String is declaring ReadData as type Variant. VBA does not support implied declarations like this. To properly, strongly type this variable, it needs to be: Dim ReadData as String, myFile as String.

VBA Scripting Runtime Library with Unix file - LF as End Of Line instead of CRLF issue

I'm writing a very simple parser to read text files into Excel.
Files are exceeding available lines in Excel 2012, so I have to go for a line by line approach.
I've tested Microsoft Scripting Runtime Library, TextStream Object and ReadLine method.
It works fine as far as I have Windows files with CRLF as end of line, while it fails when only LF is marking end of line.
I've seen lots of solutions outside VBA, is there any viable solution within VBA?
thanks in advance
Start by making with a test file that uses only LFs as line endings in c:\temp\lfs.txt
This will read the file into a string:
Dim FileNum As Integer
Dim sBuf As String
Dim sTemp As String
FileNum = FreeFile
Open "c:\temp\lfs.txt" For Input As FileNum
While Not EOF(FileNum)
Line Input #FileNum, sBuf
sTemp = sTemp & sBuf
Wend
Close FileNum
' Now, what do we have? First the string itself:
Debug.Print sTemp
' Are there any CRs in it?
Debug.Print Replace(sTemp, vbCr, "CR")
' LFs?
Debug.Print Replace(sTemp, vbLf, "LF")
' Replace the LFs with CRLFs:
Debug.Print Replace(sTemp, vbLf, vbCrLf)
Now if you write it back out to file, you should be able to use it
I used the following very simple text file separated by LFs. The following vba code workes for me. May be you could post short sample of your text file data where the TextStream.ReadLine method fails with?
Private Const TEXT_FILE_PATH As String = "C:\Temp\VBA\textFileForUnix.txt"
Public Sub test()
Dim targetSheet As Worksheet
Set targetSheet = ThisWorkbook.ActiveSheet
ReadText sheet:=targetSheet, textFilePath:=TEXT_FILE_PATH
End Sub
Private Sub ReadText(ByRef sheet As Worksheet, ByRef textFilePath As String)
Dim scriptingFileSystem As Scripting.FileSystemObject
Dim scriptingFile As Scripting.File
Dim scriptingStream As Scripting.TextStream
Set scriptingFileSystem = New Scripting.FileSystemObject
Set scriptingFile = scriptingFileSystem.GetFile(textFilePath)
Set scriptingStream = scriptingFile.OpenAsTextStream(ForReading)
Dim r As Long
Dim c As Byte
With scriptingStream
r = 1
c = 1
Do While Not .AtEndOfStream
sheet.Cells(r, c).Value = .ReadLine
r = r + 1
Loop
.Close
End With
Set scriptingFile = Nothing
Set scriptingFileSystem = Nothing
End Sub
This one-liner will fix any "unusual" end-of-line I've ever came across to a proper CRLF. In particular it will fix either single LF's or single CR's or LF-CR's.
result$ = Replace(Replace(Replace(Replace(Replace(txt$, vbLf & vbCr, vbLf), vbCrLf, vbLf), vbLf, vbCrLf), vbCr, vbCrLf), vbCrLf & vbLf, vbCrLf)

Word VBA: Table cell range to text file

I'd like to copy a table like this in a word document and extract only the track titles and composers. The selecting of the range goes according to plan:
Dim myCells As Range
With ActiveDocument
Set myCells = .Range(Start:=.Tables(1).Cell(2, 3).Range.Start, _
End:=.Tables(1).Cell(.Tables(1).Rows.Count, 3).Range.End)
myCells.Select
End With
Now, when I copy this selection manually and paste it into notepad, I get exactly what I want:
Title
Composer
Title
Composer
etc.
However, I want to write this selection automatically into a text file. When I try to do this, all content is stuffed in one line of text and little squares (paragraph signs?) pop up everywhere.
How would be I be able to get the result of the manual copying, using VBA?
Try this
Sub Allmusic()
Dim filesize As Integer
Dim FlName As String, tempStr As String
Dim i As Long
Dim MyAr() As String
'~~> Name of Output File
FlName = "C:\Sample.Txt"
'~~> Get a free file handle
filesize = FreeFile()
'~~> Open your file
Open FlName For Output As #filesize
With ActiveDocument
For i = 2 To .Tables(1).Rows.Count
'~~> THIS LINE WILL NOT REFLECT CORRECTLY IN THE BROWSER
'~~> PLEASE REFER TO THE SCREENSHOT OR THE ATTACHED FILE
tempStr = Replace(.Tables(1).Cell(i, 3).Range.Text, "", "")
If InStr(1, tempStr, Chr(13)) Then
MyAr = Split(tempStr, Chr(13))
Print #filesize, MyAr(0)
Print #filesize, MyAr(1)
Else
Print #filesize, tempStr
End If
Print #filesize, ""
Next i
End With
Close #filesize
End Sub
SNAPSHOT
SAMPLE FILE
http://sdrv.ms/Mo7Xel
Download the file and run the procedure Sub Allmusic()
OUTPUT

Reading all files in Folder and showing content in Excel

I want to show 7000 files content that are in a folder and in excel?
I have a found a piece of code that helped me but its only reading one by one. However, I want to read 7000 all in one go. Please help.
Option Explicit
Sub Import_TXT_File()
Dim strg As Variant
Dim EntireLine As String
Dim FName As String
Dim i As String
Application.ScreenUpdating = False
FName = Application.GetOpenFilename("Text Files (*.txt), *.txt", , "Choose File to Import")
Open FName For Input Access Read As #1
i = 1
While Not EOF(1)
Line Input #1, EntireLine
strg = EntireLine
'Change "Sheet1" to relevant Sheet Name
'Change "A" to the relevant Column Name
Sheets("Sheet1").Range("A" & i).Value = strg
i = i + 1
Wend
EndMacro:
On Error GoTo 0
Application.ScreenUpdating = True
Close #1
End Sub
user1185158
The code which you are using will be very slow when you are reading 7000 files. Also there is no code which can read 7000 files in 1 go. You will have to loop through the 7000 files. However there is one good news :) Instead of looping through every line in the text file, you can read the entire file into an array and then write it to excel. For example see this code which is very fast as compared to the code that you have above.
TRIED AND TESTED
Sub Sample()
Dim MyData As String, strData() As String
Open "C:\MyFile.Txt" For Binary As #1
MyData = Space$(LOF(1))
Get #1, , MyData
Close #1
strData() = Split(MyData, vbCrLf)
End Sub
Now using the same code in a loop we can write it into an Excel File
'~~> Change this to the relevant path
Const strPath As String = "C:\Temp\"
Sub Sample()
Dim ws As Worksheet
Dim MyData As String, strData() As String
Dim WriteToRow As Long, i As Long
Dim strCurrentTxtFile As String
Set ws = Sheets("Sheet1")
'~~> Start from Row 1
WriteToRow = 1
strCurrentTxtFile = Dir(strPath & "*.Txt")
'~~> Looping through all text files in a folder
Do While strCurrentTxtFile <> ""
'~~> Open the file in 1 go to read it into an array
Open strPath & strCurrentTxtFile For Binary As #1
MyData = Space$(LOF(1))
Get #1, , MyData
Close #1
strData() = Split(MyData, vbCrLf)
'~~> Read from the array and write to Excel
For i = LBound(strData) To UBound(strData)
ws.Range("A" & WriteToRow).Value = strData(i)
WriteToRow = WriteToRow + 1
Next i
strCurrentTxtFile = Dir
Loop
MsgBox "Done"
End Sub
What the above code does is that it reads the contents of the 7000 text files in sheet 1 (one below the other). Also I have not included error handling. Please do that.
CAUTION: If you are reading heavy text files, say, each file has 10000 lines then you will have to tweak the code in the above scenario as you will get errors. for example
7000 Files * 10000 lines = 70000000 lines
Excel 2003 has 65536 rows and Excel 2007/2010 has 1048576 rows.
So once the WriteRow reaches the maximum row, you might want to read the text file contents into Sheet 2 and so on...
HTH
Sid
Taking Siddharth's solution a little further. You probably don't want to write each row one at a time, calls to the worksheet are extremely slow in Excel, it is better to do any looping in memory and write back in one fell swoop :)
Sub Sample()
Dim ws As Worksheet
Dim MyData As String, strData() As String, strData2() As String
Dim WriteToRow As Long, i As Long
Dim strCurrentTxtFile As String
Set ws = Sheets("Sheet1")
'~~> Start from Row 1
WriteToRow = 1
strCurrentTxtFile = Dir(strPath & "*.Txt")
'~~> Looping through all text files in a folder
Do While strCurrentTxtFile <> ""
'~~> Open the file in 1 go to read it into an array
Open strPath & strCurrentTxtFile For Binary As #1
MyData = Space$(LOF(1))
Get #1, , MyData
Close #1
strData = Split(MyData, vbCrLf)
'Resize and transpose 1d array to 2d
ReDim strData2(1 To UBound(strData) + 1, 1 To 1)
For i = 1 To UBound(strData)
strData2(i, 1) = strData(i - 1)
Next i
Sheet1.Range("A1").Offset(Sheet1.Rows.Count - 1, 0).End(xlUp).Offset(1).Resize(UBound(strData), 1).Value = strData2
strCurrentTxtFile = Dir
Loop
MsgBox "Done"
End Sub