VBAでOKwaveの特定のカテゴリを取得する方法は?
- 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> ></li><li><a href=""/214/c905.html"">出産・育児</a> ></li><li><a href=""/214/905/c906.html"">育児</a> </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> ></li><li><a href=""/214/c905.html"">出産・育児</a> ></li><li><a href=""/214/905/c906.html"">育児</a> </li>""" intStart = InStr(1, mystr, "a href=""") mystr = Mid(mystr, intStart) End Sub なら行けるのですが、一番右を取得する方法、 もしくはもっと効率の良い方法があれば教えてください。
- nyoqpdipa
- お礼率87% (134/153)
- オフィス系ソフト
- 回答数4
- ありがとう数4
- みんなの回答 (4)
- 専門家の回答
質問者が選んだベストアンサー
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
その他の回答 (3)
- real beatin(@realbeatin)
- ベストアンサー率82% (174/211)
' 前の投稿(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&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 ' //
お礼
回答ありがとうございました。
- real beatin(@realbeatin)
- ベストアンサー率82% (174/211)
こんにちは。お邪魔します。 > 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 ' // ' 次の投稿へ続きます。
お礼
回答ありがとうございました。
- watabe007
- ベストアンサー率62% (476/760)
>カテゴリの「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> ></li><li><a href=""/214/c905.html"">出産・育児</a> ></li><li><a href=""/214/905/c906.html"">育児</a> </li>""" arrStr = Split(mystr, "a href=""/") mystr2 = arrStr(UBound(arrStr) - 1) MsgBox mystr2 mystr3 = Split(mystr2, """>")(0) MsgBox mystr3
お礼
回答ありがとうございました。
関連する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
- ベストアンサー
- Excel(エクセル)
- 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) にすると赤くなってしまいます。 ご教授よろしくお願いします。
- ベストアンサー
- その他MS Office製品
- 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 やはり、区切る文字が複数ある場合は不可能でしょうか? ご教授よろしくお願いします。
- ベストアンサー
- オフィス系ソフト
お礼
回答ありがとうございました。