twitterアカウントへのリンクをhttpsに変えるGreasemonkey

単なるオレオレスクリプトだけど、もしかすると需要があるかもしれないので公開してみる。

効果

タイトルの通り。twitterアカウントへのリンクのプロトコルをhttpからhttpsに変える。それだけ。

Before
After

↓みたいなのには効かない。

ソース

// ==UserScript==
// @name           twitter's link http to https
// @namespace      http://www.hatena.ne.jp/so_blue/
// @description    twitterアカウントへのリンクurlをhttpsに変換します
// @include        http://*
// ==/UserScript==
(function(){

	xpath = '//a[contains(@href, "http://twitter.com/")]|//area[contains(@href, "http://twitter.com/")]';
	
	function changeProtocol(page) {
		var anchors = document.evaluate(xpath, page, null, 7, null);
		if (anchors) {
			for (var i = 0, len = anchors.snapshotLength; i < len; i++) {
				var url = anchors.snapshotItem(i).href.toLowerCase();
				anchors.snapshotItem(i).href = url.replace('http', 'https');
			}
		}
	}

	//AutoPagerize対応
	document.body.addEventListener('AutoPagerize_DOMNodeInserted', function(evt) {
		var doc = evt.target;
		changeProtocol(doc);
	}, false);

	changeProtocol(document.body);

})();

感想

xpath式を完全にアボーンしてた*1ので、どれ、困った時のチートシートを…とブクマからジャンプしたら、リンク切れてて
エエエェェェ( ゚Д゚;)ェェェエエエってなったけど、ググったら見つかったので一安心。ブクマされてる方は、ブクマし直した方がよいかも。
XPath使いのための日本語チートシート

という訳で

こんなのでよければこちらからどうぞ。
twitters link http to https

*1:つーか、そもそもちゃんと憶えてない訳なんですが…

OnActionのマクロに引数を渡す方法と、それActionControlプロパティで出来るよ!ってお話

先日、業務でとあるツールを作ってた際にハマったので自分用メモと、有効な代替策が見つかったのでエントリにしてみます。

まずはハマった内容

マクロでオリジナルのコマンドバーやボタンを作って、そこからマクロを実行させる事は結構あります。こういった場合、自作のコントロールのOnActionプロパティに実行させるマクロを設定します。で、この時は、そのマクロに引数を渡したかったので、↓みたいなコードを書いたんですが、

'ThisWorkbookモジュール
Private Sub Workbook_Open()

    Const cnsCaption As String = "Sample Macro"

    Dim btn     As CommandBarButton

    On Error Resume Next
    With Application.CommandBars("Cell")
        .Controls(cnsCaption).Delete '新規作成するボタンを予め削除しておく
        Set btn = .Controls.Add(msoControlButton)
    End With
    On Error GoTo 0

    With btn
        .Caption = cnsCaption
        .OnAction = "ForExample(0)" 'ForExmapleがプロシージャ名。()内が引数でこのサンプルでは0が引数
    End With
        
    Set btn = Nothing

End Sub

'標準モジュール
Sub ForExample(arg As Variant)

    MsgBox arg '渡された引数を表示するだけ

End Sub

↑を実行すると、セル上右クリックで表示されるコンテキストメニューに、↓なボタンが追加されます。

で、追加されたボタンをクリックすると、なんとビックリ!マクロが2回実行されちゃいます。↓が2回表示されます。

どこをどう見ても2回も表示させる様には書いてないので、ホントもう ( ゚ д ゚ )ポカーン です。
穴があくほどコードを見てもどこが悪いのかわからないので、仕方なくコードを書き直してみたり、別のモジュールに書いてみたり、プロシージャ名変えてみたり、と色々試してみたところで状況は変わらず。更に苛立ったのが、デバッグしようと、ForExampleプロシージャのMsgBox関数んとこにブレークポイントを置いても華麗にスルー、ブレークポイントで処理が止まってくれない*1んです。なもんで、しばらくはホント悩んでました。

OnActionに引数を渡したい時は

こういう時には困った時のグーグル先生です。という訳でググってみたところ、あっさりOnActionプロパティの書き方が拙い、って事がわかりました。OnActionに引数付きのプロシージャを設定したい場合、↓の様にシングルコーテーションで囲ってやらないと駄目らしいです。

    With btn
        .Caption = cnsCaption
        .OnAction = "'ForExample(0)'"
    End With

