3.その他のマクロ

3-1.グラフのgif保存
作成したチャートをgif保存できると、便利の場合が多々あります



Sub gif保存()
Dim cname As String  'シートに表示されているチャート名
Dim gname As String  'gif保存のチャート名

' チャート名
For Each zu In ActiveSheet.ChartObjects               '[1]
    cname = zu.Name
Next
If cname = "" Then
   MsgBox "このシートにグラフがありません"
   Exit Sub
End If
    
'保存場所確認                                         '[2]
    phn = ActiveWorkbook.Path
    
'保存ファイル名
    gname = "TestChart"                               '[3]
    
    msg = "縮小する場合は縮小率を入力して下さい。" & Chr$(10) & Chr$(10) _
    & "  例:80%→80 (数字のみ入力)"
  ritu = Application.InputBox(msg, "縮小率の指定", "100", Type:=1)       '[4]
  If ritu = False Then
     Exit Sub
  End If
  
'拡大・縮小                                                              '[5]
  ritu1 = ritu / 100
   ActiveSheet.Shapes(cname).ScaleWidth ritu1, msoFalse, msoScaleFromTopLeft
   ActiveSheet.Shapes(cname).ScaleHeight ritu1, msoFalse, msoScaleFromTopLeft
  
'gif化                                                                   '[6]
   ActiveSheet.ChartObjects(cname).Chart.Export phn & "\" & gname & ".gif"
   
'後処理                                                                  '[7]
    MsgBox "「" & phn & "\" & gname & ".gif」へ保存しました"
End Sub
[1] シートに表示されているチャート名を取得(1個でない場合最後に書いたチャートが対象となにます)
[2] 表示中のブックの保存場所を取得し、チャートを同じ場所へ保存します
[3] gname = "TestChart"  → ここで指定した名前でgifファイルを保存
[4] 拡大・縮小の率を指定 (メッセージは上図参照)
[5] チャートの拡大・縮小を実行
・ ScaleWidth → 変数(ritu1)で指定した倍率の係数で、チャートの幅を拡大又は縮小
・ ScaleHeight → 変数(ritu1)で指定した倍率の係数で、チャートの高さを拡大又は縮小
[6]Exportメソッドでグラフをgif保存します
・本例は拡張子".gif"ですが、".jpg"に指定を変えた場合は、jpg形式で保存されます
[7] 終了で保存した場所とファイル名を表示


3-2.グラフのプリントアウト
作成したチャートをボタンクリックで印刷できると、便利の場合が多々あります

Sub プリント()
Dim cname As String  'シートに表示されているチャート名
' チャート名
For Each zu In ActiveSheet.ChartObjects              '[1]
    cname = zu.Name
Next
If cname = "" Then
   MsgBox "このシートにグラフがありません"
   Exit Sub
End If

'印刷                                                '[2]
	ActiveSheet.ChartObjects(cname).Activate  
    	ActiveChart.ChartArea.Select
   	ActiveWindow.SelectedSheets.PrintOut Copies:=1
End Sub
[1] シートに表示されているチャート名を取得(1個でない場合最後に書いたチャートが対象となにます)
[2] 印刷
・ 印刷対象のチャートを選択
・ PrintOutメソッドで印刷実行(Copies:=1で印刷部数を「1」に指定)

3-3.テキストファイルの取り込み
本マクロは、txtファイルの銘柄リストをファイルを開かず高速でExcelシートへ取り込例です。

txtファイル元データシートへ取込済みデータ

Dim fname As String '指定したtxtファイル名

Sub txtファイル読込()

'ファイル指定                             '[1]
 flt$ = "txtファイル(*.txt),*.txt"        
fname = Application.GetOpenFilename(flt$, , Title:="txtファイル指定")

If fname = "False" Then
    MsgBox "txtファイル指定の指定がありません"
    Exit Sub
Else
    Call 銘柄表取込                                                    '[2]
End If
End Sub
[1]GetOpenFilename → ファイルダイアログ表示(下図)(本例はファイルの種類は"txt")


[2] プロシージャ[銘柄表取込]コール

'----------------------------------------------------------------------------
Sub 銘柄表取込()
Dim dat(3000, 1) As String

'過去削除                                              '[1]
Cells.Select
    Selection.ClearContents
    Range("A1").Select

'txtデ−タ取り込み                         
    i = 0
    Open fname For Input As #1                          '[2]                 
Do Until EOF(1)                                         '[3]
    On Error GoTo rest                                  '[4]
    Input #1, dat(i, 0), dat(i, 1)                      '[5]                    
    On Error GoTo 0
     i = i + 1                      
Loop
Close #1                                                '[6]

