アーカイブ

Access+MySQLでDSNレス接続

Access + MySQLの環境で開発するとき、テーブルはリンクテーブルにして使う事が多いです。
リンクテーブルを使うと、Accessの中でテーブルが簡単に参照できるし更新もできるから
便利といえば便利なのですが、お客様の環境にセットアップする際に少し設定が手間だったりします。
とはいえ、Access開発なので小規模前提だとは思うのです。
だからそんなに手間かな~?とも思うけれど、お客様がPC買い換えた時とか
そういう場面を考えると、DSNレス接続できると良いよね、と確かに思いました。

DSNとは?
DSNとは・・・という話しは割愛します。調べてください。
簡単に書くと、accessからODBC接続する際に接続するのに必要なものです。
予め、ODBC→DSN設定をしないと使えません。

この設定をしないでもaccessからMySQLに接続できないか?という事です。

ちなみにこちらの開発環境(access2010 + MySQL 5.1)
SQLServerで接続するものの情報は割とあるのですが、MySQLの情報少なく少々手間取りました。

◆DSN接続

DoCmd.TransferDatabase acLink, "ODBC データベース", "ODBC;DSN=db1;UID=yumi;PWD=pass;LANGUAGE=us_english;DATABASE=db1", acTable, tblNm, tblNm, False

◆DSNレス接続

    Set td = CurrentDb.CreateTableDef(stLocalTableName, dbAttachSavePWD, stRemoteTableName, "ODBC;DRIVER=MySQL ODBC 5.1 DRIVER;SERVER=localhost;DATABASE=db1;UID=yumi;PWD=pass")
    CurrentDb.TableDefs.Append td

今までは、DSN設定を予め各PCにしておいてから上記のDSN接続でテーブルリンクしていましたが
それをしないでもDSNレス接続の文字列でもテーブルリンクできるのを確認しました。

更に、パススルークエリーこれは便利です。

mysql用のSQLで実行して結果をaccessが取得するので速度も速いし
なんといってもSQLがmysqlのが書きやすいので楽なのです。
なので最近は、クエリーもパススルークエリーにすることが多いかな。
帳票もパススルークエリーで行けるし、正直テーブルリンクいらないかも・・とさえ
最近思っています。

    '------------------------------------------------------------
    ' パススルークエリを作成してMySqlでSQLを実行して返却します
    '------------------------------------------------------------
    Set objQd = CurrentDb.CreateQueryDef("")
    ' パススルークエリー接続文字
'    objQd.Connect = "ODBC;DSN=db1;LANGUAGE=us_english;DATABASE=db1"
    objQd.Connect = "ODBC;DRIVER=MySQL ODBC 5.1 DRIVER;SERVER=localhost;DATABASE=db1;UID=yumi;PWD=pass"
    
    ' SQL
    objQd.SQL = "select * from d_order_2"
    ' レコードセット
    Set objRs = objQd.OpenRecordset()

    str = ""
    If objRs.RecordCount > 0 Then
        objRs.MoveFirst
        Do Until objRs.EOF
            
            str = str & objRs.Fields("order_id").value & ":" & objRs.Fields("subject_name").value & vbCrLf
            
            objRs.MoveNext
        Loop
    End If
    MsgBox str

DSNいらないな~便利!

 

でも、問題を発見しました。

・DSNレスでテーブルリンクすると、accessのテーブル一覧に即反映されない。
→accessを再起動するとテーブル一覧に新しいテーブルが反映された
内部的には新テーブルも参照できるので処理に問題はないと思いますが
通常のリフレッシュとか使っても反映はされませんでした。
実際にこれで正常に動作するかと確認作業は必要になると思います。

 

ワードの差込印刷をaccessと連携

70代の母が、色々な資格を取得して、現在は、相談員の仕事をしています。
市役所の契約社員のようで、時給も良いみたいで
先生と言われるのが嬉しいみたいで、楽しそうに仕事をしています。
この年代にしては珍しく、車を乗り回す母。娘の私はペーパーで運転できないけど・・

