Excel VBA質問箱 IV

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

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


674 / 13645 ツリー ←次へ | 前へ→

【79047】VBAを用いて日付を自動判別して、その横に貼り付けたい せいじ 17/4/20(木) 14:12 質問[未読]
【79048】Re:VBAを用いて日付を自動判別して、その横... マナ 17/4/20(木) 20:10 発言[未読]
【79052】Re:VBAを用いて日付を自動判別して、その横... せいじ 17/4/21(金) 16:49 発言[未読]
【79053】Re:VBAを用いて日付を自動判別して、その横... マナ 17/4/21(金) 18:59 発言[未読]
【79054】Re:VBAを用いて日付を自動判別して、その横... せいじ 17/4/21(金) 20:29 発言[未読]
【79055】Re:VBAを用いて日付を自動判別して、その横... マナ 17/4/21(金) 21:01 発言[未読]
【79056】Re:VBAを用いて日付を自動判別して、その横... せいじ 17/4/22(土) 10:31 発言[未読]
【79057】Re:VBAを用いて日付を自動判別して、その横... マナ 17/4/22(土) 11:27 発言[未読]
【79058】Re:VBAを用いて日付を自動判別して、その横... せいじ 17/4/22(土) 13:30 発言[未読]
【79059】Re:VBAを用いて日付を自動判別して、その横... マナ 17/4/22(土) 14:13 発言[未読]
【79060】Re:VBAを用いて日付を自動判別して、その横... せいじ 17/4/22(土) 14:26 発言[未読]
【79061】Re:VBAを用いて日付を自動判別して、その横... マナ 17/4/22(土) 14:47 発言[未読]
【79062】Re:VBAを用いて日付を自動判別して、その横... マナ 17/4/22(土) 15:08 発言[未読]
【79063】Re:VBAを用いて日付を自動判別して、その横... せいじ 17/4/24(月) 8:22 発言[未読]
【79064】Re:VBAを用いて日付を自動判別して、その横... せいじ 17/4/24(月) 8:59 発言[未読]
【79066】Re:VBAを用いて日付を自動判別して、その横... マナ 17/4/24(月) 20:18 発言[未読]
【79067】Re:VBAを用いて日付を自動判別して、その横... マナ 17/4/24(月) 21:05 発言[未読]
【79068】Re:VBAを用いて日付を自動判別して、その横... せいじ 17/4/25(火) 9:04 発言[未読]
【79070】Re:VBAを用いて日付を自動判別して、その横... マナ 17/4/25(火) 19:42 発言[未読]
【79071】Re:VBAを用いて日付を自動判別して、その横... せいじ 17/4/25(火) 20:43 発言[未読]
【79072】Re:VBAを用いて日付を自動判別して、その横... マナ 17/4/25(火) 20:52 発言[未読]

【79047】VBAを用いて日付を自動判別して、その横...
質問  せいじ E-MAIL  - 17/4/20(木) 14:12 -

引用なし
パスワード
   エクセルのVBAについての質問です。
シート1を入力フォームとして使用します。
シート2に入力フォームの内容を転記します。

入力フォームには

日付:内容1:内容2:・・・・

といった形で入力していきます。

シート2には

日付:内容1:内容2:・・・・
日付:内容1:内容2:・・・・



(1か月分)
といったフォームを予め用意してあります。

入力フォームで入力した内容をシート2に転記したいのですが、
その際に、日付を自動判別してシート2の該当日付の内容に転記できるよう
VBAを組みたいと思っています。

使用するメソッドはfindメソッドでいいと思うのですが、findメソッドで
判別したセルの横をselectする方法がわかりません。

わかる方がいらっしゃれば教えて頂きたい思います。
よろしくお願いいたします。

【79048】Re:VBAを用いて日付を自動判別して、その...
発言  マナ  - 17/4/20(木) 20:10 -

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

こんな感じでしょうか

