Excel VBA質問箱 IV

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

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


4099 / 76734 ←次へ | 前へ→

【78262】Re:貼り付け禁止のマクロ
発言  sy  - 16/6/12(日) 21:16 -

引用なし
パスワード
   ▼ささ さん:

初めのコードは切取に反応しませんでした。
条件分岐が複雑なので、修正を繰り返してたら、切取の確認を忘れてました。

修正コードを提示します。
一応コピペ、カット&ペースト、値のみコピペの基本的な使い方では不具合は無いと思いますが(全部は検証しきれてないので絶対大丈夫とは言い切れないですが)、カットモードにして直接入力など、ユーザーはどんな使い方するか分からないので、意図しない動きをする可能性はあります。
もし不具合が起きたら、また質問して下さい。
(対処可能かどうかは保証できませんが)

後Undoした時は都度MsgBoxが出てくると思いますが、これはVBAでは対処不可能です。
多分全て「はい」で良いと思いますが、逆のパターンもありうるので、そこは使用者に慣れてもらうしかないです。

VBAではMsgBoxとの併用は限界があります。
APIでキーのクリックの常時監視などをすれば、大抵の事は対処できますが、Undoが効かなくなるのと、Undoをクリックした時の処置はAPIでも不可能と思います。

もう複雑すぎて説明は無理です。
ThisWorkbookモジュールに丸ごとコピペして下さい。

Private Declare Function OpenClipboard Lib "User32" (ByVal hwnd As Long) As Long
Private Declare Function CloseClipboard Lib "User32" () As Long
Private Declare Function EmptyClipboard Lib "User32" () As Long


Private Sub Workbook_SheetChange(ByVal Sh As Object, ByVal Target As Range)
  Dim Ans As Integer
  Dim cb As Object, cbID As Integer, val
  Dim val1, cnt As Long
  Dim v, str1 As String
  Dim flg As Boolean, mode1 As Variant

  Application.EnableEvents = False
  mode1 = modeID(0, Target)
  If mode1(1) > 0 Then
    cbID = Application.ClipboardFormats(1)
    If cbID > -1 Or mode1(0) > 0 Then
      If Application.CutCopyMode Then
        flg = True
      Else
        val1 = Target.Value
        cnt = Selection.Count
        If cbID > -1 Then
          Set cb = CreateObject("new:{1C3B4210-F441-11CE-B9EA-00AA006B1A69}")
          cb.GetFromClipboard
          val = cb.GetText
          If cnt = 1 Then
            If InStr(val1, val) > 0 Then flg = True
          Else
            flg = True
            For Each v In val1
              If v <> "" Then
                If InStr(val, v) = 0 Then
                  flg = False
                  Exit For
                End If
              End If
            Next v
          End If
        Else
          If mode1(0) = 2 Then flg = True
        End If
      End If

      If Selection.Address <> mode1(2) And mode1(0) <> 2 Then flg = False

      If flg Then
        Ans = MsgBox("本当に貼り付けますか?", vbYesNo, "確認")
        If Ans = vbNo Then
          MsgBox "正しいデータを貼り付けてください"
          Application.Undo
          OpenClipboard (0&)
          EmptyClipboard
          CloseClipboard
        End If
      End If
    End If
  End If
  If mode1(0) < 2 Then Call modeID(2, Target)
  Application.EnableEvents = True

End Sub

Private Sub Workbook_SheetSelectionChange(ByVal Sh As Object, ByVal Target As Range)

  Call modeID(1, Target)

End Sub

Function modeID(ID As Integer, rng As Range) As Variant
  Static CopyMode As Integer, i As Integer, tgt As String

  tgt = ""
  Select Case ID
    Case 0
      If i = 0 Then
        i = 1
      Else
        i = 0
        CopyMode = 0
      End If
    Case 1
      CopyMode = Application.CutCopyMode
      tgt = rng.Address
      i = 0
    Case 2
      i = 0
      CopyMode = 0
  End Select
  If tgt = "" Then tgt = rng.Address
  modeID = Array(CopyMode, i, tgt)

End Function


▼マナ さん:

>途中で考えるのが、いやになっちゃいます。

同感です。
途中で訳わからなくなってきました。


>選択制にしたい場合は、変数を用意して、必要に応じて、
>コピペ禁止モードを解除する運用でもよいかもしれません。
>If IsCopyOK then exit sub
>みたいな感じにすれば、学校のコードが使えるかなと思います。

完全禁止なら対処も簡単ですね。
不具合も出ないでしょうし、私も選択制をお勧めします。
8 hits

【78254】貼り付け禁止のマクロ ささ 16/6/10(金) 16:34 質問[未読]
【78257】Re:貼り付け禁止のマクロ マナ 16/6/10(金) 21:02 発言[未読]
【78259】Re:貼り付け禁止のマクロ マナ 16/6/11(土) 22:59 発言[未読]
【78260】Re:貼り付け禁止のマクロ sy 16/6/12(日) 3:05 回答[未読]
【78261】Re:貼り付け禁止のマクロ マナ 16/6/12(日) 18:23 発言[未読]
【78262】Re:貼り付け禁止のマクロ sy 16/6/12(日) 21:16 発言[未読]

4099 / 76734 ←次へ | 前へ→
ページ:  ┃  記事番号:
2610219
(SS)C-BOARD v3.8 is Free