愚者の経験

「また今度」はほとんどこない

Windows10にてmshtml.dllが更新される[VBA]

Windows10のアップデート(5/10前後)でに上記のdllが更新されました。
おそらくそれが原因で下記のコードが動かなくなりました。

Option Compare Database
Option Explicit

' 擬似非同期処理クラス
' 指定したオブジェクトのパプリックプロシージャを非同期実行

Private html As Object
Private Method As String
Private Arguments As Variant
Public Target As Object

Private Sub Class_Initialize()
    Set html = CreateObject("htmlfile")
    Set html.parentWindow.onhelp = Me
End Sub

Private Sub Class_Terminate()
    Set html.parentWindow.onhelp = Nothing
    Set html = Nothing
End Sub

Public Sub AsyncCall(MethodName As String, TimeLag As Long, ParamArray Args() As Variant)
    If (Target Is Nothing) Then
        Set Target = CodeContextObject
    End If
    
    Method = MethodName
    Arguments = Args
    
    html.parentWindow.setTimeout "onhelp.CallMethod", TimeLag, "VBScript"
End Sub

' 非同期実行プロシージャ
Public Sub CallMethod()
    CallByName Target, Method, VbMethod, Arguments
End Sub

フォームのPublicのプロシージャを非同期もどきで処理していたんですがなぜか動かなくなりました。エラーが出ることもないです。

上記のプログラムをざっくり説明すると
「webページのオブジェクト作って、setTimeout関数で画面の処理(フォームのPublicプロシージャ)を呼ぼう」ってプログラムです。
本来は不可能なMsgBoxを同時に2つ出したりできます。

Private Sub Class_Initialize()
    Set html = CreateObject("htmlfile")
    Set html.parentWindow.onhelp = Me
End Sub

CreateObject(“htmlfile”)でhtmlドキュメントを作成し
parentWindowの適当なプロパティ(この場合はonhelp)にMe(このクラスオブジェクト)を代入し

    html.parentWindow.setTimeout "onhelp.CallMethod", TimeLag, "VBScript"

setTimeout関数でこのクラス(onhelpに代入されている)のメソッド呼びましょうねって感じです。

動かなくなったので代替コードが下記

Option Compare Database
Option Explicit

' 擬似非同期処理クラス
' 指定したオブジェクトのパプリックプロシージャを非同期実行

Private html As Object
Private Method As String
Private Arguments As Variant
Public Target As Object

' Set html.parentWindow.onhelp = Me
' html.parentWindow.setTimeout ~~
' 上記コードは動かなくなった(Windows10のアップデートでmshtml.dllが更新されたのが原因?)
' ので代替コードで修正

Private Sub Class_Initialize()
    Set html = CreateObject("htmlfile")
    
    Const EXEC_SCRIPT = _
            "this.async=" & _
                "function(obj,lag){" & _
                    "setTimeout(function() {obj.CallMethod()},lag)}"
    
    Call html.parentWindow.execScript(EXEC_SCRIPT)
End Sub

Private Sub Class_Terminate()
'    Set html.parentWindow.onhelp = Nothing
    Set html = Nothing
End Sub

Public Sub AsyncCall(MethodName As String, TimeLag As Long, ParamArray Args() As Variant)
    If (Target Is Nothing) Then
        Set Target = CodeContextObject
    End If
    
    Method = MethodName
    Arguments = Args
    
    'html.parentWindow.setTimeout "async.CallMethod", TimeLag, "VBScript"
    Call html.parentWindow.async(Me, TimeLag)
End Sub

' 非同期実行プロシージャ
Public Sub CallMethod()
On Error Resume Next
    CallByName Target, Method, VbMethod, Arguments
End Sub

parentWindow.execScriptでfunctionを登録して
引数でMeを指定しfunction内のsetTimeoutで指定秒数後callします。
なぜこれなら動くのか全く不明だがとりあえず動く。

広告

AccessのコンボボックスがF4キーで開かない原因

以前コンボボックスがF4キーで開かなくなったとぼやいていたんですが原因がわかりました。

その原因は…
『レイアウトビューが有効かどうか』
です。

ハイ?一見関係ないと思いますがこれが原因でした。
データシートのサブフォームでF4キーを使いたい場合は
・Accessのオプションで「カレントデータベース」→「レイアウトビューを有効にする」のチェックを外す
・メインフォームのプロパティで「レイアウトビューを許可」を「いいえ」
のどちらかを設定すればF4キーが使えるようになります。

なぜかはわかりません。

[SQL Server]apply句を使わないなんてとんでもない

