[No.130 Access クエリーをExcelシートへ10行x3列で出力する]
[No.131 Access クエリーをExcelシートへ罫線を付けて出力する]
[No.132 Excel ショートカットキーにマクロを割り当てる]
[No.133 仕様変更が来たら?落胆しないで前向きに?]
[No.134 Excel As CommandBarControlでメニューにマクロを]

www.ken3.org(サイト内)から Google を利用して、

三流君 VBAで楽しくプログラミング(Excel/Access VBAの解説/サンプルです)
[VBA系のバックナンバー] [VBA系 TOP] [三流君 TOP]



No.130 2003/09/19
Access クエリーをExcelシートへ10行x3列で出力する
[ページTOPへ戻る]

<Access クエリーをExcelシートへ10行x3列で出力する>

どうも、三流プログラマーのKen3です。 最近、質問もらうけど、 なかなか、解答できてない三流プログラマーのKen3です。 ※私のレベルで手に余る高度な質問が多くて。 今回の、サンプルファイルは、 http://www.ken3.org/vba/lzh/vba130.lzh にdb130.mdb(Access2000版)が保存されています。 ※クエリーやプログラムをいじって、遊んでみてください。

/* * 1. 今回のキッカケ */

郵便番号の集計システムを題材にして最近メルマガ書いてます。 [No.127 要求を聞き、疑問点をつぶし、仕様書を書く] http://www.ken3.org/backno/backno_vba26.html#127 [No.128 AccessにExcelのシートをインポートする] http://www.ken3.org/backno/backno_vba26.html#128 [No.129 Access いろいろとクエリーでグループ集計をしてみる] http://www.ken3.org/backno/backno_vba26.html#129 前回、 データを集計するクエリーまで、なんとかやりました。 パターン1 Q_YUBIN_7 郵便番号7桁(−付で8桁)、カウント10以上 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 郵便番号 郵便番号のカウント 桁数 220-0021 14 8 --- 条件は >=10(10以上) で =8(桁数は8桁) ↑設定・実行結果イメージ パターン2 Q_YUBIN_ETC 郵便番号7桁以外(−付で8桁以外)、カウント10以上 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 郵便番号 郵便番号のカウント 桁数 232 11 3 --- 条件は >=10(10以上) で <>8(桁数はNot 8桁) ↑設定・実行結果イメージ パターン3 Q_YUBIN_1to9 カウント数が10以下(1〜9)郵便番号が何桁であろうが ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 郵便番号 郵便番号のカウント 桁数 194-0012 1 8 228 1 3 700-0941 1 8 --- 条件は <10 (10以下) で (桁数の条件は無し) ↑設定・実行結果イメージ 今回は、このクエリーを元に、データを出力してみたいと思います。

/* * 2.方針を考える */

Q_YUBIN_7 : 郵便番号7桁(−付で8桁)、カウント10以上 Q_YUBIN_ETC : 郵便番号7桁以外(−付で8桁以外)、カウント10以上 Q_YUBIN_1to9 : カウント数が10以下(1〜9)郵便番号が何桁であろうが と3つのクエリーが存在します。 ここから、2つのシートを作るんだけど、さて、どうしましょう・・・ シートだけ作るなら、 ^^^^^^^^^^^^^^^^^^^^ 昔の自分のメルマガサンプルを見てみると、 <Access97からExcel形式へExport時に書式設定を行いたい> http://www.ken3.org/backno/hosoku/e025/index.html で、 DoCmd.TransferSpreadsheet acExport, 5, "管理MST", "C:\TEST.XLS", True, "" <書式付きエクスポート DoCmd.OutputToで、できます> http://www.ken3.org/backno/hosoku/ETC_026.html で、 DoCmd.OutputTo acOutputTable, "T_管理MST", acFormatXLS, "C:\TEST.xls", True を使ってました。 DoCmd.TransferSpreadsheet や DoCmd.OutputTo で、AccessデータをExcelのシートに変換できるけど、 郵便番号 集計数 郵便番号 集計数 郵便番号 集計数 2280002 20 2600003 15 330005 20 2280003 15 2600004 20 330010 25 2280005 12 2600005 25 330015 12 みたいに、データをn列*n行で出力できないので、 自分で、クエリーを読み込んで、 Excelへ出力してみたいと思います。

/* * 3.ADOでクエリーを開いて、Excelへデータをセットする */

自分でレコードセットを開いて、出力かぁ・・・めんどいなぁ(オイオイ) [No.93 Access2000 ADOでクエリーのレコードを参照 Excelへ出力] http://www.ken3.org/backno/backno_vba19.html#93 で、 チョコット解説しているけど、 Recordset を開く場合 ^^^^^^^^^^^^^^^^^^^^^ DAOだと、 Dim db as Database Dim rs as DAO.Recordset Set db = CurrentDB() Set rs = db.OpenRecordset("Employees") ADOだと、 Dim rs as New ADODB.Recordset rs.Open "社員", CurrentProject.Connection, adOpenKeySet, adLockOptimistic らしいので、 テストで、クエリー Q_YUBIN_7 を出力してみます。 CreateObject("Excel.Application") で、 オブジェクト作成後、 Workbooks.Addで、Excelのブックを作成 Sheets.Addで、シートを追加して、 ActiveSheet.Name = "DATA" なんて感じで、.Nameプロパティを変更。 あとは、レコードセットを開いて、 ループでレコードエンドまでデータをセットしてます。
Private Sub btnTEST001_Click()

    Dim rs As New ADODB.Recordset  'ADOのレコードセット
    Dim objEXCEL As Object  'Excel参照用
    Dim nYLINE   As Long    'セット位置

    'Excelを起動する、オブジェクトの作成
    Set objEXCEL = CreateObject("Excel.Application") 'オブジェクトの作成
    objEXCEL.Visible = True  'Excelを見えるようにする
    
    '新規のブックを追加する
    objEXCEL.Workbooks.Add   'Excelのブックを作成

    'Excelのシートを追加、シート名を変更する
    objEXCEL.Sheets.Add  'シートを追加する
    objEXCEL.ActiveSheet.Name = "DATA"  'シート名をDATAにする

    'レコードセットを開く(Q_YUBIN_7)
    rs.Open "Q_YUBIN_7", CurrentProject.Connection, _
                    adOpenKeyset, adLockOptimistic

    '見出しの代入とカウンタの初期化
    objEXCEL.Cells(1, "A") = "郵便番号"
    objEXCEL.Cells(1, "B") = "件数"
    nYLINE = 2  '2行目からデータをセットする

    'レコードセットからExcelへデータをセットする
    'ループ処理
    While rs.EOF = False  'いつものEOFが偽の間
        'データをセットする(Accessから転記)
        objEXCEL.Cells(nYLINE, "A") = rs("郵便番号").Value
        objEXCEL.Cells(nYLINE, "B") = rs("郵便番号のカウント").Value
        '次を読む And カウンタを移動する
        rs.MoveNext  '次のレコードに移動しないと、とんでもないことに(笑)
        nYLINE = nYLINE + 1  'カウンタも忘れずに+1する
    Wend
    '通常は、ここでExcelを保存するんだけど、今回は開きっぱなしの手抜き

    rs.Close   '開いたら閉じろ、ドアを開けたら閉めるってしつけられたでしょ(笑)
    Set rs = Nothing  '変数も後始末しますか。使った器はキレイにしろって?

End Sub
まぁ、縦には、なんとかセットできたよね。 でも、これって?普通に出力した時と同じジャン? A列 B列 郵便番号 件数 107-0052 27 112-0002 27 113-0033 28 135-0034 27 135-0044 27 136-0072 28 そうですよ(開き直りか?) ↑エクセルへのクエリー結果出力イメージ

/* * 4.パズルは得意ですか?n列*n行の出力を考える */

