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

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

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

Re[8]: エクセル出力した後に TAB化とグラフ化


(過去ログ 141 を表示中)

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

■82672 / inTopicNo.1)  エクセル出力した後に TAB化とグラフ化
  
□投稿者/ HARE (1回)-(2017/01/26(Thu) 09:54:57)

分類:[VB.NET/VB2005 以降] 

こんにちは、業務でプログラムを作っているものです

現在、いきづまって全くわからないので
教えてください。

現在、VBのデータを エクセルへ出力してるのですが
毎日データ保存していて

保存を日付で管理しています

例: 20170126

毎日、17:10になると
自動でLabel Text の数値を保存している動作になります

'システムを終了させエクセルへ出力する
If 1710 <= hm And hm < 1711 Then

'エクセルへの書き込みメソッド====

Dim ExcelApp As New Excel.Application 'エクセルを宣言する
Dim Book As Workbook

'ワークブックの宣言
Book = ExcelApp.Workbooks.Add '新しいワークブックを追加


'セルに「指定数」を入力
Book.Worksheets(1).Range("A1") = Date.Now.ToString("yyyy/MM/dd (ddd)")
Book.Worksheets(1).Range("A2") = "本日の記録"
Book.Worksheets(1).Range("A4") = "記録名"
Book.Worksheets(1).Range("B4") = "記録数"
Book.Worksheets(1).Range("A5") = "A"
Book.Worksheets(1).Range("B5") = Label19.Text
Book.Worksheets(1).Range("A6") = "B"
Book.Worksheets(1).Range("B6") = Label20.Text
Book.Worksheets(1).Range("A7") = "C"
Book.Worksheets(1).Range("B7") = Label13.Text
Book.Worksheets(1).Range("A8") = "D"
Book.Worksheets(1).Range("B8") = Label16.Text
Book.Worksheets(1).Range("A9") = "E"
Book.Worksheets(1).Range("B9") = Label12.Text


Book.Worksheets(1).Range("D4") = "合計数値"
Book.Worksheets(1).Range("D5") = Label59.Text
Book.Worksheets(1).Range("D7") = "合計時間"
Book.Worksheets(1).Range("D8") = Label61.Text

Book.Worksheets(1).Range("D1") = "作業者名"
Book.Worksheets(1).Range("E1") = Label63.Text



ExcelApp.Visible = False 'エクセルの表示をしない



'出力エクセルを保存=====
'名前をつけて保存(デフォルト日付)

Dim FilePath As String
FilePath = System.IO.Path.Combine( _
Environment.GetFolderPath(Environment.SpecialFolder.Desktop), _
"\\VBfile01\●記録データ\管理", _
Format(Now, "yyyyMMdd") & ".xlsx")
Book.SaveAs(FilePath)

Book.Close()

これだと、1ファイル生成で日付で管理はしていますが

月をまとめて見たいとき、1ファイルごと見ないといけないので

1月というファイルに
日付でシートを作りたいです


あと、合計時間 と 合計数値を自動でグラフ化を日ごとに生成させたい
これは、毎日の時間と数値を日ごとにグラフが増えていき

推移をみるためです

どうやって

@エクセルをシートで1つにまとめる
Aグラフを生成

教えてください
よろしくお願い致します。



引用返信 編集キー/
■82673 / inTopicNo.2)  Re[1]: エクセル出力した後に TAB化とグラフ化
□投稿者/ 魔界の仮面弁士 (1080回)-(2017/01/26(Thu) 10:45:33)
No82672 (HARE さん) に返信
> Book.Worksheets(1).Range("A2") = "本日の記録"
Excel オブジェクトの扱いに色々問題を抱えていそうなコードですね…。
本題からは外れてしまうので、修正例などについては下記に任せますが。
http://hanatyan.sakura.ne.jp/vb2005/vb2013excel01.htm



> 1月というファイルに
> 日付でシートを作りたいです
新規にワークブックを作成するなら Workbooks.Add ですが、
既存ワークブックを開くのであれば Workbooks.Open です。

新規にシートを作成するには、Worksheets.Add です。
作成後、そのシートの Name プロパティを日付文字列に変更しましょう。

初月に月末までのシートを用意しておいても良いでしょうし、
毎日 1 シートずつ増やしていく方式でも良いでしょうね。


なお、新規ワークブックを作成する際の初期シート数は
SheetsInNewWorkbook プロパティにて調整できます。