set f=Sheets("sheet2").Columns(1).find(…
f.offset(,1).value=…
とか
f.entirerow.range("b1").value=…

-------

findのかわりに、matchでもよいです

m=application.match(…
Sheets("sheet2").cells(m, "b").value=…

------
あるいは、日付なら、検索しなくても行番号がわかるのでは?
2行目から日付がはじまるなら、こんな感じで。
r=Day(日付)+1
Sheets("sheet2").cells(r, "b").value=…

【79052】Re:VBAを用いて日付を自動判別して、その...
発言  せいじ E-MAIL  - 17/4/21(金) 16:49 -

引用なし
パスワード
   早速の回答ありがとうございました。
私の質問の方法がわかりくかったので例を出しながら書いてみます。

現在作っているのは出勤表です。
シート1では前日の勤務内容・売上金額等を担当者毎に入力します。
シート2以降では各担当者の当該月の出勤状況が見られるようにします。

シート1に入力された内容はマクロボタンを押すと、シート2の該当箇所に
転記されるようなVBAを組みたいと思っています。

(シート1例)
           日付  勤務時間  現場  売上
担当者名:川田  1/1  8時〜5時  町田市 150,000   ボタン
担当者名:田中  1/1  8時〜5時  日野市 100,000   ボタン

*出勤表入力は毎日行います。その為日付は毎日変わります。

(シート2例)
日付  勤務時間  現場  売上
1/1 
1/2
1/3
1/4
.
.
.
.

*予め、日付だけは入力しておきます。

以上のようなシートを用意しておきます。
シート1の内容を各担当者のシートに転記するのは簡単ですが、
問題はどの列に転記するかということになります。
そこで基準となるのが日付です。シート1に入力された日付を自動で判別して
シート2の該当する日付の横に内容を転記するVBAを作成したいのです。
たとえば上記の例だと、シート1の入力フォームには1/1となっているので、
シート2の1/1の横に転記され、翌日1/2に入力すればシート2の1/2の横に
転記されるようなものです。
以下に作成途中のコードを記載します。

sub test35 ()
dim rng as range  ←勤務時間・現場・売上の内容を変数にします。
dim dat as date   ←シート1の日付を変数にします。
dim rng2 as range  ←シート2の日付列を変数にします。

set rng = range(勤務時間〜売上のセル範囲)
set dat = range(シート1の日付のセル)
set rng2 = Range("シート2日付列").Find(What:=dat)

rng.copy Destination:=worksheet("川田").rng2.offset(0,-1)

勤務時間以下の内容をコピーして、川田シートのfindメソッドで見つかったセルの
一つ左のセルに貼り付け

…でうまくいきませんでした。
そもそもの考え方が間違っているのでしょうか?

長くなってしまい申し訳ございません。
もしお助けいただけるのであれは、よろしくお願いいたします!

【79053】Re:VBAを用いて日付を自動判別して、その...
発言  マナ  - 17/4/21(金) 18:59 -

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

>見つかったセルの一つ左のセルに貼り付け

左ではなく、右では?

-------
本題と関係ないですが…

人数分ボタンを用意しようとしていませんか。
一人ずつ転記するなら、入力フォームは1行分あればよいのでは?
まとめて転記するなら、ボタンは一つでよいのでは?

と思ってしまいます。

【79054】Re:VBAを用いて日付を自動判別して、その...
発言  せいじ  - 17/4/21(金) 20:29 -

引用なし
パスワード
   ご指摘の通り右のセルです、すいません!

ボタンの件ですがこちらもご指摘の通り、
本当は入力したものがそれぞれの担当者ごとの
シートに一括で転記されるのが望ましいのですが、
そうすると、worksheetもfindメソッドで探さなければ
ならなくなり、私のスキルでは無理そうなので、
とりあえず一担当者毎に作ろうと思いまして。

【79055】Re:VBAを用いて日付を自動判別して、その...
発言  マナ  - 17/4/21(金) 21:01 -

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

何をしているかわかりますか


Option Explicit

Sub test()
  Dim ws入力 As Worksheet
  Dim ws転記 As Worksheet
  Dim c As Range
  Dim 転記行 As Long
  
  Set ws入力 = Worksheets("入力フォーム")
  
  For Each c In ws入力.Range("B2", ws入力.Range("B" & Rows.Count).End(xlUp))
    Set ws転記 = Nothing
    On Error Resume Next
    Set ws転記 = Worksheets(c.Value)
    On Error GoTo 0
    If Not ws転記 Is Nothing Then
      転記行 = Day(c.Offset(, 1).Value) + 1
      ws転記.Range("B" & 転記行).Resize(, 3).Value = c.Offset(, 2).Resize(, 3).Value
    End If
  Next
  
End Sub

【79056】Re:VBAを用いて日付を自動判別して、その...
発言  せいじ E-MAIL  - 17/4/22(土) 10:31 -

引用なし
パスワード
   返信ありがとうございます!
確認しました。

Dim ws入力 As Worksheet
  Dim ws転記 As Worksheet 
  Dim c As Range
  Dim 転記行 As Long
  
  Set ws入力 = Worksheets("入力フォーム")
  
  For Each c In ws入力.Range("B2", ws入力.Range("B" & Rows.Count).End(xlUp))
”入力フォームのB2セルからB列全てのセルから、Cを取出し”

    Set ws転記 = Nothing
”ws転記”のオブジェクト参照を解除(これは何のためでしょうか?)

    On Error Resume Next
    Set ws転記 = Worksheets(c.Value)
    On Error GoTo 0
”ws転記を変数Cの値のワークシートとする”(すいません、わからないです。)
”エラー発生時には以下より再開する”

    If Not ws転記 Is Nothing Then
”ws転記がnothingでなかったら”(入力があったらという意味?)

      転記行 = Day(c.Offset(, 1).Value) + 1
”変数Cの一つ右のセルの値に1を足す(この場合は日付ですね)

      ws転記.Range("B" & 転記行).Resize(, 3).Value = c.Offset(, 2).Resize(, 3).Value
”ws転記のB列と変数転記行の・・・
(このコード意味は理解できませんでした。)
    
End If
  Next
  
End Sub

ここで変数Cはどのように代入するのでしょうか?
VBA知識が足りず申し訳ございません。
色々と調べたのですがわかりませんでした。

【79057】Re:VBAを用いて日付を自動判別して、その...
発言  マナ  - 17/4/22(土) 11:27 -

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

B2に、「川田」
C2に、「1/1」

だとして、これで、1人分のデータの転記です。


Sub test2()
  Dim ws転記 As Worksheet
  Dim 転記行 As Long
 
  Set ws転記 = Worksheets(Worksheets("入力フォーム").Range("B2").Value)

  転記行 = Day(Worksheets("入力フォーム").Range("C2").Value) + 1
  
  ws転記.Range("B" & 転記行 & ":D" & 転記行).Value = Worksheets("入力フォーム").Range("D2:F2").Value
 
End Sub


↓が転記でよく使わる構文です。

転記先.Value=転記元,Value

もちろん、

転記元,Copy 転記先

でもできます。

まずは、ここまで理解できますか。

【79058】Re:VBAを用いて日付を自動判別して、その...
発言  せいじ E-MAIL  - 17/4/22(土) 13:30 -

引用なし
パスワード
   以下の解釈で合っていますでしょうか?

Set ws転記 = Worksheets(Worksheets("入力フォーム").Range("B2").Value)

ws転記を入力フォームのB2の値とする。

  転記行 = Day(Worksheets("入力フォーム").Range("C2").Value) + 1

転記行は入力フォームのC2の値(日付)に1を足したもの?
  
  ws転記.Range("B" & 転記行 & ":D" & 転記行).Value = Worksheets("入力フォーム").Range("D2:F2").Value
 
転記先のBセルと転記行とDと転記行?を入力フォームのD2〜F2セルを転記する。

・ws転記はワークシートなのにrange"B2"の値を代入出来るのですか?
・転記行に+1する理由は何でしょうか?

【79059】Re:VBAを用いて日付を自動判別して、その...
発言  マナ  - 17/4/22(土) 14:13 -

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


>ws転記を入力フォームのB2の値とする。

少し違うかも。B2が「山田」なら

Set ws転記 = Worksheets(Worksheets("入力フォーム").Range("B2").Value)

は、

Set ws転記 = Worksheets("山田")

と同じです。

>・ws転記はワークシートなのにrange"B2"の値を代入出来るのですか?


ws転記に代入しているのではなく、ワークシート名にB2の値を使っています。

B2の値を名前とするワークシートをws転記に代入しているのです。

-----

>転記行は入力フォームのC2の値(日付)に1を足したもの?
>・転記行に+1する理由は何でしょうか?

もし、転記先が2行目から始まっているなら、
何月であっても、日+1が転記先の行番号になりませんか。

1日なら、2行目
2日なら、3行目
3日なら、4行目
4日なら、5行目

31日なら、32行目

-----
>転記先のBセルと転記行とDと転記行?を入力フォームのD2〜F2セルを転記する。

転記先.Value=転記元.Value

なので、

ws転記の転記行のB〜D列に、入力フォームのD2〜F2セルを転記する。

です。「左辺に右辺を代入する」です。

>Range("B" & 転記行 & ":D" & 転記行)

の部分は、もし、日付が1/2なら、転記行は3になるので、

Range("B3:D3")

と同じことになります。

ここまで、理解できましたか。

【79060】Re:VBAを用いて日付を自動判別して、その...
発言  せいじ  - 17/4/22(土) 14:26 -

引用なし
パスワード
   詳しいご説明ありがとうございます!
ここまでは理解できました!

セルに入力された文字や値をそのまま使えるということですね!

【79061】Re:VBAを用いて日付を自動判別して、その...
発言  マナ  - 17/4/22(土) 14:47 -

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

では、次ですが、

>> ws転記.Range("B" & 転記行).Resize(, 3).Value = c.Offset(, 2).Resize(, 3).Value

>(このコード意味は理解できませんでした。)

Offsetは、理解できているとして、

あわせてよく使われるものにResizeがあります。
test3 を ステップ実行で、確認してみてください。
ステップ実行わかりますよね。

Sub test3()

  Range("B2").Select
  Range("B2").Offset(, 1).Select
  Range("B2").Offset(, 1).Resize(, 3).Select

End Sub


ht tp://excel-ubara.com/excelvba4/EXCEL210.html

-----

で、OffsetとResizeを使って、test2を書き直すと

Sub test4()
  Dim ws転記 As Worksheet
  Dim 転記行 As Long
 
  Set ws転記 = Worksheets(Worksheets("入力フォーム").Range("B2").Value)

  転記行 = Day(Worksheets("入力フォーム").Range("C2").Value) + 1
  
  ws転記.Range("B" & 転記行).Resize(, 3).Value = Worksheets("入力フォーム").Range("B2").Offset(, 2).Resize(, 3).Value
 
End Sub

になります。
OffsetとResizeは、今後も必ず使うと思います。ぜひ理解してください。

ここまで理解できましたか。

【79062】Re:VBAを用いて日付を自動判別して、その...
発言  マナ  - 17/4/22(土) 15:08 -

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

test4 は、test5 にすべきでした。
どこを変えたかわかりますね。

Sub test5()
  Dim ws転記 As Worksheet
  Dim 転記行 As Long
 
  Set ws転記 = Worksheets(Worksheets("入力フォーム").Range("B2").Value)

  転記行 = Day(Worksheets("入力フォーム").Range("B2").Offset(, 1).Value) + 1
  
  ws転記.Range("B" & 転記行).Resize(, 3).Value = Worksheets("入力フォーム").Range("B2").Offset(, 2).Resize(, 3).Value
 
End Sub

【79063】Re:VBAを用いて日付を自動判別して、その...
発言  せいじ E-MAIL  - 17/4/24(月) 8:22 -

引用なし
パスワード
   おはようございます。
出張で2日ほど留守にしてしまいました。

早速ですが、引き続き解説ありがとうございます。

resizeの使い方を確認しました。
offsetで選んだセル範囲を拡大(縮小)することができるのですね!

sub test5を以下に記述してみます。

Dim ws転記 As Worksheet
Dim 転記行 As Long
 
Set ws転記 = Worksheets(Worksheets("入力フォーム").Range("B2").Value)
「ws転記は入力フォームのB2に入力された値と同じワークシート名とする。」

転記行 = Day(Worksheets("入力フォーム").Range("B2").Offset(, 1).Value) + 1
「転記行は入力フォームB2の一つ右のセルに入力された値(日付)に1を足した整数」
  
ws転記.Range("B" & 転記行).Resize(, 3).Value = Worksheets("入力フォーム").Range("B2").Offset(, 2).Resize(, 3).Value
「ws転記のB列と転記行の右3つのセル範囲の値を入力フォームのB2の2つ右のセルから3つ分(←つまりD2からG2までです)の値と同じにする。

この解釈で大丈夫でしょうか?

【79064】Re:VBAを用いて日付を自動判別して、その...
発言  せいじ E-MAIL  - 17/4/24(月) 8:59 -

引用なし
パスワード
   ws転記.Range("B" & 転記行).Resize(, 3).Value = Worksheets("入力フォーム").Range("B2").Offset(, 2).Resize(, 3).Value

このコードの
ws転記.Range("B" & 転記行)
"B"を仮に"C"に変えるとCセルへ転記されるのですね。
range(a & a)構文は基本同様の使い方になるのでしょうか?

重ね重ねすいません。

【79066】Re:VBAを用いて日付を自動判別して、その...
発言  マナ  - 17/4/24(月) 20:18 -

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

Rangeの使い方としては、

1)こんな感じで、Range()の中にセルアドレスをあらわす文字列を入れる方法
Range("B2")
Range("B2:D2")
Range("B2","D2")

2)または、Rangeオブジェクトを入れる方法
Range(Rage("B2"),Range("D2"))
Range(Cells(2, 2), Cells(2, 4))

