copy paste not working in windows 10 office 365 while splitting word document using VBA - vba

The following code split the document by section breaks. however it is working correctly in windows 7 but not in windows 10 office 365, having "run time error 4605 : the command is not available." on windows 10? while I try to paste the copied content using oNewDoc.Range.Paste. I came to know it was due to oNewDoc windows not activate or pasting take place without waiting to oNewDoc to be created. because when I press debug and wait for 1 second then run again it executes correctly.
Private Sub GenerateFiles_Click()
'Pages Update 1.0 By M.B.A.
Dim oNewDoc As Document
Dim oDoc As Document
Dim CR As Range
Dim firstLine As String
Dim strLine As String
Dim DocName As String
Dim pdfName As String
Dim arrSplit As Variant
Dim Counter As Integer
Dim i As Integer
Dim PS As String
PS = Application.PathSeparator
'Progress
pBarCurrent 0
If pdfCheck.Value = False And docCheck.Value = False Then
PagesLB = "**Please Select at least one check boxes!"
Beep
Exit Sub
End If
Set oDoc = ActiveDocument
Set CR = oDoc.Range
Letters = oDoc.Range.Information(wdActiveEndSectionNumber)
Counter = 1
While Counter < Letters + 1
With oDoc.Sections.First.Range
.MoveEnd wdSection, 0
.MoveEnd wdCharacter, -1
.Copy
'.Select
Set oNewDoc = Documents.Add(Visible:=True)
oNewDoc.Range.Paste 'Run-time error '4605': This command is not available
End With
firstLine = oNewDoc.Paragraphs(1).Range.Text
For i = 1 To 2
strLine = oNewDoc.Paragraphs(i).Range.Text
If InStr(strLine, ".pdf") > 0 Then
arrSplit = Split(strLine, ".pdf")
DocName = arrSplit(0) & ".pdf"
Exit For
End If
Next i
If i = 3 Then
DocName = Left(firstLine, 45)
DocName = Replace(DocName, vbCr, "")
End If
DocName = Replace(DocName, Chr(11), "")
pdfName = Counter & " - " & DocName & IIf(i = 3, ".pdf", "")
DocName = Counter & " - " & IIf(i < 2, Replace(DocName, ".pdf", ""), DocName) & ".docx"
'Debug.Print pdfName; vbNewLine; DocName
If docCheck Then
oNewDoc.SaveAs FileName:=oDoc.Path & PS & ValidWBName(DocName), AddToRecentFiles:=False
End If
If pdfCheck Then
oNewDoc.SaveAs FileName:=oDoc.Path & PS & ValidWBName(pdfName), FileFormat:=wdFormatPDF
End If
oDoc.Sections.First.Range.Cut
'== Progress Bar =='
DoEvents
PagesLB = " Letter " & Counter & " of " & Letters & vbCr & " " & Int((Counter / (Letters)) * 100) & "% Completed..."
pBarCurrent Int((Counter / (Letters)) * 100)
oNewDoc.Close False
Counter = Counter + 1
Wend
PagesLB = Letters & " Letters has been Created..."
oDoc.Close wdDoNotSaveChanges
Beep
End Sub

You can avoid using the clipboard by using the FormattedText property
With oDoc.Sections.First.Range
.MoveEnd wdSection, 0
.MoveEnd wdCharacter, -1
Set oNewDoc = Documents.Add(Visible:=True)
oNewDoc.Range.FormattedText = .FormattedText
End With

Related

Debugging MS Word Macro for importing JPGs that is returning duplicate images

