Access VBA質問箱 IV

当質問箱は、有志のボランティア精神のおかげで成り立っています。
問題が解決したら、必ずお礼をしましょうね。
本サイトの基本方針をまとめました。こちら をご一読ください。

投稿種別の選択が必要です。ご注意ください。
迷惑投稿防止のため、URLの入力を制限しています。ご了承ください。


441 / 2272 ツリー ←次へ | 前へ→

【11664】MDBでMDE風みたいな pon 10/5/26(水) 14:20 質問[未読]
【11672】Re:MDBでMDE風みたいな YU-TANG 10/6/1(火) 16:04 回答[未読]
【11687】Re:MDBでMDE風みたいな pon 10/6/10(木) 15:13 質問[未読]
【11688】Re:MDBでMDE風みたいな 小僧 10/6/10(木) 17:05 回答[未読]
【11692】Re:MDBでMDE風みたいな pon 10/6/11(金) 11:06 質問[未読]
【11695】Re:MDBでMDE風みたいな YU-TANG 10/6/11(金) 17:20 回答[未読]

【11664】MDBでMDE風みたいな
質問  pon E-MAIL  - 10/5/26(水) 14:20 -

引用なし
パスワード
   こんにちは
よろしくお願いします

AC2003

サブフォームをデータシート形式で使用しています

MDBであれば、このサブフォーム上の
フィールドの入れ替えや列幅の調整がマウスで出来
再起動後もその設定を保持した状態で開きます

MDEにしてしまうと、MDEの起動中は上記操作は可能ですが
再起動後は、オリジナルの状態で開いてしまいます


Q1
MDEでも手動調整した設定を保持させることは、可能でしょうか
アドバイスよろしくお願いいたします

Q2
MDEの代わりにMDBのフォームを
・右上 ×ボタンの無効
・フォーム閉じるボタン設置 閉じるとき Application.Quit
・起動時の設定 DBウインドウ非表示、メニュー非表示
・モジュール保護
・ Shift キーバイパスの無効
とすれば、MDEに近い運用が可能なような気がしますが
他に注意すべき事項等とか、予想される不具合とか有りますか

アドバイスよろしくお願いいたします

【11672】Re:MDBでMDE風みたいな
回答  YU-TANG  - 10/6/1(火) 16:04 -

引用なし
パスワード
   こんにちは、YU-TANG です。

> Q1
> MDEでも手動調整した設定を保持させることは、可能でしょうか

はい。
フォームを閉じるときに設定を退避して、開くときに復元すればいいだけです。

> Q2
(中略)
> 他に注意すべき事項等とか、予想される不具合とか有りますか

その MDB の作りに依存するので、第三者には想定しようがないです。
MDE であることをアテにして実装した箇所(あるいは実装しなかった
箇所)があれば、そこが留意点になるとは思いますが、そもそも
あるのかないのか、あったとしてどこなのか、第三者には知りようが
無いので、おそらく最良のアドバイスは、しっかりテストしてください、
ということになるでしょう。

ただ、率直な感想を言うなら(感想なんか訊いてないでしょうが)、
MDE のように振舞うインターフェイスが欲しいなら、すなおに MDE を
使ったほうがいいように思います。

それでは。

【11687】Re:MDBでMDE風みたいな
質問  pon E-MAIL  - 10/6/10(木) 15:13 -

引用なし
パスワード
   YU-TANG さん 遅くなりました ありがとうございます m(_ _)m 

>その MDB の作りに依存するので、第三者には想定しようがないです。
ですね
自分自身でもなんか ? な Q だなと感じていました
そんな中,書き込み頂きましてありがとうございました
>おそらく最良のアドバイスは、しっかりテストしてください、
>ということになるでしょう。
了解です
ありがとうございました


MDEの動作について漠然とした理解しかありませんでした
アドバイスを頂いて調べてみましたが

ht tp://support.microsoft.com/kb/882282/ja
MDB ファイルは、フォーム、レポート、モジュールなどの編集や削除を行うことが
できますが、MDE ファイルに変換することによって、実行のみ可能で編集できない