さてと、n行になったら、となりの列を作成してみますか。 (作成って言うのか?たんにセット位置を移動というのか?) いきなり考えるのは難しいので、手で表を自分で作ってみます。 データは A列 B列 郵便番号 件数 107-0052 27 112-0002 27 113-0033 28  ・  ・  ・ なんて感じを、10行、3列にしてみると ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ (1) (2) (3) (4) (5) (6) (7) (8) (9) n行目 A列 B列 C列 D列 E列 F列 G列 H列 I列 001行 郵便番号 件数 空白 郵便番号 件数 空白 郵便番号 件数 空白 002行 107-0052 27 160-0023 27 193-0833 27 003行 112-0002 27  ・  ・  ・ 011行 113-0033 28 012行 空白行-------------------- 空白行 --------- 013行 郵便番号 件数 空白 郵便番号 件数 空白 郵便番号 件数 空白 014行 107-0052 27 160-0023 27 193-0833 27 015行 112-0002 27 ____________________________________________________________________ A列 B列 C列 D列 E列 F列 G列 H列 I列 (1) (2) (3) (4) (5) (6) (7) (8) (9) 10行いったら次の列 3列貯まったら空白1行空けて頭に戻る(次ページ分) そんなセット方法を考えてみる時、 まずは、 10単位でデータを処理するので、 11個目のデータは2行目D列(4)にセットされる。 ここをポイントにして、 次のレコードを読む 行カウンタ=行カウンタ+1 データカウンタ=データカウンタ+1 したあと、 カウンタが11だったら(11になったら) 列を+3する(A列の1からD列の4になる) 行を−10する。  データカウンタを1に戻す なんて、処理を入れると、10レコード単位で次の行に進めそうです。 進めるけどさぁ、 3列進んだら、空白1行空けて頭に戻る(次ページ分) は、どうするの? そっか、列もカウントしないといけないのか・・・ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ カウンタが11だったら(11になったら) 列を+3する(A列の1からD列の4になる) 列が9(3列)を越えたかチェックする  越えていれば:列をカウンタを1にして見出しを表示、行を増やす 越えていなければ:行を−10する。  データカウンタを1に戻す と、行が越えたかをチェックして、データをセットしてみます。 ↑データセットのイメージ プログラムを書くと、少し複雑だけど、 (まだまだ、改良の余地アリダケド) nRCNT = nRCNT + 1 '処理レコード数を増やす If nRCNT > 10 Then '処理したレコードが10を越えた(次の列) nXLINE = nXLINE + 3 '次の列へカウンタを移動 If nXLINE > 9 Then '列が越えた? nXLINE = 1 '1列目(A列)に戻す nYLINE = nYLINE + 2 '空白行にしたいのでセット位置を+2する Else nYLINE = nYLINE - 10 '列が変わったので行カウンタをマイナスする End If '見出しの表示 objEXCEL.Cells(nYLINE, nXLINE) = "郵便番号" objEXCEL.Cells(nYLINE, nXLINE + 1) = "件数" nYLINE = nYLINE + 1 '見出し表示分行数が増えます nRCNT = 1 '見出し表示後は1レコード目だよ Else ' nYLINE = nYLINE + 1 '次の行へセット位置を移動 End If で、なんとか、 セット位置を移動しながらデータをセルにセットすることが出来きました。
Private Sub btnTEST002_Click()
    
    Dim rs As New ADODB.Recordset  'ADOのレコードセット
    Dim objEXCEL As Object  'Excel参照用
    Dim nYLINE   As Integer '行セット位置
    Dim nXLINE   As Integer '列セット位置
    Dim nRCNT    As Integer 'レコードカウンタ

    'Excelを起動する、オブジェクトの作成
    Set objEXCEL = CreateObject("Excel.Application") 'オブジェクトの作成
    objEXCEL.Visible = True  'Excelを見えるようにする
    
    '新規のブックを追加する
    objEXCEL.Workbooks.Add   'Excelのブックを作成

    'Excelのシートを追加、シート名を変更する
    objEXCEL.Sheets.Add  'シートを追加する
    objEXCEL.ActiveSheet.Name = "DATA"  'シート名をDATAにする

    'レコードセットを開く(Q_YUBIN_7)
    rs.Open "Q_YUBIN_7", CurrentProject.Connection, _
                    adOpenKeyset, adLockOptimistic

    'カウンタの初期化 スタート位置のセット
    nYLINE = 1 '1行目だよ
    nXLINE = 1 '1列目(A列)だよ
    
    '見出しをセットする
    objEXCEL.Cells(nYLINE, nXLINE) = "郵便番号"
    objEXCEL.Cells(nYLINE, nXLINE + 1) = "件数"
    nYLINE = nYLINE + 1 '見出し分行数が増えます
    nRCNT = 1  '見出し表示後は1レコード目だよ
    
    'レコードセットからExcelへデータをセットする
    'ループ処理
    While rs.EOF = False  'いつものEOFが偽の間
        'データをセットする(Accessから転記)
        objEXCEL.Cells(nYLINE, nXLINE) = rs("郵便番号").Value
        objEXCEL.Cells(nYLINE, nXLINE + 1) = rs("郵便番号のカウント").Value
        '次を読む And カウンタを移動する
        rs.MoveNext  '次のレコードに移動しないと、とんでもないことに(笑)
        nRCNT = nRCNT + 1   '処理レコード数を増やす
        If nRCNT > 10 Then  '処理したレコードが10を越えた(次の列)
            nXLINE = nXLINE + 3  '次の列へカウンタを移動
            If nXLINE > 9 Then '列が越えた?
                nXLINE = 1  '1列目(A列)に戻す
                nYLINE = nYLINE + 2  '空白行にしたいのでセット位置を+2する
            Else
                nYLINE = nYLINE - 10 '列が変わったので行カウンタをマイナスする
            End If
            
            '見出しの表示
            objEXCEL.Cells(nYLINE, nXLINE) = "郵便番号"
            objEXCEL.Cells(nYLINE, nXLINE + 1) = "件数"
            nYLINE = nYLINE + 1 '見出し表示分行数が増えます
            nRCNT = 1  '見出し表示後は1レコード目だよ
        Else  '
            nYLINE = nYLINE + 1  '次の行へセット位置を移動
        End If
    Wend
    '通常は、ここでExcelを保存するんだけど、今回は開きっぱなしの手抜き

    rs.Close   '開いたら閉じろ、ドアを開けたら閉めるってしつけられたでしょ(笑)
    Set rs = Nothing  '変数も後始末しますか。使った器はキレイにしろって?

End Sub
-【けんぞう!】--------------------------------------------------------- 月500円、タバコなら2箱、120円缶コーヒーなら4缶分の謝礼をGetするなら http://www.ken3.org/etc/500yen/ ←無料アンケート系の広告です。 『チッ、がんばって回答して月500円かよ』(お馬鹿なプログラマー:30歳) ------------------------------------------------------------------------ 

/* * 5.終わりの挨拶 */

今回は、 クエリーをExcelのシートにセットする処理で、 10行3列でデータをセットしてみました。 なんか、あまりスマートじゃなかったけど、 こんな方法もあるってことで。 今回の、サンプルファイルは、 http://www.ken3.org/vba/lzh/vba130.lzh にdb130.mdb(Access2000版)が保存されています。 ※クエリーをいじって、遊んでみてください。 何かの参考となれば幸いです。 Excel/Access大好き、三流プログラマーKen3でした。

No.131 2003/09/22
Access クエリーをExcelシートへ罫線を付けて出力する
[ページTOPへ戻る]

<Access クエリーをExcelシートへ罫線を付けて出力する>

どうも、三流プログラマーのKen3です。 最近、質問もらうけど、 なかなか、解答できてない三流プログラマーのKen3です。 ※私のレベルで手に余る高度な質問が多くて。 今回の、サンプルファイルは、 http://www.ken3.org/vba/lzh/vba131.lzh にdb131.mdb(Access2000版)が保存されています。 ※クエリーやプログラムをいじって、遊んでみてください。 Access から Excel 連携 http://www.ken3.org/cgi-bin/group/vba_access_excel.asp も参考にしてください。

/* * 1. 今回のキッカケ */

前回、 データを10行X3列で、Excelへ出力しました。 データをただ、セットしただけなので、 今回は、この出力時に、罫線を付けてみたいと思います。

/* * 2.やりたいことをまとめる、実現可能か考える */