ひとまずこれで自分のやりたかった事は出来た訳ですが…

OnActionになぜ引数を渡すの?

シングルコーテーションで囲んでやる事によって、無事OnActionに引数を渡せる様になった訳ですが、そもそも、なぜOnActionのマクロに引数を渡したかったかというと、渡した引数によって処理を分岐させ、DBへ問い合わせるSQLの検索条件を変えたかったからです。

'ThisWorkbookモジュール
Private Sub Workbook_Open()

    Const cnsCaption1 As String = "Field1で検索"
    Const cnsCaption2 As String = "Field2で検索"

    Dim btn     As CommandBarButton

    On Error Resume Next
    With Application.CommandBars("Cell")
        .Controls(cnsCaption1).Delete
        .Controls(cnsCaption2).Delete
        Set btn = .Controls.Add(msoControlButton)
    End With
    On Error GoTo 0

    With btn
        .Caption = cnsCaption1
        .OnAction = "'ForExample(1)'"
    End With
    
    Set btn = Application.CommandBars("Cell").Controls.Add(msoControlButton)
    With btn
        .Caption = cnsCaption2
        .OnAction = "'ForExample(2)'"
    End With
        
    Set btn = Nothing

End Sub

'標準モジュール
Sub ForExample(arg As Variant)

    Const cnsSQL As String = "select * from hoge where "
    Dim strSQL As String
    
    If arg = "1" Then
        strSQL = cnsSQL & "Field1 = '" & Selection.Value & "';"
    Else
        strSQL = cnsSQL & "Field2 = '" & Selection.Value & "';"
    End If

    MsgBox strSQL
    
End Sub

↑のサンプルコードを実行し、「123」という値が入力されたセル上で右クリック、Field1のボタンの方をクリックすると

なメッセージが表示されます。

これをActionControlプロパティでやると

OnActionに引数付きでマクロを登録する方法でもいけるんですが、引数の使い方が本来の使い方でない気がするし、もっとスマートな方法はないのかと調べてたら、ActionControlプロパティってのが存在する事がわかりました。
VBAのヘルプにはこうあります。

OnAction プロパティに実行中のプロシージャが設定されている CommandBarControl オブジェクトを取得します。実行中のプロシージャがコマンド バー コントロールによって開始されていない場合、このプロパティの戻り値は Nothing になります。値の取得のみ可能です。

ふむふむ、このプロパティを使うと、どのボタンをクリックしたかがわかるみたいですね。
という訳で、ActionControlを使ったコードに書き換えると

'ThisWorkbookモジュール
Private Sub Workbook_Open()

    Const cnsCaption1 As String = "Field1で検索"
    Const cnsCaption2 As String = "Field2で検索"

    Dim btn     As CommandBarButton

    On Error Resume Next
    With Application.CommandBars("Cell")
        .Controls(cnsCaption1).Delete
        .Controls(cnsCaption2).Delete
        Set btn = .Controls.Add(msoControlButton)
    End With
    On Error GoTo 0

    With btn
        .Caption = cnsCaption1
        .OnAction = "ForExample" '引数なんて要らないわよっ
    End With
    
    Set btn = Application.CommandBars("Cell").Controls.Add(msoControlButton)
    With btn
        .Caption = cnsCaption2
        .OnAction = "ForExample" 'だから要らないってば!
    End With
        
    Set btn = Nothing

End Sub

'標準モジュール
Sub ForExample()

    Const cnsSQL As String = "select * from hoge where "
    Dim strSQL As String
    
    If Application.CommandBars.ActionControl.Caption = "Field1で検索" Then
        strSQL = cnsSQL & "Field1 = '" & Selection.Value & "';"
    Else
        strSQL = cnsSQL & "Field2 = '" & Selection.Value & "';"
    End If

    MsgBox strSQL
    
End Sub

うん、こっちの方がスマートですね!*2

マクロが2回実行される理由とブレークポイントをスルーする理由

については調べてみてもわかりませんでした。単なるバグって事なんでしょうか…

*1:自分的には、2回実行されるバグ!?よりも、むしろ、ブレークポイントで止まってくれないバグの方がキツかった…