2007 help
VBA コードは、コンパイルされて .accde ファイルに組み込まれユーザーが
VBA コードを参照したり編集はできません。accde ファイルのユーザーは、
フォームやレポートのデザインを変更出来ない

ぐらいしか見つからず
調査前と調査後 知識のレベルはほとんど変わりませんでした

こんなレベルでの考えで、MDEでは
デザイン変更できない → 列移動、列幅変更できない 保存できない
と思い込んでいました

>フォームを閉じるときに設定を退避して、開くときに復元すればいいだけです。

>MDE のように振舞うインターフェイスが欲しいなら、すなおに MDE を
>使ったほうがいいように思います。

ありがとうございます、MDEで出来るなら是非そうしたいです
で、
頂いたアドバイスでチャレンジしてみましたがうまくできませんでした


下記アドバイス頂けると助かります
よろしくお願いいたします

環境 XP ac2003

本来は、データシート形式のサブフォームのレイアウトを保存したかったのですが、まずは、テーブルのレイアウト保存で試してみました

Q1
  'レイアウトセット処理  Sub set_layout()
  を実行してもうまく動作しません
  どう修正すればいいでしょうか
  
  不具合状況
  ・データシートレイアウト保存テーブル作成 Sub make_tbl_layout()
   を実行し、レイアウト保存用空テーブルt_tbl_layout作成
  ・レイアウト取得処理   Sub get_layout()
   を実行し、レイアウト保存テーブルt_tbl_layoutにレイアウト情報取得

   t_tbl_layout レイアウト変更した情報
   id    Column_Orde    Control_Source    Column_Width
   0    2    hoge2    1350
   1    1    hoge1    765
   2    3    hoge3    3870
   3    12    hoge12    1065
   4    13    hoge13    1065
   5    14    hoge14    1065
   6    15    hoge15    1065
   7    16    hoge16    1065

   t_tbl_layout 初期レイアウト情報
   id    Column_Orde    Control_Source    Column_Width
   0    1    hoge1    -1
   1    2    hoge2    -1
   2    3    hoge3    -1
   3    4    hoge4    -1
   4    5    hoge5    -1
   5    6    hoge6    -1
   6    7    hoge7    -1
   7    8    hoge8    -1

   t_tbl_layoutのDTを初期レイアウト情報に書き換えて
   レイアウトセット処理   Sub set_layout()
   を実行してみましたが、レイアウトを戻すことができませんでした
   また、エラーも生じません

   この辺の処理、理解が出来ていません


Q2
  サブフォームのレイアウト取得する場合ですが
  動作的には
  メインフォームの閉じるボタンで
  DoCmd.Close acForm, Me.Name, acSaveYes
  'Application.Quit
  としているので
  サブフォーム自体のレイアウトは保存されています
  
  For i = 0 To FRM.Controls.Count - 1
  とすると、ラベル情報も取得してしまい
  いまいち処理がすっきりしないような気がしています
  また、ラベルとテキストボックスの切り分け処理方法が
  いまいち浮かびません
  
  もう少しいい方法が有るような気がしています
  がどうでしょう
  
  ちなみに、このサブフォームのレコードソースは
  SQL直書としています
  
  
他 
  レコード検索等はよく行っているのですが
  追加、削除はあまりやったことがありません
  エラー処理等、注意事項等ありましたら
  合わせてご教示頂けると助かります
  
  よろしくお願いいたします
  
  
'データシートレイアウト保存テーブル作成
Sub make_tbl_layout()

  Dim db As Database
  Dim Newtbl As TableDef
  
  On Error Resume Next
  DoCmd.DeleteObject acTable, "t_tbl_layout"
  On Error GoTo 0

  Set db = CurrentDb
  Set Newtbl = db.CreateTableDef("t_tbl_layout")

  With Newtbl
    'indexの作成の仕方未調査につき下記はindexとはしていない
    .Fields.Append .CreateField("id", dbInteger)
    .Fields.Append .CreateField("Column_Orde", dbInteger)
    .Fields.Append .CreateField("Control_Source", dbText, 50)
    .Fields.Append .CreateField("Column_Width", dbInteger)
  End With

  db.TableDefs.Append Newtbl

