Excel2013がよく落ちる場合の対処方法(ScanSnapを使っている人)

Excel2013は不安定なようで、
例えば漢字と漢字の間でスペースキーを押しっぱなしにしただけで落ちてしまう。
http://support.microsoft.com/kb/2848815 (MSサポート技術情報)
いまだに修正されない。 →下の追記参照。

ScanSnapとの相性も悪いようだ。
http://support.microsoft.com/kb/2755838/ja (MSサポート技術情報)
↑記事中のABBYY FineReaderはScanSnap付属のソフトだ。

ScanSnapのS1500、S1300、S1100を使っている人は
関連ソフトをアップデートする必要がある。

・手順1
ABBYY FineReader for ScanSnapをアップデート。
http://scansnap.fujitsu.com/jp/downloads/abbyy4.x.html (富士通)

・手順2
ScanSnap Managerをアップデート。
スタート – すべてのプログラム – ScanSnap Manager – オンラインアップデート

ScanSnap Organizerをアップデート。
スタート – すべてのプログラム – ScanSnap Organizer – オンラインアップデート

名刺ファイリングOCRをアップデート。
スタート – すべてのプログラム – 名刺ファイリングOCR – オンラインアップデート

上記Microsoftサポート技術情報によればABBYY FineReaderの不具合らしいので、
手順2はExcel2013の不具合解消にとっては必要ないかもしれない。

スペースキー押しっぱなしの不具合はScanSnapとは関係ないようなので解消されないが、
それ以外の不具合はだいぶ解消されると思う。

(2013.11.02追記)
漢字と漢字の間でスペースキーを押しっぱなしにしただけで落ちる件は、
2013年8月の更新プログラムでようやく修正されたようだ。

Excel VBA 動的配列が空かどうかの確認方法

次のように配列の要素を確保しないでUBoundなどを使うと,
「インデックスが有効範囲にありません。」というエラーが出る.

Sub test()
    Dim i As Long
    Dim a() As Long

    For i = 0 To UBound(a) ‘エラー
        ‘~~~
    Next
End Sub

エラーを回避しようと思っても Not a Is Nothing とかは使えない。
次のようにするとエラーを回避できる.

Sub test()
    Dim i As Long
    Dim a() As Long
    If Not Not a Then ‘Notを2つ
        For i = 0 To UBound(a)
            ‘~~~
        Next
    End If
End Sub

または,

Sub test()
    Dim i As Long
    Dim a() As Long
    If Sgn(a) <> 0 Then ‘Sgn関数を使う(なぜ使えるのかは不明)
        For i = 0 To UBound(a)
            ‘~~~
        Next
    End If
End Sub

または,

Private Declare Function SafeArrayGetDim Lib “oleaut32” (ByRef psa() As Any) As Long

Sub test()
    Dim i As Long
    Dim a() As Long
    If SafeArrayGetDim(a) <> 0 Then ‘APIを使う
        For i = 0 To UBound(a)
            ‘~~~
        Next
    End If
End Sub

Excel VBA + ADO ストアドからレコードセット取得,シートへ貼付

Dim Cn As ADODB.Connection
Dim rst As New ADODB.Recordset


1.ストアドからレコードセットを取得して返す

Sub Test1(ByRef rst As ADODB.Recordset)
  Cn.stTest1 rst ‘ストアド実行
End Sub


2.ストアドからレコードセットを取得して返す(パラメーターあり)

Sub Test2(a1 AS Long, Date1 As Date, Str1 As String, ByRef rst As ADODB.Recordset)
    Dim cmd As ADODB.Command
    Dim par0 As ADODB.Parameter, par1 As ADODB.Parameter, par2 As ADODB.Parameter
    Set cmd = New ADODB.Command
    Set cmd.ActiveConnection = Cn
    cmd.CommandText = “stTest2”
    cmd.CommandType = adCmdStoredProc
    cmd.CommandTimeout = 30 ‘タイムアウト時間
    ‘パラメーター設定
    Set par0 = cmd.CreateParameter(“@a1”, adInteger, adParamInput) ‘int
    cmd.Parameters.Append par0
    par0.Value = a1
    Set par1 = cmd.CreateParameter(“@Date1”, adDBDate, adParamInput) ‘datetime
    cmd.Parameters.Append par1
    par1.Value = Date1
    Set par2 = cmd.CreateParameter(“@Str1”, adVarWChar, adParamInput, 50) ‘nvarchar(50)
    cmd.Parameters.Append par2
    par2.Value = Str1
    ‘実行
    rst.Open cmd, , adOpenForwardOnly, adLockReadOnly
    Set cmd = Nothing
End Sub


3.シートへの貼付

レコードセットの内容をそのままシートに貼り付けるにはCopyFromRecordsetメソッド
Sheet1.Cells(1, 1).CopyFromRecordset rst

普通は↑のようにそのまま貼り付けても役に立たないので配列に加工してから貼付
Dim DataArray() As Variant ‘2次元配列にする
‘レコードセットを配列に代入して加工するコード
・・・
‘配列をシートに貼付
Sheet1.Range(Sheet1.Cells(1, 1), Sheet1.Cells(UBound(DataArray, 1) + 1, UBound(DataArray, 2) + 1)).Value = DataArray


注意: VBAではレコードセットをReadOnlyで開いてもなぜかロックがかかってしまうことがあるので,レコードセットはできるだけ早く閉じた方がいい.