FC2ブログ

スポンサーサイト 


上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

--/--/--

Category: スポンサー広告

TB: --  /  CM: --

top △

変更した部分の背景色を変える 


旧記事掲載:2009/12/09

画面は、以下

kEnt89

変更した部分に背景色を付けるものになります。(条件付き書式を使用して)
フォームパターンを3つ作りました。
F4_1:レコード確定までの色付け
F4_2:レコード確定後も変更箇所を色付け(情報の置き場にTag使用)
F4_3:レコード確定後も変更箇所を色付け(情報の置き場にヘッダ部非表示の影武者使用)
また、「F4_3」は、条件付き書式をVBAで設定&レコード削除時にも対応(ぼちぼち)
 
テーブルは、「T4」「T品番」「T設備」の3つ。

「T4」は、an、日付、品番ID、設備ID、売上、生産数
「T品番」は、品番ID、品番
「T設備」は、設備ID、設備名

フォームは、「F4」「F4_1」「F4_2」「F4_3」の4つ。
(おまけで日付入力支援用に F_DATE)

「F4」は、非連結で各フォーム起動用
「F4_1」「F4_2」「F4_3」のレコードソースは「T4」
F4_1:レコード確定までの色付け
F4_2:レコード確定後も変更箇所を色付け(情報の置き場にTag使用)
F4_3:レコード確定後も変更箇所を色付け(情報の置き場にヘッダ部非表示の影武者使用)
また、「F4_3」は、条件付き書式をVBAで設定&レコード削除時にも対応(ぼちぼち)

作り方手順)

・テーブル3つ作ります。

テーブル「T品番」「T設備」は、別フォームで別途メンテします。
テーブル「T4」の「品番ID」は、
 ルックアップで(テーブル「T品番」の、品番ID、品番)
テーブル「T4」の「設備ID」は、
 ルックアップで(テーブル「T設備」の、設備ID、設備名)
an は、オートナンバー

・フォームの構成

各フォーム起動用フォームで、表示フォームを切り替えます。
切り替える際、表示されているフォームがあれば、一度閉じてからとしています。


・起動用フォーム「F4」の作成

フォームデザインで作成します。

プロパティで以下を変更します。
レコードセレクタ: いいえ
移動ボタン: いいえ
ポップアップ: はい

各フォーム起動用のコマンドボタンを3つ配置します。
(名前を「btn1」「btn2」「btn3」とします)

以下の処理を記述します。
Const FORMBASE = "F4_"

' 起動されているフォームを閉じてから、新規でフォームを開く
Private Sub WakeUpForm(iNum As Integer)
  Dim sFormName As String
  Dim i As Integer

  For i = 1 To 3
    sFormName = FORMBASE & i
    If (CurrentProject.AllForms(sFormName).IsLoaded) Then
      DoCmd.Close acForm, sFormName, acSaveNo
    End If
  Next
  If (iNum > 0) Then DoCmd.OpenForm FORMBASE & iNum
End Sub

Private Sub btn1_Click()
  Call WakeUpForm(1)
End Sub
Private Sub btn2_Click()
  Call WakeUpForm(2)
End Sub
Private Sub btn3_Click()
  Call WakeUpForm(3)
End Sub

Private Sub Form_Close()
  Call WakeUpForm(0)
End Sub

 

・フォーム「F4_1」「F4_2」「F4_3」の作成

フォームウィザードで、表形式として作成します。
見栄えを整えたところで、出来上がったフォームを2つコピーします。
各フォーム名を「F4_1」「F4_2」「F4_3」とします。

・フォーム「F4_1」への変更

デザイン画面で、テキストボックス「日付」をクリック後、条件付き書式を、
条件部分を「式」として、
IsNull([日付].[OldValue]) Or [日付].[OldValue]<>[日付] を記述後、背景色を選びます。
で、OK ボタン。

IsNull([日付].[OldValue])  の条件は、
新規レコード部分にも色を付けておこうかという、安易な考えで追加しました。
(テーブル「T4」で、それぞれの既定値を設定していないので、できるものになります)

で、詳細にある他のテキストボックス/コンボボックスも同様に設定します。
(それぞれの名前に置き換えながら)

VBAで記述した内容は以下
Private Sub Form_AfterUpdate()
  Me.Recalc
End Sub

Private Sub 日付_DblClick(Cancel As Integer)
  DoCmd.OpenForm "F_DATE"
End Sub

 

・フォーム「F4_2」への変更

このフォームでは、レコードを特定する情報の置き場として、
各テキストボックス/コンボボックスの Tag を使用します。
この Tag には格納できる文字数に制限があるので注意が必要です。

情報の持ち方として、レコードを一意に特定できる an を用います。
an = 1 の "日付" に変更があったら、テキストボックス "日付" の Tag に ,1 を、
さらに an = 2 の "日付" に変更があったら、,1,2 の様に追加していきます。

Tag が、,1,2 だったら、,1,2, に加工して、[an] を , , で囲んだパターンがあるか、で判別します。

デザイン画面で、テキストボックス「日付」をクリック後、条件付き書式を、
条件部分を「式」として、以下を記述します。
IsNull([日付].[OldValue]) Or [日付].[OldValue]<>[日付] Or InStr([日付].[Tag] & ",","," & [an] & ",")>0
記述後、背景色を選びます。
で、OK ボタン。

で、詳細にある他のテキストボックス/コンボボックスも同様に設定します。
(それぞれの名前に置き換えながら)

