guys,

im trying to get bulleting to work. I've yet to see what's the output for this one, can someone help me out?

It kept saying incompatible types between listtemplate, listlevel against variant types. But from all the examples i see on the net, the word document object is a variant! Is there any way to get it working? because i'd like to see the output of this code! :(

procedure TForm3.Button1Click(Sender: TObject);
 var
  vListTemplate: ListTemplate;
  vLevel: OleVariant;
  OutlineNum: OleVariant;
  Level: ListLevel;
  ContinuePrev: OleVariant;
var
  wrdApp, wrdDoc, wrdSelect : OleVariant;
begin

  // Create an instance of Word and make it visible
  wrdApp := CreateOleObject('Word.Application');
  wrdApp.Visible := True;
  // Create a new document
  wrdDoc := wrdApp.Documents.Add();
  wrdSelect := wrdApp.Selection;
//
  wrdSelect.TypeText('(i) phase 1' + chr(13));
  wrdSelect.TypeText('    - description, description, description.' + chr(13));
  wrdSelect.TypeText('    - description, description, description,');
  wrdSelect.TypeText('description, description, description.' + chr(13));
  wrdSelect.TypeText('(ii) phase 2' + chr(13));
  wrdSelect.TypeText('    - description, description, description,');
  wrdSelect.TypeText('description, description, description,');
  wrdSelect.TypeText('description, description, description.' + chr(13));
   
//
  wrdDoc.Application.ActiveDocument.Select;

  OutLineNum := True;
  vListTemplate := wrdDoc.ListTemplates.Add(OutLineNum, EmptyParam);

  Level := vListTemplate.ListLevels.Item(1);

  Level.NumberFormat := '?'; //ChrW(61607);
  Level.TrailingCharacter := wdTrailingTab;
  Level.NumberStyle := wdListNumberStyleBullet;
  Level.Alignment := wdListLevelAlignLeft;

  Level.Font.Bold := wdUndefined;
  Level.Font.Italic := wdUndefined;
  Level.Font.StrikeThrough := wdUndefined;
  Level.Font.Subscript := wdUndefined;
  Level.Font.Superscript := wdUndefined;
  Level.Font.Shadow := wdUndefined;
  Level.Font.Outline := wdUndefined;
  Level.Font.Emboss := wdUndefined;
  Level.Font.Engrave := wdUndefined;
  Level.Font.AllCaps := wdUndefined;
  Level.Font.Hidden := wdUndefined;
  Level.Font.Underline := wdUndefined;
  Level.Font.ColorIndex := wdUndefined;
  Level.Font.Size := 10;
  Level.Font.Animation := wdUndefined;
  Level.Font.DoubleStrikeThrough := wdUndefined;
  Level.Font.Name := 'Wingdings';

  Level.LinkedStyle := '';

  ContinuePrev := False;
  wrdDoc.Range.ListFormat.ApplyListTemplate(vListTemplate,
ContinuePrev, EmptyParam); //wdListApplyToWholeList);

end;

After having struggled to ensure that automating Word from Delphi always works - any OS, any version of Word... I finally ended up creating RTF files instead. This always works, there are no black boxes and you have complete control over the look and feel of every aspect of the document. RTF looks rather scary when you look at it but this is largely because of all the unnecessary garbage that Word puts into an RTF document. In reality it is a really well thought out standard. If want to try an RTF solution PM me and I should be able to help.

If you want to continue with Word...good luck. You will get it working but it will not be long before you want something new and have to begin all over again.

explainthat, do you mean to tell me RTF actually supports multi level bulletting? because the one from 'word' that came with windows doesn't.

If it does, then yes i'm willing to take a look at it.

explainthat, do you mean to tell me RTF actually supports multi level bulletting? because the one from 'word' that came with windows doesn't.

If it does, then yes i'm willing to take a look at it.

It has been a few months since I had anything to do with outputing RTF so I took a quick look at RTF lists. I think there shouldn't be any problem with outputting multilevel lists. Take a look at the RTF documentation - available on MSDN. The information you want is Pages 21-23.

Briefly, an RTF document is made up of a header section, a document information section and then the actual document. The header section contains lists of fonts, colors, styles etc which are then referenced in the docuement itself.