プログラムを組む前に、やりたいことを 手作業で(普通の操作でやってみる) ~~~~~~~~~~~~~~~~~~~~ プログラムを組む前に、自分の手で少し動かしてみる。 自分が手で作業するなら、データが1列セットされたら、 その列をドラッグして、右ボタン・セルの書式設定で罫線かなぁ。 ↑ドラッグして、右ボタンのショートカットメニューからセルの書式を選択 データを1列単位でまとめて、罫線を付ける。 そんな流れ、自分でやるとすれば、そんな操作かなぁ。 処理のタイミング的には、10行データが貯まったら、罫線を引く。 そんな感じかなぁ。 A列 B列 郵便番号 件数 107-0052 27 112-0002 27 113-0033 28  ・  ・  ・ 135-0044 27 136-0072 28 で、範囲を計算して、罫線を引く、そんな処理方法です。 そんなことするんだぁ? まぁそれがキレイかもしれないけど、最終データが途中6行で終わったときは? そんなの気にしないで10行罫線引くよ、いいじゃん、別に。 クレーム来たらループを出てから、6行分を計算(計算して罫線引くから)。 あっそ、まぁいいけど、 罫線引くのはコンピュータだろ!少々時間がかかってもいいんなら、 その対抗案じゃないけど、 ^^^^^^^^^^^^^^^^^^^^^^^^ 1つデータを出力したら、その位置に(その場所に)罫線を引く。 これだと、位置を気にしないでもいいし、楽だよ。 まぁ、人はデータ入力、罫線引く、次のデータ入力、罫線引く。 なんてムダなことやら無いけど、動くのはコンピュータだからいいじゃん。 う〜ん、、、、 人それぞれ、好みの方法あるのですが、 プログラム作成前に恋人候補を選ぶみたいに、いろいろと考えてみては? ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ えっ、選ばない?、すぐに目の前の異性に飛びつく(思いついた案に飛びつく)って? まぁ、選び過ぎで、迷って動けない(組み始めない)のよりはいいけど・・・ プログラムを組む前は、いろいろな処理候補を考えましょう。 でも、お金持ちにするかそれともイケメン君、やさしさ君、、にするか迷ってないで、 決めるときは決めて、組み始めたほうがイイよって感じかなぁ。 ※つきあってから(組み始めてから)、ダメなことに気が付いたりするんだけど。  まぁ、一長一短、男性(女性)同様、いろいろと処理によってあるからねぇ・・ 若いうちは、いろいろと失敗して、いい人(いい処理方法)見つけてね。  この子しかボクには(この処理しか)・・と、盲目にならないように・・・

/* * 3.単体でテストを行う(プロパティ)を探る */

一つ一つ罫線を引くか、1列まとめて罫線を引くか、迷うところだけど、 それを決定するためにも、罫線の引き方、プロパティやメソッドを調べます。 ※それが先だろって?  野球観戦なら活発な元気な女の子、映画や食事なら話のわかる子?だって?  やりたいことによって使い分けるのかぁ・・・そんな器用な男って居るの?  普通は、彼女に合わせて、デート場所を決めるのかなぁ? まぁ、そんな話は、置いといて、 [No.2 AccessからExcel出力] http://www.ken3.org/backno/backno_vba01.html#2 で、 >・ウィザードを使ってたサンプルを作れることを説明 >・マクロ記録でExcelの操作をVBAにする >・頭にオブジェクト変数を付けてAccessからExcelを操作 ↑ エクセルのマクロ記録を使用して、 記録したマクロにCreateObjectで作成した、参照用の変数を付けると、 簡単に作れます。なんて、豪語してましたね。 >'*1↓頭にCreateObjectで作成した変数を追加しただけ > oApp.Workbooks.Open FileName:="D:\vba002\TYPE.xls" > '^^^^ 同様に、まず、罫線を引くマクロを記録してみます。 なんだぁ、この長いコードは・・・(笑) 下記、記録されたコードです。
Sub Macro1()

    Range("A1:B11").Select
    Selection.Borders(xlDiagonalDown).LineStyle = xlNone
    Selection.Borders(xlDiagonalUp).LineStyle = xlNone
    With Selection.Borders(xlEdgeLeft)
        .LineStyle = xlContinuous
        .Weight = xlThin
        .ColorIndex = xlAutomatic
    End With
    With Selection.Borders(xlEdgeTop)
        .LineStyle = xlContinuous
        .Weight = xlThin
        .ColorIndex = xlAutomatic
    End With
    With Selection.Borders(xlEdgeBottom)
        .LineStyle = xlContinuous
        .Weight = xlThin
        .ColorIndex = xlAutomatic
    End With
    With Selection.Borders(xlEdgeRight)
        .LineStyle = xlContinuous
        .Weight = xlThin
        .ColorIndex = xlAutomatic
    End With
    With Selection.Borders(xlInsideVertical)
        .LineStyle = xlContinuous
        .Weight = xlThin
        .ColorIndex = xlAutomatic
    End With
    With Selection.Borders(xlInsideHorizontal)
        .LineStyle = xlContinuous
        .Weight = xlThin
        .ColorIndex = xlAutomatic
    End With
End Sub
えっと、パターン的に、よく見ると、 Selection.Borders Selectionで、現在選択されているオブジェクト .Bordersのヘルプを見ると、 >単体の Border オブジェクトを取得するには、 >Borders(index) プロパティを使用します >引数 Index で使用できる定数は、 >XlBordersIndex クラスの定数 xlDiagonalDown、xlDiagonalUp、xlEdgeBottom、 >xlEdgeLeft、xlEdgeRight、xlEdgeTop、xlInsideHorizontal、xlInsideVertical > のいずれかです。 だって、それで、各辺を選択して、 .LineStyle プロパティ 罫線または輪郭線の種類を設定 .Weight 罫線または輪郭線の太さを設定します .ColorIndex 輪郭線の色を設定します なんか、頭イタクなってきた。 上下左右と縦線(垂直)・横線(水平)を引いているから6つかぁ。

/* * 4.罫線を引くテストルーチン作成 And 参照設定の話 */

まぁ、罫線引くマクロが長い・長いとか言ってないで、組み込んでみますか。 じっさいに<b>やってみないと</b>、わからないしね(何が?何を?(謎)) Dim objRANGE As Object '範囲の代入 と、 1つセルの範囲を代入するオブジェクト変数を定義して、 Set objRANGE = objEXCEL.Range("A1:B11") '範囲の代入 で、範囲を代入(Rangeオブジェクトの代入) objRANGE.Value = "aaaa" 'テストデータ代入 あとは、テスト目的の、左右の罫線をテストで引いてみます。 With objRANGE.Borders(xlEdgeLeft) '左 .LineStyle = xlContinuous .Weight = xlThin .ColorIndex = xlAutomatic End With With objRANGE.Borders(xlEdgeRight) '右 .LineStyle = xlContinuous .Weight = xlThin .ColorIndex = xlAutomatic End With なんて感じで、 objRANGEの.Bordersに対して、値をセットします。
Private Sub btnTEST003_Click()
    
    Dim objEXCEL As Object  'Excel参照用
    Dim objRANGE As Object  '範囲の代入

    'Excelを起動する、オブジェクトの作成
    Set objEXCEL = CreateObject("Excel.Application") 'オブジェクトの作成
    objEXCEL.Visible = True  'Excelを見えるようにする
    
    '新規のブックを追加する
    objEXCEL.Workbooks.Add   'Excelのブックを作成

    'Excelのシートを追加、シート名を変更する
    objEXCEL.Sheets.Add  'シートを追加する
    objEXCEL.ActiveSheet.Name = "DATA"  'シート名をDATAにする

    'テストで罫線を引いてみる
    Set objRANGE = objEXCEL.Range("A1:B11")  '範囲の代入
    objRANGE.Value = "aaaa"  'テストデータ代入

    'テストで左右の罫線を引いてみる
    With objRANGE.Borders(xlEdgeLeft)  '左
        .LineStyle = xlContinuous
        .Weight = xlThin
        .ColorIndex = xlAutomatic
    End With

    With objRANGE.Borders(xlEdgeRight) '右
        .LineStyle = xlContinuous
        .Weight = xlThin
        .ColorIndex = xlAutomatic
    End With