VBAで記述した内容は以下
' 更新前処理で変更のあった an を Tag に追加
Private Sub Form_BeforeUpdate(Cancel As Integer)
  Dim vFld As Variant
  Dim vTmp As Variant
  Const FIXAN As String = "an"

  If (Not Me.NewRecord) Then
    vFld = Array("日付", "品番ID", "設備ID", "売上", "生産数")
    For Each vTmp In vFld
      With Me(vTmp)
        If (.Value <> .OldValue) Then
          .Tag = .Tag & "," & Me(FIXAN)
        End If
      End With
    Next
  End If
End Sub

Private Sub Form_AfterUpdate()
'  Me.Recalc
End Sub

Private Sub 日付_DblClick(Cancel As Integer)
  DoCmd.OpenForm "F_DATE"
End Sub

 

・フォーム「F4_3」への変更

このフォームでは、レコードを特定する情報の置き場として、
詳細部分のテキストボックス/コンボボックス全て選び、コピー。
ヘッダ部分に貼り付け、「可視」を「いいえ」に変更します。
コンボボックスは、コントロールの種類の変更でテキストボックスに変えます。
各名前は、詳細部分の名前に、「tk」を先頭に付けたものにします。
プロパティのコントロールソースは空欄にします。
この「tk」で始まるテキストボックスに、情報を作っていきます。

条件付き書式は、フォームの「読み込み時」にVBAで「F4_2」同様のものを設定します。
また、レコードが削除された時、「tk」の内容を見直します。
Form_Delete では、どのレコードが削除されるのか情報を蓄積し、
Form_AfterDelConfirm では、削除された時に限り「tk」の内容を見直します。

VBAで記述した内容は以下
Const FIXAN As String = "an"
Dim sDelAns As String

' 条件付き書式の設定と影武者初期化
Private Sub SetFormatConditions()
  Dim ctl As Control
  Dim sCond As String

  For Each ctl In Me.Section(acDetail).Controls
    With ctl
      If (.Name <> FIXAN) Then
        sCond = ""
        sCond = sCond & "IsNull([" & .Name & "].[OldValue]) Or "
        sCond = sCond & "[" & .Name & "].[OldValue]<>[" & .Name & "] Or "
        sCond = sCond & "InStr([tk" & .Name & "] & ',', ',' & [" & FIXAN & "] & ',')>0"
        With .FormatConditions
          .Delete
          With .Add(acExpression, , sCond)
            .BackColor = RGB(200, 240, 255)
          End With
        End With
        Me("tk" & .Name) = ""
      End If
    End With
  Next
End Sub

' 読み込み時初期処理
Private Sub Form_Load()
  Call SetFormatConditions
  sDelAns = ""
End Sub

' 削除後確認で影武者データの編集
' 今後 ,, が並ぶことがあるが処理には影響ないので、連続した場合のみ , へ
Private Sub Form_AfterDelConfirm(Status As Integer)
  Dim ctl As Control
  Dim vTmp As Variant
  Dim sDel As String
  Dim sTmp As String
  Dim i As Long

  If (Status = acDeleteOK) Then
    vTmp = Split(sDelAns, ",")
    For i = LBound(vTmp) To UBound(vTmp)
      sDel = vTmp(i)
      If (Len(sDel) > 0) Then
        For Each ctl In Me.Section(acDetail).Controls
          With ctl
            If (.Name <> FIXAN) Then
              sTmp = Me("tk" & .Name) & ","
              sTmp = Replace(sTmp, "," & sDel & ",", ",")
              sTmp = Replace(sTmp, ",,", ",")
              Me("tk" & .Name) = sTmp
            End If
          End With
        Next
      End If
    Next
  End If
  sDelAns = ""
End Sub

' 削除時で削除される an を覚えておく
Private Sub Form_Delete(Cancel As Integer)
  sDelAns = sDelAns & "," & Me.an
End Sub

' 更新前処理で影武者に変更のあった an を追加
Private Sub Form_BeforeUpdate(Cancel As Integer)
  Dim ctl As Control

  If (Not Me.NewRecord) Then
    For Each ctl In Me.Section(acDetail).Controls
      With ctl
        If (.Name <> FIXAN) Then
          If (.Value <> .OldValue) Then
            Me("tk" & .Name) = Me("tk" & .Name) & "," & Me(FIXAN)
          End If
        End If
      End With
    Next
  End If
End Sub

Private Sub Form_AfterUpdate()
'  Me.Recalc
End Sub

Private Sub 日付_DblClick(Cancel As Integer)
  DoCmd.OpenForm "F_DATE"
End Sub

 

※ 回答では
今回の例では、一意のものがオートナンバーなので、新規登録の更新前処理で確定していない(?)ため処理から外してます。
と書いてましたが、新規編集になった段階でオートナンバーは値が振られるようです。



    For Each ctl In Me.Section(acDetail).Controls
      With ctl
        If (.Name <> FIXAN) Then
という記述がありますが、今回の画面では If は不要です。
an も表示しているとか、非表示で存在するとかの場合に、an を除外するものになります。


上記で、OldValue と Value を単純に比較していますが、
Null のデータが想定される場合は、Nz とかを使って Null 対策をします。


サンプルは以下
 バージョン 20002003 (2002)2007
 ファイル kEnt89_2000.zipkEnt89_2003.zipkEnt89_2007.zip
 サイズ 60,23661,43366,946
※ ファイルは zip 形式
※ 2007 以外は、2007 保存時に変換 & 各バージョンで動作確認 & 最適化

関連記事

2011/07/03

Category: サンプルかな

TB: 0  /  CM: 0

top △

この記事に対するコメント

top △

コメントの投稿

Secret

top △

トラックバック

トラックバックURL
→http://kikutips.blog13.fc2.com/tb.php/89-604fe5fd
この記事にトラックバックする(FC2ブログユーザー)

top △


上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。