VBAでOKwaveの特定のカテゴリを取得する方法は?

このQ&Aのポイント
  • OKwaveの管理をvbaで行なっているのですが、VBAで最終的に、カテゴリの「214/905/c906.html」を取得したいのですが、どういうコードを作ればいいのでしょうか?
  • VBAでOKwaveの特定のカテゴリを取得する方法について教えてください。
  • VBAを使用してOKwaveのカテゴリ「214/905/c906.html」を取得する方法を教えてください。
回答を見る
  • ベストアンサー

OKwaveの管理をvbaで行なっているのですが

VBAで最終的に、カテゴリの「214/905/c906.html」を取得したいのですが どういうコードを作ればいいのでしょうか? Sub Sample() Dim mystr As String mystr = "<li><a href=""/c214.html"">ライフ</a>&nbsp;&gt;</li><li><a href=""/214/c905.html"">出産・育児</a>&nbsp;&gt;</li><li><a href=""/214/905/c906.html"">育児</a>&nbsp;</li>""" End Sub 私としては「a href=""」より右をMidかRightで取得しようと思うのですが このカテゴリーだと「a href=""」は3つあり、 一番最後の「a href=""」もしくは 左からではなく、右からみて一番最初の「a href=""」を取得するにはどうすればいいでしょうか? 一番左の「a href=""」なら Sub Sample() Dim mystr As String mystr = "<li><a href=""/c214.html"">ライフ</a>&nbsp;&gt;</li><li><a href=""/214/c905.html"">出産・育児</a>&nbsp;&gt;</li><li><a href=""/214/905/c906.html"">育児</a>&nbsp;</li>""" intStart = InStr(1, mystr, "a href=""") mystr = Mid(mystr, intStart) End Sub なら行けるのですが、一番右を取得する方法、 もしくはもっと効率の良い方法があれば教えてください。

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

  • ベストアンサー
回答No.1

3つだって分かってるなら、IsStr関数を3回使うとか。 intFirst = InStr(1, mystr, "a href=""") ' 最初の intSecond = InStr(intFirst+1, mystr, "a href=""") ' 2番目の intStart = InStr(intSecond+1, mystr, "a href=""") ' 3番目の あるいは、右から検索するなら、InStrRrv関数を使用とか。 intStart = InStrRev(mystr, "a href=""") InStrRev 関数 (Visual Basic) https://msdn.microsoft.com/ja-jp/library/t2ekk41a(v=vs.90).aspx

nyoqpdipa
質問者

お礼

回答ありがとうございました。

その他の回答 (3)

回答No.4

