How to copy from a text file in Excel using VBA - excel

i want to open multiple text files in excel, but with some conditions. The "4.5.ncp" file will be copied to "4.5" sheet starting in A1 and continuing to A(n) - depends on the no. of lines in the text file
I have this code
Public Function GetFileContents(ByVal srcPath As String) As String()
Dim f As Integer: f = FreeFile
Dim lines() As String, i As Long
Open srcPath For Input As #f
lines = Split(Input$(LOF(f), #f), vbNewLine)
Close #f
GetFileContents = lines
End Function
Public Sub RunMe()
Dim txtFilePath As String
Dim txtFileName As String
Dim txtFileContents() As String
txtFileName = "4.5"
txtFilePath = Excel.ThisWorkbook.Path & "\" & txtFileName & ".ncp"
MsgBox txtFilePath '<-check path is correct
With Excel.ThisWorkbook.Worksheets(txtFileName)
.Range("A:A").ClearContents 'if running multiple times, this will clear existing data
txtFileContents = GetFileContents(txtFilePath)
.Range("A1").Resize(UBound(txtFileContents), 1).Value2 = Excel.WorksheetFunction.Transpose(txtFileContents)
End With
End Sub
but for some reason my sub doesn't see "Excel.ThisWorkbook.Path". If i run the sub, my msgbox will see just "\4.5ncp" instead of "C:\User\XXX\XXX\XXXX\XXX\4.5.ncp"
but it only happens in this sub, because if i make a new excel file with a sub only to display in A1 my path, it will work perfectly. if i paste the function and the sub in the new excel, it doesn't work anymore.
Any help, please?
I've tried to search for solutions on internet but didn't find anything yet.
Hope someone will help me.

Related

Excel vba for exporting cell content to TXT file

I have an Excel file (https://www.dropbox.com/s/hv9u68s136es190/Example2.xlsx?dl=0) with in column A all the persons and in the cell next to there name text (column B).
I want to save for every person a text file containing the text in the cell next to there name.
The filename should be called like the persons name.
So in this case i would have three text files. I do not know how to manage this using VBA in Excel.
Can someone help me with this?
Try this code, please. But, you must initially try something on your own. We usually help people correct their code and learn...
The text files will be named like the people names in column A. The folder where they will be saved will be the one of the workbook which keeps the active sheet. You can define it as you need, of course.
Option Explicit
Sub SaveTxtNamePlusTekst()
Dim sh As Worksheet, lastR As Long, i As Long, strPath As String
Set sh = ActiveSheet ' use here the sheet you need
strPath = sh.Parent.path 'you can define here the path you wish...
If Dir(strpath, vbDirectory) = "" Then MsgBox "The folder path is not valid...": Exit Sub
lastR = sh.Range("A" & Cells.Rows.Count).End(xlUp).row 'Last row in A:A
For i = 2 To lastR
'calling a Sub able to create a text file in a folder and put text in it
WriteText sh.Range("A" & i).value, strPath, sh.Range("B" & i).value
Next i
End Sub
Private Sub WriteText(strName As String, strPath As String, strText As String)
Dim filePath As String
filePath = strPath & "\" & strName & ".txt" 'building the txt file path
FreeFile 1
Open filePath For Output As #1
Print #1, strText 'write the text
Close #1
End Sub

How to Import a Sheet from an external Workbook AND use the Filename (WITHOUT the .datatype at the end ) as the New Worksheet name?

How to import a Sheet from an external Workbook AND use the Filename (WITHOUT the .datatype at the end) as the new Worksheet name?
The part with WITHOUT the .datatype at the end I meant because I could split the filename from the file path with UBound, but when I try to do that with the filename and the filetype at the end, it doesn't work and gives me an error. Perhaps i dont understand ubound
well enough.
I found this Sub somewhere here on the forum.
But I don't want to import any sheet except the sheet which has the same name as the file itself. So I am not even sure if you need to specify the sheet name.
So I have this Excel file with VBA macros. And the Sheet is called Blank (Since I can't have an excel file without a sheet inside it) and
I have a Userform button where I browse for the file first, and the sheet there should be imported to my Excel File and delete the Blank sheet and import the new EXTERNAL sheet.
Also, it should import ANY Sheet from the file path. Because the names will always be different.
And also, how do I import the data as csv?
I am googling but I don't see what exactly causes it to be imported as csv at other peoples solutions.
Sub ImportSheet()
Dim sImportFile As String, sFile As String
Dim sThisBk As Workbook, wbBk As Workbook
Dim vfilename As Variant
Dim wsSht As Worksheet
Application.ScreenUpdating = False
Application.DisplayAlerts = False
Set sThisBk = ActiveWorkbook
sImportFile = Application.GetOpenFilename( _
FileFilter:="Comma Separated Value, *.csv", Title:="Open Workbook")
If sImportFile = "False" Then
MsgBox "No File Selected!"
Exit Sub
Else
vfilename = Split(sImportFile, "\")
sFile = vfilename(UBound(vfilename))
Application.Workbooks.Open Filename:=sImportFile
Set wbBk = Workbooks(sFile)
With wbBk
If SheetExists("GaebTesten.g42_2") Then
Set wsSht = .Sheets("GaebTesten.g42_2")
wsSht.Copy Before:=sThisBk.Sheets("Start")
Else
MsgBox "There is no sheet with name :US in:" & vbCr & .Name
End If
wbBk.Close SaveChanges:=False
End With
End If
Application.ScreenUpdating = True
Application.DisplayAlerts = True
End Sub
Private Function SheetExists(sWSName As String) As Boolean
Dim ws As Worksheet
On Error Resume Next
Set ws = Worksheets(sWSName)
If Not ws Is Nothing Then SheetExists = True
End Function
this is my second post here on stack overflow, and my first question was very dumb, and when I asked my first question, it was my 2nd hour with vba.
I think I am at about 30 hours now and I've learned a lot.
Question: I am doing this Excel Macro in VBA with userform too now. But mostly I google how to do what and I try to implement it WHILE understanding it, I don't just copy and paste code. Often I just do line by line and test it out.
BUT... how do you guys remember all that?
If I had to program the same thing again right now, I won't know how to, because I know how a syntax works, but I wouldn't know which syntax and stuff to actually use to achieve the desired effect...
Does it come from repeating the same things = experience?
Or how do you acquire the abilities to code without googling almost every single thing? When watching youtubers live streaming how they code something, they never look it up on the internet....
Let me present you a different way than pure string manipulation:
Set a new reference to Microsoft Scripting Runtime. This will enable the Scripting namespace. With it you can do things like the following:
sImportFile = "C:\StackFolder\PrintMyName.xlsx"
With New Scripting.FileSystemObject
Debug.Print .GetBaseName(sImportFile)
' Outputs "PrintMyName"
Debug.Print .GetExtensionName(sImportFile)
' Outputs "xlsx"
Debug.Print .GetFileName(sImportFile)
' Outputs "PrintMyName.xlsx"
Debug.Print .GetDriveName(sImportFile)
' Outputs "C:"
Debug.Print .GetParentFolderName(sImportFile)
' Outputs "C:\StackFolder"
End With
You can build a little helper function to give you the part of the file name you need:
Public Function GetFilenameWithoutExtension(ByVal filename as String) as String
With New Scripting.FileSystemObject
GetFilenameWithoutExtension = .GetBaseName(filename)
End With
End Function
and call it: sFile = GetFilenameWithoutExtension(sImportFile)
Regarding the interesting use of UBound in your subroutine, you could even get the filename (without extension) that way - assuming it doesn't contain additional dots:
vfilename = Split(sImportFile, "\")
sFile = vfilename(UBound(vfilename))
SplitName = Split(sFile, ".")
FilenameWithoutExtension = SplitName(UBound(SplitName)-1)
Extension = SplitName(UBound(SplitName))
These are, however, purely academical thoughts and I wouldn't recommend doing it this way.
Here are two ways to extract the workbook name without the file extension. Here I am removing the extension .xlsx. If the extension is constant, you can just hard code it. If not, you can use wildcards also
MsgBox Left(wbBk.Name, Len(ThisWorkbook.Name) - 5)
MsgBox Replace(wbBk.Name, ".xlsx", "")
You can refer to the sheet with the same name as the workbook by using something like
Sheets(Left(wbBk.Name, Len(ThisWorkbook.Name) - 5).Copy
Sheets(Replace(wbBk.Name, ".xlsx", "").Copy
You can use InstrRev. It is efficient as starts from the end of the string which is where the extension is located.
Left$(wbBk.Name, InStrRev((wbBk.Name, ".") - 1)

How do I change multiple reference tags in XML based on spreadsheet values

I am a technical writer and not much of a coder, I have thousands of .xml files that combined create a book. I used a VBA script from this website to rename all of the files to fit within the new guidelines, now I need to go into the xml code and find all references to those links and replace them with the new file name.
I have an excel spreadsheet where in column A it has the old file name and in column B it has the new file name.
The tag looks like this:
<?iads.link docref="R381"?>
It needs to find "R381" in column A and replace it with "R01081-1-1520-237", the file name in the adjacent cell in column B.
The Tag needs to look like this:
<?iads.link docref="R01081-1-1520-237"?>
I tried using the code from the question How can I Find/Replace multiple strings in an xml file? but it did not work and I'm not even sure if that's the correct question to be asking
My current code looks lie this:
Option Explicit ' Use this !
Public Sub ReplaceXML(rFindReplaceRange As Range) ' Pass in the find-replace range
Dim sBuf As String
Dim sTemp As String
Dim iFileNum As Integer
Dim sFileName As String
Dim i As Long
' Edit as needed
sFileName = "C:\Users\s37739\Desktop\chap3"
iFileNum = FreeFile
Open sFileName For Input As iFileNum
Do Until EOF(iFileNum)
Line Input #iFileNum, sBuf
sTemp = sTemp & sBuf & vbCrLf
Loop
Close iFileNum
' Loop over the replacements
For i = 1 To rFindReplaceRange.Rows.Count
If rFindReplaceRange.Cells(i, 1) <> "" Then
sTemp = Replace(sTemp, rFindReplaceRange.Cells(i, 1), rFindReplaceRange(i, 2))
End If
Next i
' Save file
iFileNum = FreeFile
' Alter sFileName first to save to a different file e.g.
sFileName = "C:\Users\s37739\Desktop\chap3"
Open sFileName For Output As iFileNum
Print #iFileNum, sTemp
Close iFileNum
End Sub
Sub mike1()
End Sub
You are passing the file path when in fact you should be passing the fully qualified file name (file path and file name).
You need to edit those lines
' Edit as needed
sFileName = "C:\Users\s37739\Desktop\chap3"
'...
' Alter sFileName first to save to a different file e.g.
sFileName = "C:\Users\s37739\Desktop\chap3"
With
' Edit as needed
sFileName = "C:\Users\s37739\Desktop\chap3\yourfilename.xml"
'...
' Alter sFileName first to save to a different file e.g.
sFileName = "C:\Users\s37739\Desktop\chap3\yourNEWfilename.xml"
Also, remember to provide the correct Range when running the procedure.
Supposing your Range goes from "A1:B50" you can edit your mike1 sub as follows:
Sub mike1()
' Change range as desired
Call ReplaceXML(ThisWorkbook.Worksheets("YourSheetName").Range("A1:B50"))
End Sub
After that, all you need to do is run mike1 from the Immediate window.
Access using Alt+F11 for the VBA editor then View -> Immediate.
You should see a new window at the bottom of the screen. Just type mike1 in there and hit Enter
UPDATE:
Ideally, you should first try to understand the code you currently have and change it make it work on multiple files instead of a single one per run. There are many places around that can give you examples on how to do that, either recursively or in a loop directly into a function. There are many ways to do it and also many material around it.
That being said, you can find below one of the many approaches to solve your issue. The following code consists of two Subs that you can copy/paste into your module.
You need to change the value of HOST_PATH with the main folder and the findReplaceRange with the range to work with. You need to change "Sheet1" with the name of your worksheet and the "A1:B10" with your actual range. After that, just run the ReplaceXML2() Sub.
Note: this will update ALL XML files under the folder provided, so make sure you gave it enough testing (preferably, backup your files) before running it for the entire folder. If you have further issues I suggest asking another question.
Code:
Public Sub ReplaceXML2()
Const HOST_PATH = "C:\Users\s37739\Desktop\chap3\" ' change accordingly
Dim findReplaceRange As Range
Set findReplaceRange = ThisWorkbook.Worksheets("Sheet1").Range("A1:B10") ' change accordingly
Dim FileSystem As Object
Set FileSystem = CreateObject("Scripting.FileSystemObject")
Call RecursivelyReplaceXML(FileSystem.GetFolder(HOST_PATH), findReplaceRange)
End Sub
Public Sub RecursivelyReplaceXML(parentFolder, rFindReplaceRange As Range) ' Pass in the folder and the find-replace range
Dim subFolder As Object
For Each subFolder In parentFolder.SubFolders
RecursivelyReplaceXML subFolder, rFindReplaceRange
Next
Dim file As Object
For Each file In parentFolder.Files
If Right(file.Name, 4) = ".xml" Then
Dim iFileNum As Integer
Dim sTemp As String
Dim sBuf As String
Dim i As Long
Dim fullFileName As String
fullFileName = file.Path
iFileNum = FreeFile
Open fullFileName For Input As iFileNum
sTemp = "" ' clean up to read the next file
Do Until EOF(iFileNum)
Line Input #iFileNum, sBuf
sTemp = sTemp & sBuf & vbCrLf
Loop
Close iFileNum
' Loop over the replacements
For i = 1 To rFindReplaceRange.Rows.count
If rFindReplaceRange.Cells(i, 1) <> "" Then
sTemp = Replace(sTemp, rFindReplaceRange.Cells(i, 1), rFindReplaceRange(i, 2))
End If
Next i
' Save file
iFileNum = FreeFile
' WARNING: New name definition commented out,
' which means all files will be replaced with newer versions!!
'===
' Alter fullFileName first to save to a different file e.g.
' fullFileName = "C:\Users\s37739\Desktop\chap3\"
Open fullFileName For Output As iFileNum
Print #iFileNum, sTemp
Close iFileNum
End If
Next
End Sub

Excel VBA: Copy data from multiple passwordprotected workbooks in a folder into one worksheet in another workboo

I have written a code that opens a password protected workbook in a folder, copy some values out of it and paste the values in active woorkbook. This works fine.
My problem is that I have 16 password protected files in this folder, and I need a loop that does the same thing with every file. Below you can find the code, and I think all my problems should be properly explained with comments inside the code. Please ask if anything is unclear. In advance, thanks for any help!
Code:
Sub Bengt()
Dim sPath As String
Dim vFolder As Variant
Dim sFile As String
Dim sDataRange As String
Dim mydata As String
Dim wb As Workbook
Dim WBookOther As Workbook
Dim myArray As Variant '<<does the list of passwords have to be array?
sPath = ThisWorkbook.Path & Application.PathSeparator
sDataRange = "Budsjett_resultat'!E2" '<<every file I want to open has data in this sheet and range
sFile = "BENGT.xlsm" '<< how to make sFile be every file in folder?
' here I want a loop that opens every woorkbook in the folder M::\SALG\2016\Budsjett\
Set WBookOther = Workbooks.Open(sPath & sFile, Password:="bengt123")
' all passwords starts with filename + three numbers after as you can see
' here I want to make excel find the password out of a list of passwords in range B100:B116
mydata = "='" & sPath & "[" & sFile & "]" & sDataRange
'mydata = "='M:\SALG\2016\Budsjett\Bengt.xlsmBudsjett_resultat'!E2:E54" '<< change as required
'link to worksheet
With ThisWorkbook.Worksheets(1).Range("T2:T54")
'in this case I want the loop to find "BENGT"(which is the filename) in cell T1, and paste the values in range T2:T54.
'For the other files, I want the loop to find the filename (of the file it opened) in row 1,
'and paste the values in range ?2-?54 at the column with the same name as the filename
.Formula = mydata
.Value = .Value
WBookOther.Close SaveChanges:=False
End With
End Sub
For the password array I have tried following code:
Sub passord()
Dim myArray As Variant
myArray = ThisWorkbook.Worksheets(1).Range("B100:B116")
On Error Resume Next 'turn error reporting off
For i = LBound(myArray, 1) To UBound(myArray, 1)
Set wb = Workbooks.Open("M:\SALG\2016\Budsjett\BENGT.xlsm", Password:=myArray(i, 1))
If Not wb Is Nothing Then bOpen = True: Exit For
Next i
End Sub
I have tried to implement the last sub into the first sub, but I can't figure out how to make it work.

Titles in one CSV, Hyperlinks in other CSV, create new CSV with links built in

I have plain text titles in one .csv and hyperlinks for those titles in another .csv
I currently open them in the same work book, put the titles in A, the hyperlinks in H, and use
=HYPERLINK(H1,A1)
to get my final output of Titles with hyperlinks built in.
Is there an easy way (Excel VBA or macro) to bypass the manual work and create a new output file with the "Titles with hyperlinks built in" from the original two .csv files?
Edit: My two .csv files have the respective text (hyperlink and titles) all down column A.
Sub buildlinks()
Dim i As Integer
Dim wb1, wb2 As Workbook
Set wb1 = Application.Workbooks.Open("C:/path/Links.csv")
Set wb2 = Application.Workbooks.Open("C:/path/Titles.csv")
i = 1
Do Until wb1.Sheets("Sheet1Name").Cells(i, 1).Value = ""
ThisWorkbook.Sheets("Sheet1Name").Cells(i, 1).Formula = "=HYPERLINK(" & wb1.Sheets("Sheet1Name").Cells(i, 1).Value & "," & wb2.Sheets("Sheet1Name").Cells(i, 1).Value & ")"
i = i + 1
Loop
End Sub
Assuming you want to create the hyperlinks in the current spreadsheet instead of creating a separate file.
Since you've said that the inputs are really just text files, one item per line, not comma-separated, it's actually pretty simple to implement using the VBA file handling commands.
Sub BuildLinks(titlesFilePath as String, linksFilePath As String, ByVal rowStart As Long)
Dim tf As Long, lf As Long, of As Long
tf = FreeFile
On Error Goto NO_TITLE_FILE
Open titlesFilePath For Input As #tf
lf = FreeFile
On Error Goto NO_LINKS_FILE
Open linksFilePath For Input As #lf
On Error Goto 0
While Not (EOF(tf) Or EOF(lf))
Dim curTitle As String, curLink As String
Line Input #tf, curTitle
Line Input #lf, curLink
Cells(rowStart, 1).Formula = "=HYPERLINK(""" & curLink & """,""" & curTitle & """)"
Wend
Close #tf
Close #lf
Exit Sub
NO_TITLE_FILE:
MsgBox "Can't Open Title File" & titlesFilePath
Exit Sub
NO_LINKS_FILE:
MsgBox "Can't Open Links File" & linksFilePath
End Sub

Resources