- 締切済み
VBA2010,B3の値が変わったら、A3に
VBA2010で,B列の値が変わったら、A列の同じ行に前日の日付を入力するには、マクロコードをどのように書けばよいですか?B列データ入力範囲はB3~B65536 尚、B3~B65536にはVLOOKUPで、他のブックから値を参照しています。 最後にA列の同じ日付セルを結合し、I列、P列、W列の同じ行に結合したセルをペーストたいのです。 宜しくお願い致します。
- みんなの回答 (4)
- 専門家の回答
みんなの回答
- don9don9
- ベストアンサー率47% (299/624)
今回日付を入れたいブック(以後ブックAとします)と納品.xlsxは、どういう使い方をするのでしょうか? 一人の人が二つのブックを同時に開いて使用するのでしょうか? 同時に開くことはない、あるいは同時に開くとしても別々の人が使用するものでしょうか? 前者であれば、納品.xlsxのWorkSheet_Changeイベントで、ブックAに日付を書き込むようにする。 Workbooks("ブック名").WorkSheets("シート名").Cells(行,列) = DateAdd("d", Now(), -1) のように、頭に「Workbooks("ブック名").」をつければ別のブックに書き込むことは可能です。 ただし、書き込み対象のブックが開かれていないとエラーになります。 後者であれば、ブックAのWorkbook_Openイベントでブックオープン時のB列の値を別シートに保持しておき、マクロなりボタンなりにリンクの更新と保持した値との比較、日付入力を一連の処理として設定し、そこから実行する。 この場合、ブックAを開く際にはリンクの更新をしないようにする必要があります。 リンクの更新は ThisWorkbook.UpdateLink Name:=ファイル名(納品.xlsxをフルパスで指定), Type:=xlExcelLinks
- Siegrune
- ベストアンサー率35% (316/895)
Excel2010が手元にないので、手元にあったExcel2003では、 ThisWorkBookのモジュール内に、 Workbook_SheetCalculate というのがあって、その中にやりたい処理を記載すれば、できるかも。 例) Private Sub Workbook_SheetCalculate(ByVal Sh As Object) MsgBox ("AAA") End Sub あるいは、各シートのモジュール内に Worksheet_Calculate() というのがあるのでここでも、同様。 但し、再計算されたというイベントしか拾えず、 どのセルが再計算されたかはわかりません。 ※Excel2010で、再計算されたセルの値が取れるかどうかは確認願います。 Worksheet_Calculate(ByVal Target As Range)とかになっていればとれるはずですが、 タブンだめかな。 B列の変更前の値を別のシートにコピーしておいて、 このモジュール内で、比較する。 値が変わっていたら、A列の同じ行に・・・をするとともに、 B列の変更後の値を別のシートにコピーする といった手間のかかる作業が必要になります。 (=重たい処理なのでレスポンスが悪い) 他のブックの値を変更するたびにこの処理が動きかねないので、 ボタンを作ってボタンを押したときに処理を実行させた方がいいと思われます。 以上参考まで。
- don9don9
- ベストアンサー率47% (299/624)
仮にB列の数式が同じ行のC列の値をキーに別ブックの表を引いているとすれば、C列の値の変更を拾って Private Sub Worksheet_Change(ByVal Target As Range) Dim 範囲 As Range Dim 行番号 As Long If Intersect(Target, Range("C3:C65535")) Is Nothing Then Exit Sub For Each 範囲 In Target 行番号 = 範囲.Row Sheet1.Cells(行番号, 1) = DateAdd("d", Now(), -1) Next End Sub のような形でとりあえず似たような動きをすると思いますが、これは厳密には要求通りではありません。 C列の値が変更されても、数式の計算の結果B列の値が変わらない場合があるからです。 厳密にやろうとするならば 1.ファイルオープン時点でB列の値を全部別シートに保存しておく 2.シートの値が変更された時に保存しておいた別シートの値と比較する といった処理が必要になってくると思います。 Sheet2がB列の値の保存先シートとして、ThisWorkbookに Private Sub Workbook_Open() Sheet2.Range("B:B").Value = Sheet1.Range("B:B").Value End Sub Sheet1に Private Sub Worksheet_Change(ByVal Target As Range) Dim 範囲 As Range Dim 行番号 As Long If Intersect(Target, Range("C3:C65536")) Is Nothing Then Exit Sub For Each 範囲 In Target 行番号 = 範囲.Row If IsError(Sheet1.Cells(行番号, 2)) = IsError(Sheet2.Cells(行番号, 2)) Then If Sheet1.Cells(行番号, 2) <> Sheet2.Cells(行番号, 2) Then Sheet1.Cells(行番号, 1) = DateAdd("d", Now(), -1) End If Else Sheet1.Cells(行番号, 1) = DateAdd("d", Now(), -1) End If Next End Sub といった感じでしょうか。 B列の数式の内容によっては使えないかもしれませんが。
- mindatg
- ベストアンサー率48% (110/227)
参考だけ。 B列の値が変更された際のみ検知すりゃいいので セルの値が変更された際のイベントを拾います。 ' ワークシート上のセル値が変更された場合 Private Sub Worksheet_Change(Byval Target As Range) ' B列以外なら処理せず終了 If Target.Column <> 2 Then Exit Sub ' 3~65536行以外の範囲なら処理せず終了 If Target.Row < 3 And Target.Row > 65536 Then Exit Sub ' セル番地 Bxxx から列をひとつ手前にしたセル番地の値を変更する Target.Offset(0, -1).Value = 前日の日付 ' 以後省略 End Sub 質問内容の表現が何のこっちゃだった為、後半は省略しています。 自分でなんとかしてください、結合してペースト程度なら猿でもできるほど簡単です
補足
当方の環境ではB列に関数(VLOOKUP、LOOKUP)などを使用していると、元シート値が変わっても、mindatgさんのコードでは、動きませんでした。 質問内容・表現力に不明な点お詫びいたします。 mindatgさんのコードを参考に考えてみます。 ありがとうございました。
補足
ありがとうございます。 B列には次の式が入っています。='[納品.xlsx]2013'!$B03 他のブックを読みに行っているため、納品.xlsxの値が変化しても、動きませんでした。私のスキルでは、限界です。宜しく、アドバイス願います。