web-dev-qa-db-ja.com

C#-1つのExcelワークシートを1つのブックから別のブックにコピーするにはどうすればよいですか?

あるワークブックから別のワークブックにワークシートをコピーする必要があり、少し行き詰まっています。前提は、いくつかのレポートのテンプレートを格納する「マスター」ワークブックがあり、特定のワークシートの空白のコピーを作成して、それを新しいワークブックに追加する必要があるということです。

これは私がこれまでに持っているものです:

private void CreateNewWorkbook(Tables table)
{
    Excel.Application app = null;
    Excel.Workbook book = null;
    Excel.Worksheet sheet = null;

    try
    {
        string startPath = System.IO.Path.GetDirectoryName(System.Diagnostics.Process.GetCurrentProcess().MainModule.FileName);
        string filePath = System.IO.Path.Combine(startPath, "sal1011forms.xls");
        Microsoft.Win32.SaveFileDialog sfd = new Microsoft.Win32.SaveFileDialog();

        app = new Excel.Application();
        book = app.Workbooks.Open(filePath);
        sheet = (Excel.Worksheet)book.Worksheets.get_Item((int)table + 1);

        sfd.AddExtension = true;
        sfd.FileName = table.ToString() + ".xls";
        sfd.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);

        if (sfd.ShowDialog() == true)
        {
            sheet.SaveAs(sfd.FileName);
        }
    }
    finally
    {
        if (book != null)
        {
            book.Close();
        }
        if (app != null)
        {
            app.Quit();
        }
        this.ReleaseObject(sheet);
        this.ReleaseObject(book);
        this.ReleaseObject(app);
    }
}

現在私が抱えている唯一の問題は、ワークシートで.Save()を呼び出すと、元のブックのすべてのワークシートが新しいブックに保存されることです。これを修正する方法についてのアイデアはありますか?

前もって感謝します、
Sonny

9
Sonny Boy

Sheet.Copy()メソッドを使用することもできます。

基本的に、Sheet.copyはシートをコピーし、同時に新しいブックを自動的に作成します。

Worksheets.get_Itemを呼び出した後、コードに次の行を追加してみてください。

//Copies sheet and puts the copy into a new workbook
sheet.Copy(Type.Missing, Type.Missing);

//sets the sheet variable to the copied sheet in the new workbook
sheet = app.Workbooks[2].Sheets[1];

Copy()関数のリファレンスもここにあります: MSDN Link

13
Slider345

これはやや遅い返信だと思いますが、私はこれにかなり苦労したので、他の誰かがこの問題を抱えているのを助けるために自分の解決策を投稿すると思いました。

何度も記入したいテンプレートシートがある:

    public void test()
    {

        Excel.Application excelApp;

        string fileTarget = "C:\target.xlsx";
        string fileTemplate = "C:\template.xlsx";
        excelApp = new Excel.Application();
        Excel.Workbook wbTemp, wbTarget;
        Excel.Worksheet sh;

        //Create target workbook
        wbTarget = excelApp.Workbooks.Open(fileTemplate);

        //Fill target workbook
        //Open the template sheet
        sh = wbTarget.Worksheets["TEMPLATE"];
        //Fill in some data
        sh.Cells[1, 1] = "HELLO WORLD!";
        //Rename sheet
        sh.Name = "1. SHEET";


        //Save file
        wbTarget.SaveAs(fileTarget);

        //Iterate through the rest of the files
        for (int i = 1; i < 3; i++)
        {
            //Open template file in temporary workbook
            wbTemp = excelApp.Workbooks.Open(fileTemplate);

            //Fill temporary workbook
            //Open the template sheet
            sh = wbTemp.Worksheets["TEMPLATE"];
            //Fill in some data
            sh.Cells[1, 1] = "HELLO WORLD! FOR THE " + i + ".TH TIME";
            //Rename sheet
            sh.Name = i + ". SHEET";

            //Copy sheet to target workbook
            sh.Copy(wbTarget.Worksheets[1]);
            //Close temporary workbook without saving
            wbTemp.Close(false);
        }

        //Close and save target workbook
        wbTarget.Close(true);
        //Kill excelapp
        excelApp.Quit();
    }
5
mortysporty

質問されてから1年以上経ちますが、この質問に答えたいと思います。私が開発しているプロジェクトでも同じ問題を抱えていたので、答えを見つけるのに少し時間がかかりました。私は最後に慣れていないので、C#の代わりにVB.NETコードを使用して投稿します。

これが取引です。Excelブック間でシートをコピーするには、1つのExcelアプリケーションオブジェクトのみを使用し、その単一のアプリケーションで両方のブックを開く必要があります。その後、既知のWorksheet.Copyメソッドを使用して、シートを指定するだけです。他のブックのシートの後または前にコピーされます。

Private Sub ThisWorkbook_Startup() Handles Me.Startup
    Me.Application.Workbooks.Open(filePath)
    Me.Application.Workbooks(2).Worksheets("Reporte"). _
          Copy(After:=Me.Application.Workbooks(1).Worksheets("Hoja1"))
    Me.Application.Workbooks(2).Close()
    Me.Application.DisplayAlerts = False
    Globals.Hoja1.Delete()
    Me.Application.DisplayAlerts = True
End Sub

この場合、使用しているExcelアプリケーションは、Excelワークブックプロジェクトを実行するアプリケーションですが、これも機能します。

Dim xlApp As New Excel.Application
Dim book1 As Excel.Workbook
Dim book2 As Excel.Workbook
book1 = xlApp.Workbooks.Open(filePath1)
book2 = xlApp.Workbooks.Open(filePath2)

book1.Worksheets("Sheet to be copied").Copy(After:=book2.Worksheets(1))

もちろん、Excelアプリケーションには両方のワークブックが表示されるため、コピーが終了した後、ソースワークブックを表示しない場合(または少なくともユーザーが何かを実行するのに十分な長さでない場合)は、ソースワークブックを閉じる必要があります。

xlApp.Workbooks(1).Close()

これは私がそれを行うことができる方法です、ユーザーは点滅する新しいワークブックがポップアップしてから閉じるのを見るでしょう、それは本当にきれいではありません、しかし今のところ私はそれを行う他の方法がわかりません(またはこのコピープロセスを-目に見える方法)

これがまだ価値があることを願っています。宜しくお願いします。

2
NickZucco