2014年2月18日火曜日

クロスブラウザテストができるサービス(BrowserStack)の無償期間が終わっていた

以前、ブラウザ上からクロスブラウザテストが簡単にできるサービスをご紹介しましたが、
いつの間にやら、無償サービスの期間が終わってしまっていました。

その時の記事はこちらをご覧ください。
http://knkryo.blogspot.jp/2013/11/web.html

使い続けるには、有償サービスへの移行が必要

今のところそこまでの使用頻度はなさそうなので、modern.ieより
都度、仮想環境をダウンロードして使う事になりそうです。


ツールのダウンロードはこちらから
http://loc.modern.ie/en-us/virtualization-tools

2014年2月17日月曜日

BloggerでGoogleAnalytics

Bloggerには標準でアクセス解析がついていますが、シンプルなもので
詳しい解析の機能がなかったため、GoogleAnalyticsを使う事にしました。

どちらもgoogleサービスなので、手順は簡単です。

手順

1) Google Analyticsアカウントを取得、設定

以下サイトから、「ログイン」または「アカウントを作成」で入ります。

Analytics設定から、「アカウントを作成」することで、トラッキングIDを取得します。

詳しくはGoogleのサポートにも記載されています。
https://support.google.com/analytics/answer/1032385


2) Bloggerで設定

設定で、先ほど取得しているトラッキングIDを設定します。
https://support.google.com/analytics/answer/1009610?hl=ja


ひとまず仕込み完了したので、しばらく様子を見たいと思います。


2014年2月13日木曜日

Excelで保護されたセルに色を付ける

Excelでセルの保護を使うことがありますが、あちこちに設定していると
ぱっと見で確認したいケースが出てきます。

1行Tipsですが、忘れた時のためにとっておきます。

手順

1) 条件付き書式を使用します。
2) 「数式を使用して、書式設定するセルを決定」を使用します。
3) 条件に、以下を入力し、書式で背景色などを設定します。
 =cell("protect",a1)=1
 ※開始位置が「a1」でない場合には適宜書き換えてください。

なんだかんだ言ってExcelって最強のフロントエンドツールだったりすることを最近つくづく感じます。

2014年2月12日水曜日

Excelで単一行と複数行のシートをセル参照で解決する

イメージ的には以下のような感じです。


元々1行のものを、複数行の表で参照しようとした場合、
「=表!C3」 というような表現だと、単純に参照設定を作ることができません。

1行が1行として参照するのであれば、一つ参照をつくって、コピーすれば済みますが、
複数の場合、どうやっても単純コピーではいきません。



そこで、調べてみたところ、別アプローチでの解決方法がありました。

キーワード

OFFSET ・・・ 指定した参照から指定した行数、列数の範囲への参照を返します。
ROW()  ・・・   参照の行番号を返します
COLUMN() ・・・ 参照の列番号を返します。

理屈

OFFSETで、相対位置を指定する事により、任意の場所の値が取れます。
ROW()とCOLUMNを利用して、スタート位置からの相対を指定します。


実践

別シートに分かれているものとします。
2行構成のシートから、1行校正のシートを参照します。

・行Noを取得する (行Noは、A列2行目に1行目がある)
 =OFFSET(表!$A$2,((ROW())-2)/2,0)
 ※解説
  ・表A2からスタートで、相対位置(行)を計算、列はそのまま。
  ・1行目の相対位置は、$2から見るとゼロ。ROW()-2/2もゼロ。よってそのままの行
  ・2行目はとなると、ROW()が4なので、(4-2)/2 でイチ。$A$2から行がプラスイチなので、3

相対位置のスタートを絶対指定にするのがポイントです。
これで、同じ計算式を使いまわすことが可能です。

ちなみに、名称の欄には
 =OFFSET(表!$B$2,((ROW())-2)/2,0)
と指定しています。


きちんと使うなら、
=IF(OFFSET(表!$A$2,((ROW())-2)/2,0)="","",OFFSET(表!$A$2,((ROW())-2)/2,0))

とやると、きれいにいくかもしれません。

2014年2月10日月曜日

インストール不要。簡単なデスクトップ共有 screenleap

リモートデスクトップのツールのなかで、インストール不要。複数人が
同じ画面を見れるようにできるツールがscreenleapです。