End Sub
↑、Set objRANGE = objEXCEL.Range("A1:B11") '範囲の代入 と、A1:B11の範囲の左右の罫線を引くサンプルを作ったつもりだったけど、 えっ、エラーなの? 実行時エラー '1004' アプリケーション定義 または オブジェクトのエラー あらら、テストでこけたか(私は、初デートで失敗するダメ男みたい・・) デバッグをあわてないで押すと、 With objRANGE.Borders(xlEdgeLeft) '左 の位置が黄色く反転表示されている。 ここかぁ、xlEdgeLeftにカーソルを合わせてみると、 Empty値と値が参照できていない・・・これか原因は。 ↑デバックメッセージと値の参照 ツール・参照設定を選択して、 Microsoft Excel X.X Object Library を選択します。 私の現在の環境だと、 Microsoft Excel 10.0 Object Library でした。 Microsoft Excel 9.0 Object Library -- Excel2000? Microsoft Excel 8.0 Object Library -- Excel97? と、インストールしてあるバージョンによって違うと思います。 ↑参照設定のイメージ 原因は、xlXXXXとExcelVBAで定義している定数が使えなかったためでした。 Microsoft Excel X.X Object Library ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ を参照することによって、定数を参照可能となり、エラーが消えます。 キチント参照設定して使いましょう・・で話が終われば簡単なんだけど、 環境が違ったりすると、 例えば私の環境だと Access2002 で Access2000形式のMDBファイルを作成してます。 Access2000の人でも、開いて実行可能です。 ところが、Microsoft Excel 10.0 Object Libraryを参照すると、 Access2000形式のMDBだが、Excel 10.0 Object Libraryを参照指定、 するとエラーが発生して、動かなかったりする。 社内や納品先の環境が違う場合は、注意が必要です。 それをかわすには、xlEdgeLeftなどの定数を自分で定義すればOKなのですが、 定数なのに勝手に定義すると、将来変更になった時に・・となります。 いろいろと考えさせられる処理なんですね。 トラブルの事例じゃないけど、下記に参照設定の話を載せます(掲示板から流用) --- 掲示板であったやりとり --- (一部カットしてます) 投稿時間:2003/08/12(Tue) 17:14 投稿者名:お茶犬レッド タイトル:AccessからExcelへ、そしてマクロを動かす AccessデータをExcelに移して、そこからマクロを使って綺麗なフォームに 直したいと思っています。ken3が以前に書かれていた 「AccessからExcelブックを開き、書式設定を行う」 http://www.ken3.org/backno/backno_vba10.html#48 を参照して何とかやっていたのですが、頭に「xl」がつく変数 (例えばxlLandscapeやxlFillDefault)が入っている行を、どうも読み込んでくれ ないみたいなのです。 ですから、ページ設定をするコード With oApp.ActiveSheet.PageSetup .LeftMargin = oApp.Application.InchesToPoints(0.590551181102362) .RightMargin = oApp.Application.InchesToPoints(0.590551181102362) .TopMargin = oApp.Application.InchesToPoints(0.78740157480315) .BottomMargin = oApp.Application.InchesToPoints(0.393700787401575) .Orientation = xlLandscape End With の場合、余白を指示する上の4個のコードは読み込むのですが、「xl」が含まれている 印刷の向きを指示する「.Orientation = xlLandscape」の行は読み込んでくれません。 罫線を指示する oApp.Range("c3:d3").Select With oApp.Selection.Borders(oApp.xlEdgeLeft) .LineStyle = oApp.xlContinuous End With や oApp.Selection.AutoFill Destination:=oApp.Range("H6:J7"), Type:=oApp.xlFillDefault oApp.Range("H6:J7").Select の行も読み込まなく、他の行はちゃんとマクロが動いているので「xl」が含まれている 行だけ動かないのでは!?という私の読みは正しいかと思うのですが、なぜか分かりま すでしょうか? また、解決方法などありましたら、教えていただけないでしょうか? 投稿時間:2003/08/12(Tue) 19:00 投稿者名:Ken3(管理者) タイトル:参照設定を行います 書き込みどうも。 > を参照して何とかやっていたのですが、頭に「xl」がつく変数(例えばxlLandscape やxlFillDefault)が入っている行を、どうも読み込んでくれないみたいなのです。 ・  ・  ・ > の行も読み込まなく、他の行はちゃんとマクロが動いているので「xl」が含まれてい る行だけ動かないのでは!?という私の読みは正しいかと思うのですが、なぜか分かり ますでしょうか? > また、解決方法などありましたら、教えていただけないでしょうか? 読み通り、xlが定数なんですね。 で、その定数は、excelの定数なので、 参照設定が必要なんです。 VBAの編集画面から、ツール・参照設定でExcel X.0を参照すれば OKです。 http://www.ken3.org/backno/hosoku/026/index.html に画像が載ってます。 私が、メルマガ読者から動かないぞと来ないように、 何でも入るAs Objecと型を切ったサンプルを出してたので、 引っかかったんだと思います。 いろいろとやるなら、Excelのオブジェクトを参照してください。 .と打つと、プロパティ、メソッドも出てくるし、ヘルプも見れるようになります。 何かの参考となれば幸いです。 投稿時間:2003/08/13(Wed) 12:44 投稿者名:お茶犬レッド Eメール: URL : タイトル:ありがとうございます!そして、 ここでもう一つお聞きしたいことがあります。Excel X.0の参照って デフォルトではされてませんよね?なので、他の人や違うマシンで使うとき にはその使う人が、VBを開いてExcel X.0参照をしないといけなくなります。 なにか、それを防ぐ対策はありませんでしょうか。 投稿時間:2003/08/13(Wed) 13:59 投稿者名:Ken3(管理者) Eメール: タイトル:Re: ありがとうございます!そして、 動いたみたいで、よかったですね。 > ここでもう一つお聞きしたいことがあります。Excel X.0の参照って > デフォルトではされてませんよね?なので、他の人や違うマシンで使うとき > にはその使う人が、VBを開いてExcel X.0参照をしないといけなくなります。 > > なにか、それを防ぐ対策はありませんでしょうか。 一番、カッコいいのが、 Access起動時、参照設定がされていない時、 自動的に参照設定を追加するって感じのモジュールなのですが、 参照設定がエラーだと、その自動追加のモジュールが走らなかったり、 (コンパイルエラーになぜかなる)いろいろと皆さん苦労してるみたいです。 過去に見かけたことあったので、参照設定 自動設定をキーワードに探すが、 同じような悩みの掲示板がひっかかるが、回答が見つからなかった。 いつもの逃げ手は、AS Objectと、 はじめのエラーのソースに戻します(参照設定しない方法に) でも、戻すと、参照設定してないと、xlXXXXXの定数が使えません。 だからコマってしまったのに、ふりだしに戻るの? と思ったと思いますが、 下準備で、Excel の VBAで、msgbox xlXXXXXとして、 使用している定数を紙に書き出します。 AccessのVBA側で、Const xlXXXX = 999と自分で書くと、 エラーは発生しなくて、動作すると思います。 ※参照設定しないと、xlXXXXがわからない、 だったら自分で定義してやるぞ・・・って流れです。 が、 この方法は、プロには嫌われる方法なので、 (定数の意味知ってるか?今はOKだけど、将来のバージョンで機能追加となり 定数が変更になったらとかイジメを受けることもあり) お薦め出来ないけど、そんな方法もあります。 不特定多数の人が動かすツールって、なかなか、難しいですね。 ※メルマガサンプルも、そんな理由で参照設定していない、  行儀の悪い手抜きサンプルが多かったんですね。  一流の読者からは参照設定しろとクレーム多いんだけどね。 あまり回答になってませんが、 何かの参考となれば幸いです。 投稿時間:2003/08/13(Wed) 16:59 投稿者名:お茶犬レッド Eメール: URL : タイトル:Re^2: ありがとうございます!そして、 たびたび本当にありがとうございます。 >下準備で、Excel の VBAで、msgbox xlXXXXXとして、使用している定数を  >紙に書き出します。 >AccessのVBA側で、Const xlXXXX = 999と自分で書くと、 >エラーは発生しなくて、動作すると思います。 >※参照設定しないと、xlXXXXがわからない、だったら自分で定義してやる >ぞ・・・って流れです。 の事なのですが、VBっていうかプログラム超初心者の私は定数というのが余り分かっ てなくて(なんとなくイメージは分かるんですけど)。それでここは例えば、 oApp.Range("C3:D3").Select With oApp.Selection .HorizontalAlignment = oApp.xlCenter .MergeCells = True End With というコードでしたらxlXXXXの部分のコードを .HorizontalAlignment = oApp.xlCenter = 999 とすればよいということではないですよね?(今やってみたら読みませんでした) 申し訳ありませんが、もう一度教えていただけないでしょうか。 ちなみに今は、「出力ボタン」を「押す画面を出すためのボタン」に、(分かりにく いですね) Dim strMSG strMSG = "もし出力ボタンを押してエラーが出ましたら、MicrosoftVisualBasicの 「ツール」「参照設定」から「Microsoft Excel 9.0 Object Library」を選択してく ださい" MsgBox strMSG とコードを入れて逃げています。なんて言うか「ちゃんと一言断ったでしょ・・・小声 で」みたいな感じになってます^^; 投稿時間:2003/08/13(Wed) 18:36 投稿者名:Ken3(管理者) タイトル:Const xlCenter = &HFFFFEFF4
Sub aaa()
    'Excelで走らせてね
    MsgBox "xlCenterは" & xlCenter
    '-4108って表示されると思う
    'これだとかっこ悪いのでHexで16進にする
    MsgBox "xlCenterは16進数だと" & Hex(xlCenter)
    'FFFFEFF4となる
