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

お世話になります。
Excel2013で、添付のように例えばB2:B6まで穀物と入っていれば、D2:D6セルに「穀物」という名前を定義し、以下同様にB7:B9は野菜なのでD7:D9に「野菜」という名前を定義する、みたいにしたいのですが、どうすればよろしいでしょうか?対象は、2行目から最終行までです。定義する数が多いので、なるべく高速で処理できる書き方の方がありがたいです。

VBAでの名前の定義は、あまり向いていないという話はありますが、名前の定義のやり方が分からない方に使っていただくので、申し訳ございませんがよろしくお願いいたします。

「Excel2013でVBAで対応した列の」の質問画像

質問者からの補足コメント

  • どうもありがとうございます。
    申し訳ございませんが、
    Names.Add Name:=n, RefersTo:="=" & adr
    で、実行時エラーが出てしまいました。
    どのように修正すればよろしいでしょうか?

    No.1の回答に寄せられた補足コメントです。 補足日時:2016/06/28 12:47
  • 中身を見ていて気になるのは、シート名がSheet3 (2)となっていたのでシート名のかっこを消去したらエラーがでなくなりました。"Sheet3!$D$2:$D$6"は大丈夫ですが、"Sheet3 (2)!$D$2:$D$6"となっているとダメみたいですね。なぜでしょうかね?
    Application.Names.Add Name:=n, RefersTo:="=" & adrにしても同じでした。
    とりあえず、実際に使う部分ではそのようなシート名では使用しないので大丈夫だとは思います。
    どうもありがとうございました。

    No.3の回答に寄せられた補足コメントです。 補足日時:2016/06/28 20:43
  • 考えて下さりどうもありがとうございました。
    動作に問題ないと思っていたら、参照範囲が思っていたのと違っていました。
    例えば、D2:D6の品名の方を取得したいところが、B2:B6を取得するようになっていました。
    どうすればよいでしょうか?

    No.2の回答に寄せられた補足コメントです。 補足日時:2016/06/29 02:38
  • 先ほどのfujillinさんへの補足ですが、自己解決しました。
    Names.Add Name:=nam, RefersTo:="=" & rng.Offset(, 2).Address

    Offset(, 2)を追加変更することで解決しました。
    どうもありがとうございました。

      補足日時:2016/06/29 08:26
  • №3の補足に対して。
    あれから、自己解決しました。

    adrに少し付け足して、
    adr = "'" & ActiveSheet.Name & "'!" & aRng.Offset(, 2).Address(1, 1)
    のようにすると、()付きのシートも通常のシートもどちらも動作しました。
    どうも、ありがとうございました。

      補足日時:2016/06/29 12:47

A 回答 (5件)

面倒なアルゴリズムなど使わずに、Dictionary オブジェクトでやってみました。



'//
Sub RegistNames()
  Dim dic As Object
  Dim c As Variant, i As Long
  Dim adr As String, aRng As Range
  Dim n As String, buf As String
  Set dic = CreateObject("Scripting.Dictionary")
  '2行目から
  For Each c In Range("B2", Cells(Rows.Count, 2).End(xlUp))
   '種類の名目が存在してない時
    If Not Dic.exists(Trim(c.Value)) Then
      dic.Add Trim(c.Value), c.Address(0, 0) '
    Else
      dic.Item(c.Value) = dic.Item(c.Value) & "," & c.Address(0, 0)
    End If
  Next c
  '以下で名前の登録が始まる
  For i = 0 To dic.Count - 1
    buf = dic.Items()(i)
    If buf <> "" Then
     '範囲をつなぎ合わせる
      Set aRng = Application.Union(Range(buf), Range(buf))
      adr = ActiveSheet.Name & "!" & aRng.Offset(, 2).Address(1, 1) 'Offset(,2)は、B列の2つ右先
      n = dic.Keys()(i)
      Names.Add Name:=n, RefersTo:="=" & adr
      adr = "": n = ""
    End If
  Next i
  Set dic = Nothing
End Sub

「VBAでの名前の定義は、あまり向いていないという話」
たぶん、これは、教えて!gooでの言い出しっぺは私だと信じています。トラブった時の処理の仕方がややこしいからです。たぶん、そういう場合は、過去ログにその対処法が出ていると思います。
この回答への補足あり
    • good
    • 0
この回答へのお礼

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

お礼日時:2016/07/01 00:58

それは、良かったでした。



>adrに少し付け足して、
>adr = "'" & ActiveSheet.Name & "'!" & aRng.Offset(, 2).Address(1, 1)
>のようにすると、()付きのシートも通常のシートもどちらも動作しました。

うーん、やはり私の場合は、Nameの取り扱いは、1000回に1つ程度しか使わないから、いつまでも分からなかったと思います。このシングルクォートは、自ブックの自シート(ActiveSheet)では入らなかったような気がしたのですが、正直なところ、これについては、私の守備範囲外です。ただ、この件については、覚えておくようにします。
    • good
    • 0

ANo2です。



自己解決なさったとのことなので良かったです。
私が質問文を見落としていました。申し訳ありませんでした。
    • good
    • 0
この回答へのお礼

いえいえ、どうもありがとうございました。

お礼日時:2016/07/01 01:01

#1の補足についてです。



もちろん、標準モジュールで書いているかとは思いますが、今のところ、このぐらいしか思いつきません。

Application. という単語を先頭に入れてください。

Application.Names.Add Name:=n, RefersTo:="=" & adr

後は、ローカルウィンドウで、その変数の中身を調べてみないとなんとも言えません。ここで、矛盾が生じていたら、それを直さないといけません。

VBEditor 内のローカルウィンドウの状態
「Excel2013でVBAで対応した列の」の回答画像3
この回答への補足あり
    • good
    • 0
この回答へのお礼

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

お礼日時:2016/07/01 00:59

こんにちは



回答しようとしたら、もう#1様の回答がありましたね。

私もDictionariyで考え始めたけれど、プリミティブにチェック用配列にしてみました。
あまり要領のよい方法ではありませんが、作ってみたので載せておきます。

Sub Sample()
 Dim r As Long, rw As Long, rMax As Long
 Dim nam As String, rng As Range, chk() As Boolean

 rMax = Cells(Rows.Count, 2).End(xlUp).Row
 ReDim chk(rMax)
 For r = 2 To rMax
  chk(r) = True
 Next r

 For rw = 2 To rMax
  If Cells(rw, 2) = Empty Then
   chk(rw) = False
  ElseIf chk(rw) Then
   Set rng = Cells(rw, 2)
   nam = rng.Text
   For r = rw To rMax
    If Cells(r, 2) = nam Then
     Set rng = Application.Union(rng, Cells(r, 2))
     chk(r) = False
    End If
   Next r
   Names.Add Name:=nam, RefersTo:="=" & rng.Address
  End If
 Next rw
End Sub
この回答への補足あり
    • good
    • 0
この回答へのお礼

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

お礼日時:2016/07/01 00:59

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