SSブログ

エクセル幼稚園:ワークシート上のデータを加工して、テキストファイルを出力 [コンピューター]

001.jpg

のようなデータがワークシート上にあったとき、B11セルの値のファイル名でテキストファイル"aaa.txt"を作成し、D11セルの値をop1、B14:B22セルの値をop2、C14:C22セルで項目ごとの合計をop3とする

cmd1 -op1 bbb -op2 ccc -op3 ddd

というコマンドをテキストファイルに出力するマクロを考えます。(説明が難しい。。)

上記のデータから出力されたテキストファイルは、このようになります。

002.jpg

1行目の"hoge hoge"は、ワークシート上のデータと関係なく、いつも出力される定型データです。2 - 5行目が、ワークシート上のデータを加工して出力されたコマンド行です。この処理をするために、1つのFunctionと、1つのSubを作りました。

01:Function UFCmd1(Range1, Range2, Range3 As String) As String
02:  ' 機能:引数で与えられたセル範囲のデータからコマンドの文字列を返す
03:  ' cmd1 -op1 bbb -op2 ccc -op3 ddd
04:  ' 引数
05:  ' Range1 : セル範囲(op1)
06:  ' Range2 : セル範囲(op2)
07:  ' Range3 : セル範囲(op3)
08:  Dim sum1 As Integer ' 合計(op3)
09:  ' op3の合計を出す
10:  sum1 = 0
11:  For Each objRANGE In Range(Range3).Cells
12:    sum1 = sum1 + objRANGE.Value
13:  Next
14:  ' コマンドの文字列を返す
15:  UFCmd1 = "cmd1 -op1 " & Range(Range1).Value & " -op2 " & Range(Range2).Value & " -op3 " & sum1
16:End Function

このFunctionは、op1, op2, op3の元データのセル範囲を文字列として受け取り、コマンド文字列を生成して返します。(Range型でセル範囲を渡そうとしたのですが、うまくいかず、String型で渡しています。)
8行目:sum1変数を整数変数(Integer)として宣言しています。
10行目:sum1変数に0を代入して初期化しています。
11-13行目:Range3で与えられたop3の元データのセル範囲の合計をsum1変数に代入します。
15行目:Range1のセル範囲の値をop1, Range2のセル範囲の値をop2, sum1変数の値をop3としてコマンド文字列を生成し、Functionの戻り値としています。

01:Sub aaa()
02:  ' 機能:エクセル上のデータを加工して、コマンドファイル(テキスト)を作成する
03:  Dim myRange1(3, 2) As String ' 元データのセル範囲
04:  Dim cmd2 As String ' コマンドの文字列
05:  Dim file1 As String ' ファイル名
06:  Dim nFNO As Integer 'ファイル番号
07:  Dim str1(2) As String ' 文字列
08:  Dim ans1 As Integer ' 答え
09:  Dim i As Integer ' For文用
10:  ' 元データ #0
11:  myRange1(0, 0) = "d11" ' セル範囲(op1)
12:  myRange1(0, 1) = "b14" ' セル範囲(op2)
13:  myRange1(0, 2) = "c14:c15" ' セル範囲(op3)
14:  ' 元データ #1
15:  myRange1(1, 0) = "d11" ' セル範囲(op1)
16:  myRange1(1, 1) = "b16" ' セル範囲(op2)
17:  myRange1(1, 2) = "c16:c18" ' セル範囲(op3)
18:  ' 元データ #2
19:  myRange1(2, 0) = "d11" ' セル範囲(op1)
20:  myRange1(2, 1) = "b19" ' セル範囲(op2)
21:  myRange1(2, 2) = "c19:c20" ' セル範囲(op3)
22:  ' 元データ #3
23:  myRange1(3, 0) = "d11" ' セル範囲(op1)
24:  myRange1(3, 1) = "b21" ' セル範囲(op2)
25:  myRange1(3, 2) = "c21:c22" ' セル範囲(op3)
26:  ' ファイル名を作成
27:  file1 = ThisWorkbook.Path & "\" & Range("b11").Value & ".txt"
28:  ' ファイルが存在する場合、上書きして良いか、確認する
29:  If Dir(file1) <> "" Then
30:    str1(0) = file1 & vbCrLf & "は存在します。" & vbCrLf
31:    str1(0) = str1(0) & "上書きしますか?"
32:    ' 上書きするか確認
33:    ans1 = MsgBox(str1(0), vbYesNo + vbExclamation + vbDefaultButton2)
34:    ' 場合分け
35:    Select Case ans1
36:      Case vbYes ' 「はい」
37:        ' ファイル書込みする(End If以降を実行)
38:      Case vbNo ' 「いいえ」
39:        ' ファイル書込みせず、Subを抜ける
40:        Exit Sub
41:      Case Else '「はい」でも「いいえ」でもない
42:        ' ファイル書込みせず、Subを抜ける
43:        Exit Sub
44:    End Select
45:  Else
46:    MsgBox (file1 & vbCrLf & "を作成します。")
47:  End If
48:  ' 使用可能なファイル番号を調べる
49:  nFNO = FreeFile()
50:  ' ファイルを開く
51:  Open file1 For Output As #nFNO
52:  ' ファイルへ書き込む
53:  Print #nFNO, "hoge hoge"
54:  For i = LBound(myRange1, 1) To UBound(myRange1, 1)
55:    If myRange1(i, 0) <> "" Then
56:      cmd2 = UFCmd1(myRange1(i, 0), myRange1(i, 1), myRange1(i, 2))
57:      Print #nFNO, cmd2
58:    End If
59:  Next
50:  ' ファイルを閉じる
61:  Close #nFNO
62:End Sub

