プロが教える店舗&オフィスのセキュリティ対策術

エクセルVBAで、C言語のscanf("%dxxx%dto%d"&a,&b,&c);をする方法

現在、エクセルVBAに挑戦しています。
C言語は少しだけ経験がありますが、他の言語は経験ありません。

エクセルVBAで、C言語のscanf("%dxxx%dto%d"&a,&b,&c);にあたる読み取りを、指定したセルに対して行いたいのですが、どのようにすればよいでしょうか?

ちなみにすべての%dは桁数が変わるため、右から何文字とかでは対応できません。


それと、蛇足質問を2つさせてください。こちらは回答いただかなくてもかまいません。、

セルを参照するときに、Range("A1:B2")で、データを取得しますが、A1:B2の部分を変数にすることはできないのでしょうか?

これはchr(64)+iで解決できたので、良いと言えば良いのですが、もっと標準的と感じられるしっくりくる方法があればいいのですが・・・

それからもうひとつ。VBAで参照するセルを指定した後に、シート上で行や列の挿入・削除を行うと、参照先のセルが変わってしまいますが、通常のシート上でのSUM(A1:A3)がA列に列を挿入するとSUM(B1:B3)になるように、VBAでも連動はできないのでしょうか?

エクセルは使いやすくて便利ですが、自由度が高いだけに難しいですね。
めんどくさく感じたCの型縛りが実は使いやすく感じる今日この頃です。

お忙しい中とは思いますが、よろしくお願いします。

A 回答 (5件)

例えばこんな感じ。


Sub test()
Dim a As Long, b As Long, c As Long
Dim s As String
Dim j1 As Long, j2 As Long
s = Range("a1").Value
j1 = InStr(s, "xxx")
a = CLng(Mid$(s, 1, j1 - 1))
j2 = InStr(j1 + 3, s, "to")
b = CLng(Mid$(s, j1 + 3, j2 - j1 - 3))
c = CLng(Mid$(s, j2 + 2, Len(s) - j2 - 2))
End Sub

次にRange("A1:B2")の"A1:B2"は単なる文字列です。
s = "A" & i & ":B" & j
とかすればよいし,"A"とか文字になっているのが面倒ならrange(cells(i1,j1),cells(i2,j2))とかにすればよい。

さらに,シート上で行や列の挿入・削除を行ったら...というのがよくわからないが,それに応じて参照するセルを移動させれば良いだけでは。
    • good
    • 0
この回答へのお礼

ありがとうございます!

なるほど、鍵となる文字列を検索して、そこからの位置で判定するんですね。

思いつきもしませんでした。ありがとうございます。

お礼日時:2010/08/22 15:06

>C言語のscanf("%dxxx%dto%d"&a,&b,&c);にあたる読み取り


きちんと言葉で説明していただいたほうがよいですね。
普通は、数字だけを認識させて入力させるものだと思いますから、そのコードでは、数値認識はしますが、そのまま数値の読み取りということもないはずです。

 「1は、2と足すと、3になる」(正しく認識しない)
 「12xxx145to458」(正しく認識する)
 
セルの中で、数値を読み取らせるなら、数値だけを読み出すと言えば済むように思うのです。あえて、scanf関数を持ち出されても、意味が分かりづらいです。結局の所は、言語の違いはあっても、文字列として認識されているものに対して、数値の抽出自体の方法論は変わらないはずです。たまたま、scanf という関数には、そういう機能があるだけだと思います。

通常、VBAやVB系では、文字列から数値を抜き出すことは、実験コードだけで、予めテキストボックスや、入力セルを用意して、数字だけを入れるようにします。しかし、あえてするとなれば、正規表現を使うのが一般的です。

'//
Sub PickUpFigures()
 Dim ret As Variant
 Dim strTxt As String
 Dim Ar As Variant
 Dim Matches As Object, Match As Object
 If ActiveCell.Value = "" Then Exit Sub 'ActiveCell
 strTxt = ActiveCell.Value
 With CreateObject("VBScript.RegExp")
  .Pattern = "\d+"
  .Global = True
  If .test(strTxt) Then
   Set Matches = .Execute(strTxt)
   For Each Match In Matches
    ret = ret & "," & Match.Value
   Next
   Ar = Split(ret, ",")
   '抽出
   MsgBox Ar(1) & "," & Ar(2) & "," & Ar(3)
  Else
   MsgBox "抽出できません", vbExclamation
  End If
 End With
