みんなの「教えて(疑問・質問)」にみんなで「答える」Q&Aコミュニティ

こんにちはゲストさん。会員登録(無料)して質問・回答してみよう!

解決済みの質問

VBA クラスモジュールの使い方わかりません。

為替データで検証中なのですがネットで使いたいクラスモジュールがあり、値の渡し方などわからなくて困ってます。
過去1ヶ月のデータで日付、始値、高値、安値、終値並んでいる値を標準モジュールからTRと言う名のクラスモジュールに渡して計算したいのですがわかりません。

標準モジュールのみで簡単なマクロを作れるレベルです。
下がTRクラスモジュールです。

どなたかお助けください。
Option Explicit

Public Version As Long
Public Description As String
Public NumInSequences As Long
Public NumParams As Long

Private Sub Class_Initialize()
Version = &H10000
Description = "TR(真のレンジ)"
NumParams = 0
NumInSequences = 4
End Sub

Public Sub Calc(A() As Double, O() As Double, H() As Double, L() As Double, C() As Double)

Dim I As Integer
Dim LastClose As Double '前日の終値
For I = LBound(A) To UBound(A)
If C(I) = Invalid Then
A(I) = Invalid
GoTo NextElem
End If

Dim D1 As Double '今日の高値と安値の差
Dim D2 As Double '前日の終値から今日の高値までの差
Dim D3 As Double '前日の終値から今日の安値までの差

If LastClose = Invalid Then
A(I) = Invalid
LastClose = C(I)
GoTo NextElem
End If
' 3つのパターンのレンジを計算
D1 = H(I) - L(I)
D2 = H(I) - LastClose
D3 = LastClose - L(I)
If D1 > D2 Then
A(I) = D1
Else
A(I) = D2
End If
If (A(I) < D3) Then
A(I) = D3
End If
LastClose = C(I)
NextElem:
Next
End Sub

投稿日時 - 2013-05-11 18:54:33

QNo.8083268

すぐに回答ほしいです

質問者が選んだベストアンサー

説明不足でわかりにくい回答を書いてしまったようで失礼いたしました。
もう少し具体的に説明いたします。

1.動作テストとInvalidについて
まずはTRクラスモジュールの動作テストをしてみるのがよさそうです。
以下のプロシージャを標準モジュールに入れて実行してみてください。

Sub Test_TR_1()
Dim A1(1) As Double
Dim O1(1) As Double, H1(1) As Double
Dim L1(1) As Double, C1(1) As Double
Dim TR1 As TR
Set TR1 = New TR
O1(0) = 3: O1(1) = 2: H1(0) = 3: H1(1) = 4
L1(0) = 2: L1(1) = 1: C1(0) = 2: C1(1) = 3
Call TR1.Calc(A1, O1, H1, O1, C1)
MsgBox A1(0) & vbCrLf & A1(1)
End Sub

何もエラーがなくメッセージボックスに2つの数字が2行で表示されれば成功です。
このとき、上の数字がInvalidの値です。
(CalcプロシージャのLastCloseの使い方からするとInvalidの値は0だと思われます)

もしエラーが出たら、何か対応しないといけませんが、エラーが出るのはおそらくInvalidのところでしょう。
そうであれば、標準モジュールの先頭(Option Explicitがあるならそれより下)に
Public Const Invalid = 0
と一行書き加えてみてください。
(あるいは、TRクラスモジュールの先頭(Option Explicitがあるならそれより下)に
 Private Const Invalid = 0
 と一行書き加えてもOKです。)
おそらく上記のテスト用プロシージャがエラーなく実行できると思います。

2.ワークシートからデータを取り込んで計算する
B1, C1, D1, E1ということはExcelのワークシートからデータを取り込んで計算するのですね。
データ数が不定とのこと、対応方法はいろいろ考えられますが、手っ取り早い方法として計算前に範囲を選択しておくという方法でやってみます。
計算結果はとりあえず終値のすぐ右(F列)に入れることにします。
選択の方法ですが、行方向は計算するデータの範囲を正確に選択してください。タイトル行を含めてはいけません。列方向は、始値が選択範囲の一番左になっていれば、選択する列数は何列でもかまいません。
そうやって選択したうえで TR計算 を実行してください。