End Sub
  
  
  'レイアウト取得処理
  Sub get_layout()
  
    Dim FRM As Form
    Dim CTL As Control
    Dim i As Integer
    
    Dim cn As New ADODB.Connection
    Dim rs As New ADODB.Recordset
    
    'レイアウトDT削除
    DoCmd.SetWarnings False
    DoCmd.RunSQL "DELETE * FROM t_tbl_layout"
    DoCmd.SetWarnings True
    
    'レイアウト取得テーブルを開く場合
    DoCmd.OpenTable "Sheet1"
    Set FRM = Screen.ActiveDatasheet
    
    'レイアウト取得フォームを開く場合
    'DoCmd.OpenForm "MF01_JOB選択F"
    'Set FRM = Forms("MF01_JOB選択F").Controls("T02_PJ_DT").Form
    'では、データ形式のサブフォームのラベルも
    
    'For Each CTL In FRM.Controls
    '  Debug.Print CTL.ColumnOrder & " : " & CTL.ControlSource & " : " & CTL.ColumnWidth
    'Next CTL
    
    'レイアウト取得
    On Error Resume Next
    For i = 0 To FRM.Controls.Count - 1
    
      'Debug.Print i & ":" & FRM.Controls.Item(i).ColumnOrder & ":" & _
        FRM.Controls.Item(i).ControlSource & ":" & FRM.Controls.Item(i).ColumnWidth
    
      Set cn = CurrentProject.Connection
      Set rs = New ADODB.Recordset
      rs.Open "t_tbl_layout", cn, adOpenKeyset, adLockOptimistic
      rs.AddNew
      rs.Fields(0).Value = i
      rs.Fields(1).Value = FRM.Controls.Item(i).ColumnOrder  '指定並べ替え
      rs.Fields(2).Value = FRM.Controls.Item(i).ControlSource 'フィールド名
      rs.Fields(3).Value = FRM.Controls.Item(i).ColumnWidth  '列幅
      rs.Update
    
    Next
    On Error GoTo 0
    
    DoCmd.Close acTable, "Sheet1"
    'DoCmd.Close acForm, "MF01_JOB選択F"
     
    Set CTL = Nothing
    Set FRM = Nothing
  End Sub


  'レイアウトセット処理
  Sub set_layout()
  
    Dim FRM As Form
    Dim CTL As Control
    Dim i As Integer
    
    Dim cn As New ADODB.Connection
    Dim rs As New ADODB.Recordset
    
    
    'レイアウト取得テーブルを開く
    DoCmd.OpenTable "Sheet1"
    Set FRM = Screen.ActiveDatasheet
  
    'レイアウトセット
    Set cn = CurrentProject.Connection
    Set rs = New ADODB.Recordset
    
    rs.Open "t_tbl_layout", cn, adOpenKeyset, adLockOptimistic
    
    rs.MoveFirst
    
    Do Until rs.EOF
    
     'Debug.Print rs.Fields.Item(1).Value & ":" & rs.Fields.Item(2).Value & ":" & rs.Fields.Item(3).Value
     
     FRM.Controls.Item(i).ColumnOrder = rs.Fields.Item(1).Value '指定並べ替え
     FRM.Controls.Item(i).ColumnWidth = rs.Fields.Item(3).Value '列幅
     
     rs.MoveNext
     
    Loop
    
    'On Error GoTo 0
    
    DoCmd.Save acTable, "Sheet1" 
  
    Set CTL = Nothing
    Set FRM = Nothing

  End Sub

【11688】Re:MDBでMDE風みたいな
回答  小僧  - 10/6/10(木) 17:05 -

引用なし
パスワード
   ▼pon さん、YU-TANG さん:
こんにちは。

データシート形式のサブフォームで保存できる情報には
カラムの可視/不可視やソート順などもあるのですが、
今回は列の表示順と列幅のみ対応するとします。

前準備:
下記SQLをクエリのSQLビューに貼り付けて実行し
T_列データ テーブルを作成して下さい。

Create Table T_列データ(
    フォーム名 char(50),
    サブコントロール名 char(50),
    コントロール名 char(50),
    幅 Int,
    順番 Int
);

複合主キーを下記SQLにて張ります。
Alter Table T_列データ add primary key (
  フォーム名,
  サブコントロール名,
  コントロール名
);


