テキストボックスに入力されている文字列をカンマ区切りでスプレッドに表示させるには?

解決


ゆう  2006-10-25 02:05:58  No: 96992

長文になることが想定されますので、予めご容赦下さい。
当方、VB6.0初心者、職場でプログラミングを組むようになり右も左もわからない状態です。
やりたいことを、以下に明記します。

・「実行」コマンドボタンを押下後、テキストボックスに入力されている文字列をカンマ区切りで、スプレッドの各項目へ表示させる。

文字列:aaa,bbbbb,cc,dddd
スプレッド:aaa(A列1行目に),bbbbb(B列1行目に),cc(C列1行目に),dddd(D列1行目に)

指定条件:①文字列をカンマ区切りで一旦1次元配列に読み込み、1次元配列からスプレッドへの表示には、スプレッドのRow,Col,Textプロパティーを使うこと。

②カンマ区切りで切り出すには、For文を使用し、文字列の一文字一文字をカンマかそうでないか判定し処理する。その際に、一文字の取出しにはMid関数を使用する。

どうやら、配列とFor文を使った応用問題らしきことはわかるのですが、
コードが書けないと意味がありませんよね・・・。
「本で調べてみろ」と言われましたが、似たような例題が載っておらず・・・。
誠にお手数ではございますが、どなかた救いの手を・・・・・・。


KT  2006-10-25 03:23:37  No: 96993

指定条件はほぼ回答のような気もしますが、参考までに…

文字列:aaa,bbbbb,cc,ddddのテキストボックス  を  txtCSVStr とします。
スプレッド(farpoint spread?)  を  vaSpread とします。

Dim GetVar() As Variant  'データを入れる一次元配列
Dim GetVarCnt As Long    '一次元配列要素数
Dim Cnt As Long          'Forカウンタ
Dim DataCnt As Long      '一次元配列データ格納時に使用するカウンタ

'カンマの数を調べる
GetVarCnt = 0
'テキスト文字数分ループ
For Cnt = 1 To Len(txtCSVStr.Text)
  'カンマのチェック(Chr(&H2C)  →  ",")
  If Mid(txtCSVStr.Text, Cnt, 1) = Chr(&H2C) Then
    GetVarCnt = GetVarCnt + 1  'カンマ数カウントアップ
  End If
Next Cnt

'カンマがなかったら終了
If GetVarCnt = 0 Then
  vaSpread.MaxCols = 0
  vaSpread.MaxRows = 0
  Exit Sub
End If

'領域確保
ReDim GetVar(GetVarCnt) As Variant

'一次元配列GetVarに値を入れる
DataCnt = 0
'上記と同様、文字数ループ
For Cnt = 1 To Len(txtCSVStr.Text)
  If Mid(txtCSVStr.Text, Cnt, 1) = Chr(&H2C) Then
    '文字がカンマだったら次の要素に
    DataCnt = DataCnt + 1
  Else
    'カンマ以外だったらその文字を足す
    GetVar(DataCnt) = GetVar(DataCnt) & Mid(txtCSVStr.Text, Cnt, 1)
  End If
Next Cnt

'スプレッドへの表示
vaSpread.MaxCols = GetVarCnt  '列数
vaSpread.MaxRows = 1          '行数

'配列要素数分ループ
For Cnt = 0 To GetVarCnt - 1
  vaSpread.Col = Cnt + 1  '入力する列番号
  vaSpread.Row = 1        '       行番号
  vaSpread.Text = GetVar(Cnt)  '表示
Next Cnt

#なお、上記コードは発言欄にダイレクトで記述したものですので
#もしかすると記述ミスあるかもしれません。

指定条件がなければSplit(だったかな…?)とか使用したほうがきっといいでしょうね。

> どうやら、配列とFor文を使った応用問題らしきことはわかるのですが、
> コードが書けないと意味がありませんよね・・・。
> 「本で調べてみろ」と言われましたが、似たような例題が載っておらず・・・。
  例題を探すよりもMSDN(VBの説明書みたいなもの)で
  Midの説明等々調べたほうがいいと思いますよ。
  例題をコピーしてなんとなく動いた  ではおそらく理解出来ないと思いますので…


ゆう  2006-10-25 17:58:22  No: 96994

KTさま

早速のご解答ありがとうございました。
本当にどうしようかと思っていたので、少し精神的に楽になりました。
上記のコードを基にして、自分でも本で調べたりしてみます。
また、不明な点があれば改めてご質問させていただきます。
本当にありがとうございました。


ガッ  2006-10-25 19:23:16  No: 96995

const s="aaaa,bbbb,cccc,dddd"
dim spl() as string
dim i as long
spl=split(s,",")
if ubound(spl)>=lbound(spl) then
  debug.? spl(lbound(spl))
  for i=lbound(spl)+1 to ubound(spl)
    debug.? "," & spl(i)
  next
