4


2

C#を使用してアクティブなExcelワークブックからアクティブなシートを更新する方法は?

Excelのファイル名に関係なく、現在のドキュメントの現在のシートの値を更新したいと思います。

vb6.0でできること

Set AppExcel = GetObject(, "Excel.Application")
Set SheetExcel = AppExcel.ActiveWorkbook.ActiveSheet

どのように私はC#で同じことをしようとしていますか?

C#で同じことをする方法はありますか?

3 Answer


4


using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Reflection;

public class MyClass
{
    public static void Main()
    {
        object xlApp  = Marshal.GetActiveObject("Excel.Application");
        Type t = xlApp.GetType();

        t.InvokeMember("Quit", BindingFlags.InvokeMethod, null, xlApp, null);

    }
}

http://social.msdn.microsoft.com/Forums/en-US/vbgeneral/thread/71044a7d-5424-4c84-94d3-3b29f84b1d2f/ [こちら]の例に基づいてコードを変更しました。

そうは言っても、vb.netでコードを記述し(そして `GetObject`を使用)、C#のライブラリを使用できると思います。

OR

Microsoft.VisualBasic.dllを参照できます。 +そして、http://msdn.microsoft.com/en-us/library/microsoft.visualbasic.interaction.getobject.aspx [GetObject]を呼び出します。

編集:なぜあなたはそのようなものが必要なのですか? Excelアドインのヘルプを作成しませんか?

とにかくc#でコードを記述する必要がある場合は、http://msdn.microsoft.com/en-us/library/system.runtime.interopservices.marshal.releasecomobject.aspx [を使用して作成したCOMインスタンスのリリースに注意してください。 Marshal.ReleaseComObject]

EDIT2: `ActiveSheet`への参照を取得するには、次のように記述できます。

object sheet = t.InvokeMember("ActiveSheet", BindingFlags.GetProperty, null, xlApp, null);

繰り返しになりますが、このルートを使用しないでください。 + VB6でコードを記述して、必要なことを実行し、c#/ vb.netから呼び出します。


4


要するに、答えは、絶対に、はいです。

ただし、ご存じのとおり、「GetObject」を使用してユーザーの既存のExcelアプリケーションを取得する方法は、エラーが発生しやすくなります。 実行中のExcelアプリケーションが1つだけの場合、「GetObject」は正常に機能します。 ただし、現在開いているExcelアプリケーションが複数ある場合、「GetObject」関数から返されるExcelアプリケーションを制御することはできません。返されるExcelインスタンスは、必要なものではない場合があります。

Excelアプリケーション自体で実行されるマネージドCOMアドインの作成を検討することをお勧めします。したがって、「どの」Excelアプリケーションインスタンスが制御しているのかという問題はありません。 これを行うには、http://support.microsoft.com/default.aspx/kb/302901 [Visual C#.NETを使用してOffice COMアドインを構築する方法]の記事を参照することから始めます。

プロセスIDまたはメインウィンドウハンドル(a.k.a. 制御したいExcelアプリケーションインスタンスの「Hwnd」)、この正確なインスタンスにアクセスできます。 これを行う方法については、Andrew Whitechapelのテーマに関するディスカッションhttp://blogs.officezealot.com/whitechapel/archive/2005/04/10/4514.aspx [こちら]をご覧ください。 興味のあるセクションは、「Excelアプリケーションオブジェクトを取得するために、これが実行されます」という行から始まります。議論は少し複雑ですが、あなたが彼のコードに従って文字をたどると、説明どおりに機能します。

'GetObject’アプローチを進めたい場合、次のコード例では事前バインディングを使用して、現在実行中のExcelアプリケーションのアクティブシートを取得します。 コードモジュールの上部に「using Excel」=「using Excel = Microsoft.Office.Interop.Excel」および「using System.Runtime.InteropServices」があることを前提としています。

// Note:
// using System.Runtime.InteropServices;
// using Excel = Microsoft.Office.Interop.Excel;

Excel.Application excelApp =
    Marshal.GetActiveObject("Excel.Application");

object activeSheet = excelApp.ActiveSheet;

遅延バインディングを使用している場合、次のようになります。

