none
HOw to populate a combobox on a form with the list of languages based on Word.Languages and include item in the list only if there is an active spelling dictionary RRS feed

  • Question

  • Hello guys,

    I am new at vb under studio and I am running into a problem that was easy to sort under VBA but puzzles me under Studio.

    I am trying to create a VSTO Add-in for Word. I have a form which contains a combobox and I want to programmatically list the NameLocal (display value) and ID (value) of all languages of the system for which there is an ActiveSpelling Dictionary.

    I locate this routine in the Form.Vb:

        Private Sub PopulateMyLanguages()
    
            Dim Cb As ComboBox = Me.Cbb_Languages
            Dim MyLang As Microsoft.Office.Interop.Word.Language
    
            For Each MyLang In Microsoft.Office.Interop.Word.Languages
                If MyLang.ActiveSpellingDictionary.Path IsNot vbNullString Then
                    Cb.Items.Add(MyLang.NameLocal)
                    Cb.DisplayMember = MyLang.NameLocal
                    Cb.ValueMember = MyLang.ID
                    If MyLang.ID = My.Settings.St_Target_Language Then
                        Cb.SelectedItem(Cb.Items.Count) = True
                    End If
                End If
            Next
        End Sub

    However, I get the following error message:

    Error    BC30111    'Languages' is an interface type and cannot be used as an expression.   

    What can I do to rectify this and get it to work?

    Any and all help would be much appreciated. Many thanks in advance.

    Tuesday, October 2, 2018 2:32 AM

Answers

  • In the Form, you *ought* still to be able to do this:

    Dim myLang as Word.Language

    because the relevant references are already in the project as a whole. But there is no harm in going to Project->Add Reference... and looking in the Assemblies ->Extensions section, where you should see several Word-related assemblies checked. (Things may be slightly different depending on your version of VS).

    As you say, Me. won't work in there, but in a VSTO Addin you should be able to use

           For Each MyLang In Globals.ThisAddIn.Application.Languages

    If you use intellisense, after typing Globals, ThisAddIn should be presented as an option. If it isn't, then I would guess that something has gone wrong in the project, but I could not say what that might be.

     

    Peter Jamieson

    • Marked as answer by Athlagan Thursday, October 4, 2018 4:31 PM
    Thursday, October 4, 2018 3:02 PM