end if

dim j as long
j=1
do
  i=instr(j+1,s,",")
  if i=0 then
    debug.? mid$(s, j)
    exit do
  end if
  debug.? mid$(s,j,i-j)
  j=i
loop

など


ゆう  2006-10-25 19:52:50  No: 96996

ガッさま

早速のご返信感謝いたします。
実際に表示させたいイメージをお伝えしたほうがわかりやすいですよね?
配慮が足らずに申し訳ありませんでした。
表みたいにできずに恐縮ですが、大体以下のとおりです。

テキストボックスには『aaa,bbbbb,ccc,dddd』と表示してあり、
それを以下のようにスプレッド表示させたいというものです。

  A  B  C  D  E  F
1  aaa  bbbbb  ccc  dddd    
2            
3            

以下にコードを載せておきます。

Private Sub cmd_Exe_Click()

Dim GetVar() As Variant  'データを入れる一次元配列
Dim GetVarCnt As Long    '一次元配列要素数
Dim i As Long            'Forカウンタ
Dim DataCnt As Long      '一次元配列データ格納時に使用するカウンタ

'カンマの数を調べる
GetVarCnt = 0
'テキスト文字数分ループ
For i = 1 To Len(txt_Ins.Text)
'カンマのチェック(Chr(&H2C)  →  ",")
  If Mid(txt_Ins.Text, i, 1) = Chr(&H2C) Then
    GetVarCnt = GetVarCnt + 1  'カンマ数カウントアップ
  End If
Next i

'カンマがなかったら終了
If GetVarCnt = 0 Then
  spv_Main.MaxCols = 0
  spv_Main.MaxRows = 0
  Exit Sub
End If

'領域確保
ReDim GetVar(GetVarCnt) As Variant

'一次元配列GetVarに値を入れる
DataCnt = 0
'上記と同様、文字数ループ
For i = 1 To Len(txt_Ins.Text)
  If Mid(txt_Ins.Text, i, 1) = Chr(&H2C) Then
    '文字がカンマだったら次の要素に
    DataCnt = DataCnt + 1
  Else
    'カンマ以外だったらその文字を足す
    GetVar(DataCnt) = GetVar(DataCnt) & Mid(txt_Ins.Text, i, 1)
  End If
Next i

'スプレッドへの表示
spv_Main.MaxCols = GetVarCnt  '列数
spv_Main.MaxRows = 1          '行数

'配列要素数分ループ
For i = 0 To GetVarCnt - 1
  spv_Main.Col = Cnt + 1  '入力する列番号
  spv_Main.Row = 1        '行番号
  spv_Main.Text = GetVar(i)  '表示
Next i
    
End Sub

これを実行すると、A列の1行目に『ccc』しか表示されないのです。
大変恐縮ですが、ご教示お願いいたします。


ガッ  2006-10-25 20:02:39  No: 96997

うーんと、ではこうですか?
※スプレッド(?)を良く知らないのでみよう見真似です
※複数行とは一言も書いていないので、テキストボックスの入力が複数行の場合は期待通りに動きません

const DataSpliter=","
dim cnt   as long
dim s     as string
dim v     as variant

cnt=1
s=txt_Ins.Text
with spv_Main
  .Row=1
  for each v in split(s,DataSpliter)
    .Col=cnt
    .Text=v
    Cnt=Cnt+1
  next
end with

たぶん

> これを実行すると、A列の1行目に『ccc』しか表示されないのです。
for-nextループ中にCnt=Cnt+1を適切に入れればいいです


ゆう  2006-10-25 20:14:22  No: 96998

ガッさま

ゆうでございます。
本当に、ガッさまにはなんとお礼を申し上げていいか・・・。
私のような者にお付き合いいただいて幸甚です。
私はプログラマではないのですが、社の方針でなぜか組まされることに・・・。
まったく「???」という状態のものですから、こうして質問をさせていただいております(申し訳ありません)。

で、早速ですが、aaa,bbbbb,cccまでは表示されました。
残りのddddが表示されません。
先ほど以下のコード文中で・・・

'スプレッドへの表示
spv_Main.MaxCols = GetVarCnt  '列数
spv_Main.MaxRows = 1          '行数

'配列要素数分ループ
For i = 0 To GetVarCnt - 1
  spv_Main.Col = i + 1  '入力する列番号
  spv_Main.Row = 1        '行番号
  spv_Main.Text = GetVar(i)  '表示
Next i

spv_Main.Col = i + 1  の『Cnt』を『i』に変換するのを失念してしまっていました(私がカウンタの変数宣言に『i』を用いているため)。
あと一歩なんですね。


