Elseについて

タグの編集
投稿者 だるさん  (中学生) 投稿日時 2012/8/11 19:33:56
 Private Sub WebBrowser1_DocumentCompleted・・・・・・
        If ○○○○.○○○ = ○○ Then
            Me.Button1.Visible = True
            Me.WebBrowser1.Visible = False
        Else
            Me.WebBrowser1.Visible = True
        End If
    End Sub
End Class

WebBrowserのプロパティのVisibleをFalse

まぁこんな感じにしてるんですけど、こうするとWebBrowserが最初から表示されてしまいます。
どうしれば、直りますか?

回答宜しくお願いします。
投稿者 魔界の仮面弁士  (社会人) 投稿日時 2012/8/11 22:26:28
Else 句の下の .Visible = True の行で [F9] キーを押してみてください。
茶色の、いわゆる「ブレークポイント」が付くかと思います。
(F9 キーで反応しない場合は、左余白部をクリックします)


その状態で実行すると、ブレークポイントの所で一時停止しますので、
その時、If 文の条件がどのような値になっているのかを確認してみてください。
投稿者 だるさん  (中学生) 投稿日時 2012/8/12 10:23:01
>>> 魔界の仮面弁士  さん

ブレークポイントの所で一時停止まで、できたのですが
 >If 文の条件がどのような値になっているのかを確認してみてください。
が分かりません。

もうすこし詳しく教えて頂けると幸いです。
投稿者 drm  (中学生) 投稿日時 2012/8/12 17:25:44
メニューバーの「デバッグ」から
ウィンドウ→ウォッチと進んで、画面にウォッチウィンドウを表示させてください。

コードを書いたウィンドウの
If (条件) Then
の (条件) の範囲を選択して、ウォッチウィンドウにドラッグして下さい。
ウォッチウィンドウの「名前」に 条件が、「値」にその値が表示されます。


話は変わりますが、自演なんてことはしてませんよね
投稿者 魔界の仮面弁士  (社会人) 投稿日時 2012/8/12 17:40:55
> もうすこし詳しく教えて頂けると幸いです。 
デバッグの方法は、VB中学校の[初級講座]でも触れられていますので、まだ読んだことが無ければ
 第41回 実行の一時停止とデバッグ
 第42回 初めてのデバッグ
を参考にしてみてください。図解されている VB のバージョンがやや古いですが、
書かれている内容そのものは、現在のバージョンにもあてはまります。


デバッグ中断中に[F10]キーを押すと、一行進みます(ステップ実行)。
処理順をチェックする場合にも便利なので、こうしたデバッグ機構を習得しておくと、
開発作業が楽になりますよ。



> ブレークポイントの所で一時停止まで、できたのですが
という事は、Else 句が実行されてしまう状況であることまでは確認できているかと思います。

その次に行うのは、何故 Else が実行されてしまっているのかのチェックです。
すなわち、If 文の条件がどのような値になっているのかを確認するという作業のため。


今回は説明の為、
> If ○○○○.○○○ = ○○ Then
の部分が、
If e.Url.ToString() = "http://homepage1.nifty.com/rucio/main/main.htm" Then
と書かれていたと仮定して説明していきます。


こういった条件式の値を確認する方法としては、以下のような手法があります。

デバッグにはいろいろな方法がありますので、下記に挙げた手順を一つ一つ試してみて、
その時々にあったデバッグ機能を使いわけてみてください。


===================
(1) ツールチップで確認する方法
-------------------
中断モードにおいては、変数名にマウスカーソールを重ねてしばらく待機すると、
ツールチップ内に変数の内容が表示されるようになっています。

これを使えば、e.Url が返している内容をチェックすることができるでしょう。


このツールチップは、左横の[+]ボタンで階層を展開できます。
また、VS2010 以降のバージョンでは、ツールチップ右横の虫ピンアイコンを使って、
これを常に表示させたままにしておくこともできます。

