<HOME  <お願い事項   <Access2002 TOP   <Access2000 TOP   <サイト内検索
 Access97 VBAの森>ExcelでVBA



(3)

とりあえずイメージとしては

1)A1にアクティブセル移動(これは固定なのでそのまま記述できそう)
2)[Ctrl]+[↓]または[End]+[↓]で、A列の最後のネコ番号に移動
3)そのネコ番号を取得。変数に代入しておく。
4)2)で移動したセルから行番号を割り出し、1足してひとつ下の行に移動
5)その行のB、C、D列に、フォームから入力された値を記入
6)3)で取得したネコ番号に1を足して、このネコにネコ番号を付ける。

こんな感じで行こうかと思うんですが、いかがでしょう。
Excelは正確にはデータベースではないので、アクティブセルの場所が大きなポイントになります。
フォームから入力したものが必ずいつも思ったところに代入されていくわけではないので、この感覚に慣れないとExcelVBAを使いこなすのは難しいかもしれないですね。

それ以外は特にめんどうなことはないと思います。

だいたいの処理の流れを確認できたら、次に「いつその処理をはじめるか」ということを考えます。

VBAは「イベントドリブン型」と呼ばれるタイプのプログラムです。
つまり、作った処理が働くのは「何かをクリックしたとき」とか「フォームを開いたとき」とか、私たちがマウスやキーボードを使って何かをしたときなんです。
このような私たちがマウスやキーボードを使ってする何かのことを「イベント」と申します。

いろんなイベントがありますが、代表格は「コマンドボタンをクリックしたとき」と「フォームを開くとき」「フォームを閉じるとき」ですかね。
あと、今回は「オプションボタンをクリックしたとき」というイベントも駆使しなくてはなりません。

まずは、上の1)と2)の処理を、「フォームを開くとき」にやろうと思います。

1)と2)の処理、どう書けばいいでしょう。
こういうのは、仮マクロを記録してみて、試してみましょうか。マクロの記録の仕方をおさらいしながら、

A1をクリックする
[End]+[↓]か[Ctrl]+[↓]を押す。

このふたつの動作をやってみてください。その後VBEのモジュールを見れば、この動作が記録されてるはずですよね。
まあ、記述の仕方を覚えて、ぜんぶ書き込めるならそれにこしたことはないですが、こういう使い方もあると思うんで活用してみてくださいね。

さて、わたしが試してみたところ仮マクロには

Sub Macro1()
' Macro1 Macro
'
Range("A1").Select
Selection.End(xlDown).Select
End Sub

こんなのができました。'のところは注釈行なので、実際には2行ですね。
多分こう書けばA1をクリックしたあと[End]+[↓]か[Ctrl]+[↓]を押すことになるんだと思います。
この処理がフォームを開くときに動けば、アクティブセルがどこにあっても必ずA列の最後のネコ番号のところに移動できますよね。

んじゃあ、書く手間もはぶこうってことで、この2行をコピーしておきましょう。
で、さっき作ったフォーム内の中をどこかダブルクリックします。ええと、テキストボックスとかラベルとかがないところ。グレーのところですよ。

そうすると、このフォームのコードを書くためのウィンドウが出てきます。
多分、だいたいの場合「フォームをクリックしたときのコード」を書く状態になるのかな・・・と思うんですが、いかがでしょう。
そういうわけでもないのかな。

Private Sub UserForm_Click()

End Sub

プログラムの名前が、「なにを_どうした( )」というロジックで付くようになってるので、これだと、「このフォームをクリックしたときの処理は、この下に書いてね」という意味になります。

クリックしたときじゃなくて、開いたときですよね。これではマチガイだ。

ええと、どうするかというと、右上のコンボボックスをクリックして一覧を出します。
ここにはイベントの一覧があります。Initializeというのを選びましょうか。
フォームが完全に開く前に動く処理を作ることができます。
多分、これでいけると思います。

ありゃ、ふたつになっちゃいましたね。
上のUserForm_Click()はとりあえず要らないので、この2行(End Subまで)は、後で消しちゃいましょう。まあ、あってもなにも起こらないですけどね。

