2021年11月24日水曜日

スマホでnttのdポイントクラブ(d point club)をニックネームで登録したら、IDがほぼ凍結され干されてしまった。解決策を電話で聞いたら、docomoケータイじゃなくても良いので、「docomoショップへ出掛けてください」と。果して、どうなった?

 スマホでnttのdポイントクラブ(d point club)をニックネームで登録したら、IDが半凍結された。解決策を電話で聞く。結論だけ言えば、それは、docomoショップで本名で変更するしてもらうこと。そして、IDは凍結解除された。めでたし、めでたし。

 解決までの道程をもっと、詳しく語ると、こんな感じだ。ワタシはdocomoのケータイまたはスマホのユーザではない。実はocnモバイルワンのユーザだ。にもかかわらず、dポイントクラブのことはdocomoショップで対応してくれるというので、混んでいないと思われる、平日の昼間を狙って、近所のdocomoショップへ出掛けた訳だ。

 docomoショップに到着すると、今時、そこは予約をしてからいく場所だったことがわかる。やむを得ず、入り口の機械で「受付」をして、空きを待つ。コロナ以後は、どこでも、銀行でも予約は必須のようだ。やれやれ。待つしかない。

 しばらくして、フロア係のお姉さん達が2人ががかりで、ワタシの抱えている問題を解決すべく、色々と尋ねてくれた。まさに、解決に向けて立ち向かってくれた。

 「ここの機械は、docomoのケータイまたはスマホユーザのdポイントは、名前変更ができますが、それ以外の方の分が変更できるかどうか、わかりません。が、やってみましょう」と言ってくれたのだった。

 果たして、ワタシのdポイントクラブのIDとパスワードを入れて、ログインし、本名へ変更できた。すんなりと。そして、本人確認の免許証をアップロードしてくれた。そして、IDの半凍結が解除できた。良かった。docomoユーザじゃなくても、親切、丁寧に、対応して戴いた。「本当に、お世話になりました。」とお姉さん達へ感謝の挨拶をして、帰途につく。良かったなぁ

2021年11月15日月曜日

EXCEL のフィルタ作業をvbaにしてみた。でも、currentRegionの分断で、データ破壊してしまったのは、空白列のせいだった。

 EXCELのフィルタ作業をvbaにしてみた。参考にしたのはtanakaさんのvbaページhttp://officetanaka.net/excel/vba/tips/tips155d.htm

 EXCELに様々な条件でフィルターを掛け、絞り込みつつ、色々なセルに値を設定していく。そうすることで、我々の仕事が進む。そんな作業を自動化するにはvbaが一番だ。





Dim R As range
With Range("A1")
  .Autofilter 5,"="
  .Autofilter 3,array("<60","="),xlFilterValues
  If WorksheetFunction.Subtotal(3,Range("A:A")) > 1 then
    With Range("A1").CurrentRegion.Offset(1,0) 
      For Each R in .Resize(.Rows.Count-1).SpecialCells(xlCellTypeVisible).Rows
        R.Range("E1").Value = "C"
      Next R
    End With
  End If