// Note:
// using System.Runtime.InteropServices;

object excelApp =
    Marshal.GetActiveObject("Excel.Application");

object activeSheet =
    excelApp
        .GetType()
        .InvokeMember(
            "ActiveSheet",
            BindingFlags.GetProperty,
            null,
            excelApp,
            null);

お役に立てれば…​

フォローアップ返信:

_ こんにちは、私のロジックを実行している複数のExcelアプリケーションがある場合でも、現在強調表示されているアプリケーション、つまり現在アクティブな(フォーカスを持っている)アプリケーションを使用します。 _

ああ、あなたは言ったはずです…​ 元の質問では、VB 6.0から呼び出された `GetObject`メソッドの動作を複製したいと述べています。 そのため、ここで得た答えはすべてこれに正しく答えています。

ですから、まず、あなたが今求めていることは、VB 6.0の `GetObject`メソッドの能力をはるかに超えていることに留意してください。 これを実現するには、次のことが必要です。

  1. を呼び出して、アクティブなアプリケーションのウィンドウハンドルを取得します GetForegroundWindow Windows API関数。

  2. 現在実行中のすべてのExcelプロセスを経由して繰り返します Process.GetProcessesByName("Excel ")とhttp://msdn.microsoft.com/en-を比較しますus / library / system.diagnostics.process.mainwindowhandle.aspx [Process.MainWindowHandle]は、http://www.pinvoke.net/default.aspx/user32/GetForegroundWindowを使用して以前に取得したウィンドウハンドルに対する実行中のExcelプロセスごとに実行します。 html [GetForegroundWindow] API。 一致すると仮定すると、Excelアプリケーションが現在アクティブなアプリケーションであることを確認しました。 一致するものが見つからない場合、現在フォーカスされているExcelアプリケーションはないため、これをユーザーに報告することができます。

  3. アクティブなウィンドウが実行中のExcelであることを確認した後 アプリケーションでは、http://www.pinvoke.net/default.aspx/user32/GetForegroundWindow.html [GetForegroundWindow] APIを使用して取得したウィンドウハンドルを使用して、制御可能なExcelアプリケーションオブジェクトを取得できます。 これを行うには、Andrew Whitechapelの記事http://blogs.officezealot.com/whitechapel/archive/2005/04/10/4514.aspx[Shimmed Automationアドインでアプリケーションオブジェクトを取得]を参照してください。 「Excelアプリケーションオブジェクトを取得するために、これを実行します。」複雑なトピックですが、記事の説明は素晴らしく、コード例は完全に機能します。 ただし、あなたのケースでは、コードの最初の行 int hwnd =(int)Process.GetCurrentProcess()。MainWindowHandle;`を、以前に見つけたアクティブウィンドウのウィンドウハンドルに置き換えます。 つまり、次のようなものです: `int hwnd = theHwndOfTheActiveWindowYouFoundEarlier

これは消化するのに大変なことだと思いますが、これらの手順に従えばうまく動作します。 最も難しい部分はAndrew Whitechapelのコードですが、最初の行を変更する必要がある以外は、そのまま実行されます。 がんばろう!

  • Mike


2


以下は、Excelオートメーションを使用してActiveSheetにアクセスするサンプルコンソールアプリケーションです。

using Microsoft.Office.Interop.Excel;
using System.Reflection;

namespace ExcelAutomationConsole
{
    internal class Program
    {
        private static void Main(string[] args)
        {
            _Application excelApp = null;
            try
            {
                excelApp = new Application();
                excelApp.Visible = true;

                Missing missing = Missing.Value;
                excelApp.Workbooks.Add(missing);
                // or
                //excelApp.Workbooks.Open("file.xlsx", missing, missing, missing, missing,
                //                        missing, missing, missing, missing,
                //                        missing, missing, missing, missing,
                //                        missing, missing);

                Worksheet sheet = excelApp.ActiveWorkbook.ActiveSheet as Worksheet;
                Range r = sheet.Cells[1, 1] as Range;
                r.FormulaR1C1 = "Test";
            }
            finally
            {
                excelApp.Quit();
            }
        }
    }
}