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

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

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

TextBoxにエクセルのセルの番号を表示したい

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

■92775 / inTopicNo.1)  TextBoxにエクセルのセルの番号を表示したい
  
□投稿者/ じょこびっち (8回)-(2019/10/29(Tue) 14:53:27)

分類:[C#] 

取得した値をエクセルに書き込むプログラムを作りました。
書き込む時にNumericUpDownでそれぞれ行と列と指定して書き込みます。

しかし行1・列1ではわかりにくいと思い、新しくtextboxを作りReadOnlyで
現在指定しているのは"A1"と表示させたいのですがどうすればいいでしょうか?
現在は書き込む時だけNumericUpDownの値をみています。

private void buttonStart_Click(object sender, EventArgs e) {

dynamic cell;
cell = workBook.ActiveSheet.Cells(numericRow.Value, numericColumn.Value);
cell.Value = textString.Text;

}

説明がわかりにくければ追記します。よろしくお願いします。
引用返信 編集キー/
■92776 / inTopicNo.2)  Re[1]: TextBoxにエクセルのセルの番号を表示したい
□投稿者/ 魔界の仮面弁士 (2440回)-(2019/10/29(Tue) 15:34:26)
No92775 (じょこびっち さん) に返信
> 新しくtextboxを作りReadOnlyで
> 現在指定しているのは"A1"と表示させたいのですがどうすればいいでしょうか?
ユーザーに A1 方式で指定させるようにするのではなく、
入力は行番号・列番号方式のまま、それを (Label ではなく)TextBox に
A1 表記に変換して表示したいのですね。


(方法1) Excel.Range オブジェクトの Address プロパティに対して、
  「false, false, Excel.XlReferenceStyle.xlA1」を指定して変換する
http://blog.livedoor.jp/nanoris/archives/51872690.html

(方法2) 自前で計算して A1 表記の文字列に変換する
https://memo-c-sharp.blogspot.com/2015/09/excel.html
http://hanatyan.sakura.ne.jp/patio/read.cgi?mode=view2&f=319&no=17



> cell = workBook.ActiveSheet.Cells(numericRow.Value, numericColumn.Value);

Microsoft Excel をオートメーションで操作しているのだとすれば、
COM オブジェクトごとに変数に受け取り、使用後に Marshal.ReleaseComObject メソッドで
解放処理を行ったほうが良いでしょう。

※COM 操作でない方式(たとえば EPPlus や ReoGrid 等)を用いれば、
 解放処理の手間を省けるかもしれませんが…今から直すと
 コードの書き直しになってしまうので、省力化にはならないかも。
 https://webbibouroku.com/Blog/Article/epplus1
 https://reogrid.net/jp/features/


> しかし行1・列1ではわかりにくいと思い、
Excel の設定を A1 方式ではなく R1C1 方式にしておけば、
C# 側との対応がわかりやすくなるかも。
http://www.asahi-net.or.jp/~ef2o-inue/shiki/sub03_010_02.html
引用返信 編集キー/
■92781 / inTopicNo.3)  Re[1]: TextBoxにエクセルのセルの番号を表示したい
□投稿者/ 大谷刑部 (48回)-(2019/10/30(Wed) 10:47:35)
No92775 (じょこびっち さん) に返信
> 取得した値をエクセルに書き込むプログラムを作りました。
> 書き込む時にNumericUpDownでそれぞれ行と列と指定して書き込みます。
>
> しかし行1・列1ではわかりにくいと思い、新しくtextboxを作りReadOnlyで
> 現在指定しているのは"A1"と表示させたいのですがどうすればいいでしょうか?

AからZまでの26文字の文字コードは連続しているので、Aの文字コードとの差分を演算して、
26列目以内は1文字、それ以降は26で割って商と余りに分けて1文字目、2文字目を変換すればいけるはず。

ただし、VBはasc関数をchr関数があるので、手軽に実装できるが、C#オリジナルではこの関数は使えず、
int→char→stringの2段階キャストをやるイメージになるので、ロジックの可読性は落ちるかもしれません。

https://www.atmarkit.co.jp/ait/articles/0703/22/news139.html