End with

 でも、これだと、CurrentRegionが空白列或いは空白行でいくつかに分断されている(今回は、空白列で分断)と、その塊の単位でCurrentRegionの列なり、行なり(今回は行)を検出するため、意図していないCellにも、得点が60点以下でもないのに、"C"が設定されてしまい、表(データ)破壊をきたしてしまった(下図)。















 

 これはキツいな。そこで、R.Columnが1(A列、つまり、最初のCurrentRegionであるときのみ、得点が60点以下ならば、”C”を設定するようにしてみた。つまり、この    R.Columnが1(つまり、A列だね)のところがミソなのだ。図はEXCELでなく、OpenOfficeなのは、気にしないでね。

Dim R As range
With Range("A1")
  .Autofilter 5,"="
  .Autofilter 3,array("<60","="),xlFilterValues
  If WorksheetFunction.Subtotal(3,Range("A:A")) > 1 then
    With Range("A1").CurrentRegion.Offset(1,0) 
      For Each R in .Resize(.Rows.Count-1).SpecialCells(xlCellTypeVisible).Rows
        If R.Column = 1 then
          R.Range("E1").Value = "C"
        End If
      Next R
    End With
  End If
End with

 これでいいんじゃないのかな?なぜ、CurrentRegionが分断されていると気がつくことができたか?それは、破壊されたセルの規則性と壊れた内容からの類推。そこで、先ほどのrのアドレスを出してみた。Debug.Print r.addressをイミディエートウィンドウで表示すると、複数のエリアに分割されていたのがわかったのだった。

2021年11月9日火曜日

vbaでdir("*.xls")はリモートファイル(共有フォルダ)のxlsxファイルをゲットできなかったよ。Good Grief(やれやれ)。

vbaでdir("*.xls")はローカルファイル(自分のpc)のxlsxファイルはゲットできたんだけど、リモートファイル(共有フォルダ)のxlsxファイルはゲットできなかったよ。やれやれ。また、マイクロソフトのバグ?でも、そんなときは、dir("*.xlsx*")と書けば良いようです。

2021年11月8日月曜日

モノマネvba虎の穴ルール1:vbaでは最大行を求める前にフィルターをクリアしておけ!

 モノマネvba虎の穴ルール1:vbaでは最大行を求める前にフィルターをクリアしておけ。

maxRow = ActiveWorkbook.Worksheets(1).Cells(Rows.Count,1).End(xlUp).Row
if Worksheets(1).FilterMode = True then WorkSheets(1).showAllData

ではなく、これだ

if Worksheets(1).FilterMode = True then WorkSheets(1).showAllData
maxRow = ActiveWorkbook.Worksheets(1).Cells(Rows.Count,1).End(xlUp).Row

やれやれだ。

2021年11月1日月曜日

vbaで前月同日をどう書くか?そして、それをファイル名にするにはどうすればいいのか?

vbaで前月同日は以下のように1ケ月、日を戻すdateaddで取得できる。

dateadd("m",-1,Date-1)

これを利用して、fileNameという変数に前月同日の文字列を入れるには、以下のようにコーディングする。

fileDate = Year(dateadd("m",-1,Date-1)) & Format(dateadd("m",-1,Date-1,"mm") & Format(dateadd("m",-1,Date-1),"dd")

yearもformatで出した方がいいかな

fileDate = format(dateadd("m",-1,Date-1),"yyyy") & Format(dateadd("m",-1,Date-1,"mm") & Format(dateadd("m",-1,Date-1),"dd")

 実は、最後のFormat(dateadd("m",-1,Date-1),"dd")をFormat(Date-1),"dd")としてしまい、変な日付のファイル名になってしまった。ハハハ。人生にはいろんなことが起こる。一筋縄ではいかないこともある。え、こんなミス、したの?あり得ない。

ここで、一息のコーナーだ。

 先日、特定検診をした。最初は、大きな病院の検診センターみたいなところを探したのだが、いつも予約で一杯。そこで、近所の病院の特定検診にしてみた。歩いていけたし、長い待ち行列はなかったし、意外と良かった。来年もこれでいいなぁと思った。遠くの大病院よりも近くの診療所かな。検査の科目ごとに名前と住所など書類を何個も書かされたのには、閉口した。

2021年10月28日木曜日

vbaで 起動済みの IEを捕まえて、webページから必要な情報をゲットする。

マイクロソフトはもはやIEを使うなといっているが、以下のようなvbaでwebページを捕まえて、情報を抽出してみた。

Dim objIE As InternetExplorer
Dim objITEM As Object
Dim objTD As Object
Dim i As Long
Sub Getpage()
    Set objIE = Nothing
    Set objShell = CreateObject("Shell.Application")
    For Each objWindow In objShell.Windows
    If TypeName(objWindow.document) = "HTMLDocument" then 
        Set objIE = objWindows
        debug.print objIE.document.Title
        If objIE.document.Title = "page-title" then 
            objIE.document.forms("formname").param1.value = "KEYWORD"
            objIE.navigate "javascript:js_001;"   ' Execute javascript js_001
            Application.Wait Now + TimeValue(00:00:02")  '画面表示を2秒待つ
            For Each objTD In objIE.document.getElementsByTagName("tr")                     
                For Each objITEM In objIE.document.getElementsByTagName("a")
                '↑↑↑このgetElementsByTagNameで目的のaタグを手繰るところがミソ
                    If Instr(objITEM.outerHTML,"KEYWORD") > 0 then 
                     ' KEYWORDという文字列を持つaタグ(リンク)を探し、リンクをクリックすると、詳細ページが表示されるという構図。

             'このとき、debug.print objITEM.nameとかobjITEM.vakueとかで確認するのがコツです。

                        objITEM.click 'リンク(ボタン)をクリックする
                        Exit For
                    End If
                Next
            Next
            Application.Wait Now + TimeValue(00:00:02") '画面表示を2秒待つ
    
            ' 上記コードをマネし、getElementsByTageNameでタグを手繰り、必要な情報をゲットする。
            ' HTMLページの解析には、IEの開発者タブF12を使う。
        End If
    End If
End Sub

これでいいかな

こうやって、RPA(robot process automation)をVBAの手作りで始められる。

冬の朝。まだ、日が昇る前に歩くのがいい。息は白い。

2021年10月27日水曜日

vbaでIEを起動し、webページから情報を抽出する。

マイクロソフトはもはやIEを使うな、edgeにしてくれといっているが、以下のようなvbaでIEを起動し、webページを巡回し、情報を抽出してみた。

Dim objIE As InternetExplorer
Dim objITEM As Object
Dim objTD As Object
Dim i As Long
Sub main()
    Set objIE = CreateObject("InternetExplorer.Application")
    objIE.Visible = True
    objIE.Navigate2 "http://www.sample.com/index.html")
    Do While objIE.Busy = True Or objIE.readyState<>4 
        DoEvents
    Loop
    objIE.document.forms("form01").param1.Value = "KEYWORD"
    objIE.navigate "javascript:js_001;"   ' Execute javascript js_001
    Application.Wait Now + TimeValue(00:00:02")  '画面表示を2秒待つ
    For Each objTD In objIE.document.getElementsByTagName("tr")                     
      For Each objITEM In objIE.document.getElementsByTagName("a")
        '↑↑↑このgetElementsByTagNameで目的のaタグを手繰るところがミソ
        If Instr(objITEM.outerHTML,"KEYWORD") > 0 then 'KEYWORDという文字列を持つaタグを探し
          objITEM.click                                'リンク(ボタン)をクリックする
          Exit For
        End If
      Next
    Next
    Application.Wait Now + TimeValue(00:00:02") '画面表示を2秒待つ
    
    上記コードをマネし、getElementsByTageNameでタグを手繰り、必要な情報をゲットする。
    HTMLページの解析には、IEの開発者タブF12を使う。
    
End Sub

 これでいいかな?

 途中にある以下のコードは、ページが完全に表示されるまでを待つコードとして、ググると出てくるコードだが、その機能はなさそうだ。

    Do While objIE.Busy = True Or objIE.readyState<>4 
        DoEvents
    Loop

 では、どうすればいいか?それは、表示されたページにあるはずの文字列KEYWORD2が出ているかを確認すればいい。こんな感じだ。文字列を間違えると、無限ループになるので、注意が必要だ。詳しくは、こちらで。EXCEL+VBAで仕事を効率化〜既に開いているIEページをつかまえる。InStr関数で確実に!

        Do While Instr(objIE.document.innertext,"KEYWORD2") = 0 then 'KEYWORD2という文字列が表示されていないならば
          Application.Wait Now + TimeValue(00:00:02") '画面表示を2秒待つ
        End If