' 前の投稿(No.3)の続きです。  ' // 質問ページデータ取得 / 実行マクロ Sub ReW9176572() Dim oIE As Object ' As SHDocVw.InternetExplorer ' (最初に開いたIEウィンドウの)最後に表示していたIEタブ取得  ' oIE As SHDocVw.IWebBrowser2 → As SHDocVw.InternetExplorer  If FindActiveIExpr(oIE) = False Then MsgBox "IEがActiveじゃないよ!": Exit Sub Dim sURLq As String ' 【QAページのURL】  sURLq = oIE.LocationURL Debug.? sURLq  If Not sURLq Like "http://bekkoame.okwave.jp/qa##*##.html*" Then ' ▽URLチェック   MsgBox "'bekkoame.okwave'のQAページをIEに表示してから再実行"   Set oIE = Nothing   Exit Sub  End If Dim oDoc As Object ' As MSHTML.HTMLDocument Dim colElm As Object ' As MSHTML.IHTMLElementCollection Dim oDiv As Object ' As MSHTML.HTMLDivElement  Set oDoc = oIE.document  Set oIE = Nothing  ' <ul class="bread">  ' <li><a href="/">Bekk...</a>...</li>  ' <li><a href="/c214...</a>...</li>  ' <li><a href="/214/c905...</a>...</li>  ' <li><a href="【/214/905/c906.html】">育児</a>...</li>  ' </ul> ''▽  ' > ..カテゴリの「214/905/c906.html」を取得.. Dim sCatPath As String ' 【カテゴリ パス】  Set colElm = oDoc.getElementsByClassName("bread")  With colElm(0).Children   sCatPath = .Item(.Length - 1).FirstChild.pathname ' ★最後の要素★のパス  End With Debug.? sCatPath,  ' <input type=... id="transfer_url" name=... value="【/qa#######.html】"> ''▽ Dim sQaPath As String ' 【QAパス】  Set oDiv = oDoc.getElementById("transfer_url")  sQaPath = oDiv.Value Debug.? sQaPath,  ' <input type=... id="qid" value="【#######】" /> ''▽ Dim nQaId As Long ' 【QA番号(ID)】  Set oDiv = oDoc.getElementById("qid")  nQaId = Val(oDiv.Value) Debug.? nQaId  ' <p class=... id="question_title">【QAタイトル】</p>  ' <p class="datail_tex qa_tex"><span id="question">【Q本文(行1)】<br />  ' 【Q本文(行2)】<br />  ' 【...】  ' 【Q本文(最終行)】</span></p>  ' <p>投稿日時 - 【yyyy-mm-dd hh:mm:ss】</p> ''▽▽▽ Dim sQaTitle As String ' 【QAタイトル】  Set oDiv = oDoc.getElementById("question_title")  sQaTitle = oDiv.innerText Debug.? "◆"; sQaTitle Dim sQTxt As String ' 【Q本文】  Set oDiv = oDoc.getElementById("question")  sQTxt = oDiv.innerText Debug.? sQTxt Dim dtQPost As Date ' 【Q投稿日時】  dtQPost = Replace(oDiv.ParentNode.NextSibling.NextSibling.innerText, "投稿日時 - ", "") Debug.? dtQPost,  ' <div class="ico_qLevel_box_favusr flo_l"><div class="ico_q_level_0#_?"></div></div>  ' <p class="font_siz_10 tx_align_c">【暇なときに回答ください|困ってます|すぐに回答ほしいです】</p> ''▽ Dim sQLev As String ' 【Qレベル】  Set colElm = oDoc.getElementsByClassName("ico_qLevel_box_favusr flo_l")  sQLev = colElm(0).NextSibling.NextSibling.innerText Debug.? sQLev,  ' <div class="ok_lq_detail_ttl flo_l">  '  <div class="ico_question_l"></div>  '  <h2>【回答受付中の質問|解決済みの質問|締切り済みの質問】</h2>  ' </div> ''▽ Dim sQSts As String ' 【Qステータス】  Set colElm = oDoc.getElementsByClassName("ico_question_l")  sQSts = colElm(0).NextSibling.innerText Debug.? sQSts,  ' <a id="fav_qa" href="...">お気に入りに登録</a><span id="fav_qa_span">(<font id="fav_qa_count">【#】</font>)</span> ''▽ Dim nQaFav As Long ' 【QAお気に入り】  Set oDiv = oDoc.getElementById("fav_qa_count")  nQaFav = Val(oDiv.innerText) Debug.? nQaFav,  '  <b id="sum_instructive" class="color_FFCC00">【#】</b>  '  人が「このQ&amp;Aが役に立った」と投票しています ''▽ Dim nQaInstr As Long ' 【QA役に立った】  Set oDiv = oDoc.getElementById("sum_instructive")  nQaInstr = Val(oDiv.innerText) Debug.? nQaInstr  ' <div class="ok_lq_detail_l">|<div class="ok_lq_bestA_detail_l">|<div class="ok_lq_answer_l">  '  ...  '  <div class="tx_align_c">  '  <p><a href="【user.php3?u=#######】">【ユーザー名】</a></p>  '  </div>  '  ...  ' </div> ''▽▽ Dim sUserName As String ' 【ユーザー名】 Dim sUserPath As String ' 【ユーザーパス】  Set colElm = oDoc.getElementsByClassName("tx_align_c") ' 質問者/回答者 全 名前 相対パス Debug.? "質問者:",  For Each oDiv In colElm   If oDiv.tagName = "DIV" Then    sUserName = Trim$(oDiv.innerText) ' 質問者/BA回答者/回答者 全 名前 Debug.? sUserName,    On Error Resume Next    sUserPath = "/" & oDiv.Children(0).FirstChild.nameProp ' 質問者/回答者 全 相対パス    If Err Then Debug.? "●BA●",     sUserPath = "/" & oDiv.Children(0).FirstChild.NextSibling.nameProp ' BA回答者 相対パス    End If Debug.? sUserPath    On Error GoTo 0   End If  Next End Sub  ' //

nyoqpdipa
質問者

お礼

回答ありがとうございました。

回答No.3

