Unexpected identifier in definition. Expected incomplete structured construct at or before this point or other token

Hi this is my first time using stackoverflow, so i’ll try and provide as much information as possible
I’m currently trying to set up Microsoft.Office.Interop.Word.Application so I can scan word documents for particular words and replace them

Here is a part of my code thats not working.
Microsoft.Office.Interop.Word.Application wordApp = new Microsoft.Office.Interop.Word.Application() { Visible = true };

It gives this error:
Unexpected identifier in definition. Expected incomplete structured construct at or before this point or other token.

let fileName = Path.Combine(
System.Windows.Forms.Application.StartupPath,
“document.docx”);

Microsoft.Office.Interop.Word.Application wordApp = new Microsoft.Office.Interop.Word.Application() { Visible = true };

Microsoft.Office.Interop.Word.Document aDoc = wordApp.Documents.Open(fileName, “ReadOnly: false, Visible: true”);

aDoc.Activate();

FindAndReplace(wordApp, “{id}”, “12345”);

Any help would be appreciated.

Thank you

Well, that’s because of an incorrect syntax. Some lines seems like copied from some C# source. In F# you don’t have to specify type before name of a variable.

You could try to use something like that instead:

let fileName = Path.Combine(System.Windows.Forms.Application.StartupPath, "document.docx")
let wordApp = new Microsoft.Office.Interop.Word.ApplicationClass(Visible = true)

let comarg x = ref (box x)

let aDoc = wordApp.Documents.Open(comarg fileName)
aDoc.Activate()

FindAndReplace(wordApp, "{id}", "12345")

The code above might be non-worked - I don’t have installed Office so I’m unable to check it.

I suggest you to find out some F# related topics/samples like those:

https://code.msdn.microsoft.com/F-Word-Automation-Visual-9cda5c57/sourcecode?fileId=18990&pathId=1531562970

and compare code carefully.

@Nethalin2 And a bit offtopic: Have you considered other choices except Interop to use?

There is at least DocX library. I’m sure it will be much easier to work with it.

Thank you that helps a lot, I have new errors now so that’s progress haha. I’m really grateful for your help.

I will look into docX thanks

Can you post an updated code and new errors?

let fileName = Path.Combine(System.Windows.Forms.Application.StartupPath, “document.docx”)

let wordApp = new Microsoft.Office.Interop.Word.ApplicationClass(Visible = true)

let comarg x = ref (box x)

let aDoc = wordApp.Documents.Open(comarg fileName)

aDoc.Activate()

