Excel VBA find/replace text in .txt file - excel

I have near zero experience with VBA so bear with me here.
I'm trying to create a macro that open a text file and find the text located in Excel's cell A1, and to replace it with text in cell B1. Then, it should find the text located in cell A2, and replace it with cell B2, and so on until the last cell in column A that contains data.
Now, I've searched a bit and stumbled upon this working code:
Sub Replace_Text()
Dim strFile As String
Dim i As Integer
Dim strText As String
Dim cell As Range
With Application.FileDialog(msoFileDialogFilePicker)
.InitialFileName = ThisWorkbook.Path
If .Show <> -1 Then Exit Sub
strFile = .SelectedItems(1)
End With
i = FreeFile
strText = Space(FileLen(strFile))
With CreateObject("vbscript.regexp")
.Global = True
Open strFile For Binary Access Read Write As #i
Get #i, , strText
For Each cell In Range("A1:A" & Cells(Rows.Count, "A").End(xlUp).Row)
.Pattern = Replace(Replace(Replace(Replace(cell.Value, "?", "\?"), "*", "\*"), "+", "\+"), ".", "\.")
strText = .Replace(strText, cell.Offset(, 1).Value)
Next cell
Put #i, 1, strText
Close #i
End With
End Sub
It's working exactly as intended, except for 1 minor problem. It seems to copy the last few characters in the text file and append it after the last character, making some duplication.
Example:
Column A | Column B
<Var1> | Patrick
<Var2> | ghosts
Before running code:
This is <Var1>.
There are <Var2>.
Some random text
After running code:
This is Patrick.
There are ghosts.
Some random textom text
The last few characters "om text" got duplicated and output as such. Sometimes more characters got duplicated depending on the file size. How do I fix this?

Probably, this happens when the output string is shorter than the input. You are opening the file for read and write, read the text (let's say 100 bytes), do your replaces (let's say 90 bytes). Then you write the 90 bytes at the beginning. The remaining 10 bytes in the file stay untouched.
You should open the file first just for read (and close it), then open it again to write the text into it - the old content will be thrown away when you open the file for Output
Open strFile For Binary Access Read Write As #i
Get #i, , strText
Close #i
For Each cell In Range("A1:A" & Cells(Rows.Count, "A").End(xlUp).Row)
...
Next cell
Open strFile For Output As #i
Write #i, strText
Close #i

Related

Replace a value in a file name with an other value from an excel sheet

Hallo I'm an IT student, and this is my first post here on stackoverflow.
The reason I choose to create a post is because I have run into a little problem with a bulk renameing task
I have a two list of values in an excel sheet (around 25.000 rows)
I also have around 25.000 jpg files that contains the value from row 1 in their name ex:
jpg files example:
ROS_15100.jpg
ROS_15100_1.jpg
ROS_15150.jpg
ROS_18730_18731_18732_18733_25343_25043_20709_01.jpg
Excel colon A1: 15100
Excel colon A2: 15150
Excel colon A3: 18730
Excel colon B1: 4543455460006
Excel colon B2: 4943691000545
Excel colon B3: 4943691000645
I need the jpg files name to exchange the value from colon A with the value from colon B.
Any suggestions on how to do this would be very appreciated.
I tryed playing around with Bulk Rename Utility in combination with a Visiual Basic script:
Sub RenameFiles()
Dim xDir As String Dim xFile As String Dim xRow As Long With
Application.FileDialog(msoFileDialogFolderPicker)
.AllowMultiSelect = False If .Show = -1 Then
xDir = .SelectedItems(1)
xFile = Dir(xDir & Application.PathSeparator & "*")
Do Until xFile = ""
xRow = 0
On Error Resume Next
xRow = Application.Match(xFile, Range("A:A"), 0)
If xRow > 0 Then
Name xDir & Application.PathSeparator & xFile As _
xDir & Application.PathSeparator & Cells(xRow, "B").Value
End If
xFile = Dir
Loop
End If
End With
End Sub
But because some of the jpg files have the same number with a _1 _2 and so on this didn't quite work out the way I hoped. I have tried searching on various search engines for a solution but cant seem to find any thing, so I decided to ask the smart people in the stackoverflow community.
This solution is a combination between shell and excel-formula.
Excel Sheet
First, run this code on column C.
=Concatenate ("ren ", A2, ".jpg", " ", B2, ".jpg")
Then, drag this formula starts from C2 to Cn
Second,
Shell work
copy the whole column.
Go to the images file, then create-plain-text.
Open it, and paste our values into the plain-text.
Save the file as .bat.
Run it, you will find all the images' names has been renamed.
Enjoy!

