2016-09-07 3 views
3
excelFile.VBProject.VBComponents.Add(vbext_ComponentType.vbext_ct_StdModule); 

英語版のOfficeのこのコードは、「Module1」という名前のモジュールを作成します。しかし、オフィス言語が異なる場合、「Module1」は別の言語になります。このモジュールが自分のコードでどのように呼び出されているか知る必要があります。C#Excel VBAのモジュール名が言語に依存しない

var standardModule = excelFile.VBProject.VBComponents.Item("ThisWorkbook");  

Office "ThisWorkbook"の英語版でも同じ問題が発生しますが、別の言語では別の言語で呼び出されます。

この言語を独立させることは可能ですか?

+0

どのようなオブジェクトタイプ "はThisWorkbook" とは?ワークブックまたはモジュール?編集:また、インデックスでアクセスできませんか?インデックス番号は変わるでしょうか? – Innat3

+0

@ Innat3現在のVBAプロジェクトのコードを含むホスト文書を表すグローバルな「Workbook」インスタンスです。 –

+0

それは意味を成しません、ホスト文書はすでに変数 "excelFile"、私は信じて、あなたが "ThisWorkbook"という名前でモジュールを検索しようとしている – Innat3

答えて

2

最初は簡単です - VBComponents.AddVBComponentを返します。あなただけの.Nameプロパティを調べることができます。

var module = excelFile.VBProject.VBComponents.Add(vbext_ComponentType.vbext_ct_StdModule); 
Debug.WriteLine(module.Name); 

秒1は少しトリッキーです。すべてのVBComponentsをループし、Workbookオブジェクトに固有の2つのものをテストする必要があります。これは、デフォルトではその.Propertiesコレクション内.Typevbext_ct_Documentのと134の特性を持っています:

VBComponent thisWorkbook; 
foreach (var module in excelFile.VBProject.VBComponents) 
{ 
    var test = module as VBComponent; 
    if (test.Type == vbext_ComponentType.vbext_ct_Document && 
     test.Properties.Count == 134) 
    { 
     thisWorkbook = test; 
     Debug.WriteLine(thisWorkbook.Name); 
     break; 
    } 
} 

EDIT: LINQのソリューションは、このように見えますが、それはあなたがこのようダングリング相互運用機能の参照を残す可能性があります。あなたはそれを試してみたい場合は、それは傷つけることはできません - しかし、Excelが正常にシャットダウンしない場合、それは私が見たい最初の場所のようになります。

var thisWorkbook = 
    (excelFile.VBProject.VBComponents).Cast<VBComponent>() 
     .First(x => x.Type == vbext_ComponentType.vbext_ct_Document && 
        x.Properties.Count == 134); 

EDIT2:としては@Matによって指摘'sMugのコメントでは、プロパティの数はバージョンに固有です。上記の値はおそらくExcel 2013に固有の値です。新しいワークブックの場合、ThisWorkbookモジュールは最も高いプロパティカウントを持つモジュールになります。これは、すべてのバージョンで動作するはずです:

VBComponent thisWorkbook = null; 
foreach (var component in excelFile.VBProject.VBComponents.Cast<VBComponent>()) 
{ 
    if (thisWorkbook == null || component.Properties.Count > thisWorkbook.Properties.Count) 
    { 
     thisWorkbook = component; 
    } 
} 
Debug.WriteLine(thisWorkbook.Name); 

のLINQ:

var thisWorkbook = 
    excelFile.VBProject.VBComponents.Cast<VBComponent>() 
     .Aggregate((p, x) => (p.Properties.Count > x.Properties.Count ? p : x)); 
+0

ああ、どういうわけか私はOPが「ThisWorkbook」を検索する方法を求めていることに気付いていませんでした。いい答え! =) –

+1

すべての既知のバージョンのExcelではプロパティのカウントは134ですか? –

+1

@ Mat'sMug - 今言いましたが、私は実際それを疑うでしょう。それはバージョンごとに固定する必要があります。 134は2013年の値です(ワークシートは66 BTW)。おそらく、 'vbext_ct_Document'型の' VBComponent'をすべて取得し、 'Properties.Count'でグループ化し、最も高いプロパティーカウントで結果を取得するのが最善でしょう。新しいワークブックについては、これは安全な前提です。 – Comintern

-1

あなたは自分のコード内でそのモジュールを追加したので、それはこのようにそれを実行してづけしなければなりません、最後のインデックス位置にする必要があります:

VBComponent ModuleIJustAdded = excelFile.VBProject.VBComponents.Item(excelFile.VBProject.VBComponents.Count - 1); 

あなたは、モジュールの名前がわからないので、私はあなたを示唆インデックスの周りを試してみてください。

4
excelFile.VBProject.VBComponents.Add(vbext_ComponentType.vbext_ct_StdModule); 

VBComponents.Addだけを添加したオブジェクトを返す、機能である - しかし、あなたはその参照を破棄しています。

あなたがする必要があるのは、その参照を保持することです:

var component = excelFile.VBProject.VBComponents.Add(vbext_ComponentType.vbext_ct_StdModule); 

そして、あなたは(ただし、親プロジェクト内で一意でなければなりません)の意志でそれを名前を変更することができます

component.Name = "RenameMe"; 

...またはその名前を知る必要がある場合は、すぐに読むことができます:

Debug.WriteLine(component.Name); 
関連する問題