プロが教えるわが家の防犯対策術!

入力用のエクセルの表があり、入力された数値に基づき同じシート内で計算を行い、答えを出すようしています。
入力する部分は連続しており、5列20行ほどあります。
その部分のセルのロックを解除し、シートは保護して計算式の改変を防いでいるのですが、使用者の中には入力用のセルを切り取って、別の入力用セルに貼り付ける人がいて、そんなことをされると貼り付け先を参照した計算式はREFエラーになるし、切り取られた方を参照した計算式は参照先が変わってしまいます。
結果、こんなシートは使い物にならないと文句を言われます。
。・゜゜ '゜(*/o\*)'゜゜゜・。

ならばツールバーを非表示にして、おまけにCntrl+Xのショートカットキーも無効にしてやろうかいとも考えましたが、そうすると多くのユーザーの使い勝手を阻害することになってしまいます。
多分、一番いいのは「切り取り」を察知してUndoが出来ればと思うのですが、Changeイベントでは無理ですよね?

何か良い方法はないでしょうか?

A 回答 (9件)

Tihs Workbookに、



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

If Application.CutCopyMode = xlCut Then
Application.CutCopyMode = False
End If

End Sub

と、

Private Sub Workbook_WindowDeactivate(ByVal Wn As Window)
If Application.CutCopyMode = xlCut Then
Application.CutCopyMode = False
End If

End Sub
で、よさそうだけど。
    • good
    • 0
この回答へのお礼

何度もありがとうございます。
同一シート内のみならず他BOOKへの「切り取り」&「貼り付け」の手当てをしていただき感謝いたします。
以下のようにしてうまくいきました。

Private Sub Workbook_SheetSelectionChange(ByVal Sh As Object, ByVal Target As Range)
If Application.CutCopyMode = xlCut Then
MsgBox "ごめん、「切り取り」されると困るんですぅ!", vbCritical, " (;≧o≦)ノ"
Application.CutCopyMode = False
End If
End Sub

Private Sub Workbook_SheetActivate(ByVal Sh As Object)
If Application.CutCopyMode = xlCut Then
MsgBox "ごめん、「切り取り」されると困るんですぅ!", vbCritical, " 他のSheetに? (;≧o≦)ノ"
Application.CutCopyMode = False
End If
End Sub

Private Sub Workbook_WindowDeactivate(ByVal Wn As Window)
If Application.CutCopyMode = xlCut Then
MsgBox "ごめん、「切り取り」されると困るんですぅ!", vbCritical, " 他のBOOKに? (;≧o≦)ノ"
Application.CutCopyMode = False
End If
End Sub

 (o。_。)oペコッ

お礼日時:2009/03/03 10:18

セルをドラッグ&ドロップされたらだめなのでは?


数式を再セットするほうが良いと思いますけど。

一例で、
Sub sample(flg As Boolean)
Static strFormula() As String
Dim rng As Range
Dim i As Integer

With ActiveSheet.Cells.SpecialCells(xlCellTypeFormulas, 23)
i = 1
If flg Then
ReDim strFormula(1 To .Count)
For Each rng In .Cells
strFormula(i) = rng.Formula
i = i + 1
Next
Else
Application.EnableEvents = False
For Each rng In .Cells
If rng.Formula <> strFormula(i) Then rng.Formula = strFormula(i)
i = i + 1
Next
Application.EnableEvents = True
End If
End With
End Sub

↓シートモジュールに
Private Sub Worksheet_Activate()
Call sample(True)
End Sub

Private Sub Worksheet_Change(ByVal Target As Range)
Call sample(Target.HasFormula)
End Sub

一応動きますが、不完全なのでジャンク扱い(動作保障無し)で。

考え方としては、
(1)作成済み数式を文字列で取得。
(2)その数式文字列をどこかに記録。
上記コードでは配列変数を使ってるが、未使用セルに書き出したほうがいい。
(3)数式が変更されてしまったら、記録した文字列から復元。

(1)(2)は、最初に1回実行、あとは数式を手直ししたときに実行するだけ。
(3)は、イベントまたは手動で。

やっぱりきついですか?
    • good
    • 0
この回答へのお礼

NNAQさま、貴重なご意見ありがとうございます。
ご回答に気づかず、お礼が遅くなりましたことを御詫び申し上げます。

たしかに、セルをドラッグ&ドロップされた同じことなんですが、これはオプションの設定でドラッグ&ドロップを禁じてしまえば対処は可能です。
ただ、ツールバーを隠したり、シュートカットを無効にしたり、そしてドラッグ&ドロップを禁じたら、そんなシートで誰も作業したくなくなりますよね。