*2:って、単に好みの問題かもしれませんが(;^ω^)

走ってきました! - 第14回大阪・淀川市民マラソン -

前回、前々回のエントリで書いた様に、11/7(日)に行われた第14回大阪・淀川市民マラソンのハーフに出場しました。結果から先に書いちゃうと、

グロスタイム2時間4分9秒
ネットタイム2時間3分42秒

で無事完走出来た*1訳ですが、目標にしていた

  • 一度も歩く事なくゴールする
  • タイムは2時間30分以内

については、タイムはクリア出来た*2ものの、歩かずにゴールするという目標はクリア出来ませんでした。
という訳で、早速、so_blueの初挑戦ハーフマラソン奮走記!?をお届けします。

コースコンディション

お天気は曇り、気温の方は何度かまではわかりませんが、暑くもなく寒くもなくな感じ。途中、雨がパラッと降りましたが、気になるほどでもなかったです。初マラソンなので、条件の良し悪しについてはよくわかりませんが、走ってる最中も暑いとか寒いとかは感じなかったので、悪い条件ではなかったと思います。

スタート

スタート地点はフルもハーフも同じ時間、同じ場所からのスタート。フルは淀川を下流方向(十三方向)に、自分の走ったハーフは上流方向(枚方方向)に向かって走っていきます。スタート位置は、↓の様に目標とするタイムによって並ぶ場所が変わるんですが、

自分の並んだ位置は1時間〜1時間30分を目標にしてる人達が並ぶ位置のすぐ後ろ辺り。これはちょっと無茶だったかもです。前の方に並ぶ人たちはやはりそれなりの記録を狙っているので、最初から結構とばします。そんな周りの人につられて自分もオーバーペースで走り始めちゃったと思います。

走り始めてすぐに…

