半角チルダ

ExcelVBA、その他。
覚え書きや、補足資料などのスクラップブック。
end-u(1037781)

■xl2000:yahooファイナンスとwebクエリ

2008-10-27 23:00:00 | 雑記
ヤフーファイナンスからのデータダウンロードについて - 教えて!goo
この10月以降、xl2000の環境では上記Q&Aのコードでエラーが出るようになりました。
2002/2003は問題ないです。

確認のためマクロ記録した下記コードを実行してみるとエラーは出ませんが、データが取り込めません。

Sub Macro1()
  With ActiveSheet.QueryTables.Add( _
           Connection:="URL;http://table.yahoo.co.jp/t?s=998407", _
           Destination:=Range("A1"))
    .FieldNames = True
    .RowNumbers = False
    .FillAdjacentFormulas = False
    .PreserveFormatting = False
    .RefreshOnFileOpen = False
    .BackgroundQuery = False
    .RefreshStyle = xlOverwriteCells
    .SavePassword = False
    .SaveData = True
    .AdjustColumnWidth = False
    .RefreshPeriod = 0
    .WebSelectionType = xlEntirePage
    .WebFormatting = xlWebFormattingNone
    .WebPreFormattedTextToColumns = True
    .WebConsecutiveDelimitersAsOne = True
    .WebSingleBlockTextImport = False
    .WebDisableDateRecognition = False
    .Refresh BackgroundQuery:=False
  End With
End Sub

手作業で[新しいWebクエリ]を実行すると

このwebクエリによって返されるデータがありません

こんなメッセージです。
自分では株もやらないので全然困らないのですが、急に取り込めなくなると困る方もいらっしゃるかもしれませんね。

推測ですけど、どうもyahooのソースコードが変わった事が影響している感じ。
上記 http://table.yahoo.co.jp/t?s= のページの場合だと47行目あたりに
...no-repeat;/*¥*//*/width:137px;height:16px;/**/}
という記述があります。(cssは詳しくないのですが、コメントか何か?)
ローカルにwebページを保存して確認してみると、この箇所が原因のようです。
xl2002以降ではwebクエリの仕様が変更になっていますから、2000だけ影響を受けたのでしょうか。
ソースが修正されるまでは別の方法で取り込むしかないようです。
Comment
  • X
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする

■Dialogs(xlDialogInsertPicture)の引数

2008-10-20 21:00:00 | 雑記
Application.Dialogs(xlDialogInsertPicture)...図の挿入ダイアログの事ですが、先日の xlDialogFilter の記事とは逆で、ヘルプに引数の記載はありますが、実際には機能しません。

(ヘルプの引数)
xlDialogInsertPicture file_name、filter_number

不勉強な私が知らないだけかもしれませんが、どうやっても file_name、filter_number が反映しないです。

Dim v
v = "sample.jpg"
'v = "d:¥tmp¥sample.jpg"
Application.Dialogs(xlDialogInsertPicture).Show v, 0 '1



バージョンアップの際のヘルプの修正忘れか何かでしょうかねぇ...


ついでに。
Dialog オブジェクトの Show メソッドの引数を、名前付きで使用したい場合は arg1,arg2...で使用できます。

Application.Dialogs(xlDialogSort).Show arg1:=xlTopToBottom, _
                    arg2:="列 A", _
                    arg3:=xlAscending, _
                    arg8:=xlNo
Comment
  • X
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする

■Application.Dialogs(xlDialogFilter)の引数

2008-10-17 19:00:00 | VBA Tips
.Dialogs(xlDialogFilter)...オートフィルタオプションウィンドウの事ですが、xl2000, xl2003のヘルプには引数が載っていません。(XPは未確認)
msdn にも記載がありません。
組み込みダイアログ ボックス引数一覧
Built-In Dialog Box Argument Lists [Excel 2003 VBA Language Reference]

実際には、引数を指定し、オプションウィンドウを開く事ができます。
引数の順番は、AutoFilter メソッドに準じています。

[AutoFilter メソッド]
expression.AutoFilter(Field, Criteria1, Operator, Criteria2)

[Dialogs オブジェクト]
Application.Dialogs(xlDialogFilter).Show Field, Criteria1, Operator, Criteria2

