2011-12-28 4 views
4

ユーザーがリストに新しい行を追加するたびに(たとえば、Worksheet.ListObjects()がそのインスタンスを返すリストの種類)をワークシート上に追加するたびに、Excel 10ワークシートでVBAイベントハンドラを実行します。リストの新しい行を追加してリストを展開します。新しい行の追加をリストにトラップするにはどうすればよいですか?

どうすればよいですか?とりわけ、私は新しい行の特定のセルにデフォルトを設定したいと思います。

私の現在の考えはWorksheet_Changeを処理し、Targetパラメータは、私が興味を持っていますListObject.Range内にあるかどうかを確認することです。

ユーザーが使用して新しい行を作成している場合は、どのように私は見つけるだろうセルの変更を行い、リスト内の既存のセルの編集と区別しますか?

私はおそらくちょっと愚かです。私はトラップできるリストイベントがあると思っていますが、見つけられません。

答えて

2

あなたは正しいと思いますが、ListObjectのイベントはありません。 Worksheet_Changeを使用すると正しい方法があるようです。 New RowとExisting Rowの編集を検出するには、独自のメソッドをロールバックする必要があります。

変更するタイミングを検出するために、ListOjectsの行数を追跡することをお勧めします。これを行うには、各ListOjectに現在の行数を保持するために非表示のnamed rangeを追加してみてください。開いたファイルにそれらを設定し、Worksheet_Changeでテストします。

これは、これが行われた変更の種類を検出します

Private Sub Workbook_Open() 
    Dim oList As ListObject 
    Dim sh As Worksheet 
    Dim nm As Name 
    Dim strName As String 

    For Each sh In Me.Worksheets 
    For Each oList In sh.ListObjects 
     'oList.ListRows.Count 
     strName = oList.Name & "Rows" 
     Set nm = Nothing 
     On Error Resume Next 
     Set nm = Me.Names(strName) 
     On Error GoTo 0 
     If nm Is Nothing Then 
      Set nm = Me.Names.Add(strName, CStr(oList.ListRows.Count)) 
     Else 
      nm.RefersTo = CStr(oList.ListRows.Count) 
     End If 
     nm.Visible = False 
    Next oList, sh 
End Sub 

(ワークブックモジュールに追加)開いているファイルに範囲を名前の隠された追加または更新します。私はそれをWorkBookレベルのイベントにしたので、すべてのシートに必要なのは1つだけです。

Private Sub Workbook_SheetChange(ByVal sh As Object, ByVal Target As Range) 
    Dim oList As ListObject 
    Dim nm As Name 
    Dim strName As String 

    For Each oList In sh.ListObjects 
     strName = oList.Name & "Rows" 
     If Not Application.Intersect(Target, oList.DataBodyRange) Is Nothing Then 
      Set nm = Nothing 
      On Error Resume Next 
      Set nm = Me.Names(strName) 
      On Error GoTo 0 
      If nm Is Nothing Then 
       Set nm = Me.Names.Add(strName, CStr(oList.ListRows.Count)) 
       nm.Visible = False 
      End If 
      If oList.ListRows.Count <> Val(Replace(nm.Value, "=", "")) Then 
       nm.RefersTo = CStr(oList.ListRows.Count) 
       MsgBox "List " & oList.Name & " changed" & vbCrLf & "New Line" 
      Else 
       MsgBox "List " & oList.Name & " changed" & vbCrLf & "Existing Line" 
      End If 
     End If 
    Next 
End Sub 

注:これは、既存のListObjectの名前が変更された場合を処理しません。これは読者のための練習として残されています

+0

あまりにも良くないようです。よりコンパクトな方法。しかし、ありがとう。 – TheBlastOne

関連する問題