さて、さっきコピーした2行をここに貼り付けます。
なんか注釈を付けておくと、後で分かりやすいかもしれないですね。

Private Sub UserForm_Initialize()
'--A列の一番下の行に移動
Range("A1").Select
Selection.End(xlDown).Select
End Sub

いちおうこれで、このフォームを開く直前に、ワークシートのA1に移動して、その後[End]キーを押しながら[↓]を押す動作で最後のネコ番号のところにアクティブセルが移動するはずなんです。

しかし!ここでひとつ重大な問題。今は練習ですからある程度予測が付きますが、「もし最初の1件目の入力だったら」ってことを考えなければなりません。

当然最初は、何にもデータがないので1件目の見出しの部分しか入力してない・・・って可能性もあるわけですよね。
と、このまま行くと、A1をクリックした後Selection.End(xlDown).Selectをやると、次のデータのまとまりの最後のセルを探してぴよーんと飛ぶわけですので、何もないワークシートをワープして65536行目にアクティブセルは移動するはずなんですね。
こんなとこに1件目のネコの入力をされた日にゃあんた、とんでもないことになっちまいます。

どんなキタナイ手を使ってでも、「もし1件目だったら」という識別をしなければなりません。
まあ、そんなキタナイ手を使わなくても何とかなると思います。みなさんもいろいろ工夫してみてくださいね。

わたしは、「もしアクティブセルの行番号が65536だったらEndキーと↑キーを使って戻ってこい」という感じの命令を考えてみました。

Private Sub UserForm_Initialize()
'--A列の一番下の行に移動
Range("A1").Select
Selection.End(xlDown).Select
If ActiveCell.Row = 65536 Then
 Selection.End(xlUp).Select
End If
End Sub

ActiveCellというのは、Selectionと似てますが、とにかく「アクティブセル」のことです。
で、その後ろにピリオドではさんでRowとあります。これで「アクティブセルの行番号」を獲得することができるんです。

Excel97では65536行、Excel95では16384行が1シートあたりの最大行数

ですので、この数字であるかどうかを関知すればオッケーのはず。
ははは。なんかばかみたいですけど、やむをえない。
みなさんはもうちょっとスマートなやり方、編み出してみてくださいね。


このアクティブセルの中の値に1を足せば、新しいネコ番号を作ることができますよね。
で、作ったネコ番号は、フォームの中の「ネコ番号」のテキストボックスに入れておこうと思います。

でも、まだ上のUserForm_Initialize()のときは、フォームは開いてないんですよね。
開くときのアクションになるので、この時点では「ネコ番号」のテキストボックスは、見つけられないはずなんです。

部屋のドアを開ける直前に、中にいる凶悪犯の顔を見ようとしているようなもんです。
まだ見れませんよね。

そこで、別のイベントを利用します。今度はLayoutというのを使いましょう。
右上のイベント一覧コンボボックスから選択してください。

さらにもうひとつ、確認しておかなければならないことがあります。「ネコ番号」のテキストボックスの名前です。
このテキストボックスをクリックしてから、プロパティを見ると、TextBox○という感じの名前が付いていることがわかるはずです。
わたしはTextBox3でしたけど、みなさんのはなんて名前付いてました?

このテキストボックスに、最後のネコ番号に1を足した値を代入してやりましょう。
ただし、気を付けなくてはいけないのは「ネコ番号がなかったら」、つまり最初の1件目のネコ登録だった場合のお話です。

とうぜん、1件目の場合は、足し算しようと思って参照したセルの中には"ネコ番号"という単語が入ってます。
文字に数字を足し算することはできないですよねぇ。

うーん、ここでも「もしセルの中身が"ネコ番号"だったら、TextBox3の中身は1だよ」としておく必要が出てきちゃいました。

Private Sub UserForm_Layout()
If ActiveCell.Value = "ネコ番号" Then
 TextBox3 = 1
Else
 TextBox3 = ActiveCell.Value + 1
End If
End Sub

と、こうかな・・・。
まあ、こんな処理を作らなくてもいいように、5行目くらいから入力をはじめるようにするとか、2〜3件ネコデータを入力しておくとか、いろいろ方法はありますが、ひとつの方法として参考になさってください。