End Sub
例えば、 oApp.Range("C3:D3").Select With oApp.Selection .HorizontalAlignment = oApp.xlCenter .MergeCells = True End With このコードだと、 問題の場所は、 .HorizontalAlignment = oApp.xlCenter の代入文です、参照設定されていないと、.xlCenterが使えない。 先ほどのExcel側の確認で、.xlCenterが&hFFFFEFF4と確認したので、 自分で下記のように代入してみる。
Private Sub コマンド0_Click()

    Dim oApp As Object

    Set oApp = CreateObject("Excel.Application")
    oApp.Visible = True
    'Only XL 97 supports UserControl Property
    oApp.UserControl = True

    'Access側でテストする
    oApp.Workbooks.Add 'ブックを追加
    oApp.Range("C3:D3").Select
    With oApp.Selection
        .HorizontalAlignment = &HFFFFEFF4 '-4108でもOKです
        .MergeCells = True
        .Value = "TEST DATA"
    End With

End Sub
少し、おかしく見えるが、 .HorizontalAlignment = &HFFFFEFF4 '-4108でもOKです と、調べた値を代入している。 これだと、何?&HFFFFEFF4って?としばらく経つと、本人も忘れるので、 もう一つの逃げ手を進めて、自分で勝手にExcelが使っている定数を宣言する。 定数の宣言は、Const文なので、 Const xlCenter = &HFFFFEFF4 'と定数を自分で宣言 みたいに書く、これで参照設定しなくても、xlCenterが使える。
Private Sub コマンド1_Click()
    '何回も、xlCenterを置き換えたくないし、間違えるので、
    Const xlCenter = &HFFFFEFF4  'と定数を自分で宣言
    
    Dim oApp As Object

    Set oApp = CreateObject("Excel.Application")
    oApp.Visible = True
    'Only XL 97 supports UserControl Property
    oApp.UserControl = True

    'Access側でテストする
    oApp.Workbooks.Add 'ブックを追加
    oApp.Range("C3:D3").Select
    With oApp.Selection
        .HorizontalAlignment = xlCenter '普通に定数を代入
        .MergeCells = True
        .Value = "TEST DATA"
    End With
 
End Sub
この方法が上級者に叱られると言ったのは、 私のテストのExcel2002では、 xlCenter = &HFFFFEFF4 かも知れないが、Excel2004とか未来のバージョンは? 下位のバージョンでも同じ値なのか?違ったら? と、自分で定数を定義することは、危険があると言われます。 なので、メッセージで、運用している人に注意をする。 > strMSG = "もし出力ボタンを押してエラーが出ましたら、MicrosoftVisualBasic の「ツール」「参照設定」から「Microsoft Excel 9.0 Object Library」を選択してく ださい" > MsgBox strMSG > とコードを入れて逃げています。なんて言うか「ちゃんと一言断ったでしょ・・・ 小声で」みたいな感じになってます^^; 古典的だけど、こっちが正解だと私も思ったり。 何かの参考となれば、幸いです。

/* * 5.罫線を引く、サブ関数を作成してみる */

参照設定、する、しないは、お任せして、 指定範囲を受け取ったら、 罫線を上下左右、縦・横に引く関数を作成してみます。 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 関数のポイントは、 'テストで左右の罫線を引いてみる With objRANGE.Borders(xlEdgeLeft) '左 .LineStyle = xlContinuous .Weight = xlThin .ColorIndex = xlAutomatic End With With objRANGE.Borders(xlEdgeRight) '右 .LineStyle = xlContinuous .Weight = xlThin .ColorIndex = xlAutomatic End With 左右の罫線を引く処理で、 違いは、xlEdgeLeft, xlEdgeRight ~~~~~~~~ だけで場所の指定が違い、セットしている値は一緒なので、 これを6つの上、下、左、右、垂直、水平の罫線分ループで回してみます。 'Rangeのエリアを受け取り、罫線を引く
Private Sub make_Border(objXY As Object)

    '罫線用のExcel定数(参照設定している場合は、必要無し)
    Const xlEdgeLeft = &H7
    Const xlEdgeRight = &HA
    Const xlEdgeTop = &H8
    Const xlEdgeBottom = &H9
    Const xlInsideVertical = &HB
    Const xlInsideHorizontal = &HC

    Const xlContinuous = &H1
    Const xlThin = &H2
    Const xlAutomatic = &HFFFFEFF7

    Dim n As Integer

    '配列に代入する
    Dim styleBOX As Variant
    styleBOX = Array(xlEdgeLeft, xlEdgeRight, xlEdgeTop _
                  , xlEdgeBottom, xlInsideVertical, xlInsideHorizontal)

    For n = 0 To 5 '各ラインに対して、値をセットする
        With objXY.Borders(styleBOX(n))
            .LineStyle = xlContinuous
            .Weight = xlThin
            .ColorIndex = xlAutomatic
        End With
    Next n

End Sub
参照設定をしないで、値を調べて、 Const xlEdgeLeft = &H7 Const xlEdgeRight = &HA なんて邪道な方法ですが(みなさんはマネしないでね) 今回、メルマガサンプルで不特定多数の人が使うので、使ってみました。 Array関数で、配列を初期化して、 ループで、 For n = 0 To 5 '各ラインに対して、値をセットする With objXY.Borders(styleBOX(n)) と、回して、オブジェクトを変化させてます。 呼ぶ方法は、 'テストで罫線を引いてみる Set objRANGE = objEXCEL.Range("A1:B11") '範囲の代入 objRANGE.Value = "aaaa" 'テストデータ代入 Call make_Border(objRANGE) '罫線を引く Call make_Border(objEXCEL.Range("D1:E11")) '罫線を引く みたいに、Rangeの範囲を渡してます。

/* * 6.罫線を引く処理を組み込む */