久しぶりの投稿。今回はSQL Serverの一つの機能についてご紹介。

「apply句」というものです。

DBの種類によってはLATERAL句とか言われるらしいですね。

select A.ID,X.col1,X.col2
from dbo.table1 as A
    outer apply (
        select top 1 B.col1,B.col2
        from dbo.table2 as B
        where B.ID=A.ID
        order by B.inputdate desc
    ) as X
where A.datatype=1
order by A.ID

こんな感じで記述、実行できます。LATERALは遅延実行みたいな意味なのかな?
例えばデータに対する履歴テーブルみたいなものを取っており、
「最新の1履歴だけデータごとに出す」という内容のselectをする場合に
とても有用。副問合せでは1列しか選択できないのを
複数列で対応できるようになった感じ、と言ったほうがいいかもしれません。
副問合せではこんな感じになるんですよね。

select A.ID
    ,(
        select top 1 B.col1--,B.col2
        from dbo.table2 as B
        where B.ID=A.ID
        order by B.inputdate desc
    ) as col1
from dbo.table1 as A
where A.datatype=1
order by A.ID

これだと1列ずつしか取れず複数列をselectすると当然ですがエラーが出ます。
じゃあ複数書くのか?と言われれば心情的にはNOなわけで、今までは
row_numberで番号を付けてから1で抽出するとかして要らないデータを
検索せざるを得ない状況でした。

とはいうもののapply句はバージョン2005で実装されてるんですよね…
自分は2012年くらいから気づいたけれども正直もっと早く気づきたかった。

Vue結構いいかも。

2-3年くらいだったか前にも見たけどこれは結構いい気がする。
webでシステム作るんだったらnodeサーバー側で動かしてjqueryとvueでデータベースアプリケーション
やるのが「Access畑の自分にとっては」わかりやすいと思う。

データベースと画面が連結していたAccessとはもちろん違うけど
「変数と画面を連結してくれる」のは非常にありがたい。v-modelはAccessで言うところの
「コントロールソース」みたいな感じがして個人的にGood。jqueryでDOM操作が楽になったとは言え
毎回$(セレクタ)val(値);やるのきつい。

データベースはnodeで動かせるsqlite3でやればオブジェクトでもらえるし
Vueのdataにセオリー通りにぶち込めば動いてくれる。

[Access]帳票フォームでスクロールバーが動かない

不具合多くないですかね…?スクロールバーが「ホイール」と「スクロールバーのドラッグ」で動かない状況に遭遇してます。スクロールバー上下の三角「▲」「▼」をクリックすると動かせますが、それ以外ではピクリともしません。

現在はAccess2016で確認できますがAccess2010,2013では確認できていません。
Access2016を入れているPCと2010,2013のPCは別のPCのため完全に切り分けできてはいませんが…

[追記 2017-10-25]
2017-10-11頃のアップデートを適用するとAccess2010でも帳票フォームのスクロールバーが
ホイールで動かなくなりました。WindowsUpdate適用前の復元で戻ったので何かある模様

[Access 2016]VBAモジュールが壊れるエラー(解決済み)

結構深刻でした。『データベースに含まれている VBA プロジェクトを読み取れないため、データベースを開くことができません。データベースを開くには、VBA プロジェクトを削除する必要があります。VBA プロジェクトを削除すると、モジュール、フォーム、およびレポートからすべてのコードが削除されます。データベースを開いて、VBA プロジェクトを削除する前に、バックアップ コピーを作成することをお勧めします。
データベースのバックアップ コピーを作成する場合は、[キャンセル] をクリックしてください。バックアップ コピーを作成しないでデータベースを開き、VBA プロジェクトを削除する場合は、[OK] をクリックしてください。』のようなメッセージが出て何も考えずに「OK」をクリックするとモジュールが全て消えてしまいます。

ファイルのバックアップがなかったらかなりやばいです。
現在は最新版に更新することで直りますので、最新版にしましょう。
「ファイル」→「アカウント」から「今すぐ更新」で最新版にできます。

[Access]いつの間にかF4キー動かない?

サブフォームのコンボボックス開かなくなってません?
Access2010,Access2013,Access2016で開かないことは確認してます。
帳票フォームは動く模様。サブフォームのデータシートだけが動かないのかな?

SIMアダプターっておかしくない?

絶対端子壊しにかかってると思う…

004.jpg
ここ縦の位置合わせたいだけなら不要じゃない?

0042.jpg
画像は大分やっつけですがSIMが引っかかる程度でいいと思いました。