以下のプロシージャを標準モジュールに入れてください。
Sub TR計算()
Dim Aaa() As Double '結果を受ける配列
Dim Ooo() As Double
Dim Hhh() As Double
Dim Lll() As Double
Dim Ccc() As Double
Dim CRangeUL As Range '選択範囲の左上
Dim CLines As Long '選択範囲の行数
Dim ResultOffset As Long '結果を入れる列の相対位置
Dim I As Long
Dim TR1 As TR 'TRクラスのインスタンス(実体)

ResultOffset = 4 '結果を入れる列の相対位置。4で終値のすぐ右
'ResultOffsetを変更すると結果の入る列が変わる。
Set CRangeUL = Selection.Cells(1, 1)
CLines = Selection.Rows.Count
'配列の大きさを設定
ReDim Aaa(CLines - 1)
ReDim Ooo(CLines - 1)
ReDim Hhh(CLines - 1)
ReDim Lll(CLines - 1)
ReDim Ccc(CLines - 1)
'ワークシートのデータの読み込み
For I = 0 To CLines - 1
Ooo(I) = CRangeUL.Offset(I, 0)
Hhh(I) = CRangeUL.Offset(I, 1)
Lll(I) = CRangeUL.Offset(I, 2)
Ccc(I) = CRangeUL.Offset(I, 3)
Next
'計算
Set TR1 = New TR
Call TR1.Calc(Aaa, Ooo, Hhh, Lll, Ccc)
' Call Sample_TR(Ooo, Hhh, Lll, Ccc)
'回答No.1のSample_TRは結果を表示するだけなので
'結果をワークシートに戻すのなら使えない

'ワークシートへの結果の書き出し
For I = 0 To CLines - 1
CRangeUL.Offset(I, ResultOffset) = Aaa(I)
Next
End Sub

いかがでしょうか。

投稿日時 - 2013-05-16 00:06:39

お礼

queuerev2様本当にありがとうございます。
プログラムまで作っていただいて、クラスモジュールの流れまで見ることができました。とても、解りやすくためになりました。
VBAは奥が深いですね。
また何かあったら是非またよろしくお願いします。

投稿日時 - 2013-05-16 13:03:12

このQ&Aは役に立ちましたか?

0人が「このQ&Aが役に立った」と投票しています

回答(2)

ANo.1

簡単なサンプルを書いてみました。

Sub Sample_TR(Oo() As Double, Hh() As Double, Ll() As Double, Cc() As Double)
Dim TR1 As TR 'インスタンスを保持する変数を宣言
Set TR1 = New TR 'インスタンスの作成
Dim Aa() As Double
Dim i
ReDim Aa(LBound(Cc) To UBound(Cc))
Call TR1.Calc(Aa, Oo, Hh, Ll, Cc) '計算 引数はすべてDouble型配列
For i = LBound(Aa) To UBound(Aa)
Debug.Print Aa(i)
Next
Set TR1 = Nothing 'インスタンス破棄(このサンプルではおそらく不要)
End Sub

このサンプルを動かしたところ、クラスモジュールTRのInvalidのところでエラーとなりましたが、質問者様の環境ではInvalidはどこかで定義されているのですよね。

投稿日時 - 2013-05-13 13:21:09

補足

queuerev2様ありがとうございます。
このサンプルはネットで拾ってきた物です。
使い方がわからなったものでInvalidもわからないです。
このサンプルもちょっと私のレベルではまだ勉強不足でした。
queuerev2様が書いてくださったサンプルで私なりに勉強したのですがエラーばかりで進みません。想定している物がB1始値、C1高値、D1安値、E1終値で検証したい期間も過去1ヶ月とか6ヶ月とか変わるため()なにを入れていいのかわかりません。もしよかったら()の中に何を入れればよいか教えてください。ここからいろいろ調べたりしたんですがわかりまっせんでした。

Sub TR計算()

Dim Ooo() As Double
Dim Hhh() As Double
Dim Lll() As Double
Dim Ccc() As Double

Call Sample_TR(Ooo, Hhh, Lll, Ccc)

End Sub

投稿日時 - 2013-05-15 13:32:27

あなたにオススメの質問