RTF is a vast standard. Most word processors offer pretty good support for reading RTF but what they can write is only a subset of this standard. This applies to Word too. What this means in practice is that just because you cannod do something in Word, either directly or via automation, does not mean that it is not supported.

Just one word of caution - in my experience the number of people using Word 97 is still very significant. There have been some significant changes in the way later versions of the RTF standard so make sure you use the RTF 1.7 spec to ensure maximum compatibility.

There are almost certainly "components" out there that will help you output RTF from Delphi but I am not a great fan of such black box solutions. If you are creating relatively simple documents, here is the approach I suggest

  • Create a simple Word document - get as close to the output you actually want
  • This is your template. Keep your template really simple since you will be exporting it as RTF. Word RTF is VERY verbose so you need to keep your task simple.
  • Now export the template as an RTF document.
  • Reformat the document with carriage returns in the RTF markup to make your subsequent steps easier. Each bit of markup is wrapped in braces, {}. You should be able to use any decent text editor to help you with the process of finding matching braces. I use an excellent freebie called PSPad.
  • Now start examining the reformatted RTF while refering to the RTF standard and take out all the garbage that Word put in. Typically, you can reduce the file size by a factor of 5 to 10.
  • Now focus on the bit you need to customize - in your case lists - and hand code the RTF to get the precise effects you are after.

Once you get this far you can consider how you can best use your template in your Delphi App to automate the process of generating the document you desire - without ever having to do near Word automation. Quite apart from the feeling of better control you will end up with an application that is slimmer and more responsive.

A couple of comments on the code you posted

  • Are you aware of the with keyword? You could use it to make your code execute more efficiently. Not to mention the fact that it diminishes time lost through correcting typos.
  • You are doing a lot of wdUnDefined assignments. Do you know of FillChar? This could make things faster and cleaner.
  • Also, I suppose you realize that Delphi will automatically initialize all record structures and variables declared in your procedures? Initialization is typically to zero, the lowest member of an enumeration etc. So no point doing it all over again yourself.

Before go off trying to implement your own RTF parser you might want to tell us what exactly you want to do.

Are you trying to simply display a form with a bulleted list?
Are you trying to create a document to save to disk?
Are you trying to embed and modify an external document?

Pascal is very strict when it comes to types. This is only my guess, because I know nothing about the types you are playing with, but they look like classes to me. If they have the same hierarchy then they may be assignment compatible --in which case you will have to explicitly cast one to the other. Otherwise you are trying to mix apples and oranges --in which case there should be another way to do what you want.

It is good that you are googling for information, but make sure you get some direct documentation on the OLE classes you are using (OLEVariant, ListTemplate, etc.).

I don't wish be a spoiler, but I've done RTF programming, and it isn't as simple or as organized as all that. It requires a great deal of organization and some pretty sophisticated lexing, more than it appears you are ready to handle right now.

ADrive, I leave it to you to decide whether you are competent enough to handle RTF programming. I should emphasize that what I suggested does not amount to writing an RTF parser.

Duoas, I humbly beg to differ - manipulating a simplified RTF template inside Delphi, putting in custom content and then letting RTF readers, such as Word, open the document is not difficult. RTF is a remarkably well thought out and organized standard. The RTF generated by many writers - particularly Word - is so full of redundancy that it does appear to be complex. RTF programming does require organization - but that should not come to any shock to any half decent Delphi programmer. To a VB programmer, maybe ;-/

Hi guys, thanks so much for replying me.

I'm currently fiddling around with rtf, but the original problem that I had was with alignment in word.

I'm making an application that allows users to type into a text area (doesn't matter a TMemo or TRichEdit) and saved into an oracle clob field, but no matter how I tried it, the 'tab' key would not properly align the text that were wrapped when i write it to a word document.

I thought bullets would help alot - I tried typing something like :

(i) phase 1
- description, description, description description, description.

(ii) phase 2
- phase 2.1 :
> description, description.

And highlighted it with microsoft word and assigned bullets to it. Microsoft word automatically detects and replaces all '(i)', '-' and '>' symbols and automatically aligns them. That was what im trying to achieve in the code i posted (which is supposed to be the one ported from macro recording)

This article has been dead for over six months. Start a new discussion instead.