こんにちは。お邪魔します。 > OKwaveの管理をvbaで行なっているのですが > もしくはもっと効率の良い方法があれば教えてください。 VBAでHTMLテキスト取得(&部分切り分け)が出来ているのでしたら、 正規表現 VBScript.RegExp(VBScript_RegExp_55.RegExp) で『マッチした最後のもの』を抽出出来ます。 > VBAで最終的に、カテゴリの「214/905/c906.html」を取得したいのですが  Set oRegExp = CreateObject("VBScript.RegExp")  With oRegExp   .Global = True   .IgnoreCase = True   .Pattern = "<a href=\""*([^>\""]+)\""*"  End With  Set colMatch = oRegExp.Execute(myStr)  myRet = colMatch(colMatch.Count - 1).SubMatches(0) でも、文字列の並びに頼って処理する場合は(Instrも同じ)、 ページデザインのちょっとしたマイナーチェンジにも 都度都度対策が必要になったりして(私も本家OKWAVEで何度も苦労しました) 後々不安は残ります。 そもそも、 > このカテゴリーだと「a href=""」は3つあり、 <a href= ... が3つしか無い部分を抜き出す処理を済ませてある前提ですよね? 実際はもっと数多くあるし、ページによって増減する可能性も否定できませんし、、、。 となると、その抜き出し方次第、、、ではあります。 bekkoame.okwaveのQAページをInternetExprolerで開いている、 ということのようですから(←添付画像を見ての判断)、 そのまま、HtmlDocumentに対してDOMで処理するのが普通のやり方かな、と。 データ採りしたいQAページを表示した状態から実行するマクロ(DOM版)を、   次の投稿に掲げます。 (最初に開いたIEウィンドウの)最後に表示していたIEタブを取得 する関数を   この投稿の下部に掲げます。 文字数制限の関係で、2つの投稿に分けますが、 普通に標準モジュールに2つ並べて貰って、 次の投稿にある / 実行マクロ を実行してみて下さい。 DOM操作に慣れることを意図して、幾つかのデータを取得する例を挙げてみます。  Htmlソースを併記して   .getElementsByClassName   .getElementById  だけで検索するように(解り易さ優先の練習教材として)統一しています。 ソースを読む場合は、  IE [ページ] → [ソースの表示] または [表示] → [ソース] と  IE [ツール] → [F12 開発ツール] または F12キー  の   [DOM Explorer] や [デバッガー] を活用して、 VBAで要素への参照に迷った時は、  VBE ステップ実行(F8キー や ブレークポイント等) と  VBE [ローカルウィンドウ] を組み合わせて、求める属性を指すプロパティを探してみて下さい。 基本的な技術情報等は、  VBA IE HTMLDocument getElementsByClassName getElementById などのキーワードでWeb検索をどうぞ。 因みにこの回答も、VBAで取り込んだ質問ページデータを基に状況を確認して、 解答案作成や検証にも活用しています。 以前は私もbekkoame.okwaveさんから資料を採らせて頂いていましたが、 広告なしの運営で、且、運営側に販促的な価値を求める様子もないことから、 標準的な利用以外は控えようという意見が多くなっていた時期もありました。 (ここ数年、本家はリニューアルしても追随していないこともあり、  もう、あまりコストをかけたくないのかなぁとか?まだ続くのかなぁ?とか) たぶん、、、本家OKWAVEとは違い、アクセス(閲覧)数が増えることが 利益に繋がることのない(維持管理コストばかりの)運営なのでしょう。 現に閲覧しているページのデータを採ることには問題はないだろう、という 考えで、VBAによるデータ取得のサンプルをあげますが、 私個人としては、目的の為にわざわざアクセスするような使い方は 勧めるつもりはありませんので、その点ご理解ください。  ' // (最初に開いたIEウィンドウの)最後に表示していたIEタブ取得 Function FindActiveIExpr(ByRef oIE As Object) As Boolean ' oIE As SHDocVw.InternetExplorer Dim oShell As Object ' As Shell32.Shell Dim oExpr As Object ' As SHDocVw.IWebBrowser2 Dim sStB0 As String ' 各IEタブの.StatusText:既定の値 Dim sStB As String ' 各IEタブの.StatusText:最後に表示していたかチェックする為のダミーの値 Dim blnStB As Boolean  Set oShell = CreateObject("Shell.Application")  DoEvents  For Each oExpr In oShell.Windows   If TypeName(oExpr.document) = "HTMLDocument" Then    blnStB = oExpr.StatusBar    If Not blnStB Then oExpr.StatusBar = True    sStB0 = oExpr.StatusText    sStB = CStr(Date & " " & Timer())    oExpr.StatusText = sStB    If oExpr.StatusText = sStB Then     oExpr.StatusText = sStB0     If Not blnStB Then oExpr.StatusBar = False     Exit For    End If    If Not blnStB Then oExpr.StatusBar = False   End If  Next  If oExpr Is Nothing Then Exit Function  Set oIE = oExpr  Set oShell = Nothing: Set oExpr = Nothing  FindActiveIExpr = True End Function  ' // ' 次の投稿へ続きます。