Range(Cells(3, 1), Cells(i + 3, 2)).Value = dat         '[7]

Application.StatusBar = fname & "から[" & i & "]件取り込みました"

Exit Sub
rest:                                                   '[8]
   Close #1
   MsgBox fname & "ファイルのデータ取得に失敗しました。"
   On Error GoTo 0
End Sub
[1] 同じシートへの取込を考慮し、過去データ削除
[2] Open ステートメントで読み取るファイルを指定
 ・fname  → 変数(fname)は「パス+txtファイル名」が入っている
 ・Input → 入力専用
 ・As #1 → ファイルナンバーを「1」に指定(閉じるまでこの番号で制御)
[3] Do....Loop ステートメントでコンデションが"True"になるまでデータ取得実行
 ・ EOF(1) → EOF関数はファイルの最後を超えようとした時「True」を返す
[4]txtファイルに最終にデータでない「ラインフィード」等が連続で入っていた場合、データを
  取得できずエラーになることがあります。「GoTo rest 」エラー処理を指定。
[5] Input #1ステートメントでデータ読み取る
 ・本例の場合、配列(dat)へ順次代入
 ・このステートメントでは、カンマ区切りを1データと識別(改行も区切りと識別)
[6] As #1で指定したファイル番号は、「Close #1」で閉じるまで開いたままなので
  処理が終了したら必ず閉じること。
[7] 配列(dat)に格納したデータをシートへ書き込み
[8] エラー処理
 ・エラーで止まった場合も、ファイル番号は開いた状態であり「Close #1」で閉じる
 ・エラーのメッセージ表示
 ・On Error GoTo 0 → エラー処理ルーチン(On Error GoTo rest)を無効にする

3-4.テキストファイル形式で保存
Excelシートのデータをカンマ区切りのtxtファイルで保存したい場合、VBAとしては 拡張子csvで保存しか出来ないので、本例は一旦csvで保存し後でtxtに変えた例です。

Sub テキスト化保存()
Application.ScreenUpdating = False
'txtファイル名の指定
   csvmane = "tmp"

'保存場所指定
phn = ThisWorkbook.Path                        '[1]
bok1 = ThisWorkbook.Name

'仮に別ブックへ貼り付け                        '[2]
Workbooks.Add
bok2 = ActiveWorkbook.Name
Windows(bok1).Activate
    Cells.Select
    Selection.Copy
Windows(bok2).Activate
    Range("A1").Select
    ActiveSheet.Paste
    Range("A1").Select
    
'csv保存                                        '[3]
fff = phn & "\" & csvmane
ActiveWorkbook.SaveAs Filename:=fff, FileFormat:=xlCSV, _
        CreateBackup:=False
    Range("A1").Select
    
'CSVで保存したファイルを閉じる                  '[4]
ActiveWorkbook.Saved = True
    ActiveWorkbook.Close
    