また、VS2008以降のバージョンでは、ツールチップ表示中に Ctrl キーを押すことで、
一時的にツールチップが半透明になり、下の文字を読み取めるようになっています。



===================
(2) 「自動変数」を利用する方法
-------------------
中断モードのこのウィンドウには、現在のプロシージャ内で使用中の変数が一覧されます。


自動変数ウィンドウをうっかり閉じてしまった場合には、中断モード時に、
メニューの[デバッグ]-[ウィンドウ]-[自動変数] から再表示できます。



===================
(3) 「クイック ウォッチ」を利用する方法
-------------------
デバッグしたい式、たとえば「e.Url.ToString()」の部分をドラッグで反転させた後、
マウスで右クリックします。次に右クリックメニュー(コンテキストメニュー)から、
[クイック ウォッチ]を選択すると、その式の現在の値が表示されます。

これにより、現在の URL が "http://homepage1.nifty.com/rucio/main/main.htm" なのか、
それとも "http://www.google.co.jp/" だったのかなどを確認することができます。


クイックウォッチに指定するデバッグ式は自由に設定できます。具体的には、
 「e.Url.ToString()」
 「e.Url」
 「e.Url.ToString() = "http://homepage1.nifty.com/rucio/main/main.htm"」
などといったものです。


===================
(4) 「ウォッチ」を利用する方法
-------------------
[クイックウォッチ]と似たものとして、[ウォッチ式]という機能もあり、
これも同様に、右クリックメニューから指定できるようになっています。

「クイックウォッチ」の場合は、一つのデバッグ式しか表示できなかったのですが、
「ウォッチ式」では複数の変数や式の値を同時に並べて表示できます。



一つのウォッチウィンドウには、複数の式を表示させることができますし、
ウォッチウィンドウ自体を複数(最大4枚まで)開くこともできます。
ウォッチウィンドウをうっかり閉じてしまった場合には、中断モード時に、
メニューの[デバッグ]-[ウィンドウ]-[ウォッチ] から再表示できます。

ウォッチ したい条件を増やしたい場合には、ウォッチウィンドウ上に、
条件式などを直接記述してみてください。



===================
(5) イミディエイト ウィンドウを利用する方法
-------------------
イミディエイト ウィンドウは、値のチェックや簡易ステートメント実行に利用できる、
非常に汎用性の高いデバッグツールです。

まずは中断モード中に[イミディエイト] ウィンドウを表示させてください。
これは通常、Ctrl + Alt + I のキーボードショートカットで表示されるようになっています。
(Ctrl と Alt キーを押しながら I を押すということです)

メニューから起動させる場合には、[デバッグ]-[ウィンドウ]-[イミディエイト] です。


このイミディエイト ウィンドウで、? に続けて式を書くと、その式の内容が表示されます。
たとえば「? e.Url.ToString()」などですね。


ここでは変数値の確認の他、「Me.Button1.Visible = True」などのように、プロパティや変数の
代入操作も行えますし、「MsgBox("TEST")」などのようにメソッドの実行テストも行えます。

また、イミディエイト上で「foo = 123」「abc = "TEST"」などといった、
未宣言の変数への代入を行うと、自動的に変数 foo や変数 abc が
一時的に作成されます。数値計算結果などをチェックする場合にも便利かと。



===================
(6) Debug.WriteLine や Debug.Print 等を用いる方法
-------------------
調査したい DocumentCompleted イベントの先頭に、
 Debug.WriteLine(e.Url)
という一行を記述しておきます。
こうすると、その時の変数の値がデバッグ画面上に表示されます。


出力先は、「出力 ウィンドウ」となります。
出力ウィンドウが無い場合は、[デバッグ]-[ウィンドウ]メニューで表示できます。
(EXE 作成時の構成が、"Debug"ではなく"Release"になっているときは出力されません)


