Visual COBOL Personal Edition - how to write out a MS-Word document

I have Vis CBL P/Edit with VS2012 on Win/8.1

All is well but I want to be able to write a file with simple formatting and colours, e.g. a Word doc

I am sure it can be done but I haven't been able to find it in the documentation

Can anyone please point me to the documentation to read for this?

And/or a sample program?

TIA

  • Verified Answer

    Are you looking to do this in native code or managed code?

    MS Word is accessible through a COM class in native code or through an interop class under .NET. Both allow you to create documents programatically.

    The following is an example which is provided with Net Express for creating a Word document from a native COBOL application using COM:

          *> This is required for OLE applications
          $set ooctrl( P)
    
          ****************************************************************
          * Copyright (C) 1997-1999 Micro Focus International Ltd.
          * All Rights Reserved.
          ****************************************************************
          * The program demonstrates the use of OLE Automation to        *
          * send messages to objects in another application. This        *
          * example uses Microsoft Word.                                 *
          *                                                              *
          * It also demonstrates exception handling with regard to OLE   *
          * objects, and the OLE support timeout method.                 *
          *                                                              *
          * The Word interface is documented in the file vbawrd8.hlp     *
          * shipped with Microsoft Word 97 and vbawrd9.chm shipped       *
          * with Microsoft Word 2000.                                    *
          *                                                              *
          * REQUIREMENTS: Microsoft Word 97 or above needs to be         *
          * installed.                                                   *
          *                                                              *
          * $(#) V1.0                                                    *
          ****************************************************************
    
           program-id. worddemo.
    
           class-control.
           *> Native Object COBOL classes
               olesup is class "olesup"           *> OLE support class
           *> OLE automation classes
               wordapp is class "$OLE$word.application"
               .
    
           working-storage section.
           01 wordServer       object reference value null.
           01 theDocument      object reference value null.
           01 theDocuments     object reference value null.
           01 theSelection     object reference value null.
           01 theFind          object reference value null.
           01 theParagraph     object reference value null.
           01 theParagraphs    object reference value null.
           01 theRange         object reference value null.
    
           01 found            pic s9(9) comp-5.
    
           procedure division.
               *> Set the timeout for the OLE "busy" error to 100ms
               *> Using this method is recommended for Word applications
               invoke olesup "setOLEBusyTimeout" using by value 100
    
               *> Create an instance of Word
               invoke wordapp "new" returning wordServer
    
               *> Make it visible
               invoke wordServer "SetVisible" using by value 1
    
               *> Get the Word documents collection object
               invoke wordServer "getDocuments" returning theDocuments
    
               *> Create a new document. The Template and NewTemplate
               *> parameters for this method are optional
               invoke theDocuments "add"
    
               *> We no longer need the Documents collection
               invoke theDocuments "finalize" returning theDocuments
    
               *> Get the current selection
               invoke wordServer "getSelection" returning theSelection
    
               *> Insert some lines of text in the new document
               invoke theSelection "InsertAfter" using
                                          "This is a test line" & x"0d"
               invoke theSelection "InsertAfter" using
                                         "This is the third line" & x"0d"
    
               *> Finished with the selection object
               invoke theSelection "finalize" returning theSelection
    
               *> Oops - we've put "third" instead of "second"
               *> So, we'll replace that word. This is a bit convoluted,
               *> but it's intended to give an idea of how collections work
    
               *> Get the active document
               invoke wordServer "getActiveDocument" returning theDocument
    
               *> Get the Paragraphs collection, then the second paragraph
               *> using the item method, then the range of that paragraph;
               *> Once we have the range, we've finished with paragraphs!
               *> This does *exactly* the same as the VB command
               *>   Range = Document.Paragraphs(2).Range
               invoke theDocument "getParagraphs" returning theParagraphs
               invoke theParagraphs "item" using by value 2
                                   returning theParagraph
               invoke theParagraph "getRange" returning theRange
               invoke theParagraph "finalize" returning theParagraph
               invoke theParagraphs "finalize" returning theParagraphs
    
               *> Get the Find object and ask it to find the text "third"
               *> This should change theRange object's character range
               invoke theRange "getFind" returning theFind
               invoke theFind "setForward" using by value 1
               invoke theFind "setText" using by content z"third"
               invoke theFind "execute"
               invoke theFind "getFound" returning found
               invoke theFind "finalize" returning theFind
    
               if found not = 0
                   *> Select our new range of characters
                   invoke theRange "select"
    
                   *> Finally, change the word to the correct word!
                   invoke theRange "setText" using "second"
               end-if
               invoke theRange "finalize" returning theRange
    
               *> Print the document out
               invoke theDocument "PrintOut" using by value 0
    
               *> Close it without saving it
               invoke theDocument "Close" using by value 0
    
               *> We've finished with the document object
               invoke theDocument "finalize" returning theDocument
    
               *> Tell Word to quit (it won't shut down otherwise)
               invoke wordServer "quit"
    
               *> We've now finished with the Word object
               invoke wordServer "finalize" returning wordServer
    
               exit program
               stop run.
    
    


    The following is a managed code .NET application that uses the Interop class:

          $set ilusing"System.Windows.Forms"
          $set ilusing"Microsoft.Office.Interop.Word" 
           program-id. Program1 as "testnetword.Program1".
           data division.
           working-storage section.
           01 winword type Microsoft.Office.Interop.Word.Application.
           01 document type Document.
           01 headerRange type Range.
           01 footerRange type Range.
           01 para1 type Paragraph.
           01 para2 type Paragraph.
           01 firstTable type Table.
           01 myHeaderFooter type WdHeaderFooterIndex value type WdHeaderFooterIndex::wdHeaderFooterPrimary.
           procedure division.
     
               try
                  *>Create an instance for word app
                  set winword to new Microsoft.Office.Interop.Word.Application
                  *>Set status for word application is to be visible or not.
                  set winword::Visible to false
                  *>Create a missing variable for missing value
                  declare missing as object = type System.Reflection.Missing::Value
                  *>Create a new document
                  set document to winword::Documents::Add(by reference missing, by reference missing, by reference missing, by reference missing)
                  *>Add header into the document
                  perform varying mysection as type Section thru document::Sections
                     *>Get the header range and add the header details.
                     set headerRange to mysection::Headers[myHeaderFooter]::Range
                     invoke headerRange::Fields::Add(headerRange, type WdFieldType::wdFieldPage as object, by reference missing, by reference missing)
                     set headerRange::ParagraphFormat::Alignment to type WdParagraphAlignment::wdAlignParagraphCenter
                     set headerRange::Font::ColorIndex to type WdColorIndex::wdBlue
                     set headerRange::Font::Size to 10
                     set headerRange::Text to "Header text goes here"
                  end-perform
    
                  *>Add the footers into the document
                  perform varying wordSection as type Section thru document::Sections
                     *>Get the footer range and add the footer details.
                     set footerRange to wordSection::Footers[myHeaderFooter]::Range
                     set footerRange::Font::ColorIndex to type WdColorIndex::wdDarkRed
                     set footerRange::Font::Size to 10
                     set footerRange::ParagraphFormat::Alignment to type WdParagraphAlignment::wdAlignParagraphCenter
                     set footerRange::Text to "Footer text goes here"
                  end-perform
      
                  *>adding text to document
                  invoke document::Content::SetRange(0, 0)
                  set document::Content::Text to "This is test document " & type Environment::NewLine
      
                  *>Add paragraph with Heading 1 style
                  set para1 to document::Content::Paragraphs::Add(by reference missing)
                  declare styleHeading1 as object = "Heading 1"
                  invoke para1::Range::set_Style(by reference styleHeading1)
                  set para1::Range::Text to "Para 1 text"
                  invoke para1::Range::InsertParagraphAfter
    
                  *>Add paragraph with Heading 2 style
                  set para2 to document::Content::Paragraphs::Add(by reference missing)
                  declare styleHeading2 as object = "Heading 2"
                  invoke para2::Range::set_Style(by reference styleHeading2)
                  set para2::Range::Text to "Para 2 text"
                  invoke para2::Range::InsertParagraphAfter
    
                  *>Create a 5X5 table and insert some dummy record
                  set firstTable to document::Tables::Add(para1::Range, 5, 5, by reference missing, by reference missing)
                  set firstTable::Borders::Enable to 1
                  perform varying row as type Row thru firstTable::Rows
                     perform varying cell as type Cell thru row::Cells
                        *>Header row
                        if cell::RowIndex = 1
                           set cell::Range::Text to "Column " & cell::ColumnIndex::ToString
                           set cell::Range::Font::Bold to 1
                           *>other format properties goes here
                           set cell::Range::Font::Name to "verdana"
                           set cell::Range::Font::Size to 10
                           *>cell.Range.Font.ColorIndex = WdColorIndex.wdGray25;                            
                           set cell::Shading::BackgroundPatternColor to type WdColor::wdColorGray25
                           *>Center alignment for the Header cells
                           set cell::VerticalAlignment to type WdCellVerticalAlignment::wdCellAlignVerticalCenter
                           set cell::Range::ParagraphFormat::Alignment to type WdParagraphAlignment::wdAlignParagraphCenter
                        *>Data row
                        else
                           set cell::Range::Text to (cell::RowIndex - 2   cell::ColumnIndex)::ToString
                        end-if
                     end-perform
                  end-perform
                    
                  *>Save the document
                  declare filename as object = "c:\temp\temp1.docx"
                  invoke document::SaveAs2(filename, by reference missing, by reference missing, by reference missing
                     by reference missing, by reference missing, by reference missing, by reference missing, by reference missing
                     by reference missing, by reference missing, by reference missing, by reference missing, by reference missing
                     by reference missing, by reference missing, by reference missing)
                  invoke document::Close(by reference missing, by reference missing, by reference missing)
                  set document to null
                  invoke winword::Quit(by reference missing, by reference missing, by reference missing)
                  set winword to null
                  invoke type MessageBox::Show("Document created successfully !")
                
               catch ex as type Exception
                  invoke type MessageBox::Show(ex::Message)
               end-try
               goback.
               
           end program Program1.
    
  • It is the Native I am using

    Thanks very much

    It looks to be just what I need