3)1)と2)のあわせ技で、文字列とRange オブジェクトを入れる方法
Range("B2", Range("B" & Rows.count).End(xlup))

があります。

で、今回使っているのは1)の文字列でセルを指定する方法です。
3)の方法も、あとで使うことになります。


-----
つまり、

Range("B" & 転記行)

この( )内の、"B" & 転記行 は、セルアドレスを示す文字列ということです。

「&」は、前後の文字列を連結するという意味で、

転記行が2に決っているなら、「&」なんて使わなくても
"B2" という文字列をRange()の中に入れ
Range("B2")
と書けばよいのですが、

実際は、日付によって数字部分が変化するので

"B" & 転記行

とすることで、

転記行が3の場合は、Range("B3")
転記行が5の場合は、Range("B5")

となります。
こんな感じで、「転記行」という変数を使えば
日付がいつであっても、目的のセルに転記できるようになります。

>"B"を仮に"C"に変えるとCセルへ転記されるのですね。

それで間違いありません。
なぜそうなるか理解できますよね。

【79067】Re:VBAを用いて日付を自動判別して、その...
発言  マナ  - 17/4/24(月) 21:05 -

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

ここまで理解できたとして

test5 で、

> Worksheets("入力フォーム").Range("B2")

が何度もできてくるので、こういうときも変数を使うとよいです。
こんな感じです。

