Combine several RTF texts into one RTF file using VBA - vba

I'm extracting 'task notes' from MS Project using VBA and want to create a MS Word .DOC file and also copy those texts into EXCEL.
If you use the Notes property of the Task objects you only get 255 characters and formatting will not not be retained.
In order to keep formatting you can convert the .MPP file into .MPD and extract the notes. These notes have been stored using rtf (see PJDB.HTM look for 'sub getRtf').
This way I can extract all notes and write them into a .rtf file.
If I open that file (containing multiple notes [i verified]) using MS Word I ONLY see the first note (and it has been formatted well).
Info I gathered from other sites learns only ONE rtf text in a file will be handled and it is NOT trivial to join several rtf texts.
So my question is:
does anyone know how to combine several rtf lines into ONE rtf text.
I prefer answers using VBA.
Of course, if anyone knows how to extract notes from MS Project and create a .DOC file preserving formats it's ok as well

This is probably not the right answer but you could do this in VBA :
For each RTF files, open and save to the clipboard as rich text (via API), and paste in word.
It's ugly but it works.

I had a similar task to read RTF from a database and create a report for all records preserving the RTF formatting in a Word document. The code gets the RTF from the DB, writes it to a file with .rtf extension, then inserts the file into a table cell. Not exactly what you are doing I guess, but the report does display all the formatted text from N records.
So the "files" are not really "combined."
The Word table did paste into Excel manually and the formatting was preserved. I don't know the equivalent of InsertFile in Excel.
RS.Open SQL, con
Do Until RS.EOF
Set ts = fso.CreateTextFile("c:\temp\temp.rtf", True)
ts.Write RS(0)
ts.Close
If iRow > 1 Then tbl.Rows.Add
tbl.Cell(iRow, 1).Range.InsertFile "C:\temp\temp.rtf", , False
.....
iRow = iRow + 1
RS.MoveNext
Loop
A reference to Microsoft Scripting Runtime is needed and this:
Dim ts As TextStream
Dim fso As New FileSystemObject

Related

VBA for Word - UNC Paths

I have a Word document that uses VBA forms to generate the document content based on selection boxes. The VBA copies and pastes from other word documents into the main document. I use explicit paths to specify where it should go find the word documents.
It would be nice to use UNC paths instead, to remove some of the "explicitness" of the file locations (c:\Files\Example\Content\PROFILE.docx) and maybe replace it with something like "..\Content\Profile.docx "
Example of the code:
Sub GenerateProfile()
Dim currentPathProfile As String
currentPathProfileText = ActiveDocument.Path
currentPathProfileText = currentPathProfileText & "c:\Files\Example\Content\PROFILE.docx"
Documents.Open FileName:=currentPathProfileText
Dim currentPathProfileDoc As Document
Set currentPathProfileDoc = Documents(1)
currentPathProfileDoc.Activate
Call CopyWholeContent
currentPathProfileDoc.Close
Call PasteWholeContent
End Sub
If the other word documents are in a relative path position to the template holding the code you can do it. It is easier if they are in a subfolder. Generate the path of ThisDocument (your code holder) and use that as a base.
ThisDocument.Path
However, rather than pull from documents, why not have the text stored in your template in the form of AutoText and use that instead? If the information is needed in more than one template, it can be stored in a global template as AutoText. This is much more flexible and less prone to problems, IMO.

VB.NET - Working with tab delimited text file

I need help with how to work on text file (like database).
I create excel GUI (with macro's), that search imputed string in sheets with lots of data and display entire row with matching string (for people with installed MS office)
Now I must create alternative VB.Net application working only on tab delimited text files (without ADO.Net) for people who haven't installed MS office, and I don't know how start to work with it.
import them? if yes, then how.
working directly on them? if yes, then how.
My text files is exported excels files/sheets to tab delimited .txt, with loots of columns (100+) with headers, and lots of rows 500+
need help :)
thx
If you want to get the headers from the first line of the file then do this ...
Sub Main()
Dim dt = New DataTable
Dim lines = File.ReadAllLines("TextFile1.txt")
Dim headers = lines(0).Split(vbTab)
For Each header In headers
dt.Columns.Add(header)
Next
For Each line In lines.Skip(1)
Dim parts = line.Split(vbTab)
dt.Rows.Add(parts)
Next
End Sub

Splitting MS Publisher 2010 document into multiple files

I want to split a multi-page MS Publisher 2010 document into a set of separate documents, one per page.
The starting document is from a mail-merge, and I am trying to produce a set of numbered and named tickets as PDFs to send to people for an event (this is for a charity). The mail-merge seems to work fine and I can save the merged document and it looks OK with e.g. a list of fifty people giving me a 50-page document.
Ideally the result would be a set of PDFs.
I have tried to create some simple VBA code to do this, but it is not working consistently. If I try this very simple macro below , I get the correct number of documents, but only perhaps 1 or 2 documents with the correct contents out of every five. Most of the documents are completely empty.
Sub splitter()
Dim i As Integer
Dim Source As Document
Dim Target As Document
Set Source = ActiveDocument
For i = 1 To Source.Pages.Count
Set Target = Documents.Add
Source.Pages(i).Shapes.Range.Copy
Target.Pages(1).Shapes.Paste
Target.SaveAs Filename:="C:\Temp\Ticket_" & i
Target.Close
Set Target = Nothing
Next i
End Sub
I did sometimes get an error that the clipboard is busy, but not always.
Another approach might be to start with the master document and do this looping over the separate documents and fill in the personal details for each person's ticket and directly produce the PDFs. But that seems more complex, and I am not a VB programmer (but been doing C++ etc for 20+ years, so I can program :-) )
A final annoyance is that it seems to keep opening a new Publisher window for each document. It takes a while to then close 50+ copies of publisher, and the laptop starts to crawl...
Please advise how best to get round these issues. I am probably missing something trivial, being a relative VB(A) newbie.
Thanks in advance for any suggestions
Try coding something like this:
Open Publisher application (CreateObject()?)
Open Publisher document (doc.Open(filename))
Store the total amount of pages in a global variable (doc.Pages.Count)
Close document (doc.Close())
Loop the following for each page
Copy the pub file and rename it to name & "page" & X
Open the new pub file
Remove all Pages except page X from the pub file
doc.Save()
doc.Close()
Copying files with VBA is easy, but copying pages in Publisher VBA is quite a hassle, so this should be easier to achieve

Merging Documents with Open XML

I am looking for mail merge alternatives in my vb.net app. I have used the mail merge feature of word, and find that it is quite buggy when dealing with a large volume of documents. I am looking at alternate methods of generating the merge, and have come across open xml. I think this will probably be the answer I am looking for. I have come to understand that the merge will be entirely code-driven in vb.net. I have started playing around with the following code:
Dim wordprocessingDocument As WordprocessingDocument = wordprocessingDocument.Open("C:\Users\JasonB\Documents\test.docx", True)
'for each simplefield (mergefield)
For Each field In wordprocessingDocument.MainDocumentPart.Document.Body.Descendants(Of SimpleField)()
'get the document instruction values
Dim instruction As String() = field.Instruction.Value.Split(splitChar, StringSplitOptions.RemoveEmptyEntries)
'if mergefield
If instruction(0).ToLower.Equals("mergefield") Then
Dim fieldname As String = instruction(1)
For Each fieldtext In field.Descendants(Of Text)()
fieldtext.Text = "I AM TESTING"
Next
End If
wordprocessingDocument.MainDocumentPart.Document.Save()
wordprocessingDocument.Dispose()
Now this works great and all, but I am realizing that I need to create as many documents as I will have datarows (assuming I use a datatable to handle the data).
One suggestion I found was to loop through each datarow, take my document template, save it to a folder and insert the datarow data. This could mean however that I end up with 12,000 documents in a single folder that need to be joined later and converted to pdf.
Is there another option? The other thing that stood out to me is to create a new word document, and duplicate over the xml from the template, and then replace the values. I dont know however if there is a "simpler" way of doing this, thanks.
If you don't want to save all 12,000 documents to file you should be able to process, convert and email them one at a time using temporary files.
Converting the DOCX to PDF in .NET might be an issue but looks like it's possible using Word Automation (Saving Word DOCX files as PDF).
The bottom line is you don't need to generate all documents before emailing them if you perform the process one document at a time. You can use SmtpClient in VB.NET to email the PDF after it is generated.
In terms of creating the document I have seen reports generated where a simple string replace is used to replace a string such as '%FIRSTNAME%' with the person's name and so on. This isn't necessarily the best approach but can work quite well. This way you can create your template in Word or OpenOffice and then edit it in .NET using OpenXML.

Batch add a macro to word documents?

I have several hundred .doc word documents to which I need to add a macro which runs when the .doc file is opened and creates a header for said document based on the file name. Is there a way to do this as a batch? I have been individually opening each document and going into visual basic --> Project --> This Document then inserting a .txt file which contains the code. Is there a fast way to do this for multiple documents?
As a learning exercise, put this into the "ThisDocument" part of Normal (the Normal.dot template) in the VBE
Open a word document and watch what happens.
I don't think you need to put your code in every single file, I think you should be OK with using the Document_Open event in Normal.dot.
Just make sure it shows up as a reference in your word documents that you open but I don't see why it wouldn't
If you absolutely need it in every file then it can be done but the problem is if you make one small change to the code, you have to go through all this again. The idea with code is to write it once, use it many times.
You can write VBA code that alters the VBA code in other documents, but you need to "Trust access to the VBA project object model" in the Trust Centre options. This could open you up to viral code if you download Word documents with malicious VBA code in them. What you want to do, essentially, is write a VBA virus. There are legitimate reasons for doing this, and also malicious ones, I leave the ethics of the uses of these techniques up to the user. Knowledge itself is not malicious.
Here's the meat, you will need to write your own code to loop through the documents and possibly save them as .docm files.
Sub ReplaceCode()
Set oDoc = ActiveDocument
Set oComponents = oDoc.VBProject.VBComponents
For i = oComponents.Count To 1 Step -1
If oComponents(i).Type = 100 And oComponents(i).Name = "ThisDocument" Then
With oComponents(i).CodeModule
.DeleteLines 1, .CountOfLines
.AddFromFile "C:\ThisDocument.cls"
End With
End If
Next i
End Sub
Also, if you create your code file by exporting from VBA, you will need to remove this from the top of the .cls file:
VERSION 1.0 CLASS
BEGIN
MultiUse = -1 'True
END
Personally, I would drive this from Excel, maybe using a worksheet to hold a list of the files or locations to update, and another sheet for the code to populate with a list of files updated.