見せたいPCに、JRE(JavaRuntime)さえインストールされていれば
見る側は、ブラウザだけでOKです。

見せる側の手順

1.サイトにアクセス [http://www.screenleap.com/]
2.[share your screen now]をクリック
3.Javaの実行確認画面が出るので、[OK]をクリック
 ⇒出ない場合には、Troubleshootingの説明に従い、JAVAをインストール
  ※インストール後にはブラウザの再起動が必要です。
4.Javaを実行してよいかという確認画面が出るので、[OK]
5.URLが出るので、見せたい人へ送る。

見たい側の手順

1.伝えられたURLをブラウザで開く


余談

見せる側のブラウザがIE6だとJAVAのプラグインが開きませんでした。
そのような場合には、Firefoxなどをお使いください。

2014年2月7日金曜日

Webテストを自動化 Selenium

Webシステムの開発で、テストの自動化ツールを見つけたので、
導入からファーストタッチまでを纏めておきます。

ツールについては@ITさんにて記事が公開されています。
http://www.atmarkit.co.jp/ait/articles/0908/19/news109.html


概略

1.画面で操作している内容を記録でき、再現できる。
2.実行環境が異なっても可。

インストール

1.Mozilla Firefox のアドオンとして、Selenium IDEをダウンロード、インストール。
2.Firefoxのメニューバーより「ツール」を選択し、「Selenium IDE」を選択。(またはControl+Alt+S)

以下の画面が開きます。


実行

ウインドウ右上の赤丸で記録開始終了、記録を開始すると、一覧に内容が追加されていきます。
一覧の上にある三角マークで実行開始、終了。一括でも、一つずつでもできるようです。

作成したテストケースは保存でき、他の人が開く事も可能。

ひとまず使ってみて、追って追加情報を更新したいと思います。

2014年2月6日木曜日

複数のデスクトップ環境を構築できる dexpot

百聞は一見に如かず。

dexpot

個人利用に限り、無償利用が可能です。
標準は英語版、日本語化に対応してくださっている方もいるので、
日本語で利用可能です。


主だった機能

・ホットキーで、デスクトップの切り替えができる
・デスクトップごとに、背景画像などの設定が返られる
・デスクトップマネージャ 機能により、ワンクリックでウインドウを切替可


常日頃、画面を出す、しまうという動作を繰り返しで身についてしまっているので
これを使いこなせるようになれば、日常が大幅に変わってきそうです。



追記: 使ってみたところの主要ポイント

●デスクトップごとにアイコンの指定が可能。
 用途で分ける事を考えているので、これはベストマッチ。デスクトップを見るだけで何のデスクトップ化がすぐにわかるようになります。

●アプリケーションごとに起動するデスクトップを指定可能
複数デスクトップで利用している時に、dexpotを終了すると、全てのデスクトップのアプリは元の画面へ戻ってきます。
言い換えると、その逆ができる。ということで、
「アプリケーションを割り当てる」という設定から、該当のアプリを選択。

使い方を誤ると若干びっくりしそうな機能ですが、用途別ではっきりしている時には便利そうです


●自動でアプリケーションを起動
指定したプログラムが自動的に起動するようになります。
「デスクトップごとの設定」より、「スタートアップ」を選択して指定。

アイコンが出てこなくなった時には、デスクトップを右クリックして、「表示」から「デスクトップアイコンを表示」を選択

2014年2月5日水曜日

vb.netでキーボードHook

仕事で開発・保守をしているシステムで、モジュール提供されている部品に不具合があり、
どうしても回避しないといけなかったので、Hookにて対処する事にしました。

現象としては、「ある特定の項目にフォーカスがある際に、F3を押すとゼロ除算エラー」
モジュール側の不具合であることは調査により発覚。しかし、モジュールは直せない。

ということで、HookにてF3を拾って、潰すというロジックです。

いろいろ調べていると、".net framework"ではグローバルフックができず、マウス、キーボードのみ。とか書いてはありましたが、APIを使えるのでさほど気にもならないかなと思ってます。

とはいえ、Hookは低レベル(OSに近い部分)での制御になりますので、使い方には十分ご注意ください。
何の処理でもCancelなんてしようものなら、全ての入力を受け付けなくなってしまう事もあり得ます。

ソース

クラスライブラリ側


・APIを直接フックを実施
・フックにより取得できるメッセージの中からキーコードを取得
・イベントとして外部へ公開


Imports System.Runtime.InteropServices

''' <summary>
''' キーボードフックを行うライブラリ
''' </summary>
Public Class KeyboardHook
  Implements IDisposable

  Dim WH_KEYBOARD_LL As Integer = 13
  Private Shared hHook As Integer = 0

  Private hookproc As CallBack

  Public Event KeyboardEvents(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyEventArgs)

  Public Delegate Function CallBack( _
    ByVal nCode As Integer, _
    ByVal wParam As IntPtr, _
    ByVal lParam As IntPtr) As Integer

#Region "DLL Declare"

  'Import for the SetWindowsHookEx function.
  <DllImport("User32.dll", CharSet:=CharSet.Auto, CallingConvention:=CallingConvention.StdCall)> _
   Public Overloads Shared Function SetWindowsHookEx _
     (ByVal idHook As Integer, ByVal HookProc As CallBack, _
      ByVal hInstance As IntPtr, ByVal wParam As Integer) As Integer
  End Function

  'Import for the GetModuleHandle function.
  <DllImport("kernel32.dll", CharSet:=CharSet.Auto, CallingConvention:=CallingConvention.StdCall)> _
   Public Overloads Shared Function GetModuleHandle _
      (ByVal lpModuleName As String) As IntPtr
  End Function

  'Import for the CallNextHookEx function.
  <DllImport("User32.dll", CharSet:=CharSet.Auto, CallingConvention:=CallingConvention.StdCall)> _
   Public Overloads Shared Function CallNextHookEx _
     (ByVal idHook As Integer, ByVal nCode As Integer, _
      ByVal wParam As IntPtr, ByVal lParam As IntPtr) As Integer
  End Function

  'Import for the UnhookWindowsHookEx function.
  <DllImport("User32.dll", CharSet:=CharSet.Auto, CallingConvention:=CallingConvention.StdCall)> _
     Public Overloads Shared Function UnhookWindowsHookEx _
       (ByVal idHook As Integer) As Boolean
  End Function

  'KeyboardHookStruct structure declaration.
  <StructLayout(LayoutKind.Sequential)> Public Structure KeyboardLLHookStruct
    Public vkCode As Integer
    Public scanCode As Integer
    Public flags As Integer
    Public time As Integer
    Public dwExtraInfo As Integer
  End Structure

#End Region

#Region "Constructor"

  Public Sub New()
    hookproc = AddressOf KeybordHookProc
    hHook = SetWindowsHookEx(WH_KEYBOARD_LL, hookproc, GetModuleHandle(Process.GetCurrentProcess().MainModule.ModuleName), 0)
    If hHook.Equals(0) Then
      MsgBox("SetWindowsHookEx Failed")
    End If
  End Sub

#End Region

#Region "KeybordHookProc"

  Private Function KeybordHookProc( _
    ByVal nCode As Integer, _
    ByVal wParam As IntPtr, _
    ByVal lParam As IntPtr) As Integer

    If (nCode < 0) Then
      Return CallNextHookEx(hHook, nCode, wParam, lParam)
    End If

    Dim hookStruct As New KeyboardLLHookStruct()
    hookStruct = CType(Marshal.PtrToStructure(lParam, hookStruct.GetType()), KeyboardLLHookStruct)

    Dim e As New System.Windows.Forms.KeyEventArgs(DirectCast(hookStruct.vkCode, System.Windows.Forms.Keys))
    OnKeyboardEvents(e)

    'キーCancelなら継続しない
    If (e.Handled = True) Then
      Return 1
    End If
    Return CallNextHookEx(hHook, nCode, wParam, lParam)
  End Function

#End Region

#Region "OnKeyboardEvents"

  Protected Sub OnKeyboardEvents(ByVal e As KeyEventArgs)

    RaiseEvent KeyboardEvents(Me, e)

  End Sub

#End Region

  Public Sub Dispose() Implements System.IDisposable.Dispose

    If (hHook > 0) Then
      UnhookWindowsHookEx(hHook)
    End If

  End Sub


End Class



潰す側(コントロールをラップ)


・ライブラリ初期化と解放
・イベントでF3が来るのを監視しておき、F3が来て、かつ対象のコントロールの場合、イベントキャンセル


  'F3潰し用のHookイベントハンドラ
  Private keyHook As KeyboardHook

  Protected Overrides Sub OnCreate()
    MyBase.OnCreate()

    If (Me.DesignMode = False) Then
      keyHook = New KeyboardHook()
      AddHandler keyHook.KeyboardEvents, AddressOf keyHook_KeyboardEvents
    End If

  End Sub
  Private Sub keyHook_KeyboardEvents(ByVal sender As Object, ByVal e As KeyEventArgs)

    'F3は潰す
    If (e.KeyCode = Keys.F3) Then
      If TypeOf (DirectCast(Me.TopLevelControl, System.Windows.Forms.Form).ActiveControl) Is エラーを起こすコントロールの型 Then
        e.Handled = True
      End If
    End If
  End Sub

  Protected Overrides Sub OnDestroy()
    If (Me.DesignMode = False) Then
      If Not (keyHook Is Nothing) Then
        keyHook.Dispose()
      End If
    End If
    MyBase.OnDestroy()
  End Sub

2014年2月4日火曜日

OracleClient(ODP.net)とBindingRedirect

Oracle Client 10.2.0.1で稼働していたシステムを、Windows7対応により、10.2.0.5へバージョンアップをします。

まず、OracleClient10.2.0.1がインストールされている環境で作成したモジュールを、
10.2.0.5環境で動かすと、例外エラーが出ます。

【エラー内容】
ファイルまたはアセンブリ 'Oracle.DataAccess, Version=10.2.0.100, Culture=neutral, PublicKeyToken=89b483f429c47342'、またはその依存関係の 1 つが読み込めませんでした。指定されたファイルが見つかりません。

これは、side-by-side実行 という.netの標準動作であり、
ビルドした時に使用したモジュールのバージョンを実行時のも保持している事が理由で
このエラーは、ビルド時のモジュールがないからと発生するものです。

詳しくは、@ITあたりで。
http://www.atmarkit.co.jp/fdotnet/technology/idnfw11_04/idnfw11_04_01.html

対処法の1つとして、bindingRedirectという仕組みがあります。
簡単に言うと、バージョンをリダイレクトし、異なるバージョンへ飛ばすものです。

これで、該当モジュールが存在しないときに、別のバージョンを参照することができます。
設定は、app.configに記載する必要があります。

【記載例】
    <runtime>
        <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
            <dependentAssembly>
                <assemblyIdentity name="Oracle.DataAccess" publicKeyToken="89B483F429C47342"/>
                <bindingRedirect oldVersion="10.2.0.000-10.2.0.999" newVersion="1.102.2.20"/>
            </dependentAssembly>
        </assemblyBinding>
    </runtime>


ここで、「ん?」と思ったかもしれませんが、
ODP.netのバージョン番号の付与方法は、ODP10.2.0.3以降より、大幅に変わっています。

簡単に言うと、10.2.0.2までは、ODP.netのバージョンとほぼ同等。
それ以降は、先頭にFrameworkのバージョン番号が付くようになります。

アセンブリはバージョンアップしているにもかかわらず、バージョン番号は下がっているようにみえる。
一瞬混乱しますが、bindingRedirectの仕組みは、バージョンダウンにも対応可能。
よって、本方法で動作します。

それじゃなければ、汎用的なbindingRedirectの記述方法で簡単に参照できるそうです。(未検証)


【追記】
別アプローチとして「発行者ポリシー」を作成する等方法があります。
これは、GACに対してBindingRedirectを設定されるようなイメージですが、
アプリを改修せずに実施できるので、選択肢として検討するのもいいかもしれません。


2014年2月3日月曜日

zabbixのログインパスワードを忘れてしまった場合の対処(管理者向け)

この手の記事はよく書いている気がします。

zabbixのWeb画面からログインするためのパスワードを忘れてしまった時の処置です。

以下のようにデータベースを直接修正すれば可能です。 

※ZABBIXのデータベース名がzabbixだった場合


# mysql -uroot -p zabbix

mysql> update users set passwd = 'd41d8cd98f00b204e9800998ecf8427e' where alias = 'Admin'; 

これでAdminユーザのパスワードが空白に設定されます。