さて、なんだかめんどくさい処理が続いてうんざりって感じですけど、もうちょっとですのでがんばりましょう。
ネコ番号が付いた状態でフォームが開いてくるはずです。で、あとはおなまえや毛の色、コメントなどを入力した後、どうするかを考えます。

一番スタンダードな方法は[登録]とかいうボタンを作っておいて、これクリックするとフォームからワークシート内に値が渡る・・・というやつじゃないかなと思うんですがいかがでしょう。

と、その時ちょっぴり気にかけたいのが、「うっかり登録ボタンをクリックしちゃった場合」です。せめて「おなまえ」くらいは入力がないと、あとで訳が分からないですよね。
んじゃ、「おなまえが空っぽじゃないかどうかチェック」をしましょう。これにはIf文とメッセージボックスをうまく利用したいと思います。


では、フォームの下の方にでも、コマンドボタンを作ってください。いちおうふたつ作りましょう。
ひとつは[登録]、もうひとつは[キャンセル]に使おうと思います。
どっちがどっちでもいいですよ。ボタンの標題もお任せします。もちろん後で変更するんでも結構です。

では、どっちか一方のコマンドボタンをダブルクリックしてください。
コマンドボタンのイベントをつくるためのウィンドウが出て来て、多分Private Sub CommandButton1_Click()となってると思うんですけど、Clickになってなかったら、右上のイベント一覧の中からClickを選んでください。

他の選んじゃうと、このボタンクリックしても何にも起こらなくなっちゃいますからね。「なにをしたときの処理を作ってるのか」この辺を見失わないようにしましょう。

で、まず

If TextBox1 = "" Then
MsgBox "お名前の入力がありません"

です。
テキストボックスが空っぽだったらというこの空っぽの判断がすごく難しいんですが、たぶんこれでうまく引っかかってくると思います。
で、ちゃんと名前の入力があったら、セルに値の代入をしていきます。

Private Sub CommandButton1_Click()
If TextBox1 = "" Then
 MsgBox "お名前の入力がありません"
Else
 Selection.Offset(1, 0) = TextBox3
 Selection.Offset(1, 1) = TextBox1


End Sub

ここまでは問題ないですね。
Offsetというのは、今選んでるセルから考えて、下にいくつ、右にいくつ移動したところに値を代入するのか、という座標を指定する命令文でしたよね。

で、次のオプションボタンですが、これはとりあえずカンタンにIf文を使って処理してみましょう。今日はまあ練習なので。。。
つまり「もしオプションボタンの1がクリックされていたら"黒"」という文を作ってやるわけです。

オプションボタンにも名前があります。確認しておいてくださいね。で、黒いメダマの状態をTrue、白くてメダマのない状態をFalseと呼びます。

If OptionButton1.Value = True Then
Selection.Offset(1, 2) = "黒"
End If

こうです。
同じことをあと5回やるわけですね。ちょっとめんどうですけど練習練習。がんばって挑戦してみてください。

Private Sub CommandButton1_Click()
If TextBox1 = "" Then
 MsgBox "お名前の入力がありません"
Else
 Selection.Offset(1, 0) = TextBox3
 Selection.Offset(1, 1) = TextBox1
 If OptionButton1.Value = True Then
  Selection.Offset(1, 2) = "黒"
 End If
 If OptionButton2.Value = True Then
  Selection.Offset(1, 2) = "白"
 End If
 If OptionButton3.Value = True Then
  Selection.Offset(1, 2) = "茶"
 End If
 If OptionButton4.Value = True Then
  Selection.Offset(1, 2) = "ぶち"
 End If
 If OptionButton5.Value = True Then
  Selection.Offset(1, 2) = "しま"
 End If
 If OptionButton6.Value = True Then
  Selection.Offset(1, 2) = "その他"
 End If
End If

End Sub

If文の中にさらにたくさんのIf文が入ってます。
英語の文法みたいなもんですね。どこからどこまでがどの処理にかかるのか、ひとつずつゆっくり記述していってください。