やはりおしゃるように数式を再セットするほうが良いのかなと思い始めております。
他にも使用する方々からさまざまな意見がきていますので、もうすこし考えてみようと思います。
ご提示のコード、まだまだ浅学非才なわたくしめにはわからないことだらけですが、数式を再セット方式と決めたらまた質問させていただくと思います。
その節は宜しくお願いいたします。

今回はここで一旦締め切りたいと思います。
ありがとうございました。

お礼日時:2009/03/06 14:05

こんちには。



>Application.OnKey "^{x}", ""

Application.OnKey "^x", ""

>Ctrl + x が押されたときにメッセージを出すマクロを割り当てることですね?

ということです。

>メニューバーから「切り取り」指示がされた場合の対応のことなのでしょうか?

そのとおりです。メニューの編集の中の「切り取り」と右クリックメニューの「切り取り」のことです。クラスで、「コマンドボタン」に付け加えます。私は、既存のイベントにはつけません。
    • good
    • 1
この回答へのお礼

なんどもありがとうございます。
クラス・・・・
わたしにはまだまだついていけない分野のようです。

ありがとうございました。

お礼日時:2009/03/03 17:29

こんにちは。



>「切り取り」を封じたいのですが、切り取られたことを取得する方法がわからなかったのです。

あえてコードを書く必要はないと思いますが、私は、通常は、Ctrl + X のようなショートカットは、Auto_Openの中に、OnKey で、新たに設定させ、他のイベントは使いません。ブックを限定する場合は、DeActivate,Activate によってオン・オフをさせます。

ショートカットを封じるには、ダミーのプロシージャ・マクロを置きます。ここにメッセージを出してもよいと思います。また、コマンドは、コマンドボタン側にクラスのインスタンスを設けるようにします。
    • good
    • 0
この回答へのお礼

何度もありがとうございます。
Application.OnKey "^{x}", "" でCtrl + x を無効にする方法は存じているのですが、今回は操作性の点でまさかメニューバーまで消すわけにもいかないので困っていたのです。

> ショートカットを封じるには、ダミーのプロシージャ・マクロを置きます。ここにメッセージを出してもよいと思います。

Ctrl + x が押されたときにメッセージを出すマクロを割り当てることですね?

> また、コマンドは、コマンドボタン側にクラスのインスタンスを設けるようにします。

この意味がわかりませんでした。メニューバーから「切り取り」指示がされた場合の対応のことなのでしょうか?

お礼日時:2009/03/03 10:55

下記で、切取りを取得できませんか。



Private Sub Worksheet_SelectionChange(ByVal Target As Range)

If Application.CutCopyMode = xlCut Then
MsgBox "cut"
End If

End Sub
    • good
    • 0
この回答へのお礼

そうなんですね!
セレクションチェンジの時にCutCopyModeがxlCutになってればまさに「切り取り」しようとしてるんですよね。

okormazdさま、ありがとうございました!!

お礼日時:2009/03/03 10:14

こんにちは。



落雷で外国のマーライオンさんは壊れたそうですが、お元気ですか?

>一番いいのは「切り取り」を察知してUndoが出来ればと思うのですが、Changeイベントでは無理ですよね?

ということは、Change イベントはともかくとして、Ctrl + Xでは、Cut するだけで、Undo を発生させたら、その手前に戻ってしまいます。おそらく、貼り付け時に、Undo するということではないでしょうか。でも、それは、「切り取り」を封じているということと同じではありませんか?そのブックだけ、ショートカットの「切り取り」を封じてしまってもよいと思いますし、そのブックに限定させ、数式にのみに、「切り取り」を封じてしまっても、問題はないのではありませんか?

しょせん、一部のワカランチンから文句言われるぐらいなら、メッセージを出して、こうなると事前に通告してもよいとは思います。
    • good
    • 0
この回答へのお礼

Wendy02さま、いつもありがとうございます。
はい、実家のMerlionは右耳を怪我したそうでが、わたしは至って元気です(笑)

「切り取り」を封じたいのですが、切り取られたことを取得する方法がわからなかったのです。
でもやっとわかりました。
Undoは必要なかったですね。
ありがとうございます。

お礼日時:2009/03/03 10:11

切り取り機能自体を封印すると操作性が悪化しますので、


逆の発想で、計算式のセルを再セットするマクロを作成しては
いかがでしょうか。これで変更されても復元させる訳です。

まず、エクセルのシートに名前をつけます。
(デフォルトでSheet1等の名称となっている部分です)