さてと、やっと、罫線が引けそうになったので、 データセットルーチンに組み込んでみます。 単純に、 '見出しをセットする objEXCEL.Cells(nYLINE, nXLINE) = "郵便番号" objEXCEL.Cells(nYLINE, nXLINE + 1) = "件数" '罫線を引く(見出しの位置から+10行分) Call make_Border(objEXCEL.Range(objEXCEL.Cells(nYLINE, nXLINE), _ objEXCEL.Cells(nYLINE + 10, nXLINE + 1))) と、 見出しを表示するタイミングで、 .Range範囲を、 .Cells(nYLINE, nXLINE) 見出しの左上 から .Cells(nYLINE + 10, nXLINE + 1) 10行下、隣の列まで指定して、 罫線表示ルーチンに渡しました。 ↑罫線を引いたイメージ(Exceの印刷プレビューで確認)
Private Sub btnTEST004_Click()
    
    Dim rs As New ADODB.Recordset  'ADOのレコードセット
    Dim objEXCEL As Object  'Excel参照用
    Dim nYLINE   As Integer '行セット位置
    Dim nXLINE   As Integer '列セット位置
    Dim nRCNT    As Integer 'レコードカウンタ

    'Excelを起動する、オブジェクトの作成
    Set objEXCEL = CreateObject("Excel.Application") 'オブジェクトの作成
    objEXCEL.Visible = True  'Excelを見えるようにする
    
    '新規のブックを追加する
    objEXCEL.Workbooks.Add   'Excelのブックを作成

    'Excelのシートを追加、シート名を変更する
    objEXCEL.Sheets.Add  'シートを追加する
    objEXCEL.ActiveSheet.Name = "DATA"  'シート名をDATAにする

    'レコードセットを開く(Q_YUBIN_7)
    rs.Open "Q_YUBIN_7", CurrentProject.Connection, _
                    adOpenKeyset, adLockOptimistic

    'カウンタの初期化 スタート位置のセット
    nYLINE = 1 '1行目だよ
    nXLINE = 1 '1列目(A列)だよ
    
    '見出しをセットする
    objEXCEL.Cells(nYLINE, nXLINE) = "郵便番号"
    objEXCEL.Cells(nYLINE, nXLINE + 1) = "件数"
    '罫線を引く(見出しの位置から+10行分)
    Call make_Border(objEXCEL.Range(objEXCEL.Cells(nYLINE, nXLINE), _
                                    objEXCEL.Cells(nYLINE + 10, nXLINE + 1)))
    nYLINE = nYLINE + 1 '見出し分行数が増えます
    nRCNT = 1  '見出し表示後は1レコード目だよ
    
    'レコードセットからExcelへデータをセットする
    'ループ処理
    While rs.EOF = False  'いつものEOFが偽の間
        'データをセットする(Accessから転記)
        objEXCEL.Cells(nYLINE, nXLINE) = rs("郵便番号").Value
        objEXCEL.Cells(nYLINE, nXLINE + 1) = rs("郵便番号のカウント").Value
        '次を読む And カウンタを移動する
        rs.MoveNext  '次のレコードに移動しないと、とんでもないことに(笑)
        nRCNT = nRCNT + 1   '処理レコード数を増やす
        If nRCNT > 10 Then  '処理したレコードが10を越えた(次の列)
            nXLINE = nXLINE + 3  '次の列へカウンタを移動
            If nXLINE > 9 Then '列が越えた?
                nXLINE = 1  '1列目(A列)に戻す
                nYLINE = nYLINE + 2  '空白行にしたいのでセット位置を+2する
            Else
                nYLINE = nYLINE - 10 '列が変わったので行カウンタをマイナスする
            End If
            
            '見出しの表示
            objEXCEL.Cells(nYLINE, nXLINE) = "郵便番号"
            objEXCEL.Cells(nYLINE, nXLINE + 1) = "件数"
            '罫線を引く(見出しの位置から+10行分)
            Call make_Border(objEXCEL.Range(objEXCEL.Cells(nYLINE, nXLINE), _
                                      objEXCEL.Cells(nYLINE + 10, nXLINE + 1)))

            nYLINE = nYLINE + 1 '見出し表示分行数が増えます
            nRCNT = 1  '見出し表示後は1レコード目だよ
        Else  '
            nYLINE = nYLINE + 1  '次の行へセット位置を移動
        End If
    Wend
    '通常は、ここでExcelを保存するんだけど、今回は開きっぱなしの手抜き

    rs.Close   '開いたら閉じろ、ドアを開けたら閉めるってしつけられたでしょ(笑)
    Set rs = Nothing  '変数も後始末しますか。使った器はキレイにしろって?

End Sub
-【けんぞう!】--------------------------------------------------------- 月500円、タバコなら2箱、120円缶コーヒーなら4缶分の謝礼をGetするなら http://www.ken3.org/etc/500yen/ ←無料アンケート系の広告です。 『チッ、がんばって回答して月500円かよ』(お馬鹿なプログラマー:30歳) ------------------------------------------------------------------------ 

/* * 7.終わりの挨拶 */

今回は、 AccessからExcelへデータをセットしながら 罫線を引いてみました。 参照設定の問題などあるけど、 がんばれば、こんなこともできるってことで。 今回の、サンプルファイルは、 http://www.ken3.org/vba/lzh/vba131.lzh にdb131.mdb(Access2000版)が保存されています。 ※クエリーやプログラムをいじって、遊んでみてください。 Access から Excel 連携 http://www.ken3.org/cgi-bin/group/vba_access_excel.asp も参考にしてください。 何かの参考となれば幸いです。 Excel/Access大好き、三流プログラマーKen3でした。

No.132 2003/09/24
Excel ショートカットキーにマクロを割り当てる
[ページTOPへ戻る]

<Excel ショートカットキーにマクロを割り当てる>

どうも、三流プログラマーのKen3です。 最近、質問もらうけど、 なかなか、解答できてない三流プログラマーのKen3です。 ※私のレベルで手に余る高度な質問が多くて。 http://www.ken3.org/p/h/office-028.lzh に今回のサンプル保存されてます。 CTRL+CでAAAのマクロが起動します。 普通に動かして、少し驚いてね(テストしてみてね。) ※通常Ctrl+Cはコピーだけど、横取りして使ってます。

/* * 1. 今回のキッカケ */

読者から、シートにボタンを設置する、 ダブルクリックや右ボタンで、マクロの起動方法はわかったが、 CTRL+Cでコピーのように、キーにマクロを割り当てられないか? と質問をもらいました。 マクロの起動をCTRL+キーで行う方法を探ってみます。

/* * 2.やりたいことをまとめる、実現可能か探ってみる */

キーのクリックやチェンジを探ろうと考えて、
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
    MsgBox "aa"
End Sub
とするが、これでは処理は横取りできなかった。 何かのタイミングで処理しようと試みるが、 ダメなことに気が付く。 何かないかなぁと探ってみると、 .OnKeyメソッドが見つかる。 ^^^^^^^^^^^^^^ Application.OnKeyを使用すると、ショートカットキーにマクロを割り当てられます。 ヘルプのサンプルを見ると、 使用例 ^^^^^^ 次の使用例は、InsertProc を Ctrl + a キーに、 SpecialPrintProc を Shift + Ctrl + → キーに登録します。 Application.OnKey "^{a}", "InsertProc" Application.OnKey "+^{RIGHT}", "SpecialPrintProc" 次の使用例は、Shift + Ctrl + → キーを通常の機能に戻します。 Application.OnKey "+^{RIGHT}" 次の使用例は、Shift + Ctrl + → キーを無効にします。 Application.OnKey "+^{RIGHT}", "" 設定方法、戻す方法、無効にする方法の例が出てます。

/* * 3.単体でテストを行う(プロパティ)を探る */

ヘルプで、使えそうな関数を見つけたら、 短いプログラムを作って、テストしてみるのが一番確認しやすい方法だと思います。 ※タイミングや関数の起動を見たいときは、  MsgBox "XXX"なんて手抜きで入れるのも1つの手です。 引数を変えたり、自分で実行したりして、動きを確認して、 自分のやりたいことに応用します。 ※いきなり自分のシステムに組み込まないで、  シンプルな機能・関数として、テストしてみます。 ブックのオープン時に、 Application.OnKey で、Ctrl+Cキーに関数aaaを割り当ててみます。
Private Sub Workbook_Open()
    'プロシージャーの登録
    Application.OnKey "^{c}", "aaa"
    'CTRL+Cをつぶすと(横取りすると問題あるが・・)
End Sub
.OnKeyのヘルプを見ると、設定可能なキーの組み合わせが書いてあります。 半信半疑で、CTRL+Cを設定する場合は、 "^{c}" と、^がコントロールキーです。 , "aaa"これが、起動されるマクロのプログラムです。 テスト関数aaaは、下記のように現在選択位置Selectionを塗りつぶす関数です。
Sub aaa()

    '選択位置を黄色で塗りつぶす
    With Selection.Interior
        .ColorIndex = 6
        .Pattern = xlSolid
    End With

End Sub
実際に使う時も、ブックのオープンのタイミングで走る、 Workbook_Open() のイベントで、 'プロシージャーの登録 Application.OnKey "^{c}", "aaa" 'CTRL+Cをつぶすと(横取りすると問題あるが・・) みたいに、セットすると、便利だと思います。 -【けんぞう!】--------------------------------------------------------- ASPが利用可能なレンタルサーバーをお探しのアナタ、 http://www.ken3.org/asp/server.html ← けんぞうも使っているサーバーの紹介 『おっIISでbasp21でメール送信、mdbも使えるよ』(三流PG:30歳) ------------------------------------------------------------------------

/* * 4.終わりの挨拶 */

今回は、 キーにマクロを割り当てる方法を探ってみました。 便利関数を作った人は、 空いているキーに割り当てて(Ctrl+CやV以外の人気の無いキー) 使ってみてください。 ※例題のように、CTRL+Cを横取りすると、操作者からクレーム来ると思います。 http://www.ken3.org/p/h/office-028.lzh に今回のサンプル保存されてます。 CTRL+CでAAAのマクロが起動します。 普通に動かして、少し驚いてね(テストしてみてね。) ※通常Ctrl+Cはコピーだけど、横取りして使ってます。 何かの参考となれば幸いです。 Excel/Access大好き、三流プログラマーKen3でした。