I'm looking through the following macro I inherited and trying to figure out why it's importing duplicate images when it pulls unique photos from the same folder. Any help would be much appreciated, I don't have a lot of experience with VBA.
The purpose of the macro is to pull all image files in the same folder as the word document and embed them in the word document itself. Right now it's taking the first image in the folder and embedding it multiple times. I think it's an issue with the loop logic but I'm pretty new to VBA and having trouble fixing it.
Option Explicit
Dim msPath As String
Dim msPictures() As String
Dim mlPicturesCnt As Long
Public Sub ImportJPGFiles()
On Error GoTo Err_ImportJPGFiles
Dim lngCount As Long
Dim lngPicture As Long
Dim strMsg As String
Dim sngBEGTime As Single
Dim sngENDTime As Single
'Assume JPG files are in same directory as
'as the Word document containing this macro.
msPath = Application.ActiveDocument.Path & "\"
lngCount = LoadPicturesArray
'Let user browse to correct folder if pictures aren't in the same
'folder as Word document
While lngCount < 0
strMsg = "Unable to find any JPG files in the following" & vbCrLf & _
"directory:" & vbCrLf & vbCrLf & _
msPath & vbCrLf & vbCrLf & _
"Press the 'OK' button if you want to browse to" & vbCrLf & _
"the directory containing your JPG files. Press" & vbCrLf & _
"the 'Cancel' button to end this macro."
If (MsgBox(strMsg, vbOKCancel + vbInformation, "Technical Difficulties")) = vbOK Then
With Application
.WindowState = wdWindowStateMinimize
msPath = BrowseForDirectory
.WindowState = wdWindowStateMaximize
End With
If LenB(msPath) <> 0 Then
If Right$(msPath, 1) <> "\" Then
msPath = msPath & "\"
End If
lngCount = LoadPicturesArray
Else
Exit Sub
End If
Else
Exit Sub
End If
Wend
Application.ScreenUpdating = False
sngBEGTime = Timer
For lngPicture = 0 To lngCount
Application.StatusBar = "Importing picture " & _
CStr(lngPicture + 1) & " of " & _
CStr(lngCount + 1) & " pictures..."
With Selection
.EndKey Unit:=wdStory
.MoveUp Unit:=wdLine, Count:=21, Extend:=wdExtend
.Copy
.EndKey Unit:=wdStory
.InsertBreak Type:=wdPageBreak
.Paste
.MoveUp Unit:=wdLine, Count:=24
.InlineShapes.AddPicture FileName:=msPath & msPictures(lngPicture), _
LinkToFile:=False, _
SaveWithDocument:=True
End With
Next lngPicture
sngENDTime = Timer
strMsg = "Import Statistics: " & vbCrLf & vbCrLf & _
"Pictures Imported: " & CStr(lngCount + 1) & vbCrLf & _
"Total Seconds: " & Format((sngENDTime - sngBEGTime), "###0.0") & vbCrLf & _
"Seconds/Picture: " & Format((sngENDTime - sngBEGTime) / (lngCount + 1), "###0.00")
MsgBox strMsg, , "Finished"
Exit_ImportJPGFiles:
With Application
.StatusBar = "Ready"
.ScreenUpdating = True
End With
Exit Sub
Err_ImportJPGFiles:
MsgBox Err.Number & " - " & Err.Description, , "ImportJPGFiles"
Resume Exit_ImportJPGFiles
End Sub
Public Function LoadPicturesArray() As Long
On Error GoTo Err_LoadPicturesArray
Dim strName As String
strName = Dir(msPath)
mlPicturesCnt = 0
ReDim msPictures(0)
Do While strName <> ""
If strName <> "." And strName <> ".." _
And strName <> "pagefile.sys" Then
If UCase(Right$(strName, 3)) = "JPG" Then
msPictures(mlPicturesCnt) = strName
mlPicturesCnt = mlPicturesCnt + 1
ReDim Preserve msPictures(mlPicturesCnt)
'Debug.Print strName
End If
End If
strName = Dir
Loop
Call QSort(msPictures, 0, mlPicturesCnt - 1)
' Dim i As Integer
' Debug.Print "----AFTER SORT----"
' For i = 0 To mlPicturesCnt - 1
' Debug.Print msPictures(i)
' Next i
LoadPicturesArray = mlPicturesCnt - 1
Exit_LoadPicturesArray:
Exit Function
Err_LoadPicturesArray:
MsgBox Err.Number & " - " & Err.Description, , "LoadPicturesArray"
Resume Exit_LoadPicturesArray
End Function
Public Sub QSort(ListArray() As String, lngBEGOfArray As Long, lngENDOfArray As Long)
Dim i As Long
Dim j As Long
Dim strPivot As String
Dim strTEMP As String
i = lngBEGOfArray
j = lngENDOfArray
strPivot = ListArray((lngBEGOfArray + lngENDOfArray) / 2)
While (i <= j)
While (ListArray(i) < strPivot And i < lngENDOfArray)
i = i + 1
Wend
While (strPivot < ListArray(j) And j > lngBEGOfArray)
j = j - 1
Wend
If (i <= j) Then
strTEMP = ListArray(i)
ListArray(i) = ListArray(j)
ListArray(j) = strTEMP
i = i + 1
j = j - 1
End If
Wend
If (lngBEGOfArray < j) Then QSort ListArray(), lngBEGOfArray, j
If (i < lngENDOfArray) Then QSort ListArray(), i, lngENDOfArray
End Sub

How can I prevent VBA code, used to draw up a list of unique words from a word document, from slowing down as the document get's longer