なお、出力ウィンドウの代わりに「イミディエイト ウィンドウ」に
表示される場合もあります。どちらに表示されるかは、Visual Studioの
[ツール]-[オプション]ダイアログにある、[デバッグ]-[全般]の
『☑出力ウインドウの文字をすべてイミディエイトウインドウにリダイレクトする』
で切り替えられます。
上記項目が見つからない場合は、オプションダイアログ下部にある
「すべての設定を表示」の欄を切り替えてみてください。


この Debug を用いる方法だと、コードを一時停止させずに値を確認できるため、
連続したイベントの流れを追う場合などに都合が良いでしょう。

Debug の内容は、テキストファイルやイベントログ、あるいは任意の出力先(データベース等)に
出力させることもできます。開発環境が入っていない実行環境でのテスト時にも便利ですよ。
投稿者 だるさん  (中学生) 投稿日時 2012/8/12 19:29:00
Ifの後の○は

If (Strings.InStr(Me.WebBrowser1.Document.Body.InnerText, ChrW(12450) & ChrW(12513) & ChrW(12540) & ChrW(12496) & "ID" & ChrW(12418) & ChrW(12375) & ChrW(12367) & ChrW(12399) & ChrW(12497) & ChrW(12473) & ChrW(12527) & ChrW(12540) & ChrW(12489) & ChrW(12434) & ChrW(30906) & ChrW(35469) & ChrW(12375) & ChrW(12390) & ChrW(19979) & ChrW(12373) & ChrW(12356), CompareMethod.Binary) > 0) Then

ですw
長いので言いませんでした。

やり方は
(1) ツールチップで確認する方法
でやりました。

その後どうしればいいのですか?
投稿者 魔界の仮面弁士  (社会人) 投稿日時 2012/8/12 20:47:06
説明して頂いた内容からすると、
>> こうするとWebBrowserが最初から表示されてしまいます。
という状況というのは、

(1) DocumentComplted のコードが実行されたとしても実行されなかったとしても、
 WebBrowser1 の Visible がそもそも True になってるため、表示されている。

(2) WebBrowser1 自体はデザイン時に非表示に設定しているが、
 DocumentCompleted の条件分岐のコードで Else 句が実行されており、
 「Me.WebBrowser1.Visible = True」によって表示されてしまう。

のいずれかであると推測しています。

デザイナの段階で、WebBrowser1 の Visible を True にしているか False にしているのかは
流石に把握しておられるでしょうから、(1) ということは考慮しておりません。そのため、ここでは
(2) の可能性についての調査が必要と思い、デバッグ手法について説明した次第です。



> Ifの後の○は
> ですw
もっと単純に、これでは駄目でしょうか。
If WebBrowser1.Document.Body.InnerText Like "*アメーバIDもしくはパスワードを確認して下さい*" Then



> その後どうしればいいのですか? 
どう知れば良いか…と言われても、単に InnerText プロパティが返す値を調べるだけですよ。
そしてその内容が意図したものであるかを確認する、と。


提示の If 文が、どの URL に対して、何のための処理を目的として記述されたものなのかという
肝心な『コードの意図』が説明されていないため、現在のコードが適切なのかどうかは
掲示板を見ている第三者には分かりません。動作確認はご自身で行い、判断するしかないわけです。


そもそも Else 句に行ってしまうという事は、If 側の条件にヒットしなかったということですから、
 ・自身で意図した通りに If 判定が行われているのかを確認せねばならない。
 ・If 判定で確認しているのは、InnerText で得られる文字列の内容である。
 ・故にその文字列が、具体的にはどういうテキストになっているのかを確認する必要がある。
という事になります。
どんな値が返ってくるのかを調査できるのは、実際にそのコードを実行可能なだるさんさんだけです。
(どうしたいのかが説明されていない以上、どうすべきかという具体的な提案を回答することもできません)


もしも期待する文字列が返っているにも関わらず、If ではなく Else に行ってしまうようであれば、
If に書いた条件式が間違っているはずなので、御自身が意図する結果となるように
コードを見直してみてください。たとえば、半角全角の間違いなどがあるかも知れません。

