饂飩コーディング

iOSアプリやら、Unityやら、Cocos2dやらごにょごにょ書いております

サイト引越しのお知らせ

この度はてなブログから新規ドメインでのブログに引越ししました。

新ブログ https://scombu.com
新ブログ名 すこんぶ

これまで同様よろしくお願いいたします。

なおはてなブログの記事はそのまま残しておくと共に
はてなブログの記事からリダイレクトで自動転送されます。

Keychron K6 配送記録

Keychron K6 購入時のメモ
どのくらいの日数でキーボードが手元に届くか?

結論からいうと発送から3日で都内の自宅まで届きました!!

日付 所要日数
注文日 2021/10/04 -
発送日 2021/10/11 7
配達完日 2021/10/14 3

オンラインショップでの注文は 2021/10/04
f:id:appdeappuappu:20211017220437p:plain


中国ではこの時期連休なので発送が連休明けになったので
他の時期であれば発送処理がもっと早いと思います。

送料は関東ならおそらく20ドル、その他地域だと追加料金かかるそうです。
大阪近郊だとどうなんでしょうね?

10%割引コードを他の購入者が表示してくれているので自分もそちらを利用させていただきました。



Keychronからの発送日 2021/10/11
DHLでの配送完了日 2021/10/14
f:id:appdeappuappu:20211017220023p:plain


秋葉原ヨドバシカメラでもKeychronキーボードが店頭販売されていました。
自分が見かけた時はロープロファイルのキーボードだったのですが
実機に触れてみたいとか今すぐ欲しい!って時はこちらで購入するのもいいですね。

梱包はこんな感じ、一見雑だが効率的。
f:id:appdeappuappu:20211014145725j:plain
f:id:appdeappuappu:20211014150325j:plain

Amazonでも販売してるので早く欲しい場合はいいかもしれない。キー配列がJISだったりするので注意しましょう。

Keychron K6 メカニカルキーボード(MacBook と Windows)

Keychron K6 メカニカルキーボードを購入した
フルサイズキーボードの65%の大きさで小さいからマウスへの手の移動が短くてすむ。
英語配列だからプログラミングの時の記号入力が少しらく。
そもそも自分の手が小さいのでフルサイズキーボードよりも小さいキーボードの方が楽。
バックライト無しバージョンにしたので送料込みで85ドル程度の安さ!!
パームレスト必須になるけどホームセンターで1x4材を32cmに切って貰ってサンドペーパー掛ければお手軽に自作も可能。
f:id:appdeappuappu:20211015230918p:plain
Keychron K6 Wireless Mechanical Keyboardwww.keychron.com

amazonでも売ってるけど、keychronのオンラインショップの方が安いかな。DHLの送料は都内だと20ドルでおさまったけど地方だとさらに特別料金がかかるみたいですね。
www.amazon.co.jp


このキーボードの利点は他にもあって
Mac/win/iOS(iPadOS)の三種類の接続設定でき、キーボードの操作で切り替えができる。
Logicoolのマウスと合わせて使えばボタンおすだけで操作を切り替えできるので便利。
bluetooth接続なのでケーブルレス(USBケーブルで接続もでき、充電時もこのケーブルで可能)

以下はメモ

ノートPC本体 Keychron K6
MacBook JIS配列 US配列
WinPC JIS配列 US配列

MacではキーボドごとにJISorUSの設定ができるが
Winの場合はこれができないのが難点。

Kyechron K6 左側面
f:id:appdeappuappu:20211016071502p:plain
Mac/Win切り替えスイッチは常時Mac側に固定で運用
↑MacWindowsの切り替え時にはなにもしない、そのせいでwindowsKeyとAltkeyの配置がWindowsで違ってくるが気にしない。

キーバインド変更アプリ

Mac Win
karabiner-elements.pqrs.org www.vector.co.jp

キーバインド
キーボード右上のDeleteキーはENDキーに変更(自分Deleteキー使わないから)
Macはkarabinaで変更、WindowsはKyeswapで変更)
ENDキーにした理由はVisualStudioCodeでのカーソル移動時に
Homeボタンで行頭へ移動
ENDボタンで行末へ移動してくれるから

karabiner
f:id:appdeappuappu:20211015231344p:plain
f:id:appdeappuappu:20211015231430p:plain

keyswap
f:id:appdeappuappu:20211015231700p:plain
↑keyswapの注意点 アプリの起動時に右クリックで管理者として実行を選択して起動すること。
スタートアップにも入れておく

日本語入力について
Mac日本語入力
Caps 日本語/英語の切り替え(Windowsでのime切り替えっぽく使える)
左コマンド 英語固定(MacBookのキーボード合わせた使わないかもしれない)
右コマンド 日本語(MacBookのキーボード合わせた使わないかもしれない)

Windows日本語入力
Windows+spaceで日本語環境と英語環境を切り替える(USキーボード配列は英語環境時のみ有効)
日本語入力環境時にcapsにて日本語入力を可能とする
↑これが若干面倒(レジストリを変更すればUSBボート単位でUSキーボード固定にできるが今回は設定しない)

実運用
Logicool のLogicoolFlow機能でMac-Win端末間でマウスを切り替えさせ、クリップボードを共有する。
ファイルはクラウドで共有すればOK
www.logicool.co.jp


Amazonでも販売してるので早く欲しい場合はいいかもしれない。キー配列がJISだったりするので注意しましょう。

VBAでPDFファイルを同期印刷する!

VBAでPDFファイルを印刷する!で検索すると確かに情報は沢山でてきます。
しかし今回やりたいのは「同期印刷」

複数のPDFがフォルダに入っていてそれをFSOでなんとかしながら
ループで各PDFファイルを印刷処理するとループががぁ~っと流れてしまい、
適切なSleep処理を入れておかないと思ったように印刷してくれません。

この段階で印刷中の画面をぼーっと眺めていると、Acrobat ReaderDCのウィンドウにPDFファイルが順によみこまれて
複数のPDFファイルが一つのAcrobatReaderDCのウィンドウに横展開され印刷が終わってもこのウィンドウが終了してくれません。
この段階で自分は「あぁ、これじゃ同期処理できねぇ~アプリケーション終了しなきゃ同期できない。」と半ばあきらめてました。

まぁ、取り合えずはSleepでタイミングを上手にいれてけば問題なないかな?なぁ~んて軽く考えていたのですが
以下の二点でやっぱり同期させたい!同期させたい!(大事なので二回言います!)

①一枚目の印刷が終わったら間髪入れずに二枚目の印刷処理して大量印刷の場合に時間を節約する。
➁一枚目の印刷が終わったら印刷元ファイルをリネームして印刷済みとわかるようにしたい。

しかぁ~し、なかなかVBAで同期印刷するサンプルが見つからない見つからない。

あきらめずに調べてるとこんな情報が!!!
AcroRd32.exeのプロセスが二つ表示されるとか、/nオプションで新規でインスタンス化するとか・・・

どうも空のAcroRd32.exeを一つ起動しておき、印刷はそれぞれ追加でAcroRd32.exeをインスタンス化させながら印刷処理すればそれぞれのインスタンス化された実態が印刷終了後に終了してくれるという情報があって「これでできるのかな?」なんて期待をしてみました。

久しぶりにGoogle先生からの丸パクリはできないパターンだったんで以下の方針で実装してみます。
方針1 印刷コマンドを発行前にAcroRd32.exeを一つだけ空インスタンス化しておく。
方針2  shellObj.Run (exeStm), True, True オプションTrue True(二つ目のTrueで同期実行) させる。
方針3 AcroRd32.exe /n /t のオプション指定で印刷する

Private Sub ぼたん_Click()

  'プリンタ設定
  Dim prtDefault As Printer
  '現在のプリンタ設定を退避
  Set prtDefault = Application.Printer 'これがデフォルトプリンタ
  
  '印刷するぞ
  
  'Shell Objestの作成
    Dim shellObj As Object
    Set shellObj = CreateObject("WScript.shell")
    
    Dim exeStm As String
    'Acrobat Readerの一つ目インスタンスを起動
    shellObj.Run "AcroRd32.exe"
    '起動するまで長めに待機
    Sleep 5000 'Sleep APIは別途Declearしておく
    'Acrobat Readerでプリントアウトするコマンドを三つ作っておく。
    '/n インスタンスを新規で作成するオプション
    '/t 印刷オプション
        exeStm = "AcroRd32.exe /n /t" & " " & "C:\Users\xxx\Desktop\test.pdf" & " " & Application.Printer.DeviceName
        shellObj.Run (exeStm), True, True '同期処理で印刷
        
        exeStm = "AcroRd32.exe /n /t" & " " & "C:\Users\xxx\Desktop\test2.pdf" & " " & Application.Printer.DeviceName
        shellObj.Run (exeStm), True, True '同期処理で印刷
        
        exeStm = "AcroRd32.exe /n /t" & " " & "C:\Users\xxx\Desktop\test3.pdf" & " " & Application.Printer.DeviceName
        shellObj.Run (exeStm), True, True '同期処理で印刷
        
  Set prtDefault = Nothing
  Set shellObj = Nothing
  
End Sub

同期処理できてる!!!!


せっかくなんでVBScriptバージョンはこちら。
適当な名前.vbs 
で保存してPDFファイルが入ったフォルダに突っ込んで
ダブルクリックすると印刷されますw

Option Explicit

	Dim f, gf, so, ws
	dim cmdString
	Set so = CreateObject("Scripting.FileSystemObject")
	Set gf = so.GetFolder(".")
	Set ws =CreateObject("WScript.Shell")

	Dim sapi
	Set sapi = CreateObject("SAPI.SpVoice")
	
	

	'AcroRd32.exe一つ起動しておく。
	ws.Run "AcroRd32.exe"
	WScript.Sleep 5000

	'フォルダ内のPDFファイルをそれぞれ/n/tで印刷をループさせる。
	For Each f In gf.Files
		If LCase(so.GetExtensionName(f.Name)) = "pdf" Then
		
		'上手く印刷が終わるまで同期してくれる。
		cmdString = "AcroRd32.exe /n /t " & """" & f.path & """"
		ws.Run cmdString,true,true
		sapi.Speak "ichimai owattayo"
		End If
	Next
	sapi.Speak "zenbu owattayo"
	Set gf = Nothing
	Set so = Nothing
	Set ws = Nothing
	Set sapi = Nothing

	
	'MsgBox("Finished Printing")

エラートラップ作って一定時間待機させてからエラーをリトライする方法

数値変数にInputBoxから数値を入力させると処理終了なんですが、
数値以外を入力すると変数に代入する時点でエラーになり
それをトラップして三秒待ったのちに再度エラーが発生した処理を
行う流れです。リトライ回数を決めればある程度使えそう。
その時はトラップの中にCase文書くとかトライ回数を管理しておくとか
すれば何とでもなりそうですよね。

Private Sub コマンド0_Click()
    On Error GoTo errorTrap1
    
    Dim numberValue As Long
    numberValue = InputBox("数値を入力してください。何か入力して下さい。")
    
    MsgBox "数値が入力されました"
    Exit Sub
    
errorTrap1:
    MsgBox "エラー発生 リトライします"
    
    Sleep (3000)

    Resume  'エラーが発生した行に戻ってリトライします。

End Sub

Accessで日本語を読み上げさせてみる

ごめんなさい、丸パクリです
なにに使えるかって、機器設定用の番号読み上げとか入力値チェックで読み上げれば
ダブルチェックできる!

Private Sub txt_test1_AfterUpdate()
    With CreateObject("SAPI.SpVoice")
        Set .voice = .GetVoices.Item(0)
        .Rate = 5
        .Speak (Me.txt_test1.Text)
    End With
End Sub

thom.hateblo.jp

添付型フィールドにwavファイルを追加してボタンクリックで音を出す。

Accessで音を鳴らすにはいくつか方法がありますよね。
1,フォームにwavファイルを挿入して以下の様にする
  oleSound.Action = acOLEActivate
  参考にさせていただきました。
tsware.jp
2,API使って音を出す方法
  ・mciSendString
  ・PlaySound

などなど

そこでwavファイルの設置の仕方なんですが、AccessDBファイルを現場環境に納品する時に1はDBファイルに包括されているので問題ありませんが、
2の場合はwavファイルがフルパスで指定するのでDBファイルとwavファイルを別で納品して、現場の環境に合わせてwavファイルを設置しなければいけません。

ちなみに1の場合はwavファイル再生の時にMediaPlayerの画面がポップアップされるのでいまいち使い勝手がよくありません。OLEだからかなぁ・・・まぁ、それはさておき

どうせなら、2もあらかじめテーブル内にwavファイルを保持しておいて、使うときにTempフォルダに展開してからそのフルパスを使ってAPIにフルパスを渡して再生すれば、納品時に複数ファイルにならないし、設置環境にわざわざwav保管用のフォルダを作らなくても済むんじゃないかと考えました。(まぁTempフォルダに保管フォルダ作りはするんですけどね)


概略と実装方法は以下みたいな感じで!
概要
① 適切なテーブルに添付型フィールドを作成してそこにwavファイルを複数添付しておく。
➁ アプリケーションの起動時、もしくはファイルを開くときに①で添付したファイルをTempフォルダーに書き出す。
③ APIをCallして特定の音を出す。

実装方法
① 添付型フィールドを適当なテーブルに作成してそこにあらかじめ準備しておいたwavファイルを追加しておく。(複数でもOk)
➁ フォームを開く時にFSOでユーザーのtempフォルダーを取得しそこに保管用フォルダを作成する。
③ 上記保管フォルダーにテーブルに保管しておいた添付ファイル(wavファイル達)を.SaveToFileで出力する。
④ 出力したフルパスをグローバル変数にセットしておき、必要な場面でmciSendStringをcallして音を出す。

てな具合です。
さてやってみましょう

まずはテーブルに添付がたフィールドを作成してwavファイルを保管します。
f:id:appdeappuappu:20210410234703p:plain

そのフィールドにwavファイルを追加する。今回は二つ
f:id:appdeappuappu:20210410235039p:plain
f:id:appdeappuappu:20210410235335p:plainf:id:appdeappuappu:20210410235347p:plain

グローバル変数API定義の宣言

Public beepSound1DirectoryPath As String
Public beepSound2DirectoryPath As String
#If Win64 Then
    Public Declare PtrSafe Function mciSendString Lib "winmm.dll" Alias "mciSendStringA" _
    (ByVal lpstrCommand As String, ByVal lpstrReturnString As String, _
     ByVal uReturnLength As Long, ByVal hwndCallback As Long) As Long
#Else
    Public Declare Function mciSendString Lib "winmm" Alias "mciSendStringA" _
    (ByVal lpstrCommand As String, ByVal lpstrReturnString As String, _
     ByVal uReturnLength As Long, ByVal hwndCallback As Long) As Long
#End If

FSOでtempフォルダのパスを取得してそこに保管用のフォルダを作成し添付データを出力する。

Public Function test()
On Error Resume Next
    Dim fso         As New FileSystemObject     'FSO
    Dim f           As Folder                   'Folder
    Dim newFolderName As String                 '新規作成するフォルダ名
    Dim newDirectoryPath As String              '新規作成するフォルダのフルパス
    
    Set f = fso.GetSpecialFolder(TemporaryFolder) 'Tempフォルダーパスの取得
    
   
    newFolderName = "TestFolder" 'このAccess用のtempフォルダ名
    newDirectoryPath = f & "\" & newFolderName
    
    beepSound1DirectoryPath = newDirectoryPath & "\sound1.wav"
    beepSound2DirectoryPath = newDirectoryPath & "\sound2.wav"
    
    If Dir(newDirectoryPath, vbDirectory) = "" Then
        fso.CreateFolder newDirectoryPath
    End If
     
    Set fso = Nothing
    
    '添付型カラムから添付したファイルをTempフォルダに出力する。
    Dim DB As DAO.Database
    Dim R1 As Recordset

    Set DB = CurrentDb()
    Set R1 = DB.OpenRecordset("テーブル1")
    R1.MoveFirst
    Do Until R1.EOF

        With R1("AddData").Value 'AddDataカラムのそれぞれのValueに添付データが入っている
            While Not .EOF
             .Fields("FileData").SaveToFile newDirectoryPath  'FileDataに添付データが入っている。
                                                              'FileNameでnewDirectoryPathに保存される。
             .MoveNext
            Wend
        End With
        R1.MoveNext
    Loop
    
    R1.Close
    DB.Close
    Set R1 = Nothing
    Set DB = Nothing
End Function

mscSendStringで音をだす。

Private Sub コマンド5_Click()
    Call mciSendString("play " & beepSound1DirectoryPath, "", 0, 0)
End Sub

Private Sub コマンド3_Click()
    Call mciSendString("play " & beepSound2DirectoryPath, "", 0, 0)
End Sub

後は最後に閉じるフォームに作成したTempフォルダ内のテストフォルダを削除する機能を必要に応じて実装する。

ボタンおすと音がでます!!!
f:id:appdeappuappu:20210411101057p:plain