時代が自分に追いついた(違)

かなり久しぶりの投稿なのにどうでもいい話

以前こんなこといってたんですが『EpicGear DeFiant』なるキーボードが去年の10月に出てました。

あとはこの「キートップ自体が入力する文字を持つ」のが常識になってキートップの差し込みの形が統一されて色んな土台(キーボード自体の形)とキートップの外装をメーカーが出してくれれば、みんな好きなようにカスタム、セレクトできて幸せになれそうです。

[CSS]ボックスの高さをページにあわせるには?

よくhtmlとbodyにheight:100%;つけて、中のボックスにmin-height:100%;をつければ~的なのがあるんですが
height:100%;ボックスの上下に別の高さを持つ要素があれば、その分の高さ+ページの高さになってしまいます…(´・ω・`)

height:100%;は親要素の高さをそのまま持つという意味ですから当たり前なのですがどちらかと言うと
「(途中から始まったとしても)画面下まで一杯の高さを持ちたい」という要望が多いと思うのです。

これをする場合はまず親要素(bodyとかのページそのものの高さを持つもの)にposition:absolute;
途中に囲むdivなどにはheight:100%;だけを指定して、下まで伸ばすボックス要素にposition:absolute;を追加、
座標起点がページ左上になるのでボックスの上にある要素の高さXXを合計してborder-top:XX solid #fff;box-sizing:border-box;height:100%;
で、下まで伸ばすためにbottom:0;を利用する

でごり押してるんですがもっといい方法ありませんかね?

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8" />
        <title>ハイト100%</title>
        <style type="text/css">
            html{height: 100%;}
            body{height: 100%;margin: 0;position: absolute;}
            #main{height: 100%;width: 800px;position: absolute;}
            #main>#tab {height: 100%;box-sizing: border-box;border-top: 70px #fff solid;}
            
            header{margin: 10px;height: 50px;position: absolute;}
            .tabradio{display: none;}
            #contents{width: 800px;display: table;height:100%;}
                        
            #sono1lbl{background: #ffbf7f;}
            #sono1_cont{border-color: #ffbf7f;}
            #sono2lbl{background: #ffff7f;}
            #sono2_cont{border-color: #ffff7f;}
            #sono3lbl{background: #7fff7f;}
            #sono3_cont{border-color: #7fff7f;}
            #sono4lbl{background: #7fbfff;}
            #sono4_cont{border-color: #7fbfff;}
            #sono5lbl{background: #ff7fff;}
            #sono5_cont{border-color: #ff7fff;}
                        
            .tabpage{display: none;position:absolute;top: 150px;left:0;bottom: 0;right: 0;width: 120%;box-sizing:border-box;border-width: 3px;border-style:solid;font-size: 20px;}
            #sono1:checked+#sono1_cont{display:block;}
            #sono2:checked+#sono2_cont{display:block;}
            #sono3:checked+#sono3_cont{display:block;}
            #sono4:checked+#sono4_cont{display:block;}
            #sono5:checked+#sono5_cont{display:block;}
            
            #tab{width: 100%;font-size:0;height:100%;}
            .tabindex{display:inline-block;font-size:20px; width: 20%;height: 80px;text-align: center;border:#a5a5a5 1px solid;box-sizing:border-box;padding-top:25px;}
        </style>
    </head>
    <body>
        <div id="main">
            <header>
                <h1>ハイト100%テスト</h1>
            </header>
            <div id="tab">
                <label id="sono1lbl" for="sono1" class="tabindex">その1</label>
                <input id="sono1" type="radio" name="nav" class="tabradio" checked>
                <div id="sono1_cont" class="tabpage">その1</div>
                <label id="sono2lbl" for="sono2" class="tabindex">その2</label>
                <input id="sono2" type="radio" name="nav" class="tabradio">
                <div id="sono2_cont" class="tabpage">その2</div>
                <label id="sono3lbl" for="sono3" class="tabindex">その3</label>
                <input id="sono3" type="radio" name="nav" class="tabradio">
                <div id="sono3_cont" class="tabpage">その3</div>
                <label id="sono4lbl" for="sono4" class="tabindex">その4</label>
                <input id="sono4" type="radio" name="nav" class="tabradio">
                <div id="sono4_cont" class="tabpage">その4</div>
                <label id="sono5lbl" for="sono5" class="tabindex">その5</label>
                <input id="sono5" type="radio" name="nav" class="tabradio">
                <div id="sono5_cont" class="tabpage">その5</div>
             </div>
        </div>
    </body>
</html>