あるいは「表示する」「表示しない」の二択ではなく、リクエストされる内容に応じて、
「表示する」「表示しない」「Visible を変更しない」の三択が必要なのかもしれませんし、
もしかしたらご自身で気づいていなかった、全く別の InnerText が得られているのかも知れません。


それと、DocumentCompleted が複数回呼び出されていないかどうかも
確認しておいた方が良いでしょう。

たとえば、一回の Navigate 処理で 2 回の DocumentCompleted が発生しており、
 ・1回目のイベントで返された InnerText は、条件に合致せずに「.Visible = False」となった。
 ・2回目のイベントで返された InnerText は、条件に合致したため「.Visible = True」となった。
のように、If と Else の両方が実行されていたとすれば、処理順によっては
WebBrowser が表示されることも表示されないこともありうるわけです。
投稿者 だるさん  (中学生) 投稿日時 2012/8/12 23:01:20
>>>DocumentCompleted が複数回呼び出されていないかどうかも
確認しておいた方が良いでしょう。

原因はこれと思います。


Msg("IDとPWが間違っています")

と入力したところ、これが3回でました。

どうしれば直るでしょうか?
投稿者 だるさん  (中学生) 投稿日時 2012/8/12 23:13:33
InnerText 'InnerText' は宣言されていません。アクセスできない保護レベルになっています。

って出ますねw

(値)
投稿者 だるさん  (中学生) 投稿日時 2012/8/12 23:23:28
>>>(2) WebBrowser1 自体はデザイン時に非表示に設定しているが、
 DocumentCompleted の条件分岐のコードで Else 句が実行されており、
 「Me.WebBrowser1.Visible = True」によって表示されてしまう。



>>>WebBrowserのプロパティのVisibleをFalse

と書いたので、(2)の方です。


何かいっぱい投稿しちゃってすみません。
投稿者 魔界の仮面弁士  (社会人) 投稿日時 2012/8/13 02:30:24
> Msg("IDとPWが間違っています")
> と入力したところ、これが3回でました。
> どうしれば直るでしょうか? 
(「どう知れば」というのは、どこかの方言なのでしょうか。「どうすれば」ではなく?)

直すにはまず、「DocumentCompleted イベントは複数回発生する可能性がある」という
前提に立ってコーディングすることが大事です。
なお、どういうときに複数回発生するのかは、以前回答しています。
http://rucio.cloudapp.net/ThreadDetail.aspx?ThreadId=11002#CommentId24396

確認できるよう、フレームセットを利用したサイトを具体例として挙げておきます。
WebBrowser1.Navigate("http://hanatyan.sakura.ne.jp/")
' 上記を実行すると、DocumentCompleted イベントが 3 回発生します。 
' 1 回目のイベントは  http://hanatyan.sakura.ne.jp/menu.htm の読み込み完了を、 
' 2 回目のイベントは  http://hanatyan.sakura.ne.jp/top.htm の読み込み完了を、 
' 3 回目のイベントは  http://hanatyan.sakura.ne.jp/ の読み込み完了を通知しています。 


また、インラインフレームを用いたサイトなども、複数回のイベント通知を引き起こします。
WebBrowser1.Navigate("http://bbs.wankuma.com/")



ですからそれぞれの DocumentCompleted イベント内で、引数 e の内容を調べ、
どの URL に対する通知なのかを確認し、不要なものを If 文で無視するなどの
対処をとってみてください。今のままだと、それらすべてが Else 句で処理されてしまうはずです。

もしも同じ URL で異なる内容を返すような場合には、
Document の内容をみて判断することも必要になるかも知れません。