How from Columns separated dataset, to a comma separated one?

i need to separate the columns of my dataset into comma separated how con I do this? I need a dataset that looks like this:
#VBasic2008 here is what i get in the middle of the sheet: the first and second row are my tries with your function CONCAT. While i need something like the rightest part of the image.... like 6,40,45,52. Not all the values merged..
So i did it using CONCAT function but i had to manually compute that for each column i show how for the ones that eventually will need help (note i used ; instead of , beacause my excel seems not working with ,)
and this is finally the final output
Ok but what if I have a dataset of 1000 columns? This process need to be much much quicker than this. This is not optimized.
I have written several comments on your question which may be hard to follow. So I decided to make a full solution which actually a trick.
Note that Microsoft Excel tries to guess the data structure of the file content if the file is suffixed with .csv (extension). For that reason, whenever you open a .csv file, you get your data in columns instead of a single columns with comma separated values.
In order to achieve what you want, first, save your data as in the comma separated values (.csv) file format.
Then change your file extension from .csv to, i.e. .txt (text file) for example:
if your file name is "data.csv", change it to "data.txt". Please make sure you see the file extension as csv before you change it because in some case you don't see the file extension; therefore when you rename it, it remains a csv file.
Note: If you don't see file extension, if you are on Microsoft Windows, follow this link.
Once you rename the file into txt file format, you can then open it in your Excel application by going to File -> Open -> then browse the txt file.
There you go and get what you one.
You don't need to code or use any functions to achieve that although you can choose to do so if you wish as it is also a good solution.
If you are looking for a formula solution
TEXTJOIN(", ", TRUE, Range)
where Range is the column span of expected values
Option Explicit
Sub CSV()
Dim ws As Worksheet: Set ws = ThisWorkbook.Sheets("Sheet1")
Dim LR As Long, xRow As Range
LR = ws.Range("A" & ws.Rows.Count).End(xlUp).Row
Application.ScreenUpdating = False
For Each xRow In ws.Range("A1:A" & LR)
xRow.Offset(0, 6).Value = WorksheetFunction.TextJoin(", ", True, xRow.Resize(1, 6))
Next xRow
Application.ScreenUpdating = True
End Sub
This is already separated by commas, so you just have to rename it to a .csv file.
in Windows Explorer, go to the ribbon and go to the 'view' tab and enable 'File Name Extensions'.
Navigate to your file, right click and rename it to THEFILENAME.csv instead of THEFILENAME.xlsx
Now when you open this up in excel, it should have the grid.
What is the extension of the file? .xls, .txt or .csv?
If it is in .xls then you can simply open the file in Excel and then use the File->save as menu and then selecting the Comma Separated from the file type drop down.
If file has .csv extension and you are trying to open it in Excel then you will see columns even the file has commas in it. To verify that if the file is comma separated then simply open with notepad or other text editors to see the comma separated values.
If there is any other separator like colon : or other and want to replace with comma then simply use the find and replace option in notepad.
CONCAT Excel UDF
I wrote this a while ago.
In VBE add a module and copy the following code to it.
The Code
'*******************************************************************************
' Purpose: Concatenates the values of cells of a specified range.
' Read only. String.
' Syntax: CONCAT(Range, Separator, Row0Column1)
' Inputs:
' Range A valid range in any open workbook. Required.
' Separator A string to be used as a separator between the values.
' Default is the space character. Optional.
' Row0Column1 If 0 it concatenates by row, if 1 then by column.
' Default is 0. Optional.
' Returns: A string containing all the values of the specified range.
'*******************************************************************************
Function CONCAT(ByVal Range As Range, Optional Separator As String = _
" ", Optional Row0Column1 As Long = 0) As String
'***************************************
' Variables
Dim xdRowStart As Long, xdRowEnd As Long, xdRowCounter As Long
Dim xdColumnStart As Long, xdColumnEnd As Long, _
xdColumnCounter As Long
Dim xdSep As String, xdString As String, xdCheckEmptyString As String
Dim xdWS As Worksheet
'***************************************
' Values
xdString = ""
xdSep = Separator
Set xdWS = Range.Worksheet
xdRowStart = Range.Row
xdRowEnd = xdRowStart + Range.Rows.count - 1
xdColumnStart = Range.Column
xdColumnEnd = xdColumnStart + Range.Columns.count - 1
'***************************************
' Determine concatenated direction: by row or by column
Select Case Row0Column1
Case 0
GoTo ConcatenateByRow
Case 1
GoTo ConcatenateByColumn
Case Else
MsgBox "Row0Column1:" & vbCr _
& "Ommit or use 0 for Concatenating by Row." & vbCr _
& "Use 1 for Concatenating by Column."
GoTo ConcatenateFinal
End Select
'***************************************
' Concatenate by Row:
ConcatenateByRow:
For xdRowCounter = xdRowStart To xdRowEnd
For xdColumnCounter = xdColumnStart To xdColumnEnd
If xdString = "" Then 'xdString is empty; all cells were empty so far
xdCheckEmptyString = xdWS.Cells(xdRowCounter, xdColumnCounter)
If xdCheckEmptyString <> "" Then 'Cell is not empty
xdString = xdCheckEmptyString
End If
Else 'xdString is not empty
xdCheckEmptyString = xdWS.Cells(xdRowCounter, xdColumnCounter)
If xdCheckEmptyString <> "" Then 'Cell is not empty
xdString = xdString & xdSep & xdCheckEmptyString
End If
End If
Next xdColumnCounter
Next xdRowCounter
GoTo ConcatenateFinal
'***************************************
' Concatenate by Column:
ConcatenateByColumn:
For xdColumnCounter = xdColumnStart To xdColumnEnd
For xdRowCounter = xdRowStart To xdRowEnd
If xdString = "" Then 'xdString is empty; all cells were empty so far
xdCheckEmptyString = xdWS.Cells(xdRowCounter, xdColumnCounter)
If xdCheckEmptyString <> "" Then 'Cell is not empty
xdString = xdCheckEmptyString
End If
Else 'xdString is not empty
xdCheckEmptyString = xdWS.Cells(xdRowCounter, xdColumnCounter)
If xdCheckEmptyString <> "" Then 'Cell is not empty
xdString = xdString & xdSep & xdCheckEmptyString
End If
End If
Next xdRowCounter
Next xdColumnCounter
GoTo ConcatenateFinal
'***************************************
ConcatenateFinal:
CONCAT = xdString
End Function
'*******************************************************************************
Usage in Excel
=CONCAT($A1:$G1,",") and copy down:
=CONCAT($A2:$G2,",")