> あと、合計時間 と 合計数値を自動でグラフ化を日ごとに生成させたい
まず、手動でグラフを作ってみてください。

それが出来たら、その手順を Excel の
[開発]リボンの「マクロの記録」で、VBA に起こせば
VB.NET への移植時のヒントになると思いますよ。

※[開発]タブは、既定で非表示になっています。
https://support.office.com/ja-jp/article/e1192344-5e56-4d45-931b-e5fd9bea2d45



-- 以下蛇足 --

> If 1710 <= hm And hm < 1711 Then

hm の型は何でしょうか?

小数を扱える型だとしたら、And ではなく
AndAlso を使った方が良いと思います。

整数型(As Integer など)だとしたら、処理としては
 If 1710 = hm Then
が妥当かと思います。

あるいは hm As String なのだとしたら、
1710 ではなく "1710" と比較すべきですね。




> FilePath = System.IO.Path.Combine( _
> Environment.GetFolderPath(Environment.SpecialFolder.Desktop), _
> "\\VBfile01\●記録データ\管理", _
> Format(Now, "yyyyMMdd") & ".xlsx")

ここでは、「Now」だけで日時を取得しているのに、

> Book.Worksheets(1).Range("A1") = Date.Now.ToString("yyyy/MM/dd (ddd)")

ここでは「Date.Now」にしているのは何故でしょうか?
コードに対象性が無いため、雑多というか、コードを切り貼りしているような印象を受けます。


「Date.Now」は、Date 型(= System.DateTime 構造体)の Now プロパティを意味し、
「Now」だけだと、Microsoft.VisualBasic.DateAndTime モジュールの Now プロパティを意味します。

※ちなみに、VBA での「Now」は、VBA.DateTime モジュールの Now プロパティを意味します。
引用返信 編集キー/
■82703 / inTopicNo.3)  Re[2]: エクセル出力した後に TAB化とグラフ化
□投稿者/ HARE (2回)-(2017/01/30(Mon) 11:24:58)
No82673 (魔界の仮面弁士 さん) に返信

お返事遅れました ありがとうございます
まだ、初めて1年ほどで、ダメダメですので。。
ご指摘ありがとうございます。

直せる所は直していきます!


>>新規にワークブックを作成するなら Workbooks.Add ですが、
既存ワークブックを開くのであれば Workbooks.Open です。

新規にシートを作成するには、Worksheets.Add です。作成後、そのシートの Name プロパティを日付文字列に変更しましょう。
初月に月末までのシートを用意しておいても良いでしょうし、毎日 1 シートずつ増やしていく方式でも良いでしょうね。<<

そうです、特に毎日1シートずつ追加してくやつが
やりたいんですが
調べても調べてもわからず
ここに質問しました。

>>まず、手動でグラフを作ってみてください。

それが出来たら、その手順を Excel の
[開発]リボンの「マクロの記録」で、VBA に起こせば
VB.NET への移植時のヒントになると思いますよ。

※[開発]タブは、既定で非表示になっています。<<



やはりVBAでまずはですか
それをやったんですが、できなくて。。





引用返信 編集キー/
■82704 / inTopicNo.4)  Re[3]: エクセル出力した後に TAB化とグラフ化
□投稿者/ 魔界の仮面弁士 (1092回)-(2017/01/30(Mon) 13:45:35)
2017/01/30(Mon) 13:45:52 編集(投稿者)

No82703 (HARE さん) に返信
> そうです、特に毎日1シートずつ追加してくやつが
> やりたいんですが

どこまでできていて、どこが分からないのかを明確にしてみて下さい。

(1) 今日が何日かを取得する方法は分かりますか?
(2) その日付から "201701.xlsx" という文字列や "20170128" という文字列を作れますか?
(3) "201701.xlsx" というファイルが存在するかどうかを判断するコードを書けますか?
(4) ファイルがあればそれを開き(Workbooks の Open メソッド)、
 ファイルが無ければ作成する(Workbooks の Add メソッド)コードを書けますか?
(5) 開いたワークブック上の Worksheets コレクションを列挙し、各シートの名前を列挙できますか?
(6) 列挙したシート名の中に、"20170128" という名前のシートがあるかどうかを判断できますか?
(7) 該当するシートが見つかればそのワークシートオブジェクトを取得し
 該当するシートが無ければ作成する(Sheets コレクションの Add メソッド)ことはできますか?
