2016-05-02 11 views
3

C#でWord VBAマクロをプラグインに変換しています。私がこれまでに成功したC#でのすべてのステートメント、メソッドとプロパティをリファクタリングしましたが、この1つは私の苦労を与えるC#でVBAを変換してもC#にループしますが、コンパイルエラーが発生します

For Each l In Application.Languages 
    If InStr(LCase(l.NameLocal), LCase(Language)) > 0 Then 
     Selection.LanguageID = l.ID 
     Exit For 
    End If 
Next l 

次のように私はC#で上記を変換した:

using Microsoft.Office; 
using Microsoft.Office.Interop; 
using Word = Microsoft.Office.Interop.Word; 

Word.Application oWord = new Word.Application(); 
Word.Document oWordDoc = new Word.Document(); 
var Selection = oWordDoc.ActiveWindow.Selection; 
string strTgtLanguage = "Hungarian"; 

foreach (var item in oWord.Application.Languages) 
{ 
      if (item.NameLocal.IndexOf(strTgtLanguage)>-1) 
//The error is ---^ here on 'NameLocal'. 
      { 
       Selection.LanguageID = item.ID 
//And here on 'ID' -----------------------^ 
       break; 
      } 
} 

両方のインスタンスのコンパイラエラーがある:

'object'に 'NameLocal'の定義が含まれておらず、 'ObjectL'の最初の引数を受け入れる拡張メソッド 'NameLocal'が見つかりませんでした(usingディレクティブまたはアセンブリ参照がありません)

私はここで間違っていますか?私はforeachステートメントがコレクションからobjectを正しく宣言したと思った。

ありがとうございます。

+0

、私はここに何かを参照してください信じていません。あなたのC#版の 'Application.Languages'はあなたのVB版のものと同じですか?彼らは同じ名前だと思うけど、彼らは同じタイプですか?それは何が間違っているように聞こえる。私は 'C言語で' oWord.Application.Languages'を参照してください、それはちょうど 'Application.Languages'でしょうか? –

+1

1つのエラー 'Selection.LanguageID = l.ID'は' Selection.LanguageID = item.ID'である必要があります – Mostafiz

+0

つまり、これは厳密には言語の問題ではないと思います。あなたは正しい構文を持っていて、あなたが期待していると考えて行動します。これはVBでも同様に問題になるので、あなたがそこに持っていたのと同じ方法でトラブルシューティングを行います。しかし、はい、Mostafizurのコメントも正しい - ちょうど2番目の誤植。 –

答えて

1

型名とvar itemを交換しなければなりません。

foreach (var item in oWord.Application.Languages)var可変itemと最初のケースでは foreach (Word.Language item in oWord.Languages)

と交換型System.Objectです。

ため、それぞれの完全な

のLINQは、次のようになります使用のための:-各

foreach (Word.Language item in oWord.Languages.Cast<Word.Language>() 
.Where(item => item.NameLocal.IndexOf(strTgtLanguage, StringComparison.Ordinal) > -1)) 
{ 
    selection.LanguageID = item.ID; 
    break; 
} 

または、例えばと交換することができますFirstOrDefault:あなたが明示的に反復変数を宣言する必要がありますので、

Word.Language hungarian = 
oWord.Languages.Cast<Word.Language>() 
.FirstOrDefault(item => item.NameLocal.IndexOf(strTgtLanguage, StringComparison.Ordinal) > -1); 

if (hungarian != null) 
    selection.LanguageID = hungarian.ID; 
+0

はローカル変数型の推論ではなく 'var item'であるため、コンパイラは文の右側に基づいて型を調べるでしょうか?言い換えれば、強く型付けされたコードではないのですか? – user3598756

+0

@ user3598756はい、 'foreach(var item in oWord.Application.Languages)'の場合、右側の型は 'object'なので' var'は 'object'に置き換えられます。 'foreach(Word.Language in oWord.Application.Languages)'という文は、キャストを行います。キャストは既に右側で行われているので、 'foreach(var item in oWord.Languages.Cast ())'で 'var 'を使用することができます。説明のために –

+0

ありがとう。私はVSでそれを確認することができたと思うが、私はそれではなく(まだではない!)、この 'var'のことはいつも私をぼやけさせる... – user3598756

2

エラーコードの場合、最初のエラーはあなたのoWord.Application.Languagesが実際にNameLocalというコレクションフィールドを返さないと思われます。

2つ目Selection.LanguageID = l.IDSelection.LanguageID = item.ID

1

LanguagesはIEnumerableをです。

IEnumerableの.Cast<>()メソッドを使用する場合は、.Any()関数にアクセスして、反復ループを自分で書くのを避けることができます。下記の

どちらのバージョン:Officeの相互運用ライブラリの知識がなくて言えば

using wd = Microsoft.Office.Interop.Word; 

wd.Application oWord = new wd.Application(); 
wd.Document oWordDoc = new wd.Document(); 
wd.Selection oWordSelection = oWordDoc.ActiveWindow.Selection; 

// foreach loop 
foreach (wd.Language item in oWord.Languages) 
{ 
    Console.WriteLine(item.ID); 
    if (item.NameLocal.IndexOf("Hungarian") > -1) 
    { 
     oWordSelection.LanguageID = item.ID; 
     break; 
    } 
} 

// linq 
if (oWord.Languages.Cast<wd.Language>().Any(lang => lang.NameLocal.IndexOf("Hungarian") > -1)) 
    oWordSelection.LanguageID = wd.WdLanguageID.wdHungarian; 
+0

'foreach'行に' wd'が型や名前空間ではないというコンパイラエラーが発生します。 – ib11

+0

私は 'wd = Microsoft.Office.Interop.Word'を使用しました。あなたのコードを見ると、 'word'を使ったと思うので、' wd'を 'word'に置き換えてください。 – Ambie

+0

これを 'wd = Microsoft.Office.Interop.Wordを使用してコードの先頭に追加するだけでいいのですか? – ib11

関連する問題