All replies

  • Try the following for a proof of concept, not done in a VSTO but instead a Windows Form project which I did this way as I don't do VSTO thus not going to try now. Of course you could always have this thread moved to the "Word for developers" forum upon request which I can do for you.

    Imports Microsoft.Office.Interop.Word
    Public Class Form1
    
        Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    
            Dim langs As New List(Of WdLanguageID)(
                CType([Enum].GetValues(GetType(WdLanguageID)), IEnumerable(Of WdLanguageID)))
    
            ListBox1.DataSource = langs.
                Select(Function(item) item.ToString().Replace("wd", "")).
                Skip(2).OrderBy(Function(item) item).
                ToList
        End Sub
    End Class

    Version two

    Imports System.Text.RegularExpressions
    Imports Microsoft.Office.Interop.Word
    Public Class Form1
        Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    
            Dim langs As New List(Of WdLanguageID)(
                CType([Enum].GetValues(GetType(WdLanguageID)), IEnumerable(Of WdLanguageID)))
    
            ListBox1.DataSource = langs.
                Select(Function(item) New WordLanguage With {.Item = item}).
                Skip(2).OrderBy(Function(item) item.Item.ToString()).
                ToList
        End Sub
    
        Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
            Dim result = CType(ListBox1.SelectedItem, WordLanguage)
            Dim item As WdLanguageID = result.Item
            MessageBox.Show(item.ToString())
        End Sub
    End Class
    Public Module SplitCamelCaseExtension
        <Runtime.CompilerServices.Extension>
        Public Function SplitCamelCase(sender As String) As String
            Return Regex.Replace(Regex.Replace(sender,
                "(\P{Ll})(\P{Ll}\p{Ll})", "$1 $2"), "(\p{Ll})(\P{Ll})", "$1 $2")
        End Function
    End Module
    Public Class WordLanguage
        Public Property Item() As WdLanguageID
    
        Public Overrides Function ToString() As String
            Return Item.ToString().Replace("wd", "").SplitCamelCase
        End Function
    End Class


    Please remember to mark the replies as answers if they help and unmark them if they provide no help, this will help others who are looking for solutions to the same or similar problem. Contact via my Twitter (Karen Payne) or Facebook (Karen Payne) via my MSDN profile but will not answer coding question on either.
    VB Forums - moderator
    profile for Karen Payne on Stack Exchange, a network of free, community-driven Q&A sites



    Wednesday, October 3, 2018 10:39 AM
  • Dear Karen,

    Thank you very much for your help.

    However, there are 2 issues that your code does not solve:

        a) this lists ALL the languages available in Word (and not just those with a spelling dictionary installed)

        b) it does not provide the NameLocal (if tried on a non English speaking computer, the list remains in English)

    which are the 2 things I need this combobox to do.

    The code you provided does work though, but it provides the language ID values under an integer form and I am unable to pass it onto a specific language to get language ID and NameLocal to display in the list if the langugae.ID has an ActiveSpelling dictionary.

    We are still step closer to the solution than we were before.

    Kind regards,

    Wednesday, October 3, 2018 2:14 PM
  • Dear Karen,

    Thank you very much for your help.

    However, there are 2 issues that your code does not solve:

        a) this lists ALL the languages available in Word (and not just those with a spelling dictionary installed)

        b) it does not provide the NameLocal (if tried on a non English speaking computer, the list remains in English)

    which are the 2 things I need this combobox to do.

    The code you provided does work though, but it provides the language ID values under an integer form and I am unable to pass it onto a specific language to get language ID and NameLocal to display in the list if the langugae.ID has an ActiveSpelling dictionary.

    We are still step closer to the solution than we were before.

    Kind regards,

    Well hopefully you can figure out the rest as this was not suppose to be a solution as mentioned but instead a different way to look at things. The Class Enum I used list all languages regardless of if they exists on your machine as they are static members in the Enum so you would need to figure out the rest or as I mentioned before I can move your question to the "Word for developers" forum.

    Please remember to mark the replies as answers if they help and unmark them if they provide no help, this will help others who are looking for solutions to the same or similar problem. Contact via my Twitter (Karen Payne) or Facebook (Karen Payne) via my MSDN profile but will not answer coding question on either.
    VB Forums - moderator
    profile for Karen Payne on Stack Exchange, a network of free, community-driven Q&A sites

    Wednesday, October 3, 2018 2:38 PM
  • Dear Karen,

    Thank you for your reply and your help.

    I still haven't figured out how to get a language identified as a language and return its ID and NameLocal, which I also need to be able to identify the existence of the ActiveSpellingDictionary.

    If you think, moving the question to the "Word for developers" forumw ould help, yes, please do.

    In any case, I am most grateful for your support.

    Kind regards,

    Hacène

    Thursday, October 4, 2018 2:13 AM
  • The reason your code does not work is because you need to access the list of languages in the (running) Word Application object. If your VSTO application is a VSTO Word Document or Addin then you could typically access the running Application from within the ThisDocument class or the ThisAddIn class using Me.Application

    So what you actually need in that case is 

           For Each MyLang In Me.Application.Languages
     

    However, when checking for the spell-checker, you need to verify that the SpellChecker property actually points to an object before you try to check the value of its Path string.

    Within a VSTO app, you should not need to reference the Microsoft.Word.Interop.Word etc., so you could consider using code more like this:

    Dim MyLang As Word.Language
    
    For Each MyLang In Me.Application.Languages
      If Not IsNothing(MyLang.ActiveSpellingDictionary) Then
        If MyLang.ActiveSpellingDictionary.Path IsNot vbNullString Then
          Cb.Items.Add(MyLang.NameLocal)
          Cb.DisplayMember = MyLang.NameLocal
          Cb.ValueMember = MyLang.ID
          If MyLang.ID = My.Settings.St_Target_Language Then
            Cb.SelectedItem(Cb.Items.Count) = True
          End If
        End If
      End If
    Next
    

    I can't verify right now whether that will give you the correct local language names.


    Peter Jamieson

    Thursday, October 4, 2018 12:43 PM
  • Dear Peter,

    Thank you very much for your reply and your contribution.

    I tried the code you suggested, but I still get an error message based on

                                 Me.Application.Languages

    when I try to use this code in the form vb class, the message is

                                 Application is not a member of this class/form

    When I try using the code in ThisDocument.vb or in ThisAddIn.Vb, I get the message

                                 Languages is not a member of Application.

    Yes, the project is a Word 2013 and 2016 VSTO Template.

    Like you said, I was expecting all Word functionalities to be available without having to import anything, but that does not seem to be the case.

    I already recreated this project 3 times as it is basically a simple transfer from a VBA project to an Add-in, but it is not straight forward at all.

    I truly appreciate your support and advice.
    Thursday, October 4, 2018 1:52 PM
  • In the Form, you *ought* still to be able to do this:

    Dim myLang as Word.Language

    because the relevant references are already in the project as a whole. But there is no harm in going to Project->Add Reference... and looking in the Assemblies ->Extensions section, where you should see several Word-related assemblies checked. (Things may be slightly different depending on your version of VS).

    As you say, Me. won't work in there, but in a VSTO Addin you should be able to use

           For Each MyLang In Globals.ThisAddIn.Application.Languages

    If you use intellisense, after typing Globals, ThisAddIn should be presented as an option. If it isn't, then I would guess that something has gone wrong in the project, but I could not say what that might be.

     

    Peter Jamieson

    • Marked as answer by Athlagan Thursday, October 4, 2018 4:31 PM
    Thursday, October 4, 2018 3:02 PM
  • Hello Peter,

    Thank you so much for this. It did the trick although MyAddIn was not to be found, I managed to get it to work (more or less) using:

    For Each MyLang In Globals.ThisDocument.ThisApplication.Languages

    There are still a few things to smooth out (such as removing (no proofing) and selecting the default language value, but this is already tremendous progress.

    Thank you ever so much.

    Kind regards

    Thursday, October 4, 2018 4:31 PM