No.133 2003/09/24
仕様変更が来たら?落胆しないで前向きに?
[ページTOPへ戻る]

<仕様変更が来たら?落胆しないで前向きに?>

どうも、三流プログラマーのKen3です。 今回は、システム作っていると、ありがちな、 やっぱりコレにして・・・なんて話です。

/* * 1. 今回のキッカケ */

郵便番号の集計システムを題材にして最近メルマガ書いてます。 [No.127 要求を聞き、疑問点をつぶし、仕様書を書く] http://www.ken3.org/backno/backno_vba26.html#127 で、要求を理解して?簡単なプログラム分けをして、 [No.128 AccessにExcelのシートをインポートする] http://www.ken3.org/backno/backno_vba26.html#128 [No.129 Access いろいろとクエリーでグループ集計をしてみる] http://www.ken3.org/backno/backno_vba26.html#129 ・   ・ [No.131 Access クエリーをExcelシートへ罫線を付けて出力する] http://www.ken3.org/backno/backno_vba27.html#131 なんて感じで、1つ1つ作成してました。 あと少しかなぁ、完成まで・・・と安心してたら、 依頼者より、 下記のよくある話、仕様変更のお話メールが届く(ドキッ) ---- >さて、実は。。。。二人の上司から同じ依頼を受けていたのですが、 >実は片方の上司の解釈が間違っており、間違った指示が >ワタシの方にやってきてしまっていたことが >今朝判明(T_T) > >結局ですね、元々がちがっていたので、修正。 > >1.郵便番号の上から5桁を番号別に集計して・・・ > >2.5桁で集計したものの中で10通以下(9〜1通)になったものを > 今度は上から3桁で集計する > >3.3桁で集計したものの中で10通以下(9〜1通)になったものを > 今度は上から2桁で集計する > >4.2桁で集計したものの中で10通以下(9〜1通)になったものを > △△△と言う名前で集計する > >5.で、各項目(4項目)を色分けする。 > >表示の体裁は添付のエクセルのような状態になるようにする > > >と、いうわけなんです。話を聞いた瞬間、顔にタテ線入ってました・・・(T_T) >手はグーになってましたが。(^^;A ---- あらら、、、よくある話だけど、 急にヤッパリこれにしてくれ・・って感じの話ですね。 ※まぁ、私の場合は、メルマガのネタにもできたけど、  普通の担当者は、ショックを受けるパターンかなぁ。  これが続くと、仕様書がないと絶対に作らない・・  そんなプログラマーの出来上がりカナ

/* * 2.変更内容を整理する */

まぁ、文句を言ってても、状況は変わらないので、 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 前向きに、仕様の変更がどこまで影響するか、新たな仕様は? と 変更内容を整理しますか。 まず、元データは郵便番号なので、変化無しかな。 集計方法が、 In message "[VBAで楽しく No.127] - 要求を聞き、疑問点をつぶし、仕様書を書く", > 郵便番号をカウントする > 郵便番号が7桁そろっているものを集計する > 同様に、3桁しかないもの,2桁しかないもの,その他 > を集計する。 > 集計結果が10以下(1〜9)のデータは、最後に△で集計する。 から >1.郵便番号の上から5桁を番号別に集計して・・・ > >2.5桁で集計したものの中で10通以下(9〜1通)になったものを > 今度は上から3桁で集計する > >3.3桁で集計したものの中で10通以下(9〜1通)になったものを > 今度は上から2桁で集計する > >4.2桁で集計したものの中で10通以下(9〜1通)になったものを > △△△と言う名前で集計する に変更になり >5.で、各項目(4項目)を色分けする。 で、出力すればいいのね。 クエリーのExcel出力や罫線付けの処理は、流用できそうだなぁ。 集計処理の練り直しですね。

/* * 3.集計するデータの流れを考える */

頭の中で、すてきな異性とのデートを空想するのも手だけど、 データの集計方法を考える場合は、 実データと処理の流れを書いていく方が、わかり易いと思います。 今回は、郵便番号の集計なので、郵便番号を適当に書いて、 集計条件を考えてみます。 >1.郵便番号の上から5桁を番号別に集計して・・・ 7桁の郵便番号を上から5桁にして、集計するのね。 135-0034 135-0044 13500 なんてあったら、 135-0034 , 135-0044 これは、13500と-を取って、 13500で集計するのね。 データのパターンは、135-0034だけかなぁ?1350034とハイフン無しもあるのかなぁ? それと同様に5桁データも135-00と13500と2パターンあるか? なんて感じで、疑問点は問い合わせるとして、 5桁で集計する処理を作成する。 >2.5桁で集計したものの中で10通以下(9〜1通)になったものを > 今度は上から3桁で集計する 1.で集計するが、10通以下のデータは、再度、3桁でまとめて集計するのかぁ。 137-01 6件 137-02 5件 なんて5桁の集計データがあったら、 137と上3桁でまとめて集計する ^^^^^^ >3.3桁で集計したものの中で10通以下(9〜1通)になったものを > 今度は上から2桁で集計する 2.で集計して、10通以下は、同様に、再度2桁でまとめる しびれるねぇ(笑) >4.2桁で集計したものの中で10通以下(9〜1通)になったものを > △△△と言う名前で集計する 最後に残ったものを△△△でまとめるのね。 流れがわかったような、わからないような(笑) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 流れがわかったら、テーブルと抽出条件を考えます(書きます) MOTO_DATA テーブルにExcelからデータがインポートされます 郵便番号 氏名 住所 電話番号 001-0854 鉢呂 北海道札幌市 061-3772 佐々 北海道石狩郡 101-0051 小林 東京都千代田 101-0054 杉本 東京都千代田 データをキレイにしたいので、 郵便番号フィールドを −を取り除き、5桁にしたデータを作成します。 YUBIN_DATA5 テーブルが作成されます。 郵便番号 00108 06137 10100 10100 と、同時に、MOTO_DATAテーブルから 3桁の郵便番号、2桁の郵便番号のテーブルも作成します。 YUBIN_DATA3 YUBIN_DATA2 郵便番号 数 郵便番号 数 001 1 00 1 061 1 06 1 101 1 10 1 ※数のフィールドを作成データは1を固定でセット、詳細は、※1参照 次に、YUBIN_DATA5テーブルに対して、集計をかけます 郵便番号 郵便番号のカウント 00108 27 06137 27 10100 5 10106 4 ここで、カウント数によって2つの分かれ道、 10以上は、そのままExcelへデータセットに使います。 10回は、頭3桁の番号とカウント数を、YUBIN_DATA3テーブルへ追加します。 集計結果の、 10100 5 10106 4 を YUBIN_DATA3 に追加します ~~~~~~~~~~~ 郵便番号 数 001 1 (※1もともとセットされているデータ) 061 1 ( 〃 ) 101 1 ( 〃 ) 101 5 (YUBIN_DATA5の集計クエリーから10100集計5のデータ) 101 4 (YUBIN_DATA5の集計クエリーから10106集計4のデータ) ※郵便番号101数5 と 郵便番号101数4のデータが追加される そして、YUBIN_DATA3 を集計します (これで、5桁で10以下のデータを含めた集計になります) 郵便番号 数の合計 001 15 061 4 101 10 と、集計できます。 あとは、同様に、10以下のデータは、YUBIN_DATA2へ追加して、 YUBIN_DATA2を集計すれば、なんとか出来そうです。 -【けんぞう!】--------------------------------------------------------- 転職関係、在宅プログラマー、SOHOの広告まとめました http://www.ken3.org/etc/500yen/zaitaku.html いろいろとあるので転機の人はぜひ 『だだ、広告料稼ぎたいだけだろ、紹介料300円〜2000円の小金稼ぎ』 ギクっ、、、バレた(笑)登録料無料、匿名で探せるので在宅で小金稼ぎの人も見てね ------------------------------------------------------------------------ 

/* * 4.終わりの挨拶 */