nyoqpdipa
質問者

お礼

回答ありがとうございました。

  • watabe007
  • ベストアンサー率62% (476/760)
回答No.2

>カテゴリの「214/905/c906.html」を取得した 参考に Dim mystr As String, mystr2 As String, mystr3 As String Dim arrStr As Variant mystr = "<li><a href=""/c214.html"">ライフ</a>&nbsp;&gt;</li><li><a href=""/214/c905.html"">出産・育児</a>&nbsp;&gt;</li><li><a href=""/214/905/c906.html"">育児</a>&nbsp;</li>""" arrStr = Split(mystr, "a href=""/") mystr2 = arrStr(UBound(arrStr) - 1) MsgBox mystr2 mystr3 = Split(mystr2, """>")(0) MsgBox mystr3

nyoqpdipa
質問者

お礼

回答ありがとうございました。

関連するQ&A

  • VBA 複数の文字のコードを一気に返すには

    Sub test1() Dim myStr As String myStr = "abc" Debug.Print Asc("a") Debug.Print Asc(myStr) End Sub このコードは、どちらも97が返るのですが、 myStrは3文字です。 3文字全ての文字コードを返すには、 Sub test2() Dim myStr As String myStr = "abc" Debug.Print Asc(Mid(myStr, 1, 1)) & Asc(Mid(myStr, 2, 1)) & Asc(Mid(myStr, 3, 1)) End Sub のようにするしかないのでしょうか?

  • 配列 変数の宣言 VBA

    こんばんは。 Sub test() Dim myStr(200) As String For 行 = 0 To Cells(Rows.Count, 1).End(xlUp).Row myStr(行) = Cells(行 + 1, 1) Next MsgBox Join(myStr, "_") End Sub のようなコート゛を作成し、 アクティブシートのA列の最終行までを取得し、一つにまとめたいのですが 「Dim myStr(200) As String」の部分で 最終行を取得することは不可能でしょうか? 今回は200行なので大丈夫なのですが 場合によっては1行~65536行までさまざまです。 なので Dim myStr(Cells(Rows.Count, 1).End(xlUp).Row) As String としたらエラーになりました。 最初から Dim myStr(65536) As String とするべきでしょうか? しかしそうすると myStrの最後がずっと「________」となってしまいます。 どうするのが適切なのかわかりません。 ご教授よろしくお願いします。

  • セル番地をvbaで探したい

    エクセルのセルに A1→あ B1→い C1→う がはいっています。 この状態で Sub Macro1() Dim mystr1 As String mystr1 = "c1" MsgBox mystr1 & "の値は、" & "です。" End Sub を実行した時に、mystr1のアドレスを探して、msgboxに表示させたいのですが、 どのような方法があるのでしょうか? アドバイスよろしくお願いします。

  • 二次元配列のVBA

    二次元配列のVBAの書き方がよくわからないのですが、 私が作ったサンプルプログラムのSub 二次元()において 二次元配列で表すにはどうすればいいのでしょうか? Sub 二次元()では 配列を格納する変数はtmpしか使っていませんが もう一つ配列を格納する用の変数を作ればいいのでしょうか? 数字とアルファベットは別々に取り出したいです。 ----------------------------------------------------- Sub 一次元() Dim myStr As String Dim tmp As Variant Dim i As Long For i = 1 To 5 myStr = myStr & "," & i Next myStr = Mid(myStr, 2) tmp = Split(myStr, ",") For i = LBound(tmp) To UBound(tmp) Debug.Print tmp(i) Next i End Sub Sub 二次元() Dim myStr As String Dim tmp As Variant Dim i As Long For i = 1 To 5 myStr = myStr & "," & i & "と" & Chr(64 + i) Next myStr = Mid(myStr, 2) tmp = Split(myStr, ",") For i = LBound(tmp) To UBound(tmp) Debug.Print tmp(i) Next i End Sub

  • vbaでCountIf関数を使いたい(エクセル)

    A1セルにa-a-aがはいっています。 この場合aは3つですよね。 これをvbaで取得するコードを作っているのですがうまくできません。 Sub test() Dim myStr As String myStr = "a" MsgBox WorksheetFunction.CountIf(Cells(1, 1), "*" & myStr & "*") End Sub これをすると、なぜか1が返ってきます。 Aは3つあるのになぜ1が返るのでしょうか? A1にaaaaaを入れて実行しても1が返ります。

  • vbaで配列に値を格納する場合

    vbaで配列に値を格納する場合 変数の宣言はどちらを使った方が良いのでしょうか? Sub Sample1() Dim i As Long Dim myStr As String Dim tmp() As String myStr = "a,i,u,e,o" tmp = Split(myStr, ",") End Sub か Sub Sample1() Dim i As Long Dim myStr As String Dim tmp As Variant myStr = "a,i,u,e,o" tmp = Split(myStr, ",") End Sub でも問題なく動くのですが、 Variant型での宣言はあまりしない方が良いですか? あと Dim tmp() As String ならエラーにならないのですが Dim tmp As String だとエラーになってしまう理由がよくわからないので教えて頂けますか?

  • 値渡し?参照渡し?をやりたい

    「#00B7EF」を「&HEFB700」にする関数を作ってるのですが 初心者のため躓いてしまいました。 コードは ++++++++++++++++++++++++++++++++++++++++++++++++++++ Sub 色コード() myStr = "#00B7EF" Debug.Print 色コード変換(myStr) End Sub Function 色コード変換() Dim myStr1 As String Dim myStr2 As String Dim myStr3 As String myStr1 = Mid(myStr, 2, 2) myStr2 = Mid(myStr, 4, 2) myStr3 = Mid(myStr, 6, 2) 色コード変換 = "&H" & myStr3 & myStr2 & myStr1 End Function ++++++++++++++++++++++++++++++++++++++++++++++++++++ を作ったのですが、 End Functionを過ぎてから 実行時エラー_型が一致しません。(Error13) になります。 Sub 色コード()の時に、型を宣言してないからでしょうか? しかし、 Function 色コード変換(as String) にすると赤くなってしまいます。 ご教授よろしくお願いします。

  • VBA 変数にアスタリスクが含んでるかどうか

    変数にアスタリスクが含んでるかどうかをIFステートメントで取得するには? Sub test() Dim mystr As String mystr = "*/" If mystr Like "*" Then MsgBox "mystrはアスタリスクを含んでます。" End If End Sub このようなことをしたい場合、 mystr = "*/" でも mystr = "/" でも、結局は*が、どの文字でも含まれると認識してしまいます。 変数にアスタリスクが含まれてるかどうかを判定する方法を教えてください。

  • 【1】と【2】のvbaは同じ意味ですか?

    【1】 Option Explicit Sub test1() Call test2("aaa") End Sub Sub test2(MyStr As String) MsgBox MyStr End Sub 【2】 Option Explicit Dim MyStr As String Sub test1() MyStr = "aaa" Call test2 End Sub Sub test2() MsgBox MyStr End Sub 結果は同じですが、中身が違います。 今後コードを作っていく上で どちらの方式の方が良いのでしょうか?

  • 【エクセルvba】(1)(2)(3)を区切りとして分けたい 配列

    こんばんは。 もしエクセルで可能なら教えていただきたいです。(2003です) A1セルに (1)りんご(2)みかん(3)バナナ と入力されています。 これを A2にりんご、B2にみかん、C2にバナナ とSplitと使って区切りたいのですが不可能でしょうか? 以下がここのサイトを参考にして作ったサンプルマクロです。 Sub サンプル() Dim myStr As String Dim ar As Variant myStr = Cells(1, 1) ar = Split(myStr, "") '←この部分をどうすればいいのかわからない Cells(2, 1).Resize(1, UBound(ar) + 1).Value = ar End Sub やはり、区切る文字が複数ある場合は不可能でしょうか? ご教授よろしくお願いします。

専門家に質問してみよう