↓C#でVBの関数を使えるようにすることは下記のようにすれば可能ですが、
https://www.atmarkit.co.jp/fdotnet/dotnettips/254vbfunc/vbfunc.html

そんなことするくらいならVBで書けよっていう人が多いと思うのであまりお勧めはしません。
弁さんの案も含め、あとは質問者さんの好み次第ですね。

引用返信 編集キー/
■92784 / inTopicNo.4)  Re[2]: TextBoxにエクセルのセルの番号を表示したい
□投稿者/ じょこびっち (9回)-(2019/10/30(Wed) 11:45:46)
魔界の仮面弁士さんの方法1を試しているのですが

>(方法1) Excel.Range オブジェクトの Address プロパティに対して、
>「false, false, Excel.XlReferenceStyle.xlA1」を指定して変換する
http://blog.livedoor.jp/nanoris/archives/51872690.html

しかし、「'System.__ComObject' に 'XlreferenceStyle 'の定義がありません」と出てしまいます。
恐らくおかしな値を入れてしまっているのだと思うのですが。。。

var no1 = workBook.ActivrSheet.Cells(numericRow.Value, numericColumn.Value);
textBox1.Text = no1.Address(false, false, excelApp.XlreferenceStyle.xlA1, false, null);

よろしくおねがいします。
引用返信 編集キー/
■92785 / inTopicNo.5)  Re[3]: TextBoxにエクセルのセルの番号を表示したい
□投稿者/ 大谷刑部 (49回)-(2019/10/30(Wed) 12:10:03)
No92784 (じょこびっち さん) に返信
> 魔界の仮面弁士さんの方法1を試しているのですが
>
> >(方法1) Excel.Range オブジェクトの Address プロパティに対して、
> >「false, false, Excel.XlReferenceStyle.xlA1」を指定して変換する
> >http://blog.livedoor.jp/nanoris/archives/51872690.html
>
> しかし、「'System.__ComObject' に 'XlreferenceStyle 'の定義がありません」と出てしまいます。
> 恐らくおかしな値を入れてしまっているのだと思うのですが。。。
>
> var no1 = workBook.ActivrSheet.Cells(numericRow.Value, numericColumn.Value);

なぜvarを使ってる?
素直にMicrosoft.Office.Interop.Excelを参照して、rangeオブジェクトで受けた方がいいと思いますけど。
実行環境にExcelインストールできないとかの制約条件がないのなら。
暗黙型変換も起きるし、そもそも好ましくない書き方と思いますが。

引用返信 編集キー/
■92787 / inTopicNo.6)  Re[3]: TextBoxにエクセルのセルの番号を表示したい
□投稿者/ 魔界の仮面弁士 (2442回)-(2019/10/30(Wed) 14:38:39)
2019/10/30(Wed) 14:52:03 編集(投稿者)

No92784 (じょこびっち さん) に返信
> 魔界の仮面弁士さんの方法1を試しているのですが


方法2 の実装例

public static string ToColumnAlphabet(int colNumber) {
  if (colNumber < 1 || 0x4000 < colNumber) { return null; }
  return ToColumnAlphabet((colNumber - 1) / 26) + (char)('A' + ((colNumber - 1) % 26));
}



>>「false, false, Excel.XlReferenceStyle.xlA1」を指定して変換する
> しかし、「'System.__ComObject' に 'XlreferenceStyle 'の定義がありません」と出てしまいます。

私が書いたのは、XlreferenceStyle ではなく XlReferenceStyle ですよ。


> textBox1.Text = no1.Address(false, false, excelApp.XlreferenceStyle.xlA1, false, null);

上記の「excelApp」というのは恐らく、
Microsoft.Office.Interop.Excel 名前空間の
Application クラスのインスタンスを持つ変数ですよね?

そのため上記は、Excel.Application オブジェクトの
XlreferenceStyle プロパティを指定していることになってしまっています。


先に述べた「XlReferenceStyle」はプロパティではなく、
Microsoft.Office.Interop.Excel 名前空間にある
XlReferenceStyle 列挙型のことです。xlA1 はその列挙値。
https://docs.microsoft.com/en-us/dotnet/api/microsoft.office.interop.excel.xlreferencestyle?WT.mc_id=DT-MVP-8907&view=excel-pia