ガッ  2006-10-25 20:29:58  No: 96999

んー、素直にsplit()でするとスマートな気がするけど(orz

> '配列要素数分ループ
> For i = 0 To GetVarCnt - 1
もしかしてコメントしてる事としている事が違うのでは?


ゆう  2006-10-25 20:45:36  No: 97000

ガッさま

お昼に行ってきます。
また後ほどお願いいたします。


KT  2006-10-25 21:05:48  No: 97001

すいません、やっちゃいましたね…

> 'スプレッドへの表示
> spv_Main.MaxCols = GetVarCnt  '列数
> spv_Main.MaxRows = 1          '行数
> '配列要素数分ループ
> For i = 0 To GetVarCnt - 1
>   spv_Main.Col = i + 1  '入力する列番号
>   spv_Main.Row = 1        '行番号
>   spv_Main.Text = GetVar(i)  '表示
> Next i

たぶんこちらが正しいです。

'スプレッドへの表示
spv_Main.MaxCols = GetVarCnt + 1  '列数
spv_Main.MaxRows = 1              '行数
'配列要素数分ループ
For i = 0 To GetVarCnt
  spv_Main.Col = i + 1  '入力する列番号
  spv_Main.Row = 1        '行番号
  spv_Main.Text = GetVar(i)  '表示
Next i

GetVarCntの値を配列要素数と勘違いしちゃいました…
GetVarCnt=カンマ数なので1つ分足りませんでした。
申し訳ないです。


ガッ  2006-10-25 21:21:20  No: 97002

('A`)今気づいた…課題だったのね


ゆう  2006-10-25 22:44:01  No: 97003

KTさま、ガッさま

ご多忙中、お付き合いいただいて本当にありがとうございました。
無事に『aaa,bbbbb,ccc,dddd』と表示されるようになりました!!
うれしいです!!

ところで、今後のためにコード文についていくつか質問させてください。
疑問に思った箇所を以下に列挙いたしますのでよろしくお願いいたします。

1.『GetVarCnt = 0  'カンマの数を調べる』という宣言がなぜ必要なのでしょうか?

2.『GetVarCnt = GetVarCnt + 1  'カンマ数カウントアップ』の意味がよくわからないのです。

3.『'領域確保  ReDim GetVar(GetVarCnt) As Variant』の宣言内容の意味

3については、MSDNライブラリを調べたところ、『動的配列変数を保存するメモリ領域の割り当てと再割り当てを行います。』と書かれていました。
3のような宣言をすることで、しっかりと格納されるという理解でいいのでしょうか?

お忙しい中、恐縮です。
何卒よろしくお願いいたします。


KT  2006-10-25 23:20:37  No: 97004

> 1.『GetVarCnt = 0  'カンマの数を調べる』という宣言がなぜ必要なのでしょ> うか?
  この記述自体は、なくても動きはします。(Dim宣言時は初期値0なので)
  個人的な癖みたいなものですね;
  コメントの"カンマの数を調べる"はその下のFor分の内容を意味しています。
  (書く位置がよくなかったですね)

> 2.『GetVarCnt = GetVarCnt + 1  'カンマ数カウントアップ』の意味がよく> わからないのです。
  テキスト内のカンマの数を数えています。
  この部分のIf文で文字が","だったら+1としています。

> 3.『'領域確保  ReDim GetVar(GetVarCnt) As Variant』の宣言内容の意味
> 3については、MSDNライブラリを調べたところ、『動的配列変数を保存するメモ> リ領域の割り当てと再割り当てを行います。』と書かれていました。
> 3のような宣言をすることで、しっかりと格納されるという理解でいいのでしょ> うか?
  データを格納する箱(?)を用意しています。
  通常の変数は箱を一つ持っています。
  Dim i As Long
  i = 10  ←iに「10」が入ります。
  
  配列は()内の数分の箱を持っています。
  Dim GetVar(10) As Variant
  GetVar(0) = 0
  GetVar(1) = 1
        :
  GetVar(10) = 10  ←同じ名前ですが、データを11個格納できます。

  今回はカンマで区切られたテキストの内容を格納する為、
  テキストの内容により箱の数が決まります。
  そのため、
  ReDim GetVar(GetVarCnt) As Variant
  として、後から箱の数を決めています。
  この記述が無いと箱が用意されない為エラーになります。
  
  
  ちょっとわかりづらい説明ですかねぇ…


ゆう  2006-10-25 23:56:30  No: 97005

KTさま

お忙しい中、ご丁寧にありがとうございます。
KTさまの解答を基に再度コードの見直しをしてみます。


ゆう  2006-10-26 00:38:37  No: 97006

皆様へ

皆様のおかげで大変助かりました。
今後ともよろしくお願いいたします。


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加