翼型解析①:大量のテキストファイルをエクセルに読み込む

解析結果として得られた大量のテキストファイルを1つのエクセルファイルに読み込むマクロを作る

目的とフローチャート

今回の目的は,前回(>XFLR5で二次元翼を解析して結果を出力する)で出力した大量のテキストファイルを1つのエクセルファイルに読み込むことである

この手法は,学生実験などの結果がテキストファイルで与えられたときなどにも役立つと思うのでぜひ参考にしてほしい

マクロのフローチャートを以下に示す

①変数を宣言する
②必要な値をシートから読み込む
③読み込んだ値からテキストファイルのファイル数を計算し,ループを始める
④ファイル名を生成する
⑤ファイルを開く
⑥1つのセルに1つのデータが入るようエクセルシートをいじる
⑦テキストファイル内のデータの個数を計測する
⑧さらにループを回してすべての必要なデータを配列に格納する
⑨ファイルを閉じる
⑩すべてのファイルについて上の処理が終われば,配列をエクセルシートに貼り付ける

テンプレートファイルのダウンロード

エクセルシートの配置などの参考になるようにテンプレートファイルを添付しておく

※数式やマクロはすべて削除してあり,値も適当である

プログラムの解説

それでは実際に解説していく

使用する変数

マクロに使用する変数を以下に示す

Dim file_number As Integer 'ファイル数
Dim data_number As Integer 'データ数
Dim last As Integer 'データが入っている最終行
Dim Re_min  As Double '最小Re数
Dim Re_mas As Double '最大Re数
Dim Re_delta As Double 'Re数刻み
Dim foil_name As String '翼型名
Dim file_name As String 'ファイル名
Dim data(30000, 4) As Double 'データ格納用配列
'カウンター
Dim i As Integer
Dim j As Integer

データ数data_numberは最後に配列をシートに貼り付けるときのみ使用

データ格納用配列data()を動的配列にしてもよかったが,面倒なのでやめた.データ数は30000もあれば十分だろう

ほしいデータの種類はα,CL,CD,Cm,Reなので,data(0:30000, 0:4)で宣言した

前準備

(>Excel VBA/マクロ について知っておいてほしいこと)でも言ったとおり,プログラムの最初に,マクロを使うにあたって,次のコードを入れておく

ActiveWorkbook.Save '上書き保存
Application.ScreenUpdating = False '画面更新の非表示
Application.DisplayAlerts = False '警告画面の非表示

警告画面というのは,Excelファイルを閉じるときの「変更内容を保存しますか?」みたいなやつのこと

これから書くすべてのマクロの先頭にこのコードを入れるので,次回以降特に説明はしない

値の読み込み・ファイル数の計算

まず,今回のマクロに必要な値をシートから読み込む

'値の読み込み
Re_min = Cells(4, 24) '最小Re数
Re_max = Cells(4, 25) '最大Re数
Re_delta = Cells(4, 26) 'Re数刻み
foil_name = Cells(5, 24) '翼型名

読み込みに使うのはRangeでもCellsでもいいが,両方使えるときはCellsのほうが少し早いらしい

解析に使用した最小Re,最大Re,およびRe数の刻みから,解析結果のファイル数は次のように計算できる

'ファイル数の計算
file_number = (Re_max - Re_min) / Re_delta + 1

ファイルのループ開始

ファイルのループを開始する

data_number = 0
For i = 0 To file_number - 1 'すべてのファイルのループ
	(各ファイルについての処理)
next i

データ数data_numberは,配列に格納しながら数えていくので,ループが始まる前に初期値の0を入れておく

ファイル名の生成

それぞれのファイルについて,まず開きたいファイル名を生成する

i番目のファイルのファイル名をfile_nameに格納するコードは次のようになる

'開きたいファイル名を作る
file_name = foil_name & "_T1_Re" & Format((Re_min + Re_delta * i) / 1000000, "0.000") & "_M0.00_N9.0.txt"

&は複数の文字列の結合で,Format(数値,書式)を使えば,指定した桁数で数値を文字列に変換できる

ファイルを開く

ファイルを開くには,Workbooks.Openを使い,ファイルがある場所(パス)とファイル名を指定する必要がある

'設計シートと同じフォルダにあるテキストファイルを開く
Workbooks.Open Filename:=ThisWorkbook.Path & "\" & file_name

ThisWorkbook.Pathはむちゃくちゃ便利な奴で,マクロが書かれているエクセルシートと同じ場所を指定してくれる

こうすれば,だれがどのパソコンで使おうと,2つのファイルが同じフォルダにありさえすればいいので使いやすい

データの処理

ためしにここまでのプログラムを実行してみる(ループの開始の部分はコメントアウトした状態で)

このように,テキストファイルがエクセルで開くが,A行にすべてのデータが貼り付けられているのでマクロで値を読み取ることができない.

1つのセルに1つのデータが入るようにするコードを書くのはとても面倒なので,ここでは「マクロの記録」を利用する

まず,「Ctrl+space」でA行を選択し,「Alt→A→E」で「区切り位置」を選択

「次へ」→「次へ」→「完了」で1つのセルに1つのデータが入る

これを,「マクロを記録」で記録したコードは次のようになる


'「データ」→「区切り」からスペースでデータを区切る
Selection.TextToColumns Destination:=Range("A1"), DataType:=xlFixedWidth, _
	FieldInfo:=Array(Array(0, 1), Array(8, 1), Array(17, 1), Array(27, 1), Array(37, 1), _
        Array(46, 1), Array(54, 1), Array(62, 1), Array(71, 1), Array(81, 1)), _
        TrailingMinusNumbers:=True

正直何が書いてあるかさっぱりわからないが,これでいいらしい

データを格納

必要なデータを配列に格納するために,まずはデータがシートの何行目まで入っているか調べる必要がある

指定した列の,データが入っている最終行を取得するには次のコードがある

last = Cells(Rows.Count, 1).End(xlUp).Row '座標データの最終行を取得

上のコードでは,第1列(=A列)のデータが入っている最終行を取得する

これを用いて配列にデータを格納していく

For j = 12 To last
            data(data_number, 0) = Cells(j, 1)
            data(data_number, 1) = Cells(j, 2)
            data(data_number, 2) = Cells(j, 3)
            data(data_number, 3) = Cells(j, 5)
            data(data_number, 4) = Re_min + Re_delta * i
            data_number = data_number + 1
Next j

ファイルを閉じる

ファイルを閉じるには次のコードを使えばいい

ActiveWindow.Close

ここで警告画面を非表示にしておかないとすべてのファイルで「保存しますか?」というメッセージが出てきてしまう

値の貼り付け

すべてのファイルについてのループを終了すれば,最後にデータを設計シートに貼り付ける

'値の貼り付け
Range(Cells(12, 1), Cells(12 + data_number - 1, 5)) = data()

配列の貼り付けはこれでできる
くれぐれもセル1つずつに数千回貼り付けを行うようなことはしないように

これでコードは終了である

プログラムの実行

今回作成したプログラムを実際に実行してみる

46個のファイルを読み込んで実行時間は約14秒だった

まとめ

「マクロを記録」の機能はエクセルシートの処理をするうえでとても便利なのでぜひ使いこなせるようになってほしい

上の説明でわからないことがあればグーグルで検索してみよう.きっと答えはそこにあるはず


翼型解析②:解析データを最小二乗法で多項式近似するに進む

XFLR5で二次元翼を解析して結果を出力するに戻る

記事一覧に戻る

Sponsored Link

コメント

タイトルとURLをコピーしました