もしも参照設定せずに dynamic 型で指定しているのであれば、
「Excel.XlReferenceStyle.xlA1」のかわりに
int 型の「1」を渡すことで、同じ意味になります。
引用返信 編集キー/
■92788 / inTopicNo.7)  Re[3]: TextBoxにエクセルのセルの番号を表示したい
□投稿者/ 大谷刑部 (50回)-(2019/10/30(Wed) 15:07:03)
No92784 (じょこびっち さん) に返信
> 魔界の仮面弁士さんの方法1を試しているのですが
>
> >(方法1) Excel.Range オブジェクトの Address プロパティに対して、
> >「false, false, Excel.XlReferenceStyle.xlA1」を指定して変換する
> >http://blog.livedoor.jp/nanoris/archives/51872690.html
>
> しかし、「'System.__ComObject' に 'XlreferenceStyle 'の定義がありません」と出てしまいます。
> 恐らくおかしな値を入れてしまっているのだと思うのですが。。。
>
> var no1 = workBook.ActivrSheet.Cells(numericRow.Value, numericColumn.Value);
> textBox1.Text = no1.Address(false, false, excelApp.XlreferenceStyle.xlA1, false, null);

↓excelApp.XlreferenceStyle.xlA1の代わりに定数の実値を入れてみて通りますか?
https://docs.microsoft.com/ja-jp/dotnet/api/microsoft.office.interop.excel.xlreferencestyle?view=excel-pia

通るようなら、定数の親にあたるクラスを認識できてないってことです。
引用返信 編集キー/
■92790 / inTopicNo.8)  Re[4]: TextBoxにエクセルのセルの番号を表示したい
□投稿者/ 大谷刑部 (51回)-(2019/10/30(Wed) 15:24:13)
> ■No92784 (じょこびっち さん) に返信
> もしも参照設定せずに dynamic 型で指定しているのであれば、
> 「Excel.XlReferenceStyle.xlA1」のかわりに> int 型の「1」を渡すことで、同じ意味になります。

有体に言えば、そういうことになります。
なので、XlReferenceStyleクラス、さらにその親玉のExcelアプリケーションオブジェクトが正常に参照できてるかが疑うとこですね。
なので、安易にvar型で宣言するのはやめた方がいいんです。

そもそも、弁さんの提示してくれたリンクのサンプルは

using Excel = Microsoft.Office.Interop.Excel;

でExcelのcomオブジェクトを使えるようにしておいて、その前提で書かれているので、
盲目的にvar型で受けて無条件に自動判別してすべてのオブジェクト、クラスが使えるかどうか保証の限りじゃないということなのだと思うのですけど。
イベントプロシージャでちゃんと型をキャストしてからじゃないとプロパティーが正常に使えなかったりすることがあるのと同等のことが懸念されるのですけど。

確実にすべてのメソッドとプロパティーを使用したいなら、汎用型でなく、しかるべきオブジェクトやクラスの型で宣言するのが王道と思います。
引用返信 編集キー/
■92791 / inTopicNo.9)  Re[4]: TextBoxにエクセルのセルの番号を表示したい
□投稿者/ じょこびっち (10回)-(2019/10/30(Wed) 15:38:59)
No92787 (魔界の仮面弁士 さん) に返信
> 2019/10/30(Wed) 14:52:03 編集(投稿者)
>
> ■No92784 (じょこびっち さん) に返信
>>魔界の仮面弁士さんの方法1を試しているのですが
>
>
> 方法2 の実装例

> 上記の「excelApp」というのは恐らく、
> Microsoft.Office.Interop.Excel 名前空間の
> Application クラスのインスタンスを持つ変数ですよね?
>
> そのため上記は、Excel.Application オブジェクトの
> XlreferenceStyle プロパティを指定していることになってしまっています。
>
>
> 先に述べた「XlReferenceStyle」はプロパティではなく、
> Microsoft.Office.Interop.Excel 名前空間にある
> XlReferenceStyle 列挙型のことです。xlA1 はその列挙値。
> https://docs.microsoft.com/en-us/dotnet/api/microsoft.office.interop.excel.xlreferencestyle?WT.mc_id=DT-MVP-8907&view=excel-pia

