C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

Re[2]: C#でExcelシートに入力されている最終行を


(過去ログ 95 を表示中)

[トピック内 3 記事 (1 - 3 表示)]  << 0 >>

■56974 / inTopicNo.1)  C#でExcelシートに入力されている最終行を取得する
  
□投稿者/ C#入門者 (3回)-(2011/02/07(Mon) 23:56:59)

分類:[C#] 

・使用言語:C#
・使用ソフト:Visual Studio 2008 Pro
・内容:C#でExcelに接続後、フォームにあるボタンをクリックするとExcelシートに入力されている一番最後の行数を取得したい。

内容は先にした通りでございます。色々調べ、何とか取得できたのですが、もっと分かりやすい方法がありましたら教えてください。
*今回やりたいことは、VBAで言うところの MsgBox SheetName.Cells(65563, 1).End(xlUp).Row です。

・現在のコード
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Excel = Microsoft.Office.Interop.Excel; 

namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
      
        private void button2_Click_1(object sender, EventArgs e)
        {
            //Excel接続の各変数設定
            string ExcelFile;                               
            Excel.Application ExcelApp;     
            Excel.Workbook wb;
            Excel.Worksheet ws;
            Excel.Range rng;

            //接続開始
            ExcelFile = @"D:\test2.xls";
            ExcelApp = new Excel.Application();
            ExcelApp.Visible = false;
            
            wb = ExcelApp.Workbooks.Open(ExcelFile,
                Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing,
                Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing);
            ws = (Excel.Worksheet)wb.Sheets[1];
            
            ws.Select(Type.Missing);
      
      //★★問題の箇所★★現在のところ下記の2行で、値が入力されている最終行が取得できています。
            rng = ws.get_Range("A65536", ExcelApp.ActiveCell.get_End(Excel.XlDirection.xlUp));
            MessageBox.Show("最大Rowは" + (65536 - rng.Rows.Count + 1).ToString());
      
            wb.Close(false, Type.Missing, Type.Missing); 
            ExcelApp.Quit(); 
        }
    } 
} 

よろしくお願いいたします。

引用返信 編集キー/
■56977 / inTopicNo.2)  Re[1]: C#でExcelシートに入力されている最終行を取得する
□投稿者/ 魔界の仮面弁士 (2059回)-(2011/02/08(Tue) 03:20:36)
No56974 (C#入門者 さん) に返信
> ・内容:C#でExcelに接続後
Marshal.ReleaseComObject は?

> Excelシートに入力されている一番最後の行数を取得したい。
SpecialCells メソッドで xlCellTypeLastCell を指定すると言う手があります。
ただし、入力後に値を削除した後でも、以前の最終セルが返されます。

値を削除したセルを含めたくないなら、UsedRange プロパティを使ってみてください。


> *今回やりたいことは、VBAで言うところの MsgBox SheetName.Cells(65563, 1).End(xlUp).Row です。
それだと、一列目が未使用で、二列目以降からデータが記載されていたような場合に対応できないかと。


> wb = ExcelApp.Workbooks.Open(ExcelFile,
これだと、Workbooks の解放に問題が生じる可能性が高くなります。

COM を扱う際に、2つ以上の「.」が続くような記述は避けた方が良いかと思いますよ。
(名前空間を指定するための「.」は構いませんが)


> rng = ws.get_Range("A65536", ExcelApp.ActiveCell.get_End(Excel.XlDirection.xlUp));
Active〜系プロパティは多用しないようにしましょう。コードが曖昧になります。
引用返信 編集キー/
■57011 / inTopicNo.3)  Re[2]: C#でExcelシートに入力されている最終行を
□投稿者/ C#入門者 (4回)-(2011/02/09(Wed) 00:35:27)
2011/02/09(Wed) 20:23:03 編集(投稿者)
No56977 (魔界の仮面弁士 さん) に返信
早速のご指摘ありがとうございます。


>>・内容:C#でExcelに接続後
> Marshal.ReleaseComObject は?

まだ、調べていませんが、Excelを閉じてもプロセスに残ってしまうという事でしょうか?
これからちょっと調べてみます。


> 値を削除したセルを含めたくないなら、UsedRange プロパティを使ってみてください。
> 
>>*今回やりたいことは、VBAで言うところの MsgBox SheetName.Cells(65563, 1).End(xlUp).Row です。
> それだと、一列目が未使用で、二列目以降からデータが記載されていたような場合に対応できないかと。

UsedRange。VBAでも使えたのですね。調べて初めて分かりました。
ということで、★★問題の箇所★★の部分を以下のように書き直してみました。

rng = ws.UsedRange;
    MessageBox.Show(rng.get_End(Microsoft.Office.Interop.Excel.XlDirection.xlDown).Row.ToString() + ":" +
          rng.get_End(Microsoft.Office.Interop.Excel.XlDirection.xlToRight).Column.ToString());

こちらの方法で最後の行と列を取得してみました。また、やっているうちに以下でも取得できるようになりました。

int EndRow = ws.get_Range("A1",TypeMissing).get_End(Excel.XlDirection.xlDown).Row;

ただし、後者の場合、最初や途中に抜けているセルがあると、魔界の仮面弁士さんの
>それだと、一列目が未使用で、二列目以降からデータが記載されていたような場合に対応できないかと。
のご指摘どおり、対応できません。


>>wb = ExcelApp.Workbooks.Open(ExcelFile,
> これだと、Workbooks の解放に問題が生じる可能性が高くなります。 
> COM を扱う際に、2つ以上の「.」が続くような記述は避けた方が良いかと思いますよ。
> (名前空間を指定するための「.」は構いませんが)

知識不足のため、理解し切れていませんが、これから調べて見ようかと思います。
 
 
>>rng = ws.get_Range("A65536", ExcelApp.ActiveCell.get_End(Excel.XlDirection.xlUp));
> Active〜系プロパティは多用しないようにしましょう。コードが曖昧になります。

はい。その通りだと感じました。素人ながらVBAでもActiveCellは使わないようにしてました。


結果、何とか目的は達成できたと感じています。
しかし、「ここがおかしい!」等感じることがございましたら、大変恐縮ではございますが、
ご指摘お願いいたします。少し、日がたってから"解決済み"にしたいと思います。

解決済み
引用返信 編集キー/


トピック内ページ移動 / << 0 >>

このトピックに書きこむ

過去ログには書き込み不可

管理者用

- Child Tree -