(8) 得られたシートに対し、Range プロパティでセルを指定してデータを書き込めますか?
(9) ワークブックの SaveAs メソッドを用いて、"201701.xlsx" というファイル名に上書き保存できますか?
(10) 処理完了後、Close メソッドでワークブックを閉じ、Quit メソッドで Exxel 本体を終了させられますか?


また、同じ日にもう一回同じプログラムを動作させた場合の動作も
考えておく必要がありますね。

たとえば、さらにもう 1 シート追加するのか、それとも
既存の追加済みシートの内容を上書きするのか、あるいは
該当日のシートを削除してからもう一度再作成するのか、
それとも、該当シートが既にあれば何もせずに終わるのかなど。



>> まず、手動でグラフを作ってみてください。
> やはりVBAでまずはですか
いえ。VBA ではなく、手動操作で、です。

Excel のどの機能を使って、どのようなグラフを作るのかが
明確になっていなければ、それをプログラムで指示することさえできませんよね。

その指示するためのコードが VBA なのか VB.NET なのかは、その後の話です。
引用返信 編集キー/
■82705 / inTopicNo.5)  Re[4]: エクセル出力した後に TAB化とグラフ化
□投稿者/ HARE (3回)-(2017/01/30(Mon) 15:17:03)
No82704 (魔界の仮面弁士 さん) に返信
> 2017/01/30(Mon) 13:45:52 編集(投稿者)

>どこまでできるか??

エクセル保存はできるので、やれてはいますが
実際理解してるかといわれれば自信はありません

お手数ではありますが
(1)〜(10)まで教えて頂けると
勉強になります

ちなみ、時間指定で最後に1回だけ書き込み保存
しているので
一月のファイル⇒ファイル内のシートを日ごとに
保存追加

>vbaじゃない
そういうことですか
まだまだ勉強不足ですね。。

引用返信 編集キー/
■82708 / inTopicNo.6)  Re[5]: エクセル出力した後に TAB化とグラフ化
□投稿者/ 魔界の仮面弁士 (1093回)-(2017/01/30(Mon) 17:48:40)
2017/01/30(Mon) 17:49:56 編集(投稿者)

No82705 (HARE さん) に返信
> お手数ではありますが
> (1)〜(10)まで教えて頂けると

本当に全部の説明をした方が良いのですか?


分からないのが一部の手順だけなのであれば、分かっている範囲を端折って解説できますので、
分からない手順に絞って質問して頂けると助かります。

少なくとも、提示した手順のうちの幾つかは HARE さん自身で提示されたコードそのままを
手順として示したものですから、まったく分からないほどでも無いだろうと思っていたのですが…。
教えるのは吝かでないのですが、どこから説明するべきなのか思いあぐねています。


もし本当に、一から十まで教わらないと組めないほどの状況なのだとしたら、
回りくどいようですが、コーディングを始めるのはもう少し待ってください。
提示した「手順」を把握してからにしましょう。


自身の書いたコードにさえ自信が持てないのなら、他者のコードを解析するどころでは無いので、
単純にサンプルコードを提示するだけでは解決できません。
動作しているものを切り貼りして、トライ&エラーで組み上げていったとしても、
一応は動作するものの、保守できる自信が無いという曖昧なプログラムになってしまいますから。


いずれにせよ、まずはどこが分からないのか把握しないと、
掲示板のやり取りだけで進めていくのは困難です。


ということで、こちらからのお願いです。

保存処理を書けているのなら、そこそこ分かっている範囲もあろうかと思いますし、
No82704 で示した手順の中で、分からない点に絞って質問してみてもらえないでしょうか。

VB のコードに置き換える方法が分からない、といった直接的な点だけでなく、
手順に書かれている作業の文章の「意味」が分からない、といった疑問や、
何故この手順が必要なのか「意図」が分からない、といった質問でも構いません。




> エクセル保存はできるので、やれてはいますが
> 実際理解してるかといわれれば自信はありません


もし No82704 の手順の意図を把握することすら難しそうであれば、御自信が
No82672 で書かれた元コードについて、「自信が無い」という部分を教えてください。


本題とは外れる所も出てくるかもしれませんが、もしかしたら、
曖昧な点をクリアにしてから次に進めた方が、理解が進むかもしれませんので。


---