例えばユーザー操作を伴うマクロを作成する時などに、簡易的に使えるかもしれません。



Sub try()
  Dim r As Range  'フィルタ範囲

  With ActiveSheet
    '.Cells(3).Select
    'オートフィルタ解除
    .AutoFilterMode = False
    On Error Resume Next
    ActiveCell.AutoFilter
    If Err.Number <> 0 Then Exit Sub
    On Error GoTo 0

    '■オートフィルタダイアログ表示
    '■引数は Field,Criteria1,Operator,Criteria2
    '例)Application.Dialogs(xlDialogFilter).Show 2, ">", xlAnd, "<"
    Application.Dialogs(xlDialogFilter).Show ActiveCell.Column

    '.FilterMode = True...つまりキャンセルされていないなら。
    If .FilterMode Then
      'フィルタ範囲をセット
      Set r = .AutoFilter.Range
      '抽出件数のチェック
      If WorksheetFunction.Subtotal(3, r) > _
        WorksheetFunction.Subtotal(3, r.Rows(1)) Then

        'ここでいろいろな処理など。
        .PrintOut preview:=True

      End If
      Set r = Nothing
    End If
    .AutoFilterMode = False
  End With
End Sub

ユーザー操作によって抽出条件を指定する場合、InputBox などで条件を直接入力してもらったり、予め作成したデータリストから選択してもらったりする方法が考えられます。ユーザー操作の簡便性を考えると、リスト選択方式が好まれる事が多いでしょう。
この時に、抽出フィールドが変動する場合は、その都度、重複データを除いたリストを作成する必要があります。
Dictionary オブジェクトを使いこなせればそれほど難しくありませんが、Excel の基本機能を活用する事で対応できるケースもあるのではないでしょうか。
コード作成アプローチの選択肢の1つとして、知っておいて損はないかもしれません。
Comment
  • X
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする

■挙動不思議な"ATPVBAEN.XLA!Xirr"

2008-10-06 22:00:00 | 気をつけたほうがいいこと
もう1年程前になりますが、コマンドバーに登録したアドイン関数実行マクロがエラーになるという案件がありました。ATPVBAEN.XLA(分析ツール - VBA)の XIRR 関数です。
標準モジュールから実行すると問題ないのですが、CommandBars.Controls の OnAction に登録して実行するとエラー結果を返します。
その時は Application.OnTime メソッドを使って一応の解決を見ました。
Control のイベントなどから呼び出したマクロが上手くいかない場合、

Application.OnTime Now, "マクロ名"

...とやって、一旦呼び出したマクロを終了させた後に標準モジュールに置いたマクロに引渡すと、上手くいく場合があります。ましてこのケースは標準モジュールで実行するとエラーが出ないという事でしたので、それで結果オーライだったわけですね。

今回、前述した Application.OnTime メソッドの効用について記事を書こうと思い、古いログを引っ張り出して、違う角度から検証してみると、他にも要因があったのでは?と思い至りました。

以下は検証用コードです。
([win2000sp4/xl2000sp3][winXPsp2/xl2003sp3]の環境で稼動確認してますが、もし試される場合は自己責任でお願いしますね)
コード内容は、[分析ツール - VBA]のアドインを登録し、ユーザー設定 CommandBar を追加し、5つのテストプロシージャを Control に登録するものです。
Temporary:=True にしていますから、Excel を終了すれば CommandBar は破棄されます。
一応削除用の Control も最後に追加してあります。
アドインの ATPVBAEN.XLA が見つからないというエラーが出る場合は、手動で[分析ツール - VBA]アドインをチェックしてください。
また、一部 ActiveSheet の値を書き換えますので気をつけてください。

Option Explicit
Const barName = "XIRRテスト"
Const str1 = "-10000000,2750000,4250000,3250000,2750000"
Const str2 = "1998/1/1,1998/3/1,1998/10/30,1999/2/15,1999/4/1"
'-------------------------------------------------
'コマンドバー削除
Sub DeleteMenuBar()
  On Error Resume Next
  Application.CommandBars(barName).Delete
  '必要なければ後で手動でAddIn撤去してください。
  'Application.AddIns("分析ツール - VBA").Installed = False
  On Error GoTo 0