そんな母も、私の影響でパソコンを使う人です。
相談の内容をレポート提出しなくてはいけないらしく
結構面倒そうだなと思って、私が簡単にシステム化すると安請け合いして
しまったのがことの発端。

ワードのテンプレートがあってレイアウトは変えたくないとのことなので
あくまでもデータ入力をaccessで行って、ワードの差込印刷をすれば
良いんではと思いました。

入力画面と一覧画面をaccessで作成しました。
accessの一覧からワードを起動して差込印刷を実行するのは
現在、セキュリティの問題でできないらしいです

この画像は、差込印刷機能のワードを起動するときに表示されます。
この表示はどうやら消すことはできないそうです。
消すにはレジストリをいじらないとダメだそうです。

また、accessからワードを操作して起動するとき、このダイアログの「いいえ」を
押して起動するものになるらしく、accessで操作はできないんだと断念しました。

ワードの方にマクロを作成して、そのマクロ起動することで
自動的に差込印刷できるようにしました。

実家に帰った時に、試しに動かすと問題勃発

 

◆問題
・officeのバージョン違いにより、参照設定でエラーになりました。
→accessからワードを操作するのをやめました。
参照設定を解除しました。

・ワードのバージョンが古いので、差込印刷のデータを私のaccessデータを
読み込めずにエラーになりました。
→accessのデータをmdb形式にバージョン落としました。

・私のワードのマクロが下位バージョンだと見れなかったので新規に作成しなおしました。

・バージョンが変わると差込印刷するやり方も変わるみたいで・・
試行錯誤の上、なんとか印刷できるまでになりました。

 

◆私の環境:office2010

◆母の環境:office2003

これだけバージョン違うと全然違うなと思いました。

簡単に差込印刷の連携方法を記載します。

 

 

右クリック→エクスポート→ワード差込を選択します。

クエリーでもテーブルでもなんでも良いです。

 

既存のワードに差込を選んでOK

 

ワードのメニュー差し込み文書→差込フィールドの挿入を選択すると

テーブルの項目名がずらずらっと出てきますので選択して差込たい場所までドラッグします。

ドラッグすると<<address>>という風にワードに掛かれます。

メニューの「結果のプレビュー」をクリックすると1件ずつ表示されます。

 

完了と差し込みをクリックで印刷すると全件印刷されます。

ワードの画面は、1ページ分のレイアウトしか表示されません。

 

そこで面倒なのでマクロを作成しました。

メニューの表示→マクロをクリックしてマクロを起動すると

・PDF一括出力
・ワードのまとめて出力
・全て印刷

 

が出来るようにしました。(office2010)
office2003では使えなかったので別途マクロ作成して提供しました。
母のPCには、印刷一括機能のマクロのみしか入っていません。

 

マクロソースはこちら

 


Public Sub 全て印刷()
 ' Print all records in mail merge
Dim bPrintBackgroud As Boolean
Dim oMerged As Document
     
     'Disable to display all the alerts
    bPrintBackgroud = Options.PrintBackground
    Options.PrintBackground = False
    Application.DisplayAlerts = wdAlertsNone
     'Print all records
    With ActiveDocument.MailMerge
        .Destination = wdSendToNewDocument
        .SuppressBlankLines = True
        With .DataSource
            .FirstRecord = wdDefaultFirstRecord
            .LastRecord = wdDefaultLastRecord
        End With
        .Execute Pause:=False
    End With
     
    Set oMerged = ActiveDocument
     'Show the Print dialog box
    Dialogs(wdDialogFilePrint).Show
    oMerged.Close 0
     'Restore all the alerts
    Application.DisplayAlerts = wdAlertsAll
    Options.PrintBackground = bPrintBackgroud
     
End Sub
Public Sub PDF出力()
 ' Print all records in mail merge
Dim bPrintBackgroud As Boolean
Dim oMerged As Document
Dim strOutPath As String