次にマクロ機能を使い、簡単な実行プログラムを作成します。
マクロ機能といっても簡単なコードしか使用しなくて済むため、
未経験でもすぐに着手が可能かと思われます。

Excel VBA についての知識は以下のサイトがお勧めです。

■Excel VBA 入門講座
http://excelvba.pc-users.net/

まず、マクロを記述するためのVisual Basic Editor を起動します。
起動方法については以下のページが参考になります。

■Excel VBA 入門講座 | Visual Basic Editorの起動
http://excelvba.pc-users.net/fol1/1_1.html

マクロに記述する機能はただ一つ。
『セルの指定とプロパティセット』というものです。
この機能については以下のページが参考になります。

■Excel VBA 入門講座 | セルの指定とプロパティセット
http://excelvba.pc-users.net/fol2/2_1.html

具体的に言うと、以下のようなコードを記述していきます。
-----------------------------------------------------
Worksheets("シート名").Activate
Worksheets("シート名").Cells(1,21).Value="=SUM(A1:A20)"
Worksheets("シート名").Cells(5,21).Value="=SUM(E1:E20)"
…(以降同様)
-----------------------------------------------------

1行目の記述は指定したシートをアクティブにするものです。
2行目以降の記述は指定したシート『Worksheets("シート名")』
の、指定したセル『.Cells(X,Y)』を、Valueで指定した値
『.Value="セルの値"』に書き換えるといった物です。

2行目と同様の行を作成していき、指定するセルの番号と、
セットする値を書いていくことで全ての計算セルを埋めます。

このマクロを実行すると、プログラムで記述されたセルが一斉に
指定された値に置き換わるので、計算式を含むセルが変更されても
一括で指定した状態に戻すことができるようになります。

もちろん使用者が間違って切り取ってセル内容を消失していても、
マクロを実行すれば管理者も、利用者も簡単に復元できますね。

このマクロの実行は、エクセルシート内にボタンを作成して、
そのボタンを押すだけでマクロを実行するように登録もできます。
VBAマクロボタンについては以下のページを参照下さい。

■印刷のテクニック EXCEL編 VBAマクロボタン
http://homepage1.nifty.com/tabotabo/insat/excelp …

以上の方法であれば、わざわざ切り取り操作を復元したり、
切り取り操作を察知してUndoするような高度なプログラムを
作成する必要はありませんし、エクセルシート側には特定セルに
編集ロックをかけておくだけで良くなります。

VBAに慣れてきたら、たとえば計算式以外のセルをボタン押下で
すべて初期状態にリセットするボタンを作成してみたり、
勤怠票であれば日付を見て1日~31日の曜日を振ってみたり、
土日祝のセルに背景色をつける、といったマクロ機能を作成したりと
応用もできますし、興味があれば挑戦していただければと思います。
    • good
    • 0
この回答へのお礼

なるほど・・・。
たしかに計算式でREFエラーがでたら「復元」ボタンを押させるという手がありますね。
検討します。
ありがとうございます。

ただ、イベントで「切り取り」を取得できさえすればUndoのプログラムはさして難しいものではないんですが。むしろ数多の計算式を復元させる方が全部で30シートあるBOOKなのできついです。

お礼日時:2009/03/02 13:42

入力するセルの座標が固定であれば、こんな方法もあります。



例 : A1~C3に入力するとして、A7~C10でそれを呼び出すとします。
まず、A4~C6に、それぞれA1~C3の参照名をデータとして入れた
文字列を入れておき、隠しておきます。
A7~C10で、INDIRECT(A4)~INDIRECT(C6)という風にして呼び出すと
A1~C3の所で切り取り貼り付けを行われてもA7~C10で得られる参照結果は変わりません。

切り取りされても問題がないようにする、という別のアプローチ方法ですが、
参考になれば幸いです。
    • good
    • 0
この回答へのお礼

そうか、直接セル番地を指定しないという方法もありですね。
前面作り直しになるのがちときついですが・・・。
(全部で30シートあるんです!)

お礼日時:2009/03/02 13:37

シートを保護し、入力用のシート(または入力フォーム)を別に作成。


入力完了後にマクロで指定した保存シートに追加していく形式に変更しては?

入力後の結果表示が必要なら、計算結果を表示するマクロをつけ足せばよいかと。
    • good
    • 0
この回答へのお礼

ありがとうございます。
たしかにすべての入力が終わってから計算させるだけでよければそういう方法も取れますね。

ただ、今回は入力している途中にも途中までの計算結果を確認させるのでこれは使えそうもありません。
すみません。
でも今後の参考にします。
ありがとうございました。

お礼日時:2009/03/02 13:36

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!


このQ&Aを見た人がよく見るQ&A