まさに「excelApp」が原因でした。
.Address[false, false, Excel.XlReferenceStyle.xlA1]
に直したら表示されました。

原因がわからず何をどうしたらいいかわからず迷走していましたがお二人のおかげでなんとかなりました。
魔界の仮面弁士さん、大谷刑部さん
ありがとうございました。またよろしくお願いします。
解決済み
引用返信 編集キー/
■92792 / inTopicNo.10)  Re[4]: TextBoxにエクセルのセルの番号を表示したい
□投稿者/ じょこびっち (11回)-(2019/10/30(Wed) 16:45:13)
No92788 (大谷刑部 さん) に返信
> ■No92784 (じょこびっち さん) に返信
>>魔界の仮面弁士さんの方法1を試しているのですが
>>
>>>(方法1) Excel.Range オブジェクトの Address プロパティに対して、
>>>「false, false, Excel.XlReferenceStyle.xlA1」を指定して変換する
>>>http://blog.livedoor.jp/nanoris/archives/51872690.html
>>
>>しかし、「'System.__ComObject' に 'XlreferenceStyle 'の定義がありません」と出てしまいます。
>>恐らくおかしな値を入れてしまっているのだと思うのですが。。。
>>
>>var no1 = workBook.ActivrSheet.Cells(numericRow.Value, numericColumn.Value);
>>textBox1.Text = no1.Address(false, false, excelApp.XlreferenceStyle.xlA1, false, null);
>
> ↓excelApp.XlreferenceStyle.xlA1の代わりに定数の実値を入れてみて通りますか?
> https://docs.microsoft.com/ja-jp/dotnet/api/microsoft.office.interop.excel.xlreferencestyle?view=excel-pia
>
> 通るようなら、定数の親にあたるクラスを認識できてないってことです。
引用返信 編集キー/
■92793 / inTopicNo.11)  Re[5]: TextBoxにエクセルのセルの番号を表示したい
□投稿者/ じょこびっち (12回)-(2019/10/30(Wed) 17:02:06)
すみません。どこに実装したらいいのでしょうか?
テスト中はとりあえず表示する事だけ考えており
ワークシートがアクティブになったタイミングで記述していたので
エクセル起動時だけ反映されることに気が付きました。

でも、そのタイミングだと上下ボタンを押しても反映されないことに気が付きました。
どこに実装したらいいのでしょう?

引用返信 編集キー/
■92794 / inTopicNo.12)  Re[6]: TextBoxにエクセルのセルの番号を表示したい
□投稿者/ 魔界の仮面弁士 (2443回)-(2019/10/30(Wed) 17:06:53)
2019/10/30(Wed) 20:08:29 編集(投稿者)

No92793 (じょこびっち さん) に返信
> すみません。どこに実装したらいいのでしょうか?

毎回、外部プロセスである Excel に計算させるのは手間なので、
この程度なら、C# 側で算出した方が手っ取り早いかと思います。
算出するためのコードの例は No92787 を参照してみてください。


No92790 (大谷刑部 さん) に返信
>>もしも参照設定せずに dynamic 型で指定しているのであれば、
>>「Excel.XlReferenceStyle.xlA1」のかわりに
> int 型の「1」を渡すことで、同じ意味になります。
> なので、XlReferenceStyleクラス、さらにその親玉のExcelアプリケーションオブジェクトが正常に参照できてるかが疑うとこですね。

ここでいう「参照」という表現が、インスタンスの参照のことを指しているのか
ライブラリの参照設定の話なのか曖昧だったので、一応補足しますと:

修正前の "excelApp" は、Excel の Application オブジェクトへの参照を示しますが、
修正後の "Excel" は、オブジェクトではなく名前空間を指定したものなので、
それ自体が特定のオブジェクトへの参照を示しているわけではないですね。
引用返信 編集キー/
■92800 / inTopicNo.13)  Re[6]: TextBoxにエクセルのセルの番号を表示したい
□投稿者/ 大谷刑部 (52回)-(2019/10/31(Thu) 09:50:11)
No92793 (じょこびっち さん) に返信
> ワークシートがアクティブになったタイミングで記述していたので
> エクセル起動時だけ反映されることに気が付きました。
「ActivrSheet」から取得すればそりゃそうなりますよ。
マクロ記録のコードを張り付けて使ってたりするとそうなりがちですが、
狙いのシートが固定なら、ちゃんとシートオブジェクトの変数を設定すれば済む話ですし、
シート名とかが可変ならば、ある程度シート名の規則を仕様として決めておいて、
for each ループでbookオブジェクト内を回して、狙いのシートを見つければよいだけです。