サブフォームのUnload時に情報を取得しようとするとうまくいかなかった為、
メインフォームの方に下記の様なコードを設定します。

Private Sub Form_Load()
  If get_column_data(Me.Name) = False Then
    MsgBox "列データの設定に失敗しました"
  End If
End Sub

Private Sub Form_Unload(Cancel As Integer)

  If set_column_data(Me.Name, "objF_Sub") = False Then
                '^^^^^^^^^^
                'サブフォームを配置するコントロール名
    MsgBox "列データの取得に失敗しました"
  End If
  
End Sub


標準モジュールに下記を設定します。

Function set_column_data(strFormName As String, strSubFormName As String) As Boolean
Dim WS As DAO.Workspace
Dim DB As DAO.Database
Dim objCont As Control
Dim strSQL As String

On Error GoTo ErrEXE
  

  Set DB = CurrentDb
  Set WS = DBEngine.Workspaces(0)
  WS.BeginTrans
  
  strSQL = " DELETE FROM T_列データ " _
      & " WHERE フォーム名 ='" & strFormName & "'"
  DB.Execute strSQL, dbFailOnError
  
  
  For Each objCont In Forms(strFormName) _
        .Controls(strSubFormName).Form.Controls
    If objCont.ControlType = acTextBox Then
      strSQL = " INSERT INTO T_列データ " _
          & " VALUES ('" & strFormName & "' " _
              & ",'" & strSubFormName & "' " _
              & ",'" & objCont.Name & "' " _
              & "," & objCont.ColumnWidth _
              & "," & objCont.ColumnOrder _
              & ");"
      DB.Execute strSQL, dbFailOnError
    End If
  Next objCont


  WS.CommitTrans
  set_column_data = True
  Exit Function
ErrEXE:

  set_column_data = False
  WS.Rollback

End Function

Function get_column_data(strFormName As String) As Boolean
Dim DB As DAO.Database
Dim RS As DAO.Recordset
Dim objCont As Control
Dim strSQL As String

On Error GoTo ErrEXE
  
  Set DB = CurrentDb
  
  strSQL = " SELECT * FROM T_列データ " _
      & " WHERE フォーム名 ='" & strFormName & "' ORDER BY 順番"
  Set RS = DB.OpenRecordset(strSQL, dbOpenSnapshot)
  
  Do Until RS.EOF
    Forms(strFormName).Controls(RS![サブコントロール名]) _
      .Form.Controls(RS![コントロール名]).ColumnWidth = RS![幅]
    Forms(strFormName).Controls(RS![サブコントロール名]) _
      .Form.Controls(RS![コントロール名]).ColumnOrder = RS![順番]
    RS.MoveNext
  Loop
  get_column_data = True
  Exit Function
ErrEXE:

  get_column_data = False

End Function


当方はWinXP、Access2007の環境ですが、
上記コードを accdb にて設定した後に accde ファイルに変換し
列幅、列順が保存されることを確認しております。

ご参考になれば幸いです。

【11692】Re:MDBでMDE風みたいな
質問  pon  - 10/6/11(金) 11:06 -

引用なし
パスワード
   小僧 さん ありがとうございます

素敵なコードのご提示頂き勉強になります
今までばらばらに知っていたことが
1つになって理解できたような気がします
また
動作確認することが出来、希望の操作かないました
ありがとうございました

試してみようと思う方への注意点ですが
Create Table T_列データ(
    フォーム名 char(50),
    サブコントロール名 char(50),
    コントロール名 char(50),
    幅 Int,
    順番 Int
);
のインデントに2バイトのスペースがあって
そのまま保存しようとすると
フィールド定義の構文エラーです。
となってしまいます
Create Table T_列データ(
フォーム名 char(50),
サブコントロール名 char(50),
コントロール名 char(50),
幅 Int,
順番 Int
);
とかすると保存できるようになります


下記2点アドバイス頂けると助かります
よろしくお願いいたします

Q1

ちょっと長ったらしいですがよろしくお願いいたします