VBA code to extract multiple words within multiple bracket from a text file

How to take input from a text file and extract each word within the square bracket (a simple text within each bracket) to an Excel sheet.
For example:
text file->(Hi this is [john doe] and phone number is [12345]..... )
output->john doe
12345
If all of the strings are the same, it would be easiest to open the notepad document, go to edit, replace and replace all brackets with commas and just before the content write what the headers would be. for example, your file would look like:
remove, name, remove, phone
Hi this is ,john doe, and phone number is ,12345,
then save it as file.csv, open the file in excel, and remove the columns that say remove on them
you could use
Option Explicit
Sub main()
Dim fileNr As Integer
Dim lines() As String
Dim iLine As Long
Dim arr As Variant
fileNr = FreeFile '<--| get a free file index for subsequent `Open` statement
Open "C:\Users\Luvish\Data\Test.txt" For Input As #fileNr '<--| open your file (change path and name as per your actual needs
lines = Split(Input$(LOF(fileNr), fileNr), vbNewLine) '<-- read all lines
Close fileNr '<--| close text file
For iLine = 0 To UBound(lines) '<--| loop through all read lines
If InStr(lines(iLine), "]") > 0 Then '<--| if current line has a "]" character
arr = Split(Replace(lines(iLine), "]", "]["), "[") '<--| split current line and collect wanted data in even index elements
MsgBox Left(arr(1), Len(arr(1)) - 1) & " " & Left(arr(3), Len(arr(3)) - 1) '<--| build your current line data
End If
Next
End Sub