> でも、そのタイミングだと上下ボタンを押しても反映されないことに気が付きました。
これはどういうことですか?NumericUpDownコントロールの操作時点で反映したいという意味ですか?
であるならば、ValueChangedあたりで同じこと書けば制御はできると思いますが、
WinFormがいろいろイベント設定できるからと言って多用すれば、無限ループ回避等の整合性とるために、無駄なロジック増やすだけになるケースが世の中には散見されるので
(これはVB6の時代から同じ)
シンプルに、コマンドボタンクリック等で状態みて実施の方が不安定挙動が少ないロジックになると思います。

引用返信 編集キー/
■92806 / inTopicNo.14)  Re[7]: TextBoxにエクセルのセルの番号を表示したい
□投稿者/ じょこびっち (13回)-(2019/10/31(Thu) 12:01:48)
No92794 (魔界の仮面弁士 さん) に返信
> 2019/10/30(Wed) 20:08:29 編集(投稿者)
>
> ■No92793 (じょこびっち さん) に返信
>>すみません。どこに実装したらいいのでしょうか?
>
> 毎回、外部プロセスである Excel に計算させるのは手間なので、
> この程度なら、C# 側で算出した方が手っ取り早いかと思います。
> 算出するためのコードの例は No92787 を参照してみてください。

ありがとうございます。
教えていただいたコードを使用してアルファベット表示まではすぐに出来たのですが
他の問題にぶち当たって四苦八苦しております。

1.フォーム起動時にtextboxの中身が空白でNumericUpDownをクリックしてから表示されるので
これを起動時からA1と表示させたい。(デフォルトのvalueにはRow/Column共に1を入れてあります)

2.Row側のNumericUpDownの扱い。
下記のコードだと当然Column側を動かした時にしかRow側の値を取得しません。

private void numericColumn_ValueChanged(object sender, EventArgs e)
{
int intColumnVal = Decimal.ToInt32(numericColumn.Value);
textbox1.Text = ToColumnAlphabet(intColumnVal) + numericRow.Value.ToString();//これでいいの?
}
private void numericRow_ValueChanged(object sender, EventArgs e)
{
// ここはどうすれば?
}

たびたびの質問で申し訳ありませんがよろしくお願いします。
引用返信 編集キー/
■92807 / inTopicNo.15)  Re[8]: TextBoxにエクセルのセルの番号を表示したい
□投稿者/ 魔界の仮面弁士 (2444回)-(2019/10/31(Thu) 12:15:05)
No92806 (じょこびっち さん) に返信
> 1.フォーム起動時にtextboxの中身が空白でNumericUpDownをクリックしてから表示されるので
> これを起動時からA1と表示させたい。(デフォルトのvalueにはRow/Column共に1を入れてあります)

デザイン時に予め、TextBox の Text プロパティにも
"A1" と指定しておけば良いのでは? (そういうことではない?)


> 2.Row側のNumericUpDownの扱い。
> 下記のコードだと当然Column側を動かした時にしかRow側の値を取得しません。

private void numericColumn_ValueChanged(object sender, EventArgs e)
{
 UpdateAddress();
}
private void numericRow_ValueChanged(object sender, EventArgs e)
{
 UpdateAddress();
}
void UpdateAddress()
{
 int c = (int)numericColumn.Value;
 int r = (int)numericRow.Value;
 textBox1.Text = ToColumnAlphabet(c) + row.ToString();
}
引用返信 編集キー/
■92810 / inTopicNo.16)  Re[7]: TextBoxにエクセルのセルの番号を表示したい
□投稿者/ じょこびっち (14回)-(2019/10/31(Thu) 13:03:43)
あっさり出来ました。
ありがとうございました。
解決済み
引用返信 編集キー/

このトピックをツリーで一括表示


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

このトピックに書きこむ