I have used some code from the internet, modified slightly for my specific use case, to draw up a list of unique words from a word document, the code works without a problem, but the time to execute the code seems to grow exponentially as the document length increases. Can anyone give me any suggestions to speed up the code when working with very long documents?
Sub UniqueWordList()
Dim wList As New Collection
Dim wrd
Dim chkwrd
Dim sTemp As String
Dim k As Long
Dim cWrd As Long
Dim tWrd As Long
Dim nWrd As String
Dim Flag As Boolean
Flag = False
tWrd = ActiveDocument.Range.Words.Count
cWrd = 0
For Each wrd In ActiveDocument.Range.Words
cWrd = cWrd + 1
If cWrd Mod 100 = 0 Then
Application.StatusBar = "Updating: " & (cWrd)
End If
If Flag Then
Flag = False
GoTo nw
End If
If cWrd < tWrd Then
nWrd = ActiveDocument.Words(cWrd + 1)
nWrd = Trim(LCase(nWrd))
End If
sTemp = Trim(LCase(wrd))
If sTemp = "‘" Then
sTemp = sTemp & nWrd
Flag = True
End If
If sTemp Like "*[a-zA-Z]*" Then
k = 0
For Each chkwrd In wList
k = k + 1
If chkwrd = sTemp Then GoTo nw
If chkwrd > sTemp Then
wList.Add Item:=sTemp, Before:=k
GoTo nw
End If
Next chkwrd
wList.Add Item:=sTemp
End If
nw:
Next wrd
sTemp = "There are " & ActiveDocument.Range.Words.Count & " words "
sTemp = sTemp & "in the document, before this summary, but there "
sTemp = sTemp & "are only " & wList.Count & " unique words."
ActiveDocument.Range.Select
Selection.Collapse Direction:=wdCollapseEnd
Selection.TypeText vbCrLf & sTemp & vbCrLf
For Each chkwrd In wList
Selection.TypeText chkwrd & vbCrLf
Next chkwrd
End Sub
After some suggestions I modified my code to use a scripting dictionary, this however does not seem to have solved the problem. Also to answer the concern regarding my message at the end, I understand that the wording is off, what I want is a list of words from the document but each word only once.
Sub UniqueWordListMi()
Dim wList() As String
Dim sTemp As String
Dim cWrd As Long
Dim tWrd As Long
Dim nWrd As String
Dim Flag As Boolean
Dim IsInArray As Boolean
Dim arrsize As Long
Dim rra2 As Variant
arrsize = 0
Flag = False
tWrd = ActiveDocument.Range.Words.Count
cWrd = 1
ReDim Preserve wList(0 To arrsize)
wList(arrsize) = "UNQ"
For Each wrd In ActiveDocument.Range.Words
If cWrd Mod 100 = 0 Then
Application.StatusBar = "Updating" & (cWrd)
End If
If Flag Then
Flag = False
GoTo nw
End If
If cWrd < tWrd Then
nWrd = ActiveDocument.Words(cWrd + 1)
nWrd = Trim(LCase(nWrd))
End If
sTemp = Trim(LCase(wrd))
If sTemp = "‘" Then
sTemp = sTemp & nWrd
Flag = True
End If
If sTemp Like "*[a-zA-Z]*" Then
ReDim Preserve wList(0 To arrsize)
wList(arrsize) = sTemp
arrsize = arrsize + 1
End If
nw:
cWrd = cWrd + 1
Next wrd
Set Dict = CreateObject("scripting.dictionary")
For i = 0 To UBound(wList)
If (Not Dict.Exists(CStr(wList(i)))) Then Dict.Add CStr(wList(i)), wList(i) 'Next i
Next i
rra2 = Dict.Items
sTemp = "There are " & ActiveDocument.Range.Words.Count & " words "
sTemp = sTemp & "in the document, before this summary, but there "
sTemp = sTemp & "are only " & UBound(wList) & " unique words."
ActiveDocument.Range.Select
Selection.Collapse Direction:=wdCollapseEnd
Selection.TypeText vbCrLf & sTemp & vbCrLf
For u = 0 To UBound(rra2)
Selection.TypeText vbCrLf & rra2(u) & vbCrLf
Next u
End Sub
#AlexK beat me to it with a comment on using a Scripting.Dictionary.
Something like this might help
Option Explicit
Public Function CountUniqueWords(ByRef ipRange As Word.Range) As Scripting.Dictionary
Dim myUniqueWords As Scripting.Dictionary
Set myUniqueWords = New Scripting.Dictionary
Dim myPara As Variant
For Each myPara In ipRange.Paragraphs
Dim myWord As Variant
For Each myWord In Split(myPara.Range.Text)
If myUniqueWords.Exists(myWord) Then
myUniqueWords.Item(myWord) = myUniqueWords.Item(myWord) + 1
Else
myUniqueWords.Add myWord, 1
End If
Next
Next
Set CountUniqueWords = myUniqueWords
End Function
Some polishing might be required to meet your specific requirements.
You can't help some increase in processing time as the document gets longer but as the access to the document is limited to paragraphs rather than words is should proceed somewhat faster.
Try the following code. It uses the dictionary directly with the rules of your code.
Note that this will only improve your code. But still, the longer the document will get, the more words need to be checked and the more time it will need. That fact will not change, you can just optimize it by using the dictionary directly but more words need more time to check.
Option Explicit
Sub UniqueWordListMi()
Dim wList As Object
Set wList = CreateObject("scripting.dictionary")
Dim sTemp As String
Dim cWrd As Long
Dim tWrd As Long
Dim nWrd As String
Dim Flag As Boolean
Dim IsInArray As Boolean
Dim arrsize As Long
Dim rra2 As Variant
arrsize = 0
Flag = False
tWrd = ActiveDocument.Range.Words.Count
cWrd = 1
Dim wrd As Variant
For Each wrd In ActiveDocument.Range.Words
If cWrd Mod 100 = 0 Then
Application.StatusBar = "Updating" & (cWrd)
End If
If Flag Then
Flag = False
GoTo nw
End If
If cWrd < tWrd Then
nWrd = ActiveDocument.Words(cWrd + 1)
nWrd = Trim(LCase(nWrd))
End If
sTemp = Trim(LCase(wrd))
If sTemp = "‘" Then
sTemp = sTemp & nWrd
Flag = True
End If
If sTemp Like "*[a-zA-Z]*" Then
If Not wList.Exists(sTemp) Then
wList.Add sTemp, 1
Else
wList.Item(sTemp) = wList.Item(sTemp) + 1
End If
cWrd = cWrd + 1
End If
nw:
Next wrd
sTemp = "There are " & (cWrd - 1) & " words "
sTemp = sTemp & "in the document, before this summary, but there "
sTemp = sTemp & "are only " & wList.Count & " distinct words."
ActiveDocument.Range.Select
Selection.Collapse Direction:=wdCollapseEnd
Selection.TypeText vbCrLf & sTemp & vbCrLf
Dim chkwrd As Variant
For Each chkwrd In wList
Selection.TypeText chkwrd & vbTab & wList.Item(chkwrd) & " times" & vbCrLf
Next chkwrd
End Sub
The following example:
This is an example test where every word is unique except one.
There are 12 words in the document, before this summary, but there are only 11 distinct words.
this 1 times
is 2 times
an 1 times
example 1 times
test 1 times
where 1 times
every 1 times
word 1 times
unique 1 times
except 1 times
one 1 times
With everyone's help and some additional reading, as well as some help from a reddit user this code work's perfectly:
Sub UniqueWordListFast()
Dim WordDictionary As Object
Dim SourceText As Document
Dim objWord As Object
Dim sTemp As String, strWord As String, nxtWord As String
Dim count As Long
count = 0
Set WordDictionary = CreateObject("Scripting.Dictionary")
Set SourceText = Application.ActiveDocument
For Each objWord In SourceText.Range.Words
count = count + 1
strWord = Trim(objWord.Text)
If strWord = nxtWord Then GoTo nw
If strWord Like "*[a-z]*" Then WordDictionary(strWord) = strWord
If strWord Like "‘" Then
nxtWord = Trim(SourceText.Words(count + 1))
strWord = strWord & nxtWord
WordDictionary(strWord) = strWord
End If
nw:
Next
sTemp = "[DOCUMENT] " & vbTab & SourceText.Name & vbCrLf & vbCrLf & _
"There are " & SourceText.Range.Words.count & " words in the document, " & _
"before this summary, but there are only " & WordDictionary.count & " unique words."
Dim NewDocument As Document
Set NewDocument = Documents.Add
NewDocument.Range.Text = sTemp & vbCrLf & Join(WordDictionary.Keys, vbCrLf)
End Sub
Extremely fast and efficient. Thank you everyone!