今回は、 仕様変更の話 と 集計プランの作り方、 そんな話でした。 プログラムは、設計が命・・って言葉、なんとなくわかったでしょ。 集計のプランの作り方1つで、実は、簡単な集計を難しくしたり、 難しい集計が簡単な集計の組み合わせとなったり・・・ 実は、集計プランの作り方、ここがポイントなんだけど、 今回も、一番いいプランの検討は置いといて、 思い付きで、集計の仕様書を作成しました。 う〜ん、肝心な所が書いてないメルマガなんですよね・・・ まぁ、そのあたりのネタは取っといて、 作成した集計プラン(仕様書)に基づいて 次回は、また、クエリーの嵐で攻めてみたいと思います。 何かの参考となれば幸いです。 Excel/Access大好き、三流プログラマーKen3でした。

No.134 2003/09/25
Excel As CommandBarControlでメニューにマクロを登録
[ページTOPへ戻る]

<Excel As CommandBarControlでメニューにマクロを登録>

こんにちは、三流プログラマーのKen3です。 今回は、まだ実用的なツールも作っていないのに、 メニューにマクロを割り当てる方法を探ってみました。 http://www.ken3.org/p/h/office-029.lzh に今回のサンプル保存されてます。

/* * 1. 今回のキッカケ */

前回、下記のようにして、 ショートカットキーにマクロを割り当てました。 .OnKeyメソッドが見つかる。
Private Sub Workbook_Open()
    'プロシージャーの登録
    Application.OnKey "^{c}", "aaa"
    'CTRL+Cをつぶすと(横取りすると問題あるが・・)
End Sub
と、 Application.OnKeyを使用すると、ショートカットキーにマクロを割り当てられます。 http://www.ken3.org/p/h/office-028.lzh に前回のサンプル保存されてます。 CTRL+CでAAAのマクロが起動します。 今回は、ファイル 編集 ....などの横に、 Excelのメニューにオリジナルの項目を作ってみます。 ~~~~~~~~~~~~~~~

/* * 2.As CommandBarControl を 探ってみた */

いろいろと調べてみて、CommandBarControlを使ってみました。 使い方は、わかってしまえば簡単で、 As CommandBarControl と、コマンドバーのコントロールを定義して、 CommandBars("Worksheet Menu Bar").Controls.Add で、メニューバーにコントロールを追加します。 ※"Worksheet Menu Bar"など、イロイロとあるので、   ヘルプで確認してみてください。 あとは、同様に、下のメニューも作成して、 '階層の下を作成する Set objSUBMENU = objMENU.Controls.Add 'アイテムを追加する objSUBMENU.Caption = "VBAのSUB AAA" '表題 objSUBMENU.OnAction = "aaa" 'モジュール名を文字列で .Captionで表題 .OnActionで起動したいモジュールを文字列で指定します。 下記が、作成したサンプルです。
Sub menu_add()

    Dim objMENU As CommandBarControl
    Dim objSUBMENU As CommandBarControl
    
    'メインメニューを追加する
    Set objMENU = CommandBars("Worksheet Menu Bar").Controls.Add(msoControlPopup, , , , True)
    objMENU.Caption = "Ken3テスト"

    '階層の下を作成する
    Set objSUBMENU = objMENU.Controls.Add   'アイテムを追加する
    objSUBMENU.Caption = "VBAのSUB AAA"  '表題
    objSUBMENU.OnAction = "aaa" 'モジュール名を文字列で
    Set objSUBMENU = Nothing '設定後開放してもOKです。
    
    '階層の下を作成する
    Set objSUBMENU = objMENU.Controls.Add   'アイテムを追加する
    objSUBMENU.Caption = "SUB BBBを起動"  '表題
    objSUBMENU.OnAction = "bbb" 'モジュール名を文字列で
    Set objSUBMENU = Nothing '設定後開放してもOKです。

End Sub
Sub aaa()
    MsgBox "AAAが呼ばれました"
End Sub
Sub bbb()
    MsgBox "BBBが呼ばれました"
End Sub
↑メニューの追加実行のイメージです。 通常は、_Openのイベントなどで、メニューを初期化すればOKだと思います。 -【けんぞう!】--------------------------------------------------------- 三流君の、小金稼ぎ、お小遣い稼ぎシリーズ第2弾(稼げないだろコラ!!) http://www.ken3.org/etc/500yen/yosou.html キャンペーン参加で得たコインを予想問題に投票。正解するとコインが倍増、 それを換金という画期的“お得エンタメ”です。 運と実力で誰でも現金獲得のチャンスがあります。 思ったよりもあたらないけど、無料なのでチャレンジしてみては? ------------------------------------------------------------------------

/* * 3.終わりの挨拶 */

今回は、 メニューにコマンドを追加する、 そんな話でした。 http://www.ken3.org/p/h/office-029.lzh に今回のサンプル保存されてます。 メニューが変更されることを確認してください。 マクロの登録よりも先に、 使えるツールを作らないと・・・ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ※メニュー登録方法より先に、使える便利モジュールだろ・・・ う〜ん、肝心な所が書いてないメルマガなんですよね・・・ 何かの参考となれば幸いです。 Excel/Access大好き、三流プログラマーKen3でした。


検索して目的の情報を探す。

目的の情報を探すには、最近はググれとよく聞きます。なので、検索ボックスを付けました。
いろいろなキーワードを入れて、検索してみてください。

カスタム検索
三流君(site:www.ken3.org) 内を Googleを利用してキーワード する

ページフッター

ここまで、読んでいただきどうもです。ここから下は、三流君宛のメッセージ送信や 三流君のホームページの紹介・案内です
目的の情報が見つかったか?少々心配しつつ、、、※質問や感想は、気軽に送ってくださいね。

質問や要望など メッセージを送る(三流君に連絡する)

質問や要望など連絡方法でお互い確認が取りやすく、便利なのが掲示板なのですが、私の対応のまずさから不定期で荒れてしまい、掲示板は現在封鎖中です。(反省しなきゃ)
感想や質問・要望・苦情など 三流君へメッセージを送る。
時間的余裕のある要望・質問・苦情の場合は、下記のフォームからメッセージを送ることができます。
あなたのお名前(ニックネーム):さん
返信は?: 不用(HP更新を待つ) , E-mail→ アドレス:に返事をもらいたい



(感想や質問・要望 メッセージはHPで記事に載せることがあります。)

急ぎで連絡がほしい、そんな時は:[三流君連絡先]に連絡してください。

リンクや広告など

項目別に↓に人気の記事をまとめてみました。お探しのジャンルを選択してください。
人気記事(来場者が多いTOP3):
[VBAでIE,WebBrowserを操作]・・・VBAでIE,WebBrowserを操作する サンプルです
[Access から Excel 連携 CreateObject("Excel.Application")]・・・AccessからExcelを操作したりデータの書き出しなどです
[VBAでOutlookの操作 CreateObject("Outlook.Application" )]・・・VBAからOutlookを使い、メール関係を処理するサンプルです
↑上記3つみたいなCreateObjectで他のアプリケーションを操作するサンプルが人気です。

開発時の操作: [F1を押してHELPを見る]/ [Debug.Print と イミディエイトウインドウ]/ [実行時エラーでデバッグ]/ [ウォッチ式とSTOP]/ [参照設定を行う]

仕様書(設計書?) XXXX書類: [基本設計書や要求仕様書]/ [テスト仕様書 テストデータ]/ [バグ票]/ [関数仕様書]/ [流れは 入力・処理・出力]

Excel関係:
[Excel UserFormを操作する]・・・エクセルでユーザーフォームを作成して入力などを行ってます
[ExcelからAccessを操作する]・・・ExcelからAccessのマクロを起動してみました、
[Excel関係 関数、その他]・・・その他Excel関係です

Access関係:
[Access UserForm/サブフォーム 操作]・・・アクセスでフォームを使ったサンプルです
[Access レポート操作]・・・レポートを操作してみました
[Access クエリーやその他関数]・・・あまりまとまってませんが、スポット的な単体関数の解説です

その他:VBAの共通関数やテキストファイルの操作など
[VBAでテキストファイル(TextFile)の操作]・・・普通のテキストファイルを使ったサンプルです
[VBA 標準関数関係とその他解説]・・・その他、グダグタ解説してます

Blog:[三流君の作業日記]/ [サンプルコードのゴミ箱]/ 広告-[通販人気商品の足跡]



[三流君(TOP ken3.org へ戻る)] / [VBA系TOPへ] / [VBA系バックナンバー目次へ移動]