VBAで、セルの値をつなげて入力したいのですが・・・
エクセル2007を使用しています。
Ctrlキーで2つのセルを選択し、最初に選択したセルの値にスラッシュをつけて、
2番目に選択したセルの値をつなげ、再び1番目に選択したセルに代入したいと思っています。
例えば、A1セルに「佐藤」B1セルに「鈴木」と入力されており、
A1を選択し、Ctrlキーを押しながらB1セルを選択し、コマンドボタンを押すと
A1セルに「佐藤 / 鈴木」と入力させたいと思っています。
選択するセルは、1番目も2番目も、変化します。
そこで、下記のようなマクロを書いてみたのですが、
「実行時エラー13 型が一致しません」というエラーが出ます。
Private Sub CommandButton7_Click()
If Selection.Areas.Count <> 2 Then Exit Sub
Dim a As Variant
Dim b As Variant
a = Selection.Areas(1)
b = Selection.Areas(2)
Selection.Areas(1) = a & "/" & b
End Sub
変数の型が問題なのでしょうか?
ちなみに
Selection.Areas(1) = b
とすると、2番目に選択した「鈴木」がA1に入力されます。
また、
Selection.Areas(1) = a & b
としても同じエラーが出ます。
解決法があるなら、ご教授いただけませんでしょうか?
よろしくお願いいたします。
>回答番号:No.2 この回答への補足
独学なので雑駁な説明しかできませんが、、、
結合セルでは左上端セルのデータが保持されます。
ということで
Selection.Areas(1).Item(1)
あるいはItemは記述を省略できるので
Selection.Areas(1)(1)
でAreas(1)のItemが1番目のセル、つまり左上端セルということになります。
結合セルが複数行/複数列なら
Selection.Areas(1).Item(2, 2)
でAreas(1)の2行目2列目のセルを指定することができます。
Dim i As Integer
Dim j As Integer
Range("A1:B2").Merge
Range("C1:C2").Merge
Range("A1,C1").Select
For i = 1 To Selection.Areas.Count
For j = 1 To Selection.Areas(i).Cells.Count
MsgBox "Areas" & i & " - " & j & vbCrLf & _
Selection.Areas(i).Item(j).Address & vbCrLf & _
Selection.Areas.Item(i)(j).Address
Next j
Next i
Item プロパティ
http://www012.upp.so-net.ne.jp/scotchegg/ExcelVBA/Range/Item.htm
結合セルを調べる
http://officetanaka.net/excel/vba/tips/tips50.htm
ちょっと口を挟ませていただきます。
ご質問者さんにはむつかしい話ですが、
#3様のリンク先の「Deep Decryption」という所の記述に、
「Item プロパティは単一セルを表すRangeオブジェクトを返すプロパティです。引数でオフセット値を指定します。」
となっていますが、この著者の記述は、誤解しているのではないかと思います。
Rangeオブジェクトは、オブジェクトの集合体、コレクションの面も持っているのだと思います。仮に、Item プロパティをつけようとも、必ずしもRangeオブジェクトの単一のセルを表すものではないはずです。それは、取得したオブジェクトが、セルを含んだRangeオブジェクトに限るわけで、Cells プロパティとの混同だと思うのです。
以下は、Areas では、取れませんが、このような例が考えられると思います。
Sub Test1()
Dim rng As Range
Set rng = Rows("1:2")
MsgBox rng.Item(2).Address 'これでは、単一のセルを示していません。
MsgBox rng.Cells(2).Address 'または、rng.Cells(2,1).Address
End Sub
ただ、これも、厳密にいうと、rng.Cells(2)というものは、単純に、単一のセルを指しているわけではなくて、rng.Cells.[_Default]( 2).Address ということです。.[_Default]というのは、非表示メンバーです。
Areasは、Rangeオブジェクトのコレクションであり、Item というのは、Index を示すものです。Areas からは、直接、Cells と同等の構造は持っていません。Selection.Areas(1)だけですと、1つしかなければ、暗黙のプロパティで、値を返しますが、結合セルでは、値は取れません。
追求すれば、なかなか難しいものだと思いますし、あまり出会わないコードのひとつだと思います。だから、Excel VBAというのは例外とか、隠しオブジェクトとかあって、覚えにくいのだと思います。
一応、私の書き方だとこのようになります。
Sub Test2()
If TypeName(Selection) <> "Range" Then Exit Sub
With Selection
If .Areas.Count = 2 Then
.Areas(1).Cells(1).Value = .Areas(1).Cells(1).Value & "/" & .Areas(2).Cells(1).Value
End If
End With
End Sub
結合セルを扱っていませんか?
左上のセルを指定すればどうでしょうか。
ついでに(無関係ですが)プロパティも省略せず記述するようにしましょう。
a = Selection.Areas(1).Item(1).Value
b = Selection.Areas(2).Item(1).Value
Selection.Areas(1).Value = a & "/" & b
不思議ですね。当方では問題なく動作しますが。
次のようにしてみてはどうでしょう?
Private Sub CommandButton7_Click()
If Selection.Areas.Count <> 2 Then Exit Sub
Dim a As String
Dim b As String
a = Selection.Areas(1).Value
b = Selection.Areas(2).Value
Selection.Areas(1).Value = a & "/" & b
End Sub
お礼
なるほどです、勉強になりました! 丁寧にご解説いただきまして、ありがとうございました。