VBA Replace last field in ALL rows within csv around double quotes?

On Error Resume Next
Set FileSysObj = CreateObject("Scripting.FileSystemObject")
Const ForReading = 1 ' Declare constant for reading for more clarity
Dim cntFile, strCSVFullFile, strCSVFile, strDIR, cntBadLines, cntAllLines, strArchiveDir, strSafeTime,strSafeDate
' -------------------------------------------------------------------------------------------
' Specify CSV file name from the input argument
strCSVFile = Wscript.Arguments(1) ' Transactions
strDIR = Wscript.Arguments(2) & "\" ' C:\Temp
strArchiveDir = Wscript.Arguments(3) & "\"
strSafeTime = Right("0" & Hour(Now), 2) & Right("0" & Minute(Now), 2) & Right("0" & Second(Now), 2)
strSafeDate = Year(Date) & Month(Date) & day(Date)
set folder = FileSysObj.getFolder(strDIR)
cntFile = 0
cntBadLines = 0
cntAllLines = 0
for each file in folder.Files
' check if the file is there and echo it.
if InStr(1,file.name,strCSVFile,1) <> 0 then
strCSVFullFile = file.name
cntFile = cntFile + 1
end if
next
if cntFile > 1 or cntFile = 0 then
' error and end
Wscript.Echo "Error - only 1 file required for this process. There are " & cntFile & " file(s) in the directory"
WScript.Quit
end if
wscript.echo "Checking the file " & strCSVFullFile & " in " & strDIR
NoOfCols = Wscript.Arguments(0) ' usually 8
strTemp = "temp.csv"
strmissing = "missingdata.csv"
Set objOutFile = FileSysObj.CreateTextFile(strDIR & strTemp,True)
Set objOutFileM = FileSysObj.CreateTextFile(strDIR & strmissing,True)
Set inputFile = FileSysObj.OpenTextFile(strDIR & strCSVFullFile, ForReading, True)
' Set inputFile as file to be read from
Dim row, column, outline
Dim fields '(7) '8 fields per line
inputFile.ReadAll 'read to end of file
outline = ""
ReDim MyArray(inputFile.Line-2,NoOfCols) 'current line, minus one for header, and minus one for starting at zero
inputFile.close 'close file so that MyArray can be filled with data starting at the top
Set inputFile = FileSysObj.OpenTextFile(strDIR & strCSVFullFile, ForReading, True) 'back at top
strheadLine = inputFile.ReadLine 'skip header , but keep it for the output file
objOutFile.Write(strheadLine & vbCrLf)
anyBadlines = False
badlineflag = False
Do Until inputFile.AtEndOfStream
fullLine = inputFile.Readline
fields = Split(fullLine,",") 'store line in temp array
For column = 0 To NoOfCols-1 'iterate through the fields of the temp array
myArray(row,column) = fields(column) 'store each field in the 2D array with the given coordinates
'Wscript.Echo myArray(row,column)
if myArray(row,0) = " " or myArray(row,1) = " " then
badlineflag = True
'missline = myArray(row,0) & ", " & myArray(row,1) & ", " & myArray(row,2) & ", " & myArray(row,3) & ", " & myArray(row,4) & ", " & myArray(row,5) & ", " & myArray(row,6) & ", " & myArray(row,7)
'Wscript.Echo missline
'Exit For
end if
if column = NoOfCols-1 then
outline = outline & myArray(row,column) & vbCrLf
else
outline = outline & myArray(row,column) & ","
'csvFile = Regex.Replace(csvFile, "(,\s*?"".*?)(,)(\s+.*?""\s*?,)", "$1$3") 'TEST
end if
Next
cntAllLines = cntAllLines + 1
' Wscript.Echo outline
if badlineflag = False then
objOutFile.Write(fullLine & vbCrLf)
else
' write it somewhere else, drop a header in the first time
if anyBadlines = False Then
objOutFileM.Write(strheadLine & vbCrLf)
End if
objOutFileM.Write(outline)
cntBadLines = cntBadLines + 1
badlineflag = False
anyBadlines = True
end if
outline = ""
row = row + 1 'next line
Loop
objOutFile.Close
objOutFileM.Close
inputFile.close
Wscript.Echo "Total lines in the transaction file = " & cntAllLines
Wscript.Echo "Total bad lines in the file = " & cntBadLines
The below line is able to work as it contains 7 commas (8 columns).
URXW_99,BYQ0JC6,2603834418,2017-10-30,Test,4.962644,2278.0000,ABC
The below line will throw an error as a result of more commas than 7 in the script.
URXW_99,BYQ0JC6,2603834418,2017-10-30,Test,4.962644,2278.0000,Redburn, Europe. Limited
If greater than 7 commas in the CSV file line, the aim is to wrap it all greater than 7 into one field.
E.g. how do you replace Redburn, Europe. Limited string with double quotes as it is one name.
For example, in a text file it would appear like below:
URXW_99,BYQ0JC6,2603834418,2017-10-30,Test,4.962644,2278.0000,"Redburn, Europe. Limited"
Is there a way to write a VB or VBA script to do the above and save it as a .csv file (which is opened via notepad to check the double quotes)?
Option Explicit
Option Compare Text
Public Sub ConvertFile()
Dim lngRowNumber As Long
Dim strLineFromFile As String
Dim strSourceFile As String
Dim strDestinationFile As String
strSourceFile = "U:\Book3.csv"
strDestinationFile = "U:\Book4.csv"
Open strSourceFile For Input As #1
Open strDestinationFile For Output As #2
lngRowNumber = 0
Do Until EOF(1)
Line Input #1, strLineFromFile
strLineFromFile = Right(Replace(strLineFromFile, ",", " ", 1), 1000)
Write #2, strLineFromFile
strLineFromFile = vbNullString
Loop
Close #1
Close #2
End Sub
As I see, you use MS Access (due to Option Compare Text line), so there is better built-in instruments for this task.
Use DoCmd.TransferText for it.
1st step is to create output specification via:
Here you can setup delimiters, even that differs from ", and handle other options.
After that you can use your set-up specification via following command
DoCmd.TransferText acExportDelim, "TblCustomers_export_spec", "TblCustomers", "C:\test\1.txt", True
In this case all characters escaping would be done through built-in instruments. It seems to be more easier to correct this code further.
As mentioned, there is VBScript workaround. For given input data, following function will do desired actions for given string:
Option Explicit
Function funAddLastQuotes( _
strInput _
)
Dim arrInput
arrInput = Split(strInput, ",")
Dim intArrSize
intArrSize = UBound(arrInput)
Dim intCurrentElement
Dim strOutput
Dim intPreLastElement
intPreLastElement = 6
For intCurrentElement = 1 To intPreLastElement
strOutput = strOutput & "," & arrInput(intCurrentElement)
Next
Dim strOutputLastField
For intCurrentElement = intPreLastElement + 1 To intArrSize
strOutputLastField = strOutputLastField & "," & arrInput(intCurrentElement)
Next
strOutputLastField = Right(strOutputLastField, Len(strOutputLastField) - 1)
strOutput = Right(strOutput, Len(strOutput) - 1)
strOutput = strOutput & "," & """" & strOutputLastField & """"
funAddLastQuotes = strOutput
End Function
MsgBox funAddLastQuotes("RXW_99,BYQ0JC6,2603834418,2017-10-30,Test,4.962644,2278.0000,Redburn, Europe,,, Limited")
Finally, here is working VBScript solution.
Option Explicit
Const ColumnsBeforeCommadColumn = 6
Function funAddLastQuotes( _
strInput _
)
Dim arrInput
arrInput = Split(strInput, ",")
Dim intArrSize
intArrSize = UBound(arrInput)
Dim intCurrentElement
Dim strOutput
Dim intPreLastElement
intPreLastElement = ColumnsBeforeCommadColumn
For intCurrentElement = 1 To intPreLastElement
strOutput = strOutput & "," & arrInput(intCurrentElement)
Next
Dim strOutputLastField
If (intPreLastElement + 1) < intArrSize _
Then
For intCurrentElement = intPreLastElement + 1 To intArrSize
strOutputLastField = strOutputLastField & "," & arrInput(intCurrentElement)
Next
Else
strOutputLastField = strOutputLastField & "," & arrInput(intArrSize)
End If
strOutputLastField = Right(strOutputLastField, Len(strOutputLastField) - 1)
strOutput = Right(strOutput, Len(strOutput) - 1)
strOutput = strOutput & "," & """" & strOutputLastField & """"
funAddLastQuotes = strOutput
End Function
Public Sub ConvertFile( _
strSourceFile _
)
Dim objFS
Dim strFile
Dim strTemp
Dim ts
Dim objOutFile
Dim objFile
Set objFS = CreateObject("Scripting.FileSystemObject")
Dim strLine
Dim strOutput
Dim strRow
strFile = strSourceFile
strTemp = strSourceFile & ".tmp"
Set objFile = objFS.GetFile(strFile)
Set objOutFile = objFS.CreateTextFile(strTemp,True)
Set ts = objFile.OpenAsTextStream(1,-2)
Do Until ts.AtEndOfStream
strLine = ts.ReadLine
objOutFile.WriteLine funAddLastQuotes(strLine)
Loop
objOutFile.Close
ts.Close
objFS.DeleteFile(strFile)
objFS.MoveFile strTemp,strFile
End Sub
ConvertFile "C:\!accsoft\_in.csv"
You should change following part: ConvertFile "C:\!accsoft\_in.csv as path to your file.
And ColumnsBeforeCommadColumn = 6 is the setting, at which column the chaos with commas begins

