I have a MS-Word .docm document with a macro inside. In this macro I want to get the full content from the document as a byte array. The content should contain the full information of the document and when I save this content I should be able to open this file in Word again.
Im totally new to vba and don't have any idea where to start. I thought about saving the document in a temp folder to read this file to get the content but maybe there is a better way.
I suggest you to use
ThisDocument.SaveAs "c:\temp\mydoc.docm"
Then simply use that file for your further operation.
Or to print out your file as bytes:
Sub SaveAsByteArray()
Dim thisFile As String
thisFile = ActiveDocument.FullName
Dim targetFile As String
targetFile = "C:\temp\doc.docm"
Dim sourceFileNum As Integer
Dim targetFileNum As Integer
Dim aByte As Byte
sourceFileNum = FreeFile
Open thisFile For Random Access Read As sourceFileNum Len = 1
targetFileNum = FreeFile
Open targetFile For Random Access Write As targetFileNum Len = 1
Do While Not EOF(sourceFileNum)
Get #sourceFileNum, , aByte
Put #targetFileNum, , aByte
Loop
Close sourceFileNum
Close targetFileNum
End Sub
But this sub adds an extra byte at the end, so Excel will open a dialog asking if you want to fix the contents. If you choose yes, then word is able to open the file.
Or put it into an array:
Sub SaveAsByteArray()
Dim thisFile As String
thisFile = ActiveDocument.FullName
Dim sourceFileNum As Integer
Dim arr()
Dim arr_n as long
arr_n = 0
Dim aByte As Byte
sourceFileNum = FreeFile
Open thisFile For Random Access Read As sourceFileNum Len = 1
Do While Not EOF(sourceFileNum)
Get #sourceFileNum, , aByte
ReDim Preserve arr(0 to arr_n)
arr(arr_n) = aByte
arr_n=arr_n+1
Loop
Close sourceFileNum
End Sub
Related
Hello I would like to take my txt file containing string of data, split it into array by line. However, I am not able to either input data to array correctly or I have problem with the function GetArrLength. I am pretty new to VBA and can't figure the problem out. The macro stops with Run-time error '13': type mismatch and highlights this section of the code:
GetArrLength = UBound(arr) - LBound(arr) + 1
Hopefully it's not a big issue.
Thanks for any ideas.
Sub apokus()
'PURPOSE: Send All Data From Text File To A String Variable
Dim TextFile As Integer
Dim filePath As String
Dim FileContent As String
Dim strAll As String
Dim arrString() As String
'File Path of Text File
filePath = InputBox("Path to your MD file.", "Path to MD", "actual path to the file")
'Determine the next file number available for use by the FileOpen function
TextFile = FreeFile
'Open the text file
Open filePath For Input As TextFile
'Store file content inside a variable
FileContent = Input(LOF(TextFile), TextFile)
Close TextFile
arrString = Strings.Split(FileContent, vbCr)
Selection.TypeText Text:=GetArrLength(1)
Dim i As Long
For i = 1 To GetArrLength(arrString)
Selection.TypeText Text:=GetArrLength(i) + vbNewLine
Next i
End Sub
Public Function GetArrLength(arr As Variant) As Long
If IsEmpty(arr) Then
GetArrLength = 0
Else
GetArrLength = UBound(arr) - LBound(arr) + 1
End If
End Function
Your code should be as follows:
arrString = Strings.Split(FileContent, vbCr)
Selection.TypeText Text:=GetArrLength(arrString)
Dim i As Long
For i = 0 To UBound(arrString)
Selection.TypeText Text:=arrString(i) + vbNewLine
Next i
However, I can't see the point of your code. You take a text file that contains a number of paragraphs, remove the carriage returns, then insert the text into Word adding carriage returns back in.
I have been using the code below (not my code) with success to have users open a presentation and from the title slide, be able to select a .txt file from any location on their computer and have Powerpoint import the text into the Powerpoint and create the slides adhering to the master slide formatting I have set.
Sub AddSlides(text As String)
Dim Pre As Presentation
Dim Sld As Slide
Set Pre = ActivePresentation
Set Sld = Pre.Slides.Add(Index:=Pre.Slides.Count + 1, Layout:=1)
Sld.Shapes(1).TextFrame.TextRange = text
End Sub
Sub ReadFile(sFileName As String)
Dim iFileNum As Integer
Dim sBuf As String
' edit this:
'sFileName = "test.csv"
' does the file exist? simpleminded test:
If Len(Dir$(sFileName)) = 0 Then
Exit Sub
End If
iFileNum = FreeFile()
Open sFileName For Input As iFileNum
Do While Not EOF(iFileNum)
Line Input #iFileNum, sBuf
AddSlides (sBuf)
Loop
' close the file
Close iFileNum
End Sub
Sub SelectFile()
Dim In_file As Variant
Dim dlgOpen As FileDialog
Set dlgOpen = Application.FileDialog(Type:=msoFileDialogOpen)
dlgOpen.AllowMultiSelect = False
If dlgOpen.Show = -1 Then
In_file = dlgOpen.SelectedItems.Item(1)
ReadFile (In_file)
End If
End Sub
However, now I would like to work with sections, effectively creating a title and a conclusion slide. Section 1 would include the title slide and button for users to select their .txt file. Section 2 would consist of a single slide that concludes the presentation. My problem is, when the code generates the slides from the .txt file, it places them after the conclusion slide in Section 2 instead of after the title slide in Section 1.
I have researched various codes for working with sections and codes for importing/inserting from external files and have had no success working with them to achieve this.
Although I wanted the number of slides generated between the first and last slides to be variable, I can specify how many slides can be generated if this is more feasible. If this does need to be specified, I would also be comfortable creating the slides first and have them populated with the text from the .txt file if this is a more workable option.
Appreciate any help with this.
Note: Current code limits text import to single lines on each slide. If there is a simple way to append this to include 2 lines per slide - that would be extremely useful.
Ok, I'll start with where to put the new slides. You need to change the addSlides function so that it places all of the slides in the position of your conclusion slide.
This ones easy, you just change the index from
Index:=Pre.Slides.Count + 1
to
Index:=Pre.Slides.Count
Making the addSlides function as follows:
Sub AddSlides(text As String)
Dim Pre As Presentation
Dim Sld As Slide
Set Pre = ActivePresentation
Set Sld = Pre.Slides.Add(Index:=Pre.Slides.Count, Layout:=1)
Sld.Shapes(1).TextFrame.TextRange = text
End Sub
On your second issue, getting two lines of text per slide, this is mildly more difficult. You need to read each line, and everytime you get to the second line, add the page, then reset the holding variable. Something like the following should work:
Sub ReadFile(sFileName As String)
Dim iFileNum As Integer
Dim sBuf As String
Dim bFlag As Boolean
Dim sHolder As String
' edit this:
'sFileName = "test.csv"
' does the file exist? simpleminded test:
If Len(Dir$(sFileName)) = 0 Then
Exit Sub
End If
iFileNum = FreeFile()
Open sFileName For Input As iFileNum
bFlag = False
Do While Not EOF(iFileNum)
If bFlag = False Then
Line Input #iFileNum, sBuf
holder = sBuf
bFlag = True
Else
Line Input #iFileNum, sBuf
holder = holder & vbCrLf & sBuf
addSlides (holder)
holder = ""
bFlag = False
End If
Loop
' close the file
Close iFileNum
End Sub
I have a .txt file, Supplier Count.txt and in my excel spreadsheet, each time I run a VBA code I want this file to be opened, to read the number value in my text file, e.g. '21' and then increment it by 1.
So say our text file has one line of text, and this line of text is a number, '21'. the vba code should open the file, read this number and increment it by 1 and replace the text, save it and close the text file. so our value is then '22'
does anyone know how I can do this as I am completely new to vba and so far all ive been able to come up with is the opening the text file and reading the number out as a msgbox
Application.ScreenUpdating = False
On Error GoTo ErrHandler12:
Dim FilePath12 As String
Dim Total12 As String
Dim strLine12 As String
FilePath12 = "\\ServerFilePath\assets\Supplier Count.txt"
Open FilePath12 For Input As #1
While EOF(1) = False
'read the next line of data in the text file
Line Input #1, strLine12
Total12 = Total12 & vbNewLine & strLine12
'increment the row counter
i = i + 1
Wend
Close #1
MsgBox Total12
ErrHandler12:
Application.ScreenUpdating = True
First include a reference to the FileSystemObject (see https://stackoverflow.com/a/5798392/380384)
Then run this
Private fso As New FileSystemObject
Public Sub IncrCount()
Dim path As String
path = fso.BuildPath("\\server\share\folder", "SupplierCount.txt")
Dim fs As TextStream
Set fs = fso.OpenTextFile(path, ForReading)
Dim counter As Long
counter = CInt(fs.ReadLine())
fs.Close
Set fs = fso.OpenTextFile(path, ForWriting, True)
fs.WriteLine CStr(counter + 1)
fs.Close
End Sub
I have a simple Excel 2007 Macro that is reading a text file line by line and displaying the output.
This macro is breaking on commas. I want it to simply read the entire line breaking on a carrage return.
What am I doing wrong?
Sub Directory()
Dim strFileName As String
Dim strDirectory As String
Dim intFileKey As Integer
Dim strLine As String
strDirectory = "C:\Documents and Settings\e1009028\My Documents\embosstest"
ChDir (strDirectory)
strFileName = Dir("*.txt")
Do While Len(strFileName) > 0
intFileKey = FreeFile
Open strFileName For Input As intFileKey
Do While Not EOF(intFileKey)
Input #intFileKey, strLine
MsgBox Mid(strLine, 1, 10)
Loop
strFileName = Dir
Loop
End Sub
Here is a sample text file:
1 blahblahblabh
2 blah,blahblah
For a quick fix, try using Line input instead of input.
For a more modern solution, have a look at FileSystemObject, especially OpenTextFile.
I want to open mis file, copy all the data and write into a text file.
My mis file.
File name – 1.mis
M3;3395;44;0;1;;20090404;094144;8193;3;0;;;;
M3;3397;155;0;2;;20090404;105941;8193;3;0;;;;
M3;3396;160;0;1;;20090404;100825;8193;3;0;;;;
M3;3398;168;0;2;;20090404;110106;8193;3;0;;;;
so on...,
The above data should appear in a text file with same file name (1.txt).
I tried this code.
Dim sFileText As String
Dim iFileNo As Integer
iFileNo = FreeFile
Open "C:\Clients\Converter\Clockings.mis" For Input As #iFileNo
Do While Not EOF(iFileNo)
Input #iFileNo, sFileText
Loop
Close #iFileNo
Open "C:\Clients\Converter\2.txt" For Output As #iFileNo
Do While Not EOF(iFileNo)
Write #iFileNo, sFileText
Loop
Close #iFileNo
Nothing is saved in 1.txt.
It far easier to use the scripting runtime which is installed by default on Windows
Just go project Reference and check Microsoft Scripting Runtime and click OK.
Then you can use this code which is way better than the default file commands
Dim FSO As FileSystemObject
Dim TS As TextStream
Dim TempS As String
Dim Final As String
Set FSO = New FileSystemObject
Set TS = FSO.OpenTextFile("C:\Clients\Converter\Clockings.mis", ForReading)
'Use this for reading everything in one shot
Final = TS.ReadAll
'OR use this if you need to process each line
Do Until TS.AtEndOfStream
TempS = TS.ReadLine
Final = Final & TempS & vbCrLf
Loop
TS.Close
Set TS = FSO.OpenTextFile("C:\Clients\Converter\2.txt", ForWriting, True)
TS.Write Final
TS.Close
Set TS = Nothing
Set FSO = Nothing
As for what is wrong with your original code here you are reading each line of the text file.
Input #iFileNo, sFileText
Then here you write it out
Write #iFileNo, sFileText
sFileText is a string variable so what is happening is that each time you read, you just replace the content of sFileText with the content of the line you just read.
So when you go to write it out, all you are writing is the last line you read, which is probably a blank line.
Dim sFileText As String
Dim sFinal as String
Dim iFileNo As Integer
iFileNo = FreeFile
Open "C:\Clients\Converter\Clockings.mis" For Input As #iFileNo
Do While Not EOF(iFileNo)
Input #iFileNo, sFileText
sFinal = sFinal & sFileText & vbCRLF
Loop
Close #iFileNo
iFileNo = FreeFile 'Don't assume the last file number is free to use
Open "C:\Clients\Converter\2.txt" For Output As #iFileNo
Write #iFileNo, sFinal
Close #iFileNo
Note you don't need to do a loop to write. sFinal contains the complete text of the File ready to be written at one shot. Note that input reads a LINE at a time so each line appended to sFinal needs to have a CR and LF appended at the end to be written out correctly on a MS Windows system. Other operating system may just need a LF (Chr$(10)).
If you need to process the incoming data then you need to do something like this.
Dim sFileText As String
Dim sFinal as String
Dim vTemp as Variant
Dim iFileNo As Integer
Dim C as Collection
Dim R as Collection
Dim I as Long
Set C = New Collection
Set R = New Collection
iFileNo = FreeFile
Open "C:\Clients\Converter\Clockings.mis" For Input As #iFileNo
Do While Not EOF(iFileNo)
Input #iFileNo, sFileText
C.Add sFileText
Loop
Close #iFileNo
For Each vTemp in C
Process vTemp
Next sTemp
iFileNo = FreeFile
Open "C:\Clients\Converter\2.txt" For Output As #iFileNo
For Each vTemp in R
Write #iFileNo, vTemp & vbCRLF
Next sTemp
Close #iFileNo
If you want to do it line by line:
Dim sFileText As String
Dim iInputFile As Integer, iOutputFile as integer
iInputFile = FreeFile
Open "C:\Clients\Converter\Clockings.mis" For Input As #iInputFile
iOutputFile = FreeFile
Open "C:\Clients\Converter\2.txt" For Output As #iOutputFile
Do While Not EOF(iInputFile)
Line Input #iInputFile , sFileText
' sFileTextis a single line of the original file
' you can append anything to it before writing to the other file
Print #iOutputFile, sFileText
Loop
Close #iInputFile
Close #iOutputFile
FileCopy "1.mis", "1.txt"
An example of reading a file:
Dim sFileText as String
Dim iFileNo as Integer
iFileNo = FreeFile
'open the file for reading
Open "C:\Test.txt" For Input As #iFileNo
'change this filename to an existing file! (or run the example below first)
'read the file until we reach the end
Do While Not EOF(iFileNo)
Input #iFileNo, sFileText
'show the text (you will probably want to replace this line as appropriate to your program!)
MsgBox sFileText
Loop
'close the file (if you dont do this, you wont be able to open it again!)
Close #iFileNo
(note: an alternative to Input # is Line Input # , which reads whole lines).
An example of writing a file:
Dim sFileText as String
Dim iFileNo as Integer
iFileNo = FreeFile
'open the file for writing
Open "C:\Test.txt" For Output As #iFileNo
'please note, if this file already exists it will be overwritten!
'write some example text to the file
Print #iFileNo, "first line of text"
Print #iFileNo, " second line of text"
Print #iFileNo, "" 'blank line
Print #iFileNo, "some more text!"
'close the file (if you dont do this, you wont be able to open it again!)
Close #iFileNo
From Here