たとえば、冒頭の System.IO.Path.Combine の意図や使い方は把握されているでしょうか。
渡している引数の内容を見るかぎりでは、適切な使い方では無さそうですが…。


HARE さんのせいではなく、前任者の所為なのかもしれませんが、
Now の使い方が統一されていないあたりからして、理解して書きおこしたというよりも
サンプルを集めて貼りあわせただけという印象を受けましたし(失礼な物言いでごめんなさい)、
ラベル名がきちんと命名されていない(順番にすらなっていない)点も
保守性の面からして、業務プログラムにしては中途半端な印象を受けました。
引用返信 編集キー/
■82709 / inTopicNo.7)  Re[6]: エクセル出力した後に TAB化とグラフ化
□投稿者/ HARE (4回)-(2017/01/30(Mon) 18:06:19)
No82708 (魔界の仮面弁士 さん) に返信

>お察しの通り
実は、前任者が作ったプログラムでして
直しても、よくわからないコードが多いんですw

そこでまだ未熟な自分に直せいわれて
困ってたんですね。。


独学で1年勉強した程度なので
初心者レベルです

特に、エクセル書き込み、読み込みなどは
正直わかりません

5〜10が特にわかりません
お手数掛けて申し訳ないです。


引用返信 編集キー/
■82712 / inTopicNo.8)  Re[7]: エクセル出力した後に TAB化とグラフ化
□投稿者/ 魔界の仮面弁士 (1094回)-(2017/01/30(Mon) 22:00:58)
No82709 (HARE さん) に返信
> 独学で1年勉強した程度なので
> 初心者レベルです

入門者レベルで無いのなら大丈夫ですよ……多分?

ただ、Excel を扱うのであれば、一つ注意しておきたい事があります。

No82672 に書かれていた
>> Book = ExcelApp.Workbooks.Add '新しいワークブックを追加
>> Book.Worksheets(1).Range("A1") = Date.Now.ToString()
といったコードをそのまま実行すると、処理が終わった後も、タスクマネージャーに
非表示の Excel.exe が残ったままになってしまうことがあります。

これを回避するためには、下記のような「オブジェクト解放」の処置が必要です。
直ぐには理解できないかもしれませんが、分からなくても良いので目を通しておいてください。
http://hanatyan.sakura.ne.jp/dotnet/Excelflm.htm



> 特に、エクセル書き込み、読み込みなどは
> 正直わかりません

簡潔にまとめるのが苦手なので、どこから説明すれば良いのか悩みますが、
まず、Excel オブジェクトの階層関係は御存知でしょうか。


基本となるのはこのあたりです。(他にも多数のオブジェクトがありますが)

Applicaion オブジェクト
┗Workbooks コレクション/Workbook オブジェクト
 ┗Sheets(Worksheets) コレクション/Worksheet オブジェクト
  ┗Range オブジェクト


===============
【Application オブジェクト】
---------------
起動した一つ一つの Excel.exe が、Application オブジェクトに該当します。

一つの Excel.Application 上で、複数のブックを開くことも、
それぞれのブックごとに個別の Excel.Application を起動することもできますが、
「別フォルダーにある同名ファイル」を開く際、具体例を出すなら
 \\VBfile01\●記録データ\管理\201612\30.xlsx
 \\VBfile01\●記録データ\管理\201701\30.xlsx
という 2 ファイルを同時に開くような場合は、Application オブジェクトが
複数必要になりますので御注意下さい。

これはプログラムを用いず、手動で開く場合も同様であり、
同名ファイルを開こうとした場合で警告メッセージが表示されます。
(Excel.exe を二つ起動してからであれば個別に開けます)


このオブジェクトを使うには、
 Dim ExcelApp As Excel.Application
という変数を宣言しておき、
 ExcelApp = New Excel.Application()
のように、New でインスタンス化してセットします。

あるいはこの 二行をまとめて、
 Dim ExcelApp As Excel.Application = New Excel.Application()
もしくは
 Dim ExcelApp As New Excel.Application()
と書くこともあります。 No82672 のコードはコレですね。
既定で非表示になっていますので、必要に応じて .Visible = True にしておきます。

もし、エクセルを 2 つ開きたいのなら、それぞれ New が必要なので、
管理用の変数も 2 つ用意するなどして対処します。



なお、プログラムから起動するのではなく、起動済みの Excel インスタンスを
取得することもできますが、今回は使わないと思いますので説明を省略します。


===============
【Workbook オブジェクト】
---------------

