2017-06-09 7 views
0

シートを作成するモジュールがあります。一連の表を含むワークシートを作成します。Excel新しいシートに.xlamモジュールのコードを挿入する

セルのOnChangeイベントを使用して、ユーザーが10進数を入力したことを検証する機能を追加したいとします。次のコードはこれを行います私が新しいワークシートに挿入できるのであれば。それが私が理解できない唯一のことです。

私たちが作成した現在のワークシートは 's'のシートコードモジュールに次のコードを挿入する方法がありますか?

Private Sub Worksheet_Change(ByVal Target As Range) 
Const CELL_ADDRESS = "$R$4:$AQ$500" 
If Not Application.Intersect(Target, Range(CELL_ADDRESS)) Is Nothing Then 
    If Not IsNumeric(Target.Value) Then 
     MsgBox "Please enter numbers only", vbCritical, "Invalid Entry" 
     Target.Value = vbNullString 
    End If 
End If 
End Sub 

EDIT:問題に選ばれた解決策を表示(ウェッジのソリューションを選択しました)。

(回答:)テンプレートから呼び出すAddinに公開関数を追加し、テンプレートから作成したすべてのシートを追加します。

テンプレートを使用してコピーすると、セキュリティ設定を変更することなくカスタムコードを新しいシートに組み込むことができます。

パブリック関数を呼び出すと、保護されたパスワードをシートのコードに入れずにシートを変更することができます。

(シート内部の公開関数呼び出し)

Private Sub Worksheet_Change(ByVal Target As Range) 

Dim wb As Workbook 
Set wb = ActiveWorkbook 


Dim ws As Worksheet 
Set ws = wb.ActiveSheet 

Application.Run "numberaddin.Validate_Input", wb, ws, Target 


End Sub 

(ユーザーがデータを変更するシートによって呼び出されますアドインに組み込まれます。Public Function。)

- すべては、この機能がないです私たちのセルが番号だけを番号として保存し、フォーマットすることを確認してください。値のないテキストはセル内で0になります。これは、ユーザーがデータをコピー&ペーストしても機能します。

Public Function Validate_Input(wb As Workbook, ws As Worksheet, r As Range) 
    CELL_ADDRESS = Cells(1, 2).Value ''''we'll use the locked Cell B1 to specify the Validation Range 
    Dim rCell As Range 
    Dim eCell As Range 
    Dim numErr As Boolean 

    numErr = False 

    Set rCell = Range(CELL_ADDRESS) 


    If Not Application.Intersect(rCell, r) Is Nothing Then 
     ActiveSheet.Protect Password:="pw", UserInterfaceOnly:=True 
     Application.EnableEvents = False 
     For Each eCell In rCell.Cells 
      If Not eCell Is Nothing And eCell.Locked = False And Not Application.Intersect(eCell, r) Is Nothing Then 
       If IsNumeric(eCell.Value) = False Or IsEmpty(eCell.Value) = True Or eCell.Value <> eCell.Value + "0" Then 
       If Not IsNumeric(eCell.Value) Then 
        numErr = True 
       End If 
         eCell.Value = Val(eCell.Value) 
       End If 
       eCell.Interior.Color = RGB(255, 255, 153) 
       eCell.NumberFormat = "_(* #,##0_);_(* (#,##0);_(* "" - ""??_);_(@_)" 
       If eCell.Value > 1000000 Then 
       eCell.Columns.AutoFit 
       eCell.ColumnWidth = eCell.ColumnWidth * 1.2 
       End If 
      End If 
     Next eCell 
     Application.EnableEvents = True 
     ActiveSheet.Protect Password:="pw", UserInterfaceOnly:=False 
    End If 

    If numErr = True Then 
     MsgBox "Only numbers are allowed here.", vbCritical, "Invalid Entry" 
    End If 

End Function 
+1

'Target 'は必ずしも単一セル範囲ではないことを忘れないでください。行/列全体、または他のユーザー選択範囲にすることができます。 'Target.Value'は2D配列であり、単一の値ではないため、あなたのコードはエラーになります。 –

答えて

1

それはあなたが求めていたものを正確にではないのですが、私はあなたがちょうどあなたがそれにしたいコードに隠された「テンプレート」シートを作成することができると思うだろうが(テンプレートを維持するために使用することができますxlVeryHiddenのオプションがありますシートがUIから隠されることもない)。次に、新しいワークシートを作成する代わりに、その「テンプレートシート」のコピーを作成します。このテンプレートシートを使用して、シートVBAコードをコピーする必要があります。

+0

私はこのメソッドを使って、 "VBAプロジェクトモデルへの信頼アクセス"を有効にする必要はありませんでした。完璧に動作します。 –

2

まず、信頼センターで[VBAプロジェクトオブジェクトモデルへのアクセスを信頼する]を有効にする必要があります。その後
あなたはこのような何かを記述する必要があります:

Sub AddModule() 
    Dim Module As VBComponent 
    Dim ModuleString As String 

    ModuleString = "Sub Test()" & vbCrLf & _ 
        " Msgbox(""Test"")" & vbCrLf & _ 
        "End Sub" 

    Set Module = Workbooks(2).VBProject.VBComponents.Add(vbext_ct_StdModule) 
    Module.CodeModule.AddFromString ModuleString 

End Sub 

もちろん、ワークブックの参照とModuleStringを変更する必要があります。また、信頼の変更にも注意してください。それは理由があります。

関連する問題