'csvをtxtに変える                               '[5]
fchk = Dir(phn & "\" & csvmane & ".txt")
If fchk = "" Then
    Name fff & ".csv" As phn & "\" & csvmane & ".txt"
Else
    Kill phn & "\" & csvmane & ".txt"
    Name fff & ".csv" As phn & "\" & csvmane & ".txt"
End If

'最終処理                                       '[6]
Windows(bok1).Activate
    Range("A1").Select
MsgBox phn & " へ " & csvmane & ".txt を保存しました。"

End Sub
[1] csvファイルの保存場所 → 本例はこのマクロの入っているブックを指定
[2] 仮に別ブックへ貼り付け
 (このアイテムは通常不要ですが、このマクロの入っているシートをtxt化の時必要)
 ・ブックを追加
 ・元ブックのスートをコピーして、追加ブックに貼り付け
[3] FileFormat:=xlCSV → 拡張子csvで保存
[4] csvで保存したファイルが開いているとファイル名変更が出来ないので閉じる
[5] Nameステートメントでcsvをtxtに変える
 ・Name 「元ファイル名」 As 「変更後のファイル名」
 ・既に「変更後のファイル名」が存在する場合エラーになる為、ある場合は削除
[6] 終了のメッセージ


3-5.ワークシート関数の有効利用
下図は終値移動平均に対と本日終値がどれだけ離れているか「乖離率」を示す表です。
この「終値移動平均」はExcelではワークシート関数で一瞬に計算できます。 ここではVBAでの記述方法について説明します。

Const NISSUU As Integer = 8  '平均する日数

Sub 関数例()
'最終セル
    Cells(10000, 1).End(xlUp).Select
    endr = ActiveCell.Row
    Range("A2").Select

'移動平均 ------------------------------------------
Cells(3, 8) = NISSUU & "移動平均"
endr1 = endr - NISSUU

Range(Cells(4, 8), Cells(endr1, 8)).Formula = "=AVERAGE(F5:F" & NISSUU + 3 & ")"  '(1)
    Columns("H").Select
    Selection.NumberFormatLocal = "0.0_ "
    Range("G1").Select

'カイリ率計算 ------------------------------------------
Cells(3, 9) = "カイリ率"
Range(Cells(4, 9), Cells(endr1, 9)).Formula = "=(F4-H4)/H4*100"                   '(2)
    Columns("I").Select
    Selection.NumberFormatLocal = "0.0_ "
    Range("G1").Select

End Sub
(1) ワークシート関数はFormulaプロパティでA1形式で記述する
[1]本例の記述では、下記のように行毎に(F5:F11)→(F6:F12)→(・・・)と計算対象行が自動的に変わる。
 (これは非常に便利なExcelの機能でこれにより株価解析のグラフデータも簡単に作成できます)
   Cells(4, 9) ⇒ =AVERAGE(F5:F11)
   Cells(5, 9) ⇒ =AVERAGE(F6:F12)
   Cells(6, 9) ⇒ =AVERAGE(F7:F13)
[2]マニアルで計算式をセルに記入する場合は、普通始めのセルに式を記入し(例:=AVERAGE(F5:F11))
  それをコピーして下のセルへ貼り付けますが、マクロ記述は(1)の全セルでダイレクト記述でよい。
この操作を自動記録すると以下のようになる。これを使用しても問題ないが見ずらいマクロになる。
    Range("H4").Select
    ActiveCell.FormulaR1C1 = "=AVERAGE(R[1]C[-2]:R[7]C[-2])"
    Range("H4").Select
    Selection.Copy
    Range("H5:H22").Select '→H22は最終セルにする必要あり
    ActiveSheet.Paste
[3]記述方法の補助説明
 ・"=AVERAGE(F5:F" & NISSUU + 3 & ")"→ 変数(NISSUU)は平均する日数。+3はデータが4行からの補正
 ・平均する日数に変数を使用しない場合→ "=AVERAGE(F5:F12)" (平均日数9日の場合)

(2)セルへ数式の記入
 ・この場合も、FormulaプロパティでA1形式で記述すれば、行がExcel機能で自動的に変わります
 ・本例の場合、F列→終値、H列→(1)で計算した移動平均値

(3)ワークシート関数をVBAで使用する方法
下記は最安値・最高値計算プロシージャです。このようにセルに書き込む場合はFormulaプロパティを 使用しますが、ここではVBAの変数へ代入する場合を説明します。

Sub 安値高値()
    Cells(10000, 1).End(xlUp).Select
    endr = ActiveCell.Row
    Range("A2").Select

    Cells(1, 11).Formula = "=MIN(E4:E" & endr & ")" 'E列は安値
    Cells(1, 12).Formula = "=MAX(D4:D" & endr & ")" 'D列は高値
    Cells(1, 11) = "最安値" & Cells(1, 11)
    Cells(1, 12) = "最高値" & Cells(1, 12)
End Sub
VBAマクロのプロシージャ内でワークシート関数を使用する場合、関数の前に"Application" を付けて指定する(使用出来るのは全部ではありません。If等のVBAとワークシート関数がダブル関数は不可)

下記の記述で変数(maxd)へ最高値を代入できます。
[1] maxd = Application.Max(Range(Cells(4, 4), Cells(endr, 4)))
又は
[2] maxd = Application.WorksheetFunction.Max(Range(Cells(4, 4), Cells(endr, 4)))


3-6.時系列100件以上の取得
Yahooファイナンス時系列データ取得方法は、(1)-1Webから株価データ取得マクロ(Yahoo)でサンプル付で 説明していますが、これは約100件までの例ですが時々100件以上の取得方法につい質問が 来ますが、100件以上は以下の方法で取得できます。

'取得1
    ymden = ymd
    ymdst = ymden - 70
    endr = 3
    Call 取得準備
'取得2
    ymden = ymdst - 1
    ymdst = ymden - 70
    
    Cells(10000, 1).End(xlUp).Select
    endr = ActiveCell.Row + 1
    Call 取得準備

上記サンプルは70*2で暦日数140日であり、株データは約100日分の取得です。

---------------------------------------------------------------------
下記のようにFor文を追加し、「取得2」を回せば1回の実行で約50日分のデータを追加できます

For cnt = 1 To 3
'取得2
    ymden = ymdst - 1
    ymdst = ymden - 70
    
    Cells(10000, 1).End(xlUp).Select
    endr = ActiveCell.Row + 1
    Call 取得準備
Next



【戻る】