End Sub
'-------------------------------------------------
'コマンドバー作成表示
Sub MakeMenuBar()
  Dim i As Long

  Call DeleteMenuBar
  Application.AddIns("分析ツール - VBA").Installed = True
  With Application.CommandBars.Add(Temporary:=True)
    .Name = barName
    .Position = msoBarTop
    .Visible = True
    For i = 1 To 5
      With .Controls.Add(Type:=msoControlButton)
        .Style = msoButtonIconAndCaption
        .OnAction = "xirrTest" & i
        .Caption = "xirrTest" & i
        .FaceId = 2950
      End With
    Next
    With .Controls.Add(Type:=msoControlButton)
      .Style = msoButtonIconAndCaption
      .OnAction = "DeleteMenuBar"
      .Caption = "閉じる"
      .FaceId = 1019
    End With
  End With
End Sub
'-------------------------------------------------
Sub xirrTest1() '元の問題コード(当時のものからちょっと修正あり)
  Dim ary1() As Variant
  Dim ary2() As Variant
  Dim varRet As Variant
  Dim i   As Long
  Dim v1, v2

  v1 = Split(str1, ",")
  v2 = Split(str2, ",")
  ReDim ary1(0 To UBound(v1))
  ReDim ary2(0 To UBound(v2))

  For i = 0 To UBound(v1)  '金額
    ary1(i) = CDec(v1(i))
  Next i
  For i = 0 To UBound(v2)  '日付
    ary2(i) = CDate(v2(i)) '■
  Next i
  varRet = Application.Run("atpvbaen.xla!xirr", ary1, ary2)
  If Not IsError(varRet) Then
    MsgBox CDec(varRet)
  Else
    MsgBox CStr(varRet)
  End If
End Sub
'-------------------------------------------------
Sub xirrTest2() '一応これで解決
  Application.OnTime Now, "xirrTest1"
End Sub
'-------------------------------------------------
Sub xirrTest3() 'CDate(v2(i))なし
  Dim ary1() As Variant
  Dim ary2() As Variant
  Dim varRet As Variant
  Dim i   As Long
  Dim v1, v2

  v1 = Split(str1, ",")
  v2 = Split(str2, ",")
  ReDim ary1(0 To UBound(v1))
  ReDim ary2(0 To UBound(v2))

  For i = 0 To UBound(v1)  '金額
    ary1(i) = CDec(v1(i))
  Next i
  For i = 0 To UBound(v2)  '日付
    ary2(i) = v2(i)
  Next i

  varRet = Application.Run("atpvbaen.xla!xirr", ary1, ary2)
  If Not IsError(varRet) Then
    MsgBox CDec(varRet)
  Else
    MsgBox CStr(varRet)
  End If
End Sub
'-------------------------------------------------
Sub xirrTest4() '簡略版
  Dim ary1  As Variant
  Dim ary2  As Variant
  Dim varRet As Variant

  ary1 = Split(str1, ",")
  ary2 = Split(str2, ",")

  varRet = Application.Run("atpvbaen.xla!xirr", ary1, ary2)
  If Not IsError(varRet) Then
    MsgBox CDec(varRet)
  Else
    MsgBox CStr(varRet)
  End If
End Sub
'-------------------------------------------------
Sub xirrTest5() 'セル経由
  Dim varRet As Variant

  Range("A1:E1").Value = Split(str1, ",")
  Range("A2:E2").Value = Split(str2, ",")

  varRet = Application.Run("atpvbaen.xla!xirr", Range("A1:E1"), Range("A2:E2"))
  If Not IsError(varRet) Then
    MsgBox CDec(varRet)
  Else
    MsgBox CStr(varRet)
  End If
End Sub

xirrTest1 のみ、エラーになります。
これは Application エラーではなく、XIRR 関数がエラー値を返すという事です。



他のテスト結果。



xirrTest3, xirrTest4, xirrTest5 は XIRR 関数へ渡す引数を少しずつ変えてあります。
結論としては、xirrTest1 の引数に
>ary2(i) = CDate(v2(i)) '■
ここで Date 型の配列を渡している事が原因のようです。
Application.OnTime メソッドを使わなくても良かったという事ですね...

ただ、標準モジュールだとエラーにならない理由は相変わらずナゾのまま......orz
Comment
  • X
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする