カテゴリー: Development

ExcelVBA覚書 Formからの情報連携

フォーム上で何のボタンを押されたのかを呼出元に返したいときとか、Public変数を利用していたのだが、面白いやり方というのをインターネットで見つけた。

FormのTagプロパティを使うのだが、「なるほど、これは便利!」と思えたので、メモしておく。

'呼出元プロシージャ(または関数)の記載例
Load HogeForm
HogeForm.Show
If HogeForm.Tag = "1" Then
    '(終了ボタン押下時の処理を記載)
Else
    '(中止ボタン押下時の処理を記載)
End If
Unload HogeForm
'呼出先(HogeForm)の記載例

'終了ボタン押下
Private Sub ExitButton_Click() 
    HogeForm.Tag = "1" 
    HogeForm.Hide
End Sub

'中止ボタン押下
Private Sub CancelButton_Click() 
    HogeForm.Tag = "0" 
    HogeForm.Hide
End Sub

使うときは、念のためフォームのInitializeプロシージャでTagプロパティを空欄にしておくといいと思った。

@PagesへFTP接続(FFFTP利用)

実はFTPサーバが変わってからFFFTPで接続できてなかったのだが、やっとこさ理由がわかった。
前はパッシブモードをONにしなければならなかったのだが、今はOFFにしなければならなくなった。
で、無事にアクセスできた・・・
って、何ヶ月かっかっとんねん!
(Web版の簡易FTPでやれてたんだから、まぁよいんだけど)

ExcelVBA覚書 セルにコメントをつける

セルにコメント(ふきだし)をつけるやり方。

Dim rng As Range
Dim msg As String
Dim clear_flg As Boolean

'選択中のセルにコメントを追加していく
Set rng = ActiveCell
msg = "あいうえお"
clear_flg = False         'コメントを刷新するときはTrueに変える

On Error Resume Next
If Not rng.Comment Is Nothing Then
    If clear_flg Then
        rng.Comment.Text  msg        '刷新
    Else
        rng.Comment.Text rng.Comment.Text() & vbNewLine
                         & msg       '追記
    End If
    Exit Sub
End If

'新しいコメントを追加する
With rng.AddComment(msg)
    .Shape.TextFrame.Characters.Font.ColorIndex = 2 'フォントは白
    .Shape.TextFrame.Characters.Font.Size = 9
    .Shape.TextFrame.AutoSize = True
    .Shape.Fill.ForeColor.RGB = RGB(0, 0, 0)         '背景は黒
    .Visible = True
End With

clear_flg=Trueならば、コメントは置き換わるが、Falseならば改行して追記していく。
なので、コメントは自動サイズ設定(AutoSize=True)にしておく。

ExcelVBA覚書 正規表現

私が苦手なものの1つ「正規表現」
いつまでも逃げられないので、がんばってみた。

まずは整数

'整数(上限が5桁 -99999~99999はOK)
Dim rng As Range           '対象セル
Dim res As Boolean         '結果

Set rng = ActiveCell       '選択しているセルをチェックする
Set reg = CreateObject("VBScript.RegExp")
With reg
     .IgnoreCase = True             '大文字小文字は関係ない
     .Global = True                 '全体をチェック
     .Pattern = "^[-]?[0-9]{1,5}$"
     If .Test(rng.Value) Then
          res = True
          Exit Function
     End If
End With

次は実数
こいつがややこしくて、整数のときと実数のときとで分けてやらないといけない
.Pattern = “^[-]?[0-9]{1,3}[.]?[0-9]{0,2}$”
だけにすると整数4桁、5桁の数値もOKになってしまった。

'実数(上限が5桁 -999.99~999.99はOK)
Dim rng As Range           '対象セル
Dim res As Boolean         '結果

Set rng = ActiveCell      
Set reg = CreateObject("VBScript.RegExp")
With reg
     .IgnoreCase = True   
     .Global = True       
     '整数の場合のチェック
     .Pattern = "^[-]?[0-9]{1,3}$"
     If .Test(rng.Value) Then
          res = True
          Exit Function
     End If
     '実数の場合のチェック
     .Pattern = "^[-]?[0-9]{1,3}[.]{1,1}[0-9]{0,2}$"
     If .Test(rng.Value) Then
          res= True
          Exit Function
     End If    
End With

そして、英数字のみ

'英数字のみ(上限が5桁で、半角のみ、大文字小文字OK)
Dim rng As Range           '対象セル
Dim res As Boolean         '結果

Set rng = ActiveCell      
Set reg = CreateObject("VBScript.RegExp")
With reg
     .IgnoreCase = True   
     .Global = True       
     .Pattern = "^[a-z0-9]{0,5}$"
     If .Test(rng.Value) Then
          res = True
          Exit Function
     End If     
End With

ExcelVBA覚書 名前定義を削除する

Excelで数式やマクロを使うとき便利だからと名前を定義する人がいるが、本当にやめてほしい「悪習」だと私は思う。
なぜかって、シートのコピーするたびにグチグチ名前重複してもいいか聞いてきて、「もう好きにしろよ!」って思っても、ずぅ~っとすべての名前について聞いてくるのが、まぁ性質の悪いこと、悪いこと!

そういうことがわかっていれば、簡単に名前定義は使わないと思うのだが、まぁ使ってますな・・・
で、削除しちゃえ!

※ 2021/03/03 ブック内の名前定義を削除させるロジック追加


Sub DeleteNamesExcludePrintX()
    
    Dim ws As Worksheet
    Dim nm As Name

    ' シート内の定義(Printから始まる名前定義は印刷設定なので除外)
    For Each ws In ThisWorkbook.Worksheets
        For Each nm In ws.Names
            Debug.Print nm.NameLocal & ": " & nm.Name
            If nm.Name Like "*Print_*" Then
            
            Else
                nm.Delete
            End If
        Next
    Next
    
    ' ブック内の定義
    For Each nm In ThisWorkbook.Names
            Debug.Print "** " & nm.NameLocal & ": " & nm.Name
            nm.Delete
    Next

End Sub


削除するのはいいんだけど、印刷設定まで消すとまずいので、「Print_」から始まる名前は消さないでおく。
(印刷範囲と印刷タイトルが該当する)

ただし、マクロとか数式とかで使ってたらエライコトになるのでご注意を。

HTML5プロフェッショナル認定資格 Level1

という資格がある。
Level1があるということはLevel2もある。
しかし、Level3は今のところない。

で、Lv1とLv2の認証票を2つくっつけると丁度図柄がそろうので、Lv1を受けようと思ったならば、それはLv2も受けなきゃという話になる。
というか、両方ともとらないと、HTML5+CSS3+JavaScriptという、Web開発者としてのスキルとしてはいささかアピールする意味がないのである。

と、奮い立たせてLevel2の試験準備に入ろうとしている。
(まだ、足は踏み入れていないが、とりあえず教科書は買った)

・・・・・・・・・・・・・・・・+・・・・・・・・・・+・・・・・・・・・・・・・・・・・

ということで、Lv1を受けてきて、まぁ合格したのだ!!

いや、まぁ今まで受けてきた簡単な試験の中でも、簡単なほうなんだろうね・・・とタカをくくっていた私が間違いでござったことでござる。

75点とかそのへんだったな・・・合格ラインが70点で。

しょっぱなから、
「こんな話知らんぞ!」
(って、一応本には載ってたんだけど星1個だったから、すっ飛ばしたんだよね、確か)

というような問題ばっかり出て、もう見返したところでわからんもんはわからんし!とプチっと終了させたんだよね。

合格って見たときはほっとしたけど、あまりに出来が悪くって、これじゃLv2なんてどうなんのよ?
だって、Lv1でこんなの見てもしょうがないっていわれている教本のLv2バージョンしかテキストがないんだよ!!

って、愚痴を言っているとたぶんまともな、いやまともに近いテキストが出てきてくれると信じて勉強し始めよう。

ExcelVBA覚書 どのボタンを押した?

シート上にある複数のボタンから1つのサブプロシージャを起動するときなんぞに、どのボタンを押したのかわかればよいなぁ~と調べたら、意外と簡単にできるらしかった。

[ A ] [ B ] [ C ]

って3つのボタンがあって、それぞれ名前(ShapeオブジェクトのName)を「A」「B」「C」とつけておく。
(図形 1とか、ボタン 1とかの名前を変えてやるのだ。もちろん、そのままでもいいけど。)

で、これらのボタン全部 にマクロ登録して、AbcButton_Click() を実行させるとすると、

Sub AbcButton_Click () 
    Dim buf As String
    buf = Application.Caller
    Select Case buf
    Case "A"
        Msgbox "Aが押された!"
    Case "B"
        Msgbox "Bを押しましたね"
    Case "C"
        Msgbox "Cなんですか?"
    End Select
End Sub

という感じで、Application.Callerがボタンの名称を教えてくれるので、そこから分岐させる処理を記述すればよい。

ん~、もっと早く知っとけばよかった。
できないだろうという思い込みはよくない。実によくない!

ExcelVBA覚書 リモート実行

リモート実行にはいろいろやり方があるようだが、レジストリを触らなきゃいけないとかいわれると気が引けるものだ。

で、行き着いたのは、CreateObject(“WbemScripting.SWbemLocator”)を利用するこのスクリプト。

[VBScript] 他端末のプログラムをリモートで実行する

これを参照してリモートサーバのバッチファイルを叩くことに成功。

ありがとう!

ExcelVBA覚書 Clipboardに格納

クリップボードに値を設定するときは、「DataObject」を使うらしいが、CreateObjectで利用するときはいかのようにするらしい。

Dim buf As String

buf = "あいうえお"
With CreateObject("new:{1C3B4210-F441-11CE-B9EA-00AA006B1A69}")
    .SetText buf
    .PutInClipboard
End With 

VBA覚書 グループ開閉(行)

マクロの記録中だと、
メニュー「データ」→「グループとアウトラインの設定」→「詳細データの表示」
と、メニュー上で行うと記録できるらしい。

Excel質問掲示板(VBA) シートの外のグループ化の展開はできますか?

ということで、開くとき
ExecuteExcel4Macro “SHOW.DETAIL(1,” & CStr(グループの開始行) & “,True)”

閉じるとき
ExecuteExcel4Macro “SHOW.DETAIL(1,” & CStr(グループの開始行) & “,False)”

VBA覚書 保存させずに終了させる方法

保存ボタンを押されたときに保存させないのは、WorkbookのBeforeSaveで「Cancel = True」の1文を入れたらよい。
では、終了時に保存確認させたくないときはどうするか。
保存したことにして確認ダイアログを出さないようにする手があるようだ。


Private Sub Workbook_BeforeClose(Cancel As Boolean)
    If MsgBoxInfomation("終了確認", "終了してよろしいですか?", vbQuestion) <> vbYes Then
        Cancel = True
    End If
    ThisWorkbook.Saved = True  '保存した!ということにする
End Sub

Webアプリ覚書 HTML5・CSS3・IE対応

Bootstrap3関連

自分はBootstrap2のときに初めて使ったのだけど結構奥深いので、公式ページではよくわからない箇所はリンクを参照。
Bootstrap3移行ガイド
Bootstrap3 徹底解説!

ファビコンを作る

結局一番使いやすいのはX-Icon Editorだった。(ただし、64、32、24、16ビットサイズにしか対応していない。)
他のは使い勝手がものすごく悪かったり、pngに対応してなかったり、下手をするとウィルス付だったり・・・

X-Icon Editor

より見やすい画面に(コントラスト比の算出)

こういうのはWebアプリだけでなく、いろいろ使えそうなので。

Contrast-A

IE対応

もうこの世から消し去りたいIE8とか9。だが、なかなか消えない・・・

IE対策 HTML5+CSS3でサイトを作ってみる

1) HTML5の反映

昔はhtml5.jsを使っていたようだけど、今はhtml5shiv.jsを使うようだ。Googleからとってくるのだ。

<!--[if lt IE 9]>
<script src="/js/html5shiv.js"></script>
<![endif]-->

2) IEの最新バージョンをレンダリング
  1)だけでうまくいかなかった・・・ということでメタ情報も(挿入する位置に注意しなければならないよう)

<meta http-equiv="X-UA-Compatible" content="IE=edge">

3) CSS3の適用

これでグラデーションとか角丸がいけるようになるらしい。
CSS3PIE

あとは旧ブラウザへの対応も見ておこう。

他にもあれば継ぎ足しておこう。

PostgresSQL覚書 関数の戻り値をレコードに

関数の戻り値というと、普通は1つの値なのだけれど、複数行とってきたいとか、テーブルとしてとってきたいとか思う。

問い合わせ言語(SQL)関数

を見ているとできなくないらしいけれど、

CREATE FUNCTION sum_n_product_with_tab (x int)
    RETURNS TABLE(sum int, product int) AS $$
    SELECT $1 + tab.y, $1 * tab.y FROM tab;
$$ LANGUAGE SQL;

で、LANGUAGEが「SQL」となっていて、「plpgsql」で作っているものだとRETURNSの後ろをTABLE(ほにゃほにゃ)に変えただけではうまくいかなかった。
戻り値が
sum | product
—–+——————
50 | aaa
66 | bbb

とかになってほしいんだけど、
sum_n_product_with_tab
———————–
( 50, aaa)
( 66, bbb)

になってしまって、せっかくTABLEにしている意味ないんじゃない?ということになった。

ふむ。どうすればよいのじゃ・・・

ということで、せめて複数行とってくることにしよう。

CREATE OR REPLACE FUNCTION hoge(parm_cd character varying)
  RETURNS numeric  AS
$BODY$
DECLARE
    ・・・・
BEGIN

  CREATE TEMP TABLE wk_master(code numeric(2,0))
  ・・・・
  RETURN QUERY SELECT code FROM wk_master;
  DROP TABLE wk_master;

END;
$BODY$
  LANGUAGE plpgsql VOLATILE
  COST 100
  ROWS 1000;

RETURN QUERY・・・とすると、複数行で返してくれる。

今日はこの辺で終了。

PostgreSQL覚書 Backup&Restore

またあっという間に時が経った。
師走だ。

WindowsバッチでAサーバにあるDBをBサーバに移すことにした。

んで、とりあえずいろいろ参考にして作ったのが下の例。

まずはパスワードを設定しておいて、途中で聞かれないようにしてから・・・
pg_dump を使って D:\backup\test.backupに 111.111.111.111:5432 のA1_DBをバックアップ。
(ユーザはpostgres)
バックアップファイルからpg_restoreを使って、111.111.111.123:5432 のA2_DBへリストア。
(こっちもユーザはpostgres)

—————————————————————–
SET PGPASSWORD=password
“C:\Program Files\PostgreSQL\9.3\bin\pg_dump.exe” -f D:\backup\test.backup -i -v -h 111.111.111.111 -p 5432 -U “postgres” -Fc “A1_DB”
if not %ERRORLEVEL%==0 stop

“C:\Program Files\PostgreSQL\9.3\bin\pg_restore.exe” -c -h 111.111.111.123 -p 5432 -U “postgres” -Fc -d “A2_DB” D:\backup\test.backup

stop
—————————————————————–
オプション関連はドキュメントを見てもらえばいいと思うけど、書き順やらがドキュメントではいまいちわからんかったのでメモっとく。

SQLServer覚書 ストアド内で別のストアドを実行

ストアドプロシージャ内で、別のストアドプロシージャを呼び出す方法。

例えば、proc_GetEmployeeIn(引数:@bumon_cd) を呼び出して結果を取得する場合だと、
以下のように、あらかじめワークテーブルを作っておいてから、
INSERT INTO ワークテーブル EXEC プロシージャ名 引数1, 引数2 , …
というようになる。

CREATE TABLE #work_table (
      emp_cd VARCHAR(1000)
    , emp_name VARCHAR(10)
)
INSERT INTO #work_table EXEC proc_GetEmployeeIn @bumon_cd

PostgreSQL覚書 IsNumericとかIsNumberの代わり

いつのまにか10月になって、いつのまにかWordPressがVer4.0になってた。
時の経つのは早いもの。

PostgreSQLにはIsNumericとかIsNumberみたいな関数はないのねぇ・・・
Function作ればいいんだよ!って、言われてもねぇ・・・

ということで、代替案を漁ってみた。

SELECT (CASE WHEN emp_cd ~'^[0-9]*$' THEN emp_cd ELSE NULL END) emp_cd FROM master_table

ってな感じで、正規表現を使うらしい。
関数作って使ったほうが楽じゃね?って言わないでね・・・

PostgreSQL覚書 接続中を調べる

昔バグった話。
接続しっぱなしでロジックを終わらせてたら、どんどん接続数が増えて処理できなくなった。
CLOSEすんのを忘れてたんです。スイマセン。

で、大騒ぎになる前に。

SELECT * FROM pg_stat_activity
 ORDER BY usename,application_name;

で、ちゃんとクローズしたことを確認する。
application_nameがpgAdmin以外で、IPアドレスを確認して、current_queryがアイドル状態になっておらず、SQL文が設定されたままだとクローズしていない。
処理が終わってもこういうのが残っていると、ちゃんと切れてないので切断すること。

このバグのせいで、運用問題にまで発展しテンヤワンヤとなったので、メモ。