Sharepoint version history in document via vba?

Here is my problem:
Duplicate versions
I checked the version history on the Sharepoint site and it doesn't show any duplicates.
Here is the code im using:
Sub versionhistory()
'
' versionhistory Macro
On Error Resume Next
' On Error GoTo message
Dim dlvVersions As Office.DocumentLibraryVersions
Dim dlvVersion As Office.DocumentLibraryVersion
Dim strVersionInfo As String
Set dlvVersions = ThisDocument.DocumentLibraryVersions
'MsgBox ActiveDocument.Bookmarks.Count
Dim tbl As Word.Table
'Set tbl = ActiveDocument.Tables.Item(2)
Set tbl = ActiveDocument.Bookmarks("VersionTable").Range.Tables(1)
If dlvVersions.IsVersioningEnabled Then
strVersionInfo = "This document has " & dlvVersions.Count & " versions: " & vbCrLf
Call InsertVersionHistory(tbl, dlvVersions)
For Each dlvVersion In dlvVersions
strVersionInfo = strVersionInfo & _
" - Version #: " & dlvVersion.Index & vbCrLf & _
" - Modified by: " & dlvVersion.ModifiedBy & vbCrLf & _
" - Modified on: " & dlvVersion.Modified & vbCrLf & _
" - Comments: " & dlvVersion.Comments & vbCrLf
Next
Else
strVersionInfo = "Versioning not enabled for this document."
End If
'MsgBox strVersionInfo, vbInformation + vbOKOnly, "Version Information"
Set dlvVersion = Nothing
Set dlvVersions = Nothing
Call GetUserName
'message:
'MsgBox Err.Description
MsgBox ("Insert Version Number in the Header and type a Title in the [Insert Title here] on the front page. It will be automatically updated in the footer." & vbNewLine & vbNewLine & "Do Not Type in the Review and Version tables.")
End Sub
Private Function InsertVersionHistory(oVerTbl As Word.Table, oVersions As Office.DocumentLibraryVersions)
Dim rowIndex As Integer
Dim oVersion As Office.DocumentLibraryVersion
Dim oNewRow As Row
'test
Dim versionIndex As Integer
For rowIndex = 2 To oVerTbl.Rows.Count
oVerTbl.Rows.Item(2).Delete
Next rowIndex
rowIndex = 1
'test
versionIndex = oVersions.Count
For Each oVersion In oVersions
If (rowIndex > 5) Then
Return
End If
rowIndex = rowIndex + 1
oVerTbl.Rows.Add
Set oNewRow = oVerTbl.Rows(oVerTbl.Rows.Count)
oNewRow.Shading.BackgroundPatternColor = wdColorWhite
oNewRow.Range.Font.TextColor = wdBlack
oNewRow.Range.Font.Name = "Tahoma"
oNewRow.Range.Font.Bold = False
oNewRow.Range.Font.Size = 12
oNewRow.Range.ParagraphFormat.SpaceAfter = 4
With oNewRow.Cells(1)
'.Range.Text = oVersion.Index
.Range.Text = versionIndex
End With
With oNewRow.Cells(2)
.Range.Text = FormUserFullName(GetUserFullName(oVersion.ModifiedBy))
End With
With oNewRow.Cells(3)
.Range.Text = oVersion.Modified
End With
With oNewRow.Cells(4)
.Range.Text = oVersion.Comments
End With
versionIndex = versionIndex - 1
Next
Set oVersion = Nothing
End Function
Function GetUserFullName(userName As String) As String
Dim WSHnet, UserDomain, objUser
Set WSHnet = CreateObject("WScript.Network")
'UserDomain = WSHnet.UserDomain
'Set objUser = GetObject("WinNT://" & UserDomain & "/" & userName & ",user")
userName = Replace(userName, "\", "/")
Set objUser = GetObject("WinNT://" & userName & ",user")
'MsgBox objUser.FullName
GetUserFullName = objUser.FullName
End Function
Function FormUserFullName(userName As String) As String
Dim arrUserName As Variant
Dim changedUserName As String
arrUserName = Split(userName, ",")
Dim length As Integer
length = UBound(arrUserName) - LBound(arrUserName) + 1
If length >= 2 Then
changedUserName = arrUserName(1) & " " & arrUserName(0)
Else
changedUserName = userName
End If
FormUserFullName = changedUserName
End Function
Private Function GetUserName()
Dim userName As String
userName = ActiveDocument.BuiltInDocumentProperties("Author")
ActiveDocument.BuiltInDocumentProperties("Author") = FormUserFullName(userName)
End Function
I know this is old, but I was looking for the same thing and found this article. I'm still trying it out, but wanted to share before I got distracted with my real job.
From: SixSigmaGuy on microsoft.public.sharepoint.development-and-programming.narkive.com/...
Wanted to share my findings, so far. Surprisingly, I could not find
anything in the SharePoint Designer object/class that supported versions,
but the Office, Word, Excel, and PowerPoint objects do support it.. It
wasn't easy to find, but once I found it, it works great, as long as the
file in the document library is one of the Office documents.
Here's some sample code, written in Excel VBA, showing how to get the
version information for a paritcular SharePoint Document Library file
created in Excel:
Public viRow As Long
Function fCheckVersions(stFilename As String) As Boolean
' stFilename is the full URL to a document in a Document Library.
'
Dim wb As Excel.Workbook
Dim dlvVersions As Office.DocumentLibraryVersions
Dim dlvVersion As Office.DocumentLibraryVersion
Dim stExtension As String
Dim iPosExt As Long
ThisWorkbook.Worksheets("Sheet1").Cells(viRow, 1) = stFilename
If Workbooks.CanCheckOut(stFilename) = True Then
Set wb = Workbooks.Open(stFilename, , True)
Set dlvVersions = wb.DocumentLibraryVersions
If dlvVersions.IsVersioningEnabled = True Then
ThisWorkbook.Worksheets("Sheet1").Cells(viRow, 3) = "Num
Versions = " & dlvVersions.Count
For Each dlvVersion In dlvVersions
ThisWorkbook.Worksheets("Sheet1").Cells(viRow, 4) = "Version: " & dlvVersion.Index
ThisWorkbook.Worksheets("Sheet1").Cells(viRow, 5) = "Modified Date: " & dlvVersion.Modified
ThisWorkbook.Worksheets("Sheet1").Cells(viRow, 6) = "Modified by: " & dlvVersion.ModifiedBy
ThisWorkbook.Worksheets("Sheet1").Cells(viRow, 7) = "Comments: " & dlvVersion.Comments
viRow = viRow + 1
Next dlvVersion
End If
wb.Close False
End If
Set wb = Nothing
DoEvents
End Function`
Fortunately, I discovered that Excel can open non-Excel files in most
cases. I.e., I can, for example, open a jpg file in Excel and use the
dlvVersions collection for that file.

Splitting Word document into multiple .txt files using a macro

I am splitting a single MS Word document into multiple using a custom delimiter. I am able to create multiple files in MS Word format, but I want to create multiple .txt files instead.
The code that I am using now is:
Sub SplitNotes(delim As String, strFilename As String)
Dim doc As Document
Dim arrNotes
Dim I As Long
Dim X As Long
Dim Response As Integer
arrNotes = Split(ActiveDocument.Range, delim)
Response = MsgBox("This will split the document into " &
UBound(arrNotes) + 1 & " sections. Do you wish to proceed?", 4)
If Response = 7 Then Exit Sub
For I = LBound(arrNotes) To UBound(arrNotes)
If Trim(arrNotes(I)) <> "" Then
X = X + 1
Set doc = Documents.Add
doc.Range = arrNotes(I)
doc.SaveAs ThisDocument.Path & "\" & strFilename & Format(X, "000")
doc.Close True
End If
Next I
End Sub
Sub test()
' delimiter & filename
SplitNotes "%%%%%%%%%%%%%%", "Notes "
End Sub
Can anyone help me with this please?
Try this and see if it does what you want.
Sub SplitNotes(delim As String, strFilename As String)
Dim doc As Document
Dim arrNotes
Dim I As Long
Dim X As Long
Dim Response As Integer
arrNotes = Split(ActiveDocument.Range, delim)
Response = MsgBox("This will split the document into " & UBound(arrNotes) + 1 & " sections. Do you wish to proceed?", 4)
If Response = 7 Then Exit Sub
For I = LBound(arrNotes) To UBound(arrNotes)
If Trim(arrNotes(I)) <> "" Then
X = X + 1
Set doc = Documents.Add
doc.Range = arrNotes(I)
doc.SaveAs ThisDocument.Path & "\" & strFilename & ".txt"
doc.Close True
End If
Next I
End Sub
Sub test()
' delimiter & filename
SplitNotes "///", "Notes "
End Sub