> InnerText 'InnerText' は宣言されていません。アクセスできない保護レベルになっています。 
> って出ますねw
それは最初のコードの
 If (Strings.InStr(Me.WebBrowser1.Document.Body.InnerText, ChrW(12450) & ChrW(12513) …
の行で発生しているという事でしょうか。それとも別の作業中に発生したものでしょうか。
また、エラーが発生したときに参照していた Web サイトは?
投稿者 だるさん  (中学生) 投稿日時 2012/8/13 09:38:11
>それは最初のコードの
 If (Strings.InStr(Me.WebBrowser1.Document.Body.InnerText, ChrW(12450) & ChrW(12513) …
の行で発生しているという事でしょうか。それとも別の作業中に発生したものでしょうか。
また、エラーが発生したときに参照していた Web サイトは? 

あ~修正しますw

名前     値      形
InnerText Nothing Object

こんな感じですね。


えと、いろいろな詳細を言うと
WebBrowserプロパティURL=なし
ログインボタンを押すと=Me.WebBrowser1.Navigate(("http://pigg.ameba.jp/core/login.do?amebaId=" & Me.TextBox1.Text & "&password=" & Me.TextBox2.Text))
Button1.Visible = Falsh

Ifの文を見直すと
If WebBrowser1.Document.Body.InnerText Like "*アメーバIDもしくはパスワードを確認して下さい*" Then
Button1.Visible = True
Else
Button1.Visible = Flash
WebBrowser1.Visible = True

にすると、Button1がFalsh WebBrowser1がTrue になります。

ということです。

そして、僕の予想では "*アメーバIDもしくはパスワードを確認して下さい*"に対するElseなので
勿論、Else以降は"*アメーバIDもしくはパスワードを確認して下さい*"が表示されていない場合の
Button1がFalsh WebBrowser1がTrue です。

ということは、最初のページから "*アメーバIDもしくはパスワードを確認して下さい*"を表示されてる状態にしなければなりません。
ですが、それはおそらく無理です。

とりあえず参考URLは
http://pigg.ameba.jp/←ログインしている時と、していない時と、対応が違います。
http://pigg.ameba.jp/core/login.do?amebaId=←上記と一緒。
http://www.ameba.jp/login.do←アメーバIDが入力されていません。パスワードが入力されていません。と出る。
http://www.ameba.jp/logout.do←アメブロのログイン画面が出る

どうしればいいでしょうか。




投稿者 だるさん  (中学生) 投稿日時 2012/8/13 11:26:08
1つ提案があります。

If WebBrowser1.Document.Body.InnerText Like "*アメーバIDもしくはパスワードを確認して下さい*" Then

この"*アメーバIDもしくはパスワードを確認して下さい*"を URLにして実行することは可能でしょうか?

可能の場合はURL=https://pigg.ameba.jp/core/login これを例として教えてください。
投稿者 (削除されました)  () 投稿日時 2012/8/13 11:58:58
(削除されました)
投稿者 魔界の仮面弁士  (社会人) 投稿日時 2012/8/13 12:49:54
> この"*アメーバIDもしくはパスワードを確認して下さい*"を URLにして実行することは可能でしょうか?
メッセージ部分をURL に変換した上で実行させる……?
ごめんなさい、仰っている意味が理解できませんでした。


>  名前     値      形
> InnerText Nothing Object
> こんな感じですね。

「形」というのは「型」のことでしょうか。

せっかく投稿していただいたものの、これだけでは何に対する調査結果を
報告しておられるのか分からないので、もう少し追加説明を加えて頂けると助かります。


…恐らくは、ウォッチウィンドウの内容を書いて頂いたものと推察しますが、
いつ、どのスコープでそれが表示されているのかといったことが分からないため、
こちらで現象を再現させるには至っていません。

仮に、予想通りウォッチ式だったとして…どこかに InnerText という名前の変数を
用意しているのでしょうか。確認するのは InnerText プロパティではなく?

もし、最初のコードのまま実行したとすれば、InnerText という変数は無いため、
下記 ★1のように表示されるかと思います。


★1:変数自体が存在しない場合


★2:Object型の変数として宣言されていた場合



> Button1.Visible = Flash
>にすると、Button1がFalsh
Flash でも Falsh でもなく、False ですよね。
間違ったスペルで記憶されているようなので、この際しっかり覚えてしまいましょう。



> ?amebaId=" & Me.TextBox1.Text & "&password=" & Me.TextBox2.Text

パスワード等は流石に公開できないでしょうし、自分もアカウントを
持ち合わせているわけではないので、検証しようも無いのですが、
ここに指定している URL 自体は間違いないのですね?

なお、本来であれば、URL に埋め込む文字列はエンコードされねばなりません。
そのため Navigate する前には、TextBox の中身を検証し、必要に応じて
UrlEncode するようなコードを組み込むのが望ましいです。



> そして、僕の予想では "*アメーバIDもしくはパスワードを確認して下さい*"に対するElseなので
> 勿論、Else以降は"*アメーバIDもしくはパスワードを確認して下さい*"が表示されていない場合の
> Button1がFalsh WebBrowser1がTrue です。

ステップ実行すれば、予想が当たっているかどうかを容易に確認できますね。


> とりあえず参考URLは
それだけたくさんの URL が使われるのに、DocumentCompleted イベント内での処理が、
たったの 2 分岐で本当に良いのでしょうか。もっと細かい場合分けが必要であるように感じます。


> ログインしている時と、していない時と、対応が違います。
ログインに成功した場合と失敗した場合とで、
遷移先の e.URL もしくは Document の内容が異なるのですね?

であれば、それらが具体的にどのように違うのかを調査・分析してみてください。
調査しない事には、それに対するコードの書き方も分かりません。

どのように違うのかを知っているのは私ではなく、他でもないだるさんさん自身なのですから。



> どうしればいいでしょうか。

こういった機械的なアクセスの仕方は、サイト運営者が嫌うところでもあるので、
まずは、『運営者側に許可を取った上で開発するべき』かと思います。

今回提示していただいた URL は、開発者向けに Web API として公開されているような
ものではなく、一般ユーザーがブラウザ経由で利用することを前提としたものですよね?

以前はアメーバでも一般向けに開発者用APIが公開されていましたが、現在は公開を終了しています。
API として公開されているものを使う分には、あまり問題とはなりませんが、
一般利用者向けの URL をそのまま使う場合は、いろいろとデリケートな問題が関わってきます。


たとえば、ページの使いやすさの向上のため、ページあたりの滞在時間などを
運営者側が調査しようとした場合、機械的なアクセスは集計の邪魔となります。

あるいは、自動巡回ツールを使ってスクレイピングする行為が多発した場合、
広告等を見ることなくデータだけを無人で読み書きできてしまうので、
それが正常な運営の妨げになると判断される場合もあります。


また、ログイン補助のツールの作り方を掲示板で根掘り葉掘り聞いたり、あるいは
そのツールを公開したとすると、それらが、DoS の温床やチート行為を
招くことにもなりかねません。たとえば、多数のパスワードを順に試して
アカウントをハックしようとする辞書攻撃なども可能となるからです。

もちろんご本人にはその気が無いでしょうが、第三者が悪用する可能性を増大させるとの
理由から、サイト運営者側からの警告、時にはアカウントの停止/抹消といった対処が
取られたケースもあります。アメーバがそうであるかどうかは分かりませんが。


たとえ本人しか使わない非公開ツールで、しかも開発者側に悪用目的は一切無かったとしても、
それによってWeb サービスを停止させてしまう事態となった場合、たとえその原因が
サーバー側の不具合が原因だったとしても、無許可の自作ツールでサービスを停止に
追いやったとして、開発者が逮捕されてしまうことも実際にありましたし。
(Librahack 事件/岡崎図書館事件)
投稿者 だるさん  (中学生) 投稿日時 2012/8/13 13:26:43
Form5_Load
 Button1.Visible = True
 WebBrowser1.Visible = Falsh
End Sub

解決しました。

有難う御座いました。