Select and Copy non blank cells in excel

I am trying to copy the nonblanks cells in my excel file to txt file. My data looks like:
1 2 3
1 2
1
1 2 3 4
So, if i select all and copy, txt file shows like the empty cells have data which is not something that i want.
I tried this:
Crtl+A
Go to special
Constants
Numbers
These commands selects the nonblank cells but I cannot copy them. Is there a way to copy them? I get:
That command cannot be used on multiple selections.
Thanks
If you got notepad++, you can use the regex find and replace to remove all the extra tabs at the end of a line.
Open the txt file in notepad++ and hit Ctrl+H.
In find, put:
\t+$
In replace, leave it blank.
Then check the radio button for the search mode from 'Normal' to 'Regular expression'. After that, hit 'Replace All' and this should be it.
Dim fso As FileSystemObject
Dim stream As TextStream
Dim str As String
Set fso = New FileSystemObject
Set stream = fso.CreateTextFile("c:\myTextFile.txt", True)
For i = 1 To 10
For Each cell In Range("A" & i & "F" & i)
If Not IsEmpty(cell) Then
str = str + cell.Text + " "
End If
Next cell
stream.writeline (str)
str = ""
Next i
stream.Close
End Sub
all you gotta do is change what you wanted separated by ( the " " at the end of the str line) and the range you want ( i = rows 1 through 10 as is) and ("a" & i ":f" & i which indicates a through f, in this case for rows 1 through 10)
hope this helps
With Word as your text editor, copy Excel as is and Paste Special as Unformatted Text. Replace ^t^t with ^t until no more replacements are made, then ^t^p with ^p.

excel export to tab delimited text file with | to start each row

I am working on a project that requires non technical people to edit an excel file.
The file contains 2 columns, one is a key and one is a value. The key is an integer and the value is html. I need a text file to be generated by a non technical person that takes the form:
|[key][ tab \t][value]
|[key][ tab \t][value]
|[key][ tab \t][value]
The | is needed because the html could be multiline.
Any help is appreciated.
It sounds like you'll need a dab of VBA to get it working. This should get you started.
Sub writeKeysValues()
Dim i As Integer
Dim outFile As String
Dim fNum1 As Integer
'Open file
outFile = "C:\temp\outfile.txt"
fNum1 = FreeFile()
Open outFile For Output As fNum1
'loop through non-blanks
i = 1
With Worksheets("Book1")
Do Until .Cells(i, 1).Value = ""
Print #fNum1, "|" & .Cells(i, 1).Value & vbTab & .Cells(i, 2).Value
i = i + 1
Loop
End With
'All done
Close #fNum1
End Sub
Notes:
You will have to save the file as an Excel-macro-enabled spreadsheet (.xlsm).
It will stop reading at a blank key.
Writing is hardcoded to the C:\temp\outfile.txt.
This will win no code design contests, but it should give you an idea of how to write it out with the pipes and tabs exactly as you desire.

Resources