No82672 にて、
> Book = ExcelApp.Workbooks.Add '新しいワークブックを追加
というコードを書いていましたが、これは Excel でいうと、
[Ctrl]+[N] を押した状態(空白のブックを新規作成)に合致します。

それに対し、既存のファイルを開く処理、たとえばエクスプローラーで
既存の Book1.xlsx を右クリックして「開く」を選択するような動作では、
 Book = ExcelApp.Workbooks.Open("C:\Folder1\Book1.xlsx")
といったコードになります。



一方、Book1.xlsx を右クリックして「新規作成」を選択するような動作では、
 Book = ExcelApp.Workbooks.Add("C:\Folder1\Book1.xlsx")
です。これは、既存のファイルをテンプレートとして作成するようなときに使います。
(テンプレートが不要な場合は、最初のコードどおり、引数なしで構いません)

このようなテンプレートを目的としたブックの場合、拡張子は
*.xls や *.xlsx ではなく、*.xlt や *.xltx とするのが一般的です。


あらかじめ、31 枚のシートを含んだテンプレートファイルを用意しておき、
それを毎月初日に Workbooks.Add で「新規作成」し、以降の日付では
Workbooks.Open で開くというのも良いかもしれません。

テンプレート側にフォントや文字色などをあらかじめセットしておけば、
データ出力処理の際の二次加工の手間を省けますね。



ただし、これらの ExcelApp.Workbooks.Open や ExcelApp.Workbooks.Add といった記述は、
先の URL で紹介した「オブジェクト解放」という面からみると、あまり望ましくはありません。

本来は、
 Books = ExcelApp.Workbooks
 Book = Books.Open("C:\Folder1\Book1.xlsx")
のように、Workbooks 変数も事前に用意して保持しておき、使用後に
 System.Runtime.InteropServices.Marshal.ReleaseComObject(Book)
 System.Runtime.InteropServices.Marshal.ReleaseComObject(Books)
 System.Runtime.InteropServices.Marshal.ReleaseComObject(ExcelApp)
のように、「ReleaseComObject メソッド」で後始末した方が丁寧です。
引用返信 編集キー/
■82713 / inTopicNo.9)  Re[7]: エクセル出力した後に TAB化とグラフ化
□投稿者/ 魔界の仮面弁士 (1095回)-(2017/01/30(Mon) 22:01:39)
No82709 (HARE さん) に返信
> 5〜10が特にわかりません
> お手数掛けて申し訳ないです。

さて、ここからが本題。

今回の場合、「時間指定で最後に1回だけ書き込み保存」とのことなので、
手順 5 、6 による、シートの存在確認は省略しても良さそうなので、
最初に 7 から説明しておきます。


===============
【シート オブジェクト】
---------------

Excel で扱えるシートは 5 種類あるのですが、もっとも良く使われるのが
ワークシート用の「Worksheet」オブジェクトですね。
グラフ専用シートであれば、「Chart」オブジェクトです。


これらを新規作成する場合は、
  newWorksheet = Book.Worksheets.Add()
  newChart = Book.Charts.Add()
のように、Worksheets コレクションや Charts コレクションの Add メソッドを呼び出すか、
  newSheet = Book.Sheets.Add(Type:=Excel.XlSheetType.xlWorksheet)
のように、Type 引数にシートタイプを指定して呼び出すようにします。

Add メソッドの引数には、シートタブが追加される位置を指定することもできます。


なお、これら Add メソッドの戻り値は As Object になっていますので、
Worksheet 型や Chart 型などの変数に受け取るのであれば、
DirectCast を使ってキャストするようにします。


そしてこれが、
>> (7) 該当するシートが見つかればそのワークシートオブジェクトを取得し
>> 該当するシートが無ければ作成する(Sheets コレクションの Add メソッド)ことはできますか?
の手順ということになります。



===============
【コレクション オブジェクト】
---------------

最初のコードでは、 Book.Worksheets(1) のように番号固定で呼び出していたようですが、
Book.Sheets("Sheet1") のように、名前を指定することもできます。

また、Worksheets や Sheets コレクションを For や For Each で列挙することで、
追加されているシートの一覧を列挙ことができます。

たとえば、
 For idxSheet As Integer = 1 To Book.Worksheets.Count
  MsgBox( Book.Worksheets(idxSheet).Name )
 Next