Sub test6()
  Dim ws入力 As Worksheet
  Dim ws転記 As Worksheet
  Dim c As Range
  Dim 転記行 As Long
 
  Set ws入力 = Worksheets("入力フォーム")
 
  Set c = ws入力.Range("B2")
  
  Set ws転記 = Worksheets(c.Value)

  転記行 = Day(c.Offset(, 1).Value) + 1
  ws転記.Range("B" & 転記行).Resize(, 3).Value = c.Offset(, 2).Resize(, 3).Value
 
End Sub


だんだん、最初に提示したコードに近づいているのがわかりますか。
このあと、test6 に繰り返し処理を追加することになります。

【79068】Re:VBAを用いて日付を自動判別して、その...
発言  せいじ E-MAIL  - 17/4/25(火) 9:04 -

引用なし
パスワード
   おはようございます。

rangeの使い方理解しました。
例えばA3セルを選択したい場合は、
range("A3")やrange("A" & "3")でも使えるということですね。

変数についてはなかなか難しいですね。
何を変数とするかは今後多くのVBAを作り慣れていかないとダメだなと思いました。
ただヒントとしてはコードの中で多く出てくるものは変数に
置き換えて簡略化できるということはわかりました。

【79070】Re:VBAを用いて日付を自動判別して、その...
発言  マナ  - 17/4/25(火) 19:42 -

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