このSubは、エクセル上のデータを加工して、コマンドファイル(テキスト)を作成します。
3-9行目:変数宣言
10-25行目:Functionを呼ぶときに必要となる3つのセル範囲をmyRange1配列に格納。
27行目:エクセルファイルが存在するフォルダのパス(ThisWorkbook.Path)に、B11セルの値と".txt"を加えて、作成するテキストファイルのフルパスの文字列を作成し、file1変数に代入。
29行目:Dir(file1) <> "" で、作成しようとしているファイルが既に存在しているか判定。
30-44行目:ファイルが既に存在している場合、上書きするか、処理を中断するか、人間に確認。(いわゆる、ばかよけ?)
46行目:ファイルが存在していない旨、人間に伝える。
49行目:使用可能なファイル番号を調べて、nFNO変数に代入。
51行目:テキストファイル(file1)を、ファイル番号:nFNO、モード:書き込み(Output)で開く。
53行目:ファイルへ、定型テキストを書き込み。
54-59行目:myRange1配列の1次元の添字の最小値(LBound)から、最大値(UBound)まで繰り返す。
55行目:セル範囲(op1)の文字列が空文字列でなかったら、56-57行目を実行。
56行目:UFCmd1関数を呼んで、コマンド文字列をcmd2変数に代入。
57行目:ファイルにコマンド文字列を出力。
61行目:ファイルを閉じる。

とりあえず、説明は、この辺でおしまい。。[猫]
タグ:エクセル VBA
ヤバイぜ!(10)  コメント(4)  トラックバック(0) 
共通テーマ:日記・雑感

ヤバイぜ! 10

コメント 4

cheese999

nice! ありがとうございます。
誤記、ありますが、今日は不調なので、修正はおいおい。。
(*_*)ノ
by cheese999 (2012-07-17 20:31) 

cheese999

Subの元データの誤記を訂正、Functionの説明を追加しました。
元データをSubの中に入れるか、入れないかは悩ましいところですね。
元データの数が多くなったら、別ファイルにすべきですが。。
ファイルが分かれるとファイル管理が面倒ですし。。
データがプログラムの中に入っていると、データ変更のたびにプログラムをいじることになり、バグ混入の原因になりますし。。
(*_*)ノ

by cheese999 (2012-07-18 04:49) 

alba0101

ご訪問&コメントありがとうございます^^
遅くなりまして ごめんなさい<(_ _)>

そうですか...放射能の風評被害は困りものですね...
きれいな海なのでしょうね(^^)
行ってみたいですね...
by alba0101 (2012-07-18 12:18) 

cheese999

alba0101さん、
どういたしまして。。。

沖縄の海に比べれば、おとりますが。。
いわき七浜で、一番いいのは、薄磯だったかと。。
(^_0)ノ
by cheese999 (2012-07-18 22:18) 

Facebook コメント

トラックバック 0

トラックバックの受付は締め切りました

この広告は前回の更新から一定期間経過したブログに表示されています。更新すると自動で解除されます。