ホントものの1分も経たないうちにトイレに行きたくなってしまいました...(;´Д`)
走る前は別にしたくもなかったし、何よりトイレ待ちの長蛇の列が出来てた事もあって、トイレには行かなかったんですが、寝る前の子供よろしく、したくなくても行っとかないと駄目ですね。なんだかそわそわして、しばらくは走りに集中出来てなかったと思います。

タイムを確認しようと腕時計を見たら

しばらく走ったところで(さて、タイムはどんなもんかな?)と腕時計を見たら、タイムが1秒くらいで止まってました。うっかりボタンを2回押しちゃったのかわかりませんが、これによってタイムがよくわからなくなりました...orz

折り返し

トイレに行きたくて落ち着かなかった感じも、この頃には汗として流れ出た*3のか、いつのまにか気にならなくなって迎えた折り返し。設置されている時計を見ると、タイムは思いのほか速い55分台。2時間切りを目標にしてるんであれば、むしろ遅いくらいかもしれませんが、膝の痛みにかまけてさっぱり練習してこなかった自分にとっては、(これは速いんじゃないのか!?もつのか!?)と少し不安になりました。そしてそれは現実のものとなるのです。

折り返し後の芝生エリア

体力的にも徐々にキツくなってきた中で迎えた芝生エリア。折り返し前にここを走った時も、(うわ、ここすげー走りにくい、キツイ><)と感じてたんですが、折り返し後は倍くらいキツく感じました。Qちゃんがランナーの皆さんにハイタッチされてたので、元気をわけてもらおうと自分もハイタッチしてもらったんですが、残念ながら効果は無かった*4様で、ここで残り少ない燃料をほぼ使い切っちゃったと思います。ボチボチ歩き始める人も出始め、自分の心の中の悪魔が(YOUも歩いちゃいなYO!!)と囁き始めたのもこの辺りからです。

残り5km

猛烈にペースが落ちました。歩いてるのと変わらないくらいだったと思います。腕がしびれだし、軽いハンガーノック*5状態、完全にスタミナ切れ、ガス欠状態でヘロヘロでした。あわせて膝・足首が痛くなってきた事もあって、とうとう歩いてしまいました。今回の目標の一つ「一度も歩く事なくゴールする」という目標が達成できなくなり、激しく自己嫌悪に陥りました。

ラスト3km

一度歩いてしまうと、もう一度走り出すのは本当にキツかったです。膝・足首の痛みが増してきたところに輪をかけて足が痙攣しだしました。つりそうになるのを必死に抑えながら、走っては歩いて、走っては歩いてを繰り返して何とか前に進んでました。

ラスト1km

沿道に家族や知人などの顔がチラホラしだし、みんなが励ましてくれます。知らない人からも「あと少し!頑張って」と声をかけられ、すごく嬉しかったです。かといって、ゼロになった体力が復活する事はなかったので(;^ω^)、気力だけで前に進みながら…

ついにゴール

なんとかかんとかゴール。初めてのマラソン、もっと達成感を得られるかと思ってたんですが、目標であった「歩かずにゴールする」をクリア出来なかったので、それほどの達成感は得られませんでした。ただ、後半は猛烈にペースが落ちたにもかかわらず、目標としていたタイムよりも早く完走できた点は救いでした。と同時に、歩かなければ2時間切れてたな…という後悔の思いも頭をよぎりました。

反省点

初めて走ってみて、色々わかった事というか、ああすればよかった、こうすればよかったという事が出てきたので、何点かあげてみます。

  • 練習不足
    • まずは何といってもこれですね。直前の1ヶ月は月間100kmも走れてませんでしたし。膝の痛みにかまけてさぼってたツケがきっちり出ました。あと、長い時間走る練習をしなかったのも×。10kmを1時間以内に走るくらいなら、ゆっくりでもいいので、2時間走った方が練習になったんじゃないかと思います。
  • 事前準備不足
    • 一緒に走った人達は、直前にアミノ酸のゼリーをチューチューしたり、バナナを食べたりと走るためのエネルギーを摂っていたにもかかわらず、自分はそういうものを準備していませんでした。見兼ねてか、バナナをもらえたのでありがたく食べさせて頂いたんですが、これ食ってなかったら、15kmよりももっと早い段階でスタミナ切れを起こしてたかもしれません。んでから睡眠。全然寝てなかった訳ではないものの、充分に睡眠をとって臨むべきところを、こんな時に限って、前日の日本シリーズが15回までやってたりするんだもんなぁ。ついつい観ちゃいましたよ。

とまぁ、他にも細かい事が色々あるんですが、自分的にはこの2点をもっとちゃんとしとかなきゃ駄目だったなぁと思いました。

という訳で

かなり大袈裟にお届けしてみた初挑戦ハーフマラソン奮走記。いかがでしたでしょうか。
やり残した感たっぷりで終えた初マラソン。このままでは終われません。来年のこの大会か、他の大会になるのかはわかりませんが、リベンジです!次こそは歩かずに走りきって、タイムも2時間以内を目指します。

頑張れオレ!!

ご清聴ありがとうございました。(;^ω^)

*1:ハーフ程度なら完走して当たり前ですかね。

*2:今思えば、目標設定があまかったです。

*3:ばっちくてすいません(;^ω^)

*4:って、単に自分の練習不足なんですけどね(;^ω^)

*5:走ってる時は、ハンガーノックだとはわかってなかったですが。

ついに今週末です

先日、第23回(2019年) 大阪・淀川市民マラソンのハーフに出るってエントリ書きましたが、この前、ついに案内が届きました。

このところさっぱり練習出来ていない*1ので、きっと、バテバテのヘロヘロで目もあてられない…なんて事になりそうですが、ここまでくればジタバタしても仕方ないし、なんとか歩くこと無くゴール出来れば、なんて考えとります。*2
ところで、参加者数が14,000〜15,000人になりそうとかいうのを風の噂で聞きました。前年の参加者数は8,510人なので、前年に比べ、倍近い人が走る事になる訳ですね。
スタート&ゴール地点が枚方から守口に変わったのとジョギングブームが参加者激増の要因!?なんて勝手に想像してますが、運営はこの状況に対応出来るのかしらん!?なんて少し心配してみたり。


運営「初めてマラソン走るお前に心配される謂れはない!!」


人の心配してる場合ではないですね、失礼しました…。

という訳で

走り終わったら、完走した感想エントリでも書こうと思います。
日曜日は頑張ってきます!

*1:膝の痛みとなまけで…

*2:目標がえらくしょぼくなっちゃいました…

ハーフマラソンに出る事にしました

http://www.furusato.gr.jp/marathon/gaiyo.htm
ハーフマラソンに出る事にしました。


こういうのに出るのはまったくの初めてなので、とりあえずは

  • 一度も歩く事なくゴールする
  • タイムは2時間30分以内

くらいを目標に頑張ろうかと思っています。


6月から走り始めて、はや3ヶ月弱。この前10km走った時のタイムは約1時間でした。2時間30分で20kmって事は、時速8kmで走り続けなきゃいけない訳で、時速8kmって事は1km7分くらいのペースで走らなきゃいけません。
ペース的には一応クリア出来てるんですが、後半はバテバテでした。涼しくなれば断然走りやすくなるので、暑さを考えれば今の状態でも問題ないのかもしれませんが、そもそも20kmを走り続ける自信はまだなかったりするので、もっと走りこまなきゃ駄目ですね。
あと自分の場合、体力以上に気持ちのスタミナがもつのかが心配だったりします。情けないですが、30分くらい走ったあたりから、体力的にはまだ大丈夫にもかかわらず、気持ちが続かなくて走るのを止めたりしちゃう事がままあります。
まぁ、体力がついてくれば、それにあわせて気持ちのスタミナもついてくる!?かもしれないですし、それに期待して頑張って練習しますかね。

という訳で

出ると決めて、目標も設定したからには、クリア出来る様に頑張ろうと思います。

Googleトップを以前の見た目に戻すユーザースタイルシート

やはりというか、もう既に効かなくなってます。
@namespace url(http://www.w3.org/1999/xhtml);

@-moz-document domain("www.google.co.jp") {
  #sbl a, #fctr a {
    color: #1111CC !important;
    text-shadow: none !important;
  }
  #fctr p {
    color: #000 !important;
    text-shadow: none !important;
  }
  #logo, #cpf, #fpdi {
    display: none !important;
  }
  #lga > div {
    height: 100px !important;
    background-image: url("http://www.google.co.jp/intl/en_ALL/images/srpr/logo1w.png") !important;
    background-position: center center !important;
    background-repeat: no-repeat !important;
  }
}
Before

After


やっぱ自分は以前のシンプルな感じが良いです。


「fpdi」とかidがランダムに付けられてるかもしれないので、突然効かなくなったりするかもですが、よければどうぞ。
Website Themes & Skins by Stylish | Userstyles.org

ExcelでCSVファイルを簡単にインポートする方法

まず最初に、csvファイルってなーに?*1な方は、↓を参考にして下さい。


で、前置き。MS-OfficeのインストールされてるPCの場合、意識的に関連付けを変えたりしていない限り、拡張子csvのファイルはExcelに関連付けられているので、csvファイルのアイコンは↓な感じだと思います。

csvファイルといっても、WikipediaやIT用語辞典にもある様に、所詮、区切り文字*2で区切られたテキストファイルでしかないので、テキストエディタで開くと↓な感じになってます。

ただ、これをアイコンダブルクリック、つまりはExcelで開いちゃうと...

あららら、なんかテキストエディタで開いたのと様子が違いますね。おかしい箇所を挙げると、

  • 店舗コードが日付になってしまっている
  • 商品コードの前ゼロが消えてしまっている

なんでこんな事になっちゃうかというと、Excelcsvファイルを普通*3に開くと、

  • 「1-1」みたいな文字列は日付と認識して、書式を日付にしてしまう
  • 前ゼロのついている値が数値のみで構成されている場合、数値だと解釈して前ゼロをカットしてしまう

こんな風に開かれては、Excelでおちおちcsvファイルの編集も出来ません。
そんな事ではまずいので、Excelの標準機能にあるcsvのインポート機能を使う訳ですが、このインポート機能も使いにくいというか、結構面倒臭いんですね。試しにsample.csvcsvインポート機能で取り込む手順を説明してみます。Excelのverは2003ですが、他のverでもそれほど違いはありません。

データファイルの選択ダイアログの呼び出し


メニューの「データ - 外部データの取り込み - データの取り込み」をクリックします。

csvファイルの選択


ファイルの種類を「すべてのファイル」に変更*4し、対象ファイルを選択して「開く」ボタンをクリックします。

テキストファイルウィザード 1/3


「カンマやタブなどの〜」を選択し、「次へ」をクリックします。

テキストファイルウィザード 2/3


サンプルファイルの区切り文字はカンマなので、区切り文字は「カンマ」にチェックを入れて、「次へ」をクリックします。

テキストファイルウィザード 3/3


今回の場合、最低限、店舗コード列と商品コード列はデータ形式:文字列として取り込む必要があるので、それぞれの列のデータ形式を「文字列」に設定し、「完了」をクリックします。

インポート開始セルを決める


インポート開始セルを指定します。選択したセルが左上端となりデータが取り込まれます。通常はA1セルを指定する事が多いと思います。

インポート完了


ようやくインポート完了です。今回の場合、店舗コード列と商品コード列のみデータ形式を指定して取り込むだけですんだので、この標準機能を使った方法でもそれほど面倒ではないですが、列数がもっと多かったり、インポートしないといけないファイルが多かったりすると、標準(推奨?)機能とはいえ非常に面倒です。かといって、横着してそのまま開くとおかしな書式が適用される恐れが…どうすればいいんだ!!ガッデム!!!!

という訳で

ようやく本題に入りますが、Excelcsvファイルを開く時に問題になるのが、余計な書式が適用される事による値の変更です。これをさせない様にするには、全て文字列として取り込んでしまう事です。これが一番間違いのない方法です。という訳でその手順です。

テキストエディタcsvファイルを開き、全文コピーする


メモ帳等のテキストエディタを起動し、対象のcsvファイルをウィンドウにドラッグ&ドロップ*5します。csvファイルを開いたら、Ctrl+Aで全文選択し、次にCtrl+Cでコピーします。ちなみに自分的には、csvファイルについては関連付けをテキストエディタにしちゃった方がいいと思ってます。仕事上、結構な頻度でcsvファイルを編集される方なら尚更関連付けを変更する事をおすすめします。csvファイルをExcelに関連付けてるとそのうち痛い目に遭うと思われます。

コピーした内容をExcelのシートに貼り付ける


Excelのファイルを開き、Ctrl+Vします。キャプチャ画像では少しわかりにくいですが、全行ともA列のセルに内容が全て貼り付けられています。

区切り位置指定ウィザードの呼び出し


A列ごと選択し、メニューの「データ - 区切り位置」をクリックします。

区切り位置指定ウィザード 1/3


csvインポート機能を使った時のウィザードとそっくりですね。この場合も「カンマやタブなどの〜」を選択し、「次へ」をクリックします。

区切り位置指定ウィザード 2/3


こちらも区切り文字「カンマ」にチェックを入れて「完了」をクリックします。ウィザードはまだ2/3ですが、終わらせてしまって構いません。

一旦、値を全て消去した後、全セルの書式を文字列にする


ウィザードを途中で終わらせたのでおかしな書式が適用されていますね。ただ、この段階ではこれで構いません。で、ひとまず、シート左上端の赤い部分をクリックして全セル選択状態にし、Deleteキーを押して全てのセルの値を消去します。

その後、赤い部分を右クリックして、コンテキストメニューの「セルの書式」を選択し、書式を「文字列」に設定します。

再度テキストエディタで開いた内容をコピペして完了


再度「テキストエディタcsvファイルを開き、全文コピーする」の要領で全文コピーし、シートのA1セルを選択した状態でCtrl+Vすれば取り込み完了です。お疲れ様でした(;^ω^)

この手順で取り込む事の利点

区切り文字情報が記憶されている為、Excelを落とさない限りは、以降、全セルの書式を文字列に設定→テキストエディタcsvファイルを開いてコピー→シートに貼り付け、とするだけでおかしな書式を適用される事無く、csvファイルをシート上に取り込む事が可能です。複数ファイルをExcelのシート上に取り込まないといけない場合、少ない手順で確実に取り込む事が出来るので非常に有効です。

長くなりましたが、頻繁にcsvファイルをExcelに取り込む必要がある仕事をされてる方で、Excel標準のcsvインポート機能で取り込むのが面倒だなぁって感じてた方は是非お試し下さい。

*1:ってな方がそもそもこのエントリを見てるとは思えませんが...(;^ω^)

*2:カンマやタブ文字が一般的ですね。

*3:後述のcsvインポート機能使えば適切なフォーマットで開く事も出来ます。

*4:でないとcsvファイルが表示されません。

*5:テキストエディタで開けばいいだけなので、もちろん他の方法でもOKです