では、次です。

test6 だと、転記できるは、1人分(B2の行)のみです。
これを、3人分(B2、B3、B4の行)のデータを転記できるようにします。

For each〜Nextという繰り返し処理の構文を使います。
ht tp://kabu-macro.com/word/a-z/for_each_next.html

Sub test7()
  Dim ws入力 As Worksheet
  Dim ws転記 As Worksheet
  Dim c As Range
  Dim 転記行 As Long
 
  Set ws入力 = Worksheets("入力フォーム")
  
  For Each c In ws入力.Range("B2:B4")

    Set ws転記 = Worksheets(c.Value)
  
    転記行 = Day(c.Offset(, 1).Value) + 1
    ws転記.Range("B" & 転記行).Resize(, 3).Value = c.Offset(, 2).Resize(, 3).Value
  
  Next

End Sub

test6 と見較べてください。

> For Each c In ws入力.Range("B2:B4")

ws入力.Range("B2:B4")のセル範囲から順番に、B2、B3、B4をとりだし、
c という変数に代入することで
繰り返し処理ができるのです。

ここまで、よいですか。
大事なところなので、わからなければ、言ってください。

【79071】Re:VBAを用いて日付を自動判別して、その...
発言  せいじ E-MAIL  - 17/4/25(火) 20:43 -

引用なし
パスワード
   通常変数に値やオブジェクトを代入する時は
"="やset *** ="を使いますが、For each〜Next構文はその代入も兼ねていると
いうことでしょうか?

【79072】Re:VBAを用いて日付を自動判別して、その...
発言  マナ  - 17/4/25(火) 20:52 -

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

はい、そうです。

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