FindAndReplace(wordApp, “{id}”, “12345”

Problem seems to be with aDoc.Activate()

Unexpected identifier in definition. Expected incomplete structured construct at or before this point or other token.

Never seen this one. Usually F# produces useful messages that easy to understand. Message isn’t totally clear to me. Is this exact text ?

Can you post a screenshot?

Also, can you give a bit of context:
Do you put your code in some type? module?

Here is the rest of my code, sorry if it’s abit messy i’m new to fsharp.
Yes it’s in a module.

Basically this is a combination of different things that i’ve combined to try and get this to work, I want it to find and replace words in word documents.

Thanks again for your help

#light
#I @“C:\Users\netha\Documents\FSharpTest\packages\Microsoft.Office.Interop.Word\lib\net20”
#r “Microsoft.Office.Interop.Word.dll”

module FTEST1 =

open Microsoft.Office.Interop.Word
open System.IO

let m_word : ApplicationClass option ref = ref None

let OpenWord() = m_word := Some(new ApplicationClass())
let GetWordInstance() = Option.get !m_word
let CloseWord() = (GetWordInstance()).Quit()
//let things = m_word.contents.Value.Documents
let comarg x = ref (box x)

let OpenDocument filePath =
printfn “Opening %s…” filePath

  m_word.contents.Value.Documents.Open(comarg filePath)

let PrintDocument (doc : Document) =

  printfn "Printing %s..." doc.Name

// let PrintDocument (doc : Document) =
//
// printfn “Printing %s…” doc.Name
//
// doc.PrintOut(
// Background = comarg true,
// Range = comarg WdPrintOutRange.wdPrintAllDocument,
// Copies = comarg 1,
// PageType = comarg WdPrintOutPages.wdPrintAllPages,
// PrintToFile = comarg false,
// Collate = comarg true,
// ManualDuplexPrint = comarg false,
// PrintZoomColumn = comarg 2, // Pages ‘across’
// PrintZoomRow = comarg 2) // Pages ‘up down’

let FindAndReplace (doc : Document, findText : string, replaceWithText : string) =

printfn "finding and replacing  %s..." doc.Name
        
//options
let matchCase = comarg false;
let matchWholeWord = comarg true;
let matchWildCards = comarg false;
let matchSoundsLike = comarg false;
let matchAllWordForms = comarg false;
let forward = comarg true;
let format = comarg false;
let matchKashida = comarg false;
let matchDiacritics = comarg false;
let matchAlefHamza = comarg false;
let matchControl = comarg false;
let read_only = comarg false;
let visible = comarg true;
let replace = comarg 2;
let wrap = comarg 1;
//execute find and replace
// m_word.Activate doc 
doc.Content.Find.Execute(
              comarg findText, 
              matchCase, 
              matchWholeWord,
              matchWildCards, 
              matchSoundsLike, 
              matchAllWordForms, 
              forward, 
              wrap, 
              format, 
              comarg replaceWithText, 
              replace,
              matchKashida,
              matchDiacritics, 
              matchAlefHamza, 
              matchControl)

let fileName = Path.Combine(System.Windows.Forms.Application.StartupPath, “document.docx”)
let wordApp = new Microsoft.Office.Interop.Word.ApplicationClass(Visible = true)

let comarg x = ref (box x)

let aDoc = wordApp.Documents.Open(comarg fileName)
aDoc.Activate()

FindAndReplace(wordApp, “{id}”, “12345”)


// example useage

let findandreplaceinfolders folder findText replaceText =
Directory.GetFiles(folder, “*.docx”)
|> Array.iter
(fun filePath ->
let doc = OpenDocument filePath
FindAndReplace doc test McTesty
CloseDocument doc)


// Notes

// m_word : the application
// doc : the document
//
// print EXAMPLE
// doc.Print
//
// f&r EXAMPLE
// m_word.Activate(doc)
// m_word.Selection.Find.Execute
//
// doc.Selection.Find.Execute

let CloseDocument (doc : Document) =
printfn “Closing %s…” doc.Name
doc.Close(SaveChanges = comarg false)

// -------------------------------------------------------------

let currentFolder = SOURCE_DIRECTORY

open System
open System.IO

  OpenWord()

  printfn "Printing all files in [%s]..." currentFolder

  Directory.GetFiles(currentFolder, "*.docx")
  |> Array.iter 
      (fun filePath -> 
          let doc = OpenDocument filePath
          FindAndReplace doc
          CloseDocument doc)

  CloseWord()

printfn “Press any key…”
Console.ReadKey(true) |> ignore

Oh, I see. In F# indentations are matter. So you have to be careful with them at first.

I’ve changed your code a bit:

open System

#light
#I @"C:\Users\netha\Documents\FSharpTest\packages\Microsoft.Office.Interop.Word\lib\net20"
#r "Microsoft.Office.Interop.Word.dll"

module FTEST1 =

    open Microsoft.Office.Interop.Word
    open System.IO

    let comarg x = ref (box x)

    let printDocument (doc : Document) =
        printfn "Printing %s..." doc.Name

    let findAndReplace (doc : Document, findText : string, replaceWithText : string) =

        printfn "finding and replacing  %s..." doc.Name
        
        //options
        let matchCase = comarg false
        let matchWholeWord = comarg true
        let matchWildCards = comarg false
        let matchSoundsLike = comarg false
        let matchAllWordForms = comarg false
        let forward = comarg true
        let format = comarg false
        let matchKashida = comarg false
        let matchDiacritics = comarg false
        let matchAlefHamza = comarg false
        let matchControl = comarg false
        let read_only = comarg false
        let visible = comarg true
        let replace = comarg 2
        let wrap = comarg 1
        //execute find and replace

        doc.Content.Find.Execute(
                    comarg findText, 
                    matchCase, 
                    matchWholeWord,
                    matchWildCards, 
                    matchSoundsLike, 
                    matchAllWordForms, 
                    forward, 
                    wrap, 
                    format, 
                    comarg replaceWithText, 
                    replace,
                    matchKashida,
                    matchDiacritics, 
                    matchAlefHamza, 
                    matchControl)

    let wordApp = new Microsoft.Office.Interop.Word.ApplicationClass(Visible = true)

    let openDocument fileName = 
        wordApp.Documents.Open(comarg fileName)

    // example useage
    let closeDocument (doc : Document) =
        printfn "Closing %s…" doc.Name
        doc.Close(SaveChanges = comarg false)

    let findandreplaceinfolders folder findText replaceText =
        Directory.GetFiles(folder, "*.docx")
        |> Array.iter (fun filePath ->
            let doc = openDocument filePath
            doc.Activate()
            printDocument doc
            findAndReplace(doc, findText, replaceText)
            closeDocument doc)

    let currentFolder = SOURCE_DIRECTORY

    printfn "Printing all files in [%s]..." currentFolder
    findandreplaceinfolders currentFolder
    
    wordApp.Quit()

printfn "Press any key…"
Console.ReadKey(true) |> ignore

But I do recommend you to learn about F# a bit more before trying to work with Interop.Word.

Or you can go step by step and get ahead only when previous stage is worked as you expected.

For example, here you could choose something like that:

  1. Open/Close single word document
  2. Open all documents in a specific directory
  3. And, finally, perform a Replace step.

You can surely split the task into a much smaller pieces since you know what you have to got :slight_smile:

Just remember: to find an answer to a specific question is much much simpler and productively than trying to find answer to a broad one.

Btw, there are some links that you might found useful:

Get Started with F#

F# Programming

F# for fun and profit

I can’t thank you enough for your help. I didn’t expect to find someone so helpful on my first coding query.
I will change my code now. I will work through the topics you’ve suggested as well :slight_smile:

Also let currentFolder = SOURCE_DIRECTORY says source directory isn’t defined, but i’m guessing i change that to the file path that I want is that correct?

Right, it should be __SOURCE_DIRECTORY__

I’ve changed it and saved it but still gives the error FTEST1.fsx(75,25): error FS0039: The value or constructor ‘SOURCE_DIRECTORY’ is not defined. Maybe you want one of the followbe you want one of the following:
Source
Sources

Are you sure you add two underscores before and after name? __SOURCE_DIRECTORY__ should just works. Otherwise, can you give a screenshot?

Odd. Are you sure you re-evaluate the script?

Can you check what happens if you send to interactive only the line below:

let currentFolder = __SOURCE_DIRECTORY__

If it also gives the error then I’d suggest creating a new question about this. __SOURCE_DIRECTORY__ is a totally valid F#.

So I managed to get it all working, yet it doesn’t find and replace words in my word document that’s in the same folder as my project. Any ideas?

Can you please create another topic with relevant code and description? It gives more chances to get the answer. People don’t like to scroll to the end of the topic especially if it marked as solved.