End Sub


//

>A1:B2の部分を変数にすることはできないのでしょうか?
>これはchr(64)+iで解決できた
唐突に、なぜ、A1:B2 の部分を変数にするのか分かりません。その必要性があるなら、文字列変数にすればよいのです。 strAdd = "A1:B2" は、Range(strAdd) です。それぞれには作業の過程があって、その途中を抜き出して言われても、意味が通じません。

i = 1
j = 2
strAdd = "A" & i &":B" & j

>通常のシート上でのSUM(A1:A3)がA列に列を挿入するとSUM(B1:B3)になるように、VBAでも連動はできないのでしょうか?

単発の技を要求されても意味は分かりませんが、こういうことは出来ます。
(ただし、以下は入門レベルのコードです)

Sub FormulaTest1()
Dim i As Long, j As Long
Dim strAdd As String
i = 1
j = 3
strAdd = "A" & i & ":A" & j
'数値の代入
Range(strAdd).Value = Application.Transpose(Split("1,2,3", ","))
Range("A4").Formula = "=SUM(" & strAdd & ")"
Columns("A").Insert
MsgBox Range("B4").Value
MsgBox Range(strAdd).Offset(, 1).Address
End Sub
    • good
    • 0
この回答へのお礼

回答ありがとうございました。
質問の仕方が下手くそですいませんでした。

実は、もう、文字列データはできていいて、そこから数値を抽出したかったのです。
ですから、あらかじめ分けて入力することはできませんでした。

正規表現というのはわかりませんが、これから勉強してみたいと思います。

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

お礼日時:2010/08/22 15:11