AC2003なんですがMDEに変換しようとすると
 Microsoft Office Access 2000 の形式で保存されたデータベースから
 Microsoft Office Access ADE または MDE ファイルは作成できません。
 データベースを Microsoft Office Access の現在のバージョンに変換してください。
 その後、ADE または MDE ファイルを作成してください。
なんて出てしまいました
というわけで、保存形式がAC2000になっていました

上記が原因かわかりませんが

Create Table T_列データ(
    フォーム名 char(50),
    サブコントロール名 char(50),
    コントロール名 char(50),
    幅 Int,
    順番 Int
);


ht tp://www.atmarkit.co.jp/fnetwork/rensai/sql10/sql1.html
char:固定長の文字列を格納するデータ型
text:可変長の文字列を格納するデータ型

とかありました


charだと
フォーム名等の後ろに半角スペース等付いて50文字となってしまい
うまく動作しませんでした
char → text
としてうまく動作することが出来ました

Create Table 初めて勉強したような気がしますか
こんな理解でいいですか


Q2
複合主キーを下記SQLにて張ります。
Alter Table T_列データ add primary key (
  フォーム名,
  サブコントロール名,
  コントロール名
);
こんな簡単に主キーの設定が出来るんですね ♪
勉強になります

なんですが
フォーム名
サブコントロール名
コントロール名
で主キーを設定しなくても重複は発生しないような気がするのですが
どうなんでしょう

また、イメージ的にはコード的なものに主キーを付けるような気がしていたのですが
こういう、名称列とうか文字列フィールドで主キーを張ることは
一般的なことなのでしょうか
なんか使いやすいような気がしますが少ない知識ではあまり見たことがないような気がします

普通だよとか コメント頂けると助かります

よろしくお願いいたします

【11695】Re:MDBでMDE風みたいな
回答  YU-TANG  - 10/6/11(金) 17:20 -

引用なし
パスワード
   こんにちは、YU-TANG です。

> というわけで、保存形式がAC2000になっていました

それはおそらく [ツール]-[オプション]-[詳細]-[既定のファイル形式] を
「Access 2000」 に設定して(あるいは設定されたまま)使っていたから
でしょう。

> 上記が原因かわかりませんが

関係ありません。原因ではないです。

> charだと
> フォーム名等の後ろに半角スペース等付いて50文字となってしまい
> うまく動作しませんでした

それが固定長ですから。そういうものです。

> char → text
> としてうまく動作することが出来ました
>
> Create Table 初めて勉強したような気がしますか
> こんな理解でいいですか

可変長にしたかったのでしたら、それでよろしいかと思います。
理解度を確認したいなら、Access 付属の JET SQL のヘルプを参照すると
よいです。インストール漏れていたら追加しておきましょう。

> また、イメージ的にはコード的なものに主キーを付けるような気がしていたのですが
> こういう、名称列とうか文字列フィールドで主キーを張ることは
> 一般的なことなのでしょうか
> なんか使いやすいような気がしますが少ない知識ではあまり見たことがないような気がします
>
> 普通だよとか コメント頂けると助かります

ふつうです。
主キーはユニークであることを保証できれば、別にコード類である
必要はないです。
ただ他のテーブルの外部キーになることを想定する場合は、ユニークな
複合キーが合っても、それとは別に単一フィールドのコードを設ける
場合もあります。
要はケースバイケースであって、DB 全体の設計の中で他テーブルとの
連携を抜きにして一律 主キー=コードとかその逆とか言うのはナンセンス
と言うことです。


余談ですが、ADO を使うとテーブル作成時に複合主キーを一発で張れます。

Dim s As String

s = "create table T1 ("
s = s & "FormName   TEXT   NOT NULL,"
s = s & "ControlName TEXT   NOT NULL,"
s = s & "ColumnOrder SMALLINT NOT NULL,"
s = s & "ColumnWidth SMALLINT NOT NULL,"
s = s & "ColumnHidden BIT   NOT NULL,"
s = s & "CONSTRAINT PrimaryKey PRIMARY KEY (FormName, ControlName)" ' ここで主キーを設定
s = s & ")"

CurrentProject.Connection.Execute s

それでは。

441 / 2272 ツリー ←次へ | 前へ→
ページ:  ┃  記事番号:
1078193
(SS)C-BOARD v3.8 is Free