On Error GoTo Error
     strOutPath = myPath & "pdf\相談受付票_" & Format(Now, "yyyymmdd") & ".pdf"
     
     'Disable to display all the alerts
    bPrintBackgroud = Options.PrintBackground
    Options.PrintBackground = False
    Application.DisplayAlerts = wdAlertsNone
     'Print all records
    With ActiveDocument.MailMerge
        .Destination = wdSendToNewDocument
        .SuppressBlankLines = True
        With .DataSource
            .FirstRecord = wdDefaultFirstRecord
            .LastRecord = wdDefaultLastRecord
        End With
        .Execute Pause:=False
    End With
     
    Set oMerged = ActiveDocument
     'Show the Print dialog box
'    Dialogs(wdDialogFilePrint).Show
    oMerged.ExportAsFixedFormat OutputFileName:=strOutPath, ExportFormat:=wdExportFormatPDF
    oMerged.Close 0
     
     'Restore all the alerts
    Application.DisplayAlerts = wdAlertsAll
    Options.PrintBackground = bPrintBackgroud
     
Exit Sub
Error:
    MsgBox "エラーが発生しました。エラー内容:" & Err.Description & Chr$(10), vbCritical, "エラー"
End Sub
Public Sub ワードにまとめて出力()
 ' Print all records in mail merge
Dim bPrintBackgroud As Boolean
Dim oMerged As Document
Dim strOutPath As String

On Error GoTo Error

     strOutPath = myPath & "out\相談受付票_" & Format(Now, "yyyymmdd") & ".doc"
     
     'Disable to display all the alerts
    bPrintBackgroud = Options.PrintBackground
    Options.PrintBackground = False
    Application.DisplayAlerts = wdAlertsNone
     'Print all records
    With ActiveDocument.MailMerge
        .Destination = wdSendToNewDocument
        .SuppressBlankLines = True
        With .DataSource
            .FirstRecord = wdDefaultFirstRecord
            .LastRecord = wdDefaultLastRecord
        End With
        .Execute Pause:=False
    End With
    
    Set oMerged = ActiveDocument
     'Show the Print dialog box
    oMerged.SaveAs2 strOutPath, wdFormatDocument
    oMerged.Close 0
     
     'Restore all the alerts
    Application.DisplayAlerts = wdAlertsAll
    Options.PrintBackground = bPrintBackgroud
     
Exit Sub
Error:
    MsgBox "エラーが発生しました。エラー内容:" & Err.Description & Chr$(10), vbCritical, "エラー"
End Sub
Rem ----------------------------------------------------------------------------------
Rem     関数名   : MyPath
Rem     処理内容 : パス情報の取得
Rem     引  数  : 無し
Rem     戻り値  : 無し
Rem ----------------------------------------------------------------------------------
Public Function myPath()
  
'  MsgBox ActiveDocument.Path & Application.PathSeparator & ActiveDocument.Name
  
  myPath = ActiveDocument.Path
  If Right(myPath, 1) <> "\" Then
    myPath = myPath & "\"
  End If
  
End Function

~感想~
差込印刷は、年賀状のあて名印刷とかでも使えます。
凄く便利で良いのですが、使い勝手はそんなに良くないなと思いました。
だけど、ワードのフォーマットそのまま使えるので手軽だと思います。
結果的に、データ入力はaccessで。出力はワードでになったので素人の母が
これを上手く使いこなせるのかどうかは謎なところです。

Accessレポートの背景色がグレーになってしまう

Accessのフォームもそうですが、レポートも背景が指定していない色になることがあります。
新規に作成した画面やレポートならそういう事も少ないと思いますが
古い時代のAccessを大事に使用していてバージョンアップ対応をすると
稀に背景色がグレーになるとかいう事象が発生しています。

その場合は、グレーになっている箇所のプロパティを修正すると解決することが多いです。
例えば、レポートの明細であれば

詳細セクション→プロパティ→代替の背景色の設定「色なし」→他のに変更