(1)Cの例を持ち出すなら、scanf(・・に担わせている意味ぐらい書いて質問すべきと思う。


何がしたいのか?
(2)>Range("A1:B2")で、データを取得しますが、A1:B2の部分を変数にすることはできないのでしょうか?
どういう場合のことを言っているのか書かないと、回答の仕様がない。文字通りでは()内は変数名で、
その変数にセル範囲として相応しい文字列を代入しておけば通用する
Sub test02()
Dim s As String
Dim m As Variant
s = "A1:C1"
m = Range(s)
Range("A3:C3") = m
End Sub
A1:C1の値がA3:C3に代入された。
ーーー
>これはchr(64)+iで解決できたので、良いと言えば良いのですが
何のことか判らない。そのとおりとしても、初心者の我流の方法。
ーーー
>VBAで参照するセルを指定した・・
早く断定しないこと。場合による。
例えば
Sub test01()
Range("a5").Formula = "=Sum(a1:A3)"
End Sub
で式をA5に入れておいて1-3行目までに行挿入すると式が変わる。
これはVBAの力でなく、エクセルの機能なのだが。
一般にはコードの中に書いた番地の行挿入等の影響の自動修正までは出来ないが。
ただしエクセルVBAでは行挿入(操作・イベント)を捉えることは難しいので即時的対処が難しいことは在る。
変更後に再実行するなら
Sub tesyt03()
d = Range("A20").End(xlUp).Row
Range("A21").Formula = "=Sum(A1:A" & d & ") "
End Sub
のような書き方も在る。
ーーー
>エクセルは使いやすくて便利ですが、自由度が高いだけに難しいですね。
めんどくさく感じたCの型縛りが実は使いやすく感じる今日この頃です
こんなことは、VBAやエクセルを十分勉強してから言うこと。
この質問表現振りからして、言語の感想を公表できる段階とは思えない(感じることは日々感じて、勉強に応じて、修正されて固まっていくものと思うが)。もっとVBAやエクセルを勉強してから言うべきと思う。
    • good
    • 0
この回答へのお礼

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

偉そうなことを書いてしまってすいませんでした。
悪気はなかったので、許してください。

また、いろいろとアドバイスありがとうございました。

お礼日時:2010/08/22 15:14

scanf など使ったのは遠い昔のことで


ご質問の『xxx』や『to』の意味がわからないまま
コメントいたしますが
要するに、セルの情報を文字列としてうけとり
チカラ技で目指す数値部分を文字列として抜き出して
VBAのVAL関数で int か long に変換します。
このとき、instr関数を多用します。

思えばVBAには printf 関数もないから、
C言語より不自由することもありますが、一般論として
VBAの方がハルカに早くプログラムできますよ。


> セルを参照するときに、Range("A1:B2")で、データを取得しますが、
> A1:B2の部分を変数にすることはできないのでしょうか?
VBAのプロパティ
   Worksheet.Cells(行, 列)
を使います。例えば セルC15は、Cells(15,3) で参照できます。


> それからもうひとつ。~~~ VBAでも連動はできないのでしょうか?
VBAとしては、できません。
但し方法はあって、VBAの中でワークシート関数を使えばよろしい。
例えば =SUM(A1:A3) をセルB1に入れておけば、後で列を挿入しても
この SUM ワークシート関数は有効で、VBAから参照できます。
慣れない間はVBAの世界とEXCELの世界の区別がハッキリせずに
頭の中がスパゲッティ状になりますが、
早く慣れて自在に使い分けてください。
    • good
    • 0
この回答へのお礼

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

まさに、頭の中がスパゲッティ状態ですw

いただいたアドバイスを参考に頑張りたいと思います!

お礼日時:2010/08/22 15:17

scanfはCの最初に出てくる関数ですが、実際はポインタ


を理解していないとその中身は初級
でも理解しにくい関数です。そのポインタについて、
エクセルVBA、あるいは他のVBAやVBも含めて、
メモリ上のポインタを取得して云々という概念は
ほぼ無い(厳密にはないとは言えませんが)、
あるいは直接扱うことはない、
ということです。もちろんポインタやアドレス関して
アドレスの取得関数などは存在しますが、
http://support.microsoft.com/kb/199824/ja
(表示されている関数はNETではなくなりますが、
Excel、Accessなどではまだ使えるようです)
これらは質問者さんの考えているものには
使えない、と考えてください。したがって、VBAやVB
ではコンソールプログラミングの概念を
一度はずして取り掛かるのがいいのでは
と思います。もちろん、フロー制御や
いろいろなアルゴリズムは概念として
は同じだと考えていいのではないでしょうか。
もちろん、Cはウィンドウを作ろうと思えば
作れるのでCがコンソールだけだとは言いませんが。
質問のニュアンスでは一応このようにしておきます。
VBAではポインタを意識することはまずありません。
しかし、ポインタの考えはどの言語においても
重要です。

したがって、scanfのようにポインタが指す
オブジェクトに、標準入力から読み込んだ値を入れる
関数は存在しない、と考えてください。
セル、あるいはフォームのテキストボックスなどの
オブジェクトに値(数値、文字、文字など)を入力し
受け取り、加工または指定変数に入れ加工と考えてください。

型の厳密さについては本来は同じだと思ってください。
参照渡し、値渡し、変数の型宣言なども明示的に
行なうのが原則で、はずれればエラーが出ますし、
結果が違ってきます。プログラムで型の間違い
、あるいは変数宣言しないでエラーがでるはずの
コードがエラーなしで実行できるかのようなコード
をこのOKWAVEでも見ます。たぶん、Option Explicit
をコードに表示せずにコンパイルしているのではと思います。

ただ、Variant型については少し研究してみて
ください。便利ですが、多用すると
どんぶり勘定になります。
また、Variantでなければならない、という場面も
あります。

それと、ついでに、メモリリークの回避、
あるいは、OSにプロセスを残してしまう
ことでのトラブルなどの回避のために、
コードの終わりに不必要なメモリ上の
オブジェクトの終了、削除はこまめに
行なう、という習慣も大事です。

VBAに似た言語で型宣言をしないVBScriptのようなものも
ありますが、ここでは割愛。
    • good
    • 0
この回答へのお礼

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

scanfを例に出したのは、文字列から特定の部分を抽出したい程度の意味で、
ポインタのことまで考えていませんでした^^;すいません。

はい。Variant型について勉強してみたいと思います。
実は、なんでも入るこのVariant型が不気味でしょうがなかったのです。

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

お礼日時:2010/08/22 15:22

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