とか、
 For Each oSheet As Excel.Worksheet In Book.Worksheets
  MsgBox( oSheet.Name )
 Next
といった具合です。


そしてこれが
>> (5) 開いたワークブック上の Worksheets コレクションを列挙し、各シートの名前を列挙できますか?
の手順に相当します。


上記では、シート名を「MsgBox で表示」しているわけですが、
それを「If ステートメント」での判定に置き換えれば、
>> (6) 列挙したシート名の中に、"20170128" という名前のシートがあるかどうかを判断できますか?
も実装できるかと思います。

たとえば、こんな感じですかね。

  Dim todaySheet As Excel.Worksheet = Nothing
  Dim oSheets As Excel.Sheets = Book.Worksheets
  For Each oSheet As Excel.Worksheet In oSheets
    If oSheet.Name = "20170128" Then
      todaySheet = oSheet '発見したシートを変数にセット
      Exit For
    End If
  Next

  If todaySheet Is Nothing Then
    ' 見つからなかったので、新規シートを追加
    todaySheet = DirectCast(oSheets.Add(), Excel.Worksheet)
    ' 新規シートに名前を指定
    newWorksheet.Name = "20170130"
  End If

Name プロパティをセットする際は、シート名に使えない文字(「/」「\」「:」「?」等々)を
含めたり、既存のシート名と重複する名前を指定しないよう御注意を。
引用返信 編集キー/
■82714 / inTopicNo.10)  Re[7]: エクセル出力した後に TAB化とグラフ化
□投稿者/ 魔界の仮面弁士 (1096回)-(2017/01/30(Mon) 22:12:01)
No82709 (HARE さん) に返信
> 5〜10が特にわかりません
> お手数掛けて申し訳ないです。

連続長文になりましたが、最後の 8〜10 について。


===============
【Range オブジェクト】
---------------

>> (8) 得られたシートに対し、Range プロパティでセルを指定してデータを書き込めますか?

既に御存知と思いますが、Worksheet オブジェクトでは、
個々のセルやセル範囲を Range オブジェクトとして扱います。

たとえば、
  todaySheet.Cells(1, 2).Value = "本日の記録"
とか、
  todaySheet.Range("A2").Value = "本日の記録"
といった具合です。
Cells プロパティや Range プロパティで、Range オブジェクトを取得できます。


Range オブジェクトの扱いについて、注意点が二つあります。


1つ目:Value プロパティについて

たとえば、
  todaySheet.Range("A2").Value = "本日の記録"
といったコードを、
  todaySheet.Range("A2") = "本日の記録"
と記述しないようにしましょう。
Range プロパティは ReadOnly なので、文字列などを代入することはできません。
読み書きの際には、Value プロパティを通じて行うようにします。


2つ目:オブジェクト解放について

Excel.Range オブジェクトは、後始末を忘れられがちです。
先の「ReleaseComObject」を意識した場合、Range プロパティ利用時は
  todaySheet.Range("A2").Value = "本日の記録"
ではなく、
  Dim oRange As Excel.Range = todaySheet.Range("A2")
  oRange.Value = "本日の記録"
  System.Runtime.InteropServices.Marshal.ReleaseComObject(oRange)
と書いた方が望ましいです。


特に注意するのは、Cells プロパティの場合で、
  todaySheet.Cells(1, 2).Value = "本日の記録"
というコードを、解放処理も意識して記述した場合、
  Dim oRange1 As Excel.Range = todaySheet.Cells
  Dim oRange2 As Excel.Range = DirectCast(oRange1(1, 2), Excel.Range)
  oRange2.Value = "本日の記録"
  System.Runtime.InteropServices.Marshal.ReleaseComObject(oRange2)
  System.Runtime.InteropServices.Marshal.ReleaseComObject(oRange1)
のように書く事になります。




注意点に先に触れたところで、Range オブジェクトの基本的な使い方について:


元のコードでは、一つ一つのセルに値をセットしていたようですが、たとえば
 newWorksheet.Range("B2:E3").Value = "TEST"
のようにすれば、2 行 4 列の範囲(計 8 セル)すべてに
「TEST」という文字列を書き込むこともできます。

逆に、
 Dim obj As Object = Sheet1.Range("B2:E3").Value
のように、複数セル範囲で取得した場合、戻り値は 2 次元配列になります。
(単一セルが相手の場合は、配列にはなりません)


これを利用して、複数セルの範囲に対して、「.Value = 配列」で代入してやれば、
複数のセル範囲に、まとめて異なる値をセットすることも出来ます。

VB と Excel の間の通信は比較的低速なので、読み書き回数が多くて
処理時間が何十秒もかかるような場合は、この方法で一括書き込みを
行うことで、処理速度を大幅に短縮できます。


なお、値ではなく数式を扱う場合には、Value プロパティの代わりに
Formula プロパティや FormulaR1C1 プロパティを使います。


Range オブジェクトにはこの他、セル書式を扱うための NumberFormat プロパティや
右寄せ中央揃えなどを扱う、HorizontalAlignment / VerticalAlignment プロパティ、
セルを結合あるいは結合解除するための Merge / UnMerge メソッドなどがありますが、
説明しきれないのでとりあえずここまで。



===============
【保存と後始末】
---------------

既に元のコードで
> Book.SaveAs(FilePath)
と書かれているので、ある程度御存知かと思いますが、次は
>> (9) ワークブックの SaveAs メソッドを用いて、"201701.xlsx" というファイル名に上書き保存できますか?
についてです。


SaveAs を使うと、新しいファイル名で保存できます。
新規ブックのように、ファイル名が未設定の場合もこれを使います。

一方、現在開いているファイルへの上書き保存の場合は、
SaveAs の代わりに、引数無しの Save メソッドを使います。
既存のファイルを Workbooks.Open して上書き編集するだけなら、
Book.SaveAs ではなく Book.Save を使うだけで良いでしょう。


あるいは、SaveAs を上書き保存のために使うことも出来ますが、
その場合、上書き確認のダイアログが表示されることになります。
このダイアログで No や Cancel が選択された場合、
SaveAs メソッドは失敗して実行時エラーとなります。

この確認ダイアログを抑制する場合には、あらかじめ、
Application オブジェクトの DisplayAlerts プロパティを
False にしておきます。たとえば
  Dim bAlerts As Boolean = ExcelApp.DisplayAlerts
  ExcelApp.DisplayAlerts = False  '警告を抑制
  Book.SaveAs(FilePath)
  ExcelApp.DisplayAlerts = bAlerts '元に戻す
といった感じです。


また、未保存状態でワークブックを閉じようとすると、
保存確認のダイアログが表示されますが、これも
DisplayAlerts で抑制できます。

あるいは、DisplayAlerts は True のままであっても、
  Book.Saved = True
のようにすれば、そのブックはまだ変更されていないことになるため、
ユーザーがワークブックを閉じる際の保存確認が表示されなくなります。


ワークブックをユーザーに閉じさせるのではなく、プログラムから閉じるのならば、
  Book.Close()
とします。あるいは編集状態を破棄して閉じるために「Book.Close(False)」としたり、
保存して閉じるために「Book.Close(True, FilePath)」とすることもできます。


後は最後に、
>> (10) 処理完了後、Close メソッドでワークブックを閉じ、Quit メソッドで Exxel 本体を終了させられますか?
ということで、
 ExcelApp.Quit()
を呼び出せば OKです。
Excel を閉じずに開きっぱなしにするのなら、Quit はしなくても構いませんが。


全てが終わったら、使い終わった Excel オブジェクトの変数を適宜、ReleaseComObject してお仕舞いです。


実際には For や For Each の場合も、適宜解放が必要だったりしますので、
もっと早い段階で解放すべきケースもありますが……慣れないと難しいところなので、
初心者を脱するまでは、解放処理については後で考えた方が良いかもしれません。
引用返信 編集キー/
■82717 / inTopicNo.11)  Re[8]: エクセル出力した後に TAB化とグラフ化
□投稿者/ HARE (5回)-(2017/01/31(Tue) 09:48:51)
No82714 (魔界の仮面弁士 さん) に返信
> ■No82709 (HARE さん) に返信
とてもわかりやすく説明して頂き、とても感謝します
うちにいた前任者は説明もできないぐらいなので、遥かに魔界の仮面弁士さんの文字だけでも
理解でき、試しに昨日家で、やってみたら
できましたw

今まで、参考書読みながらやっていたので
こうやって詳しい方に教えてもらうのはとても勉強になります

また、教えていただく時があるかもしれませんが
その時もよろしくお願い致します。

ありがとうございました

引用返信 編集キー/


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

このトピックに書きこむ

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

管理者用

- Child Tree -