ここから本文です

エクセルのマクロ初心者です。 ユーザーフォームを使って、入力済みのセルの情...

mis********さん

2017/12/1422:35:32

エクセルのマクロ初心者です。

ユーザーフォームを使って、入力済みのセルの情報を簡単に書き換えられるような仕組みを作りたいと考えています。

目指しているのは
1)一行ごとにオプションボタンを配置し、そのボタン

を押すとフォームが表示される
2)フォーム内に配置したコマンドボタン①を押すと、1)のオプションボタンが配置されている行のセルA~Eの値(項目A~E)がテキストボックスA~Eに取得される
3)変更が必要な項目を(テキストボックスで)修正する
4)フォーム内のコマンドボタン②を押すと、テキストボックスに入力した値が1)のオプションボタンの配置された行のセル(項目A~E)に上書きされる

というような動きなのですが、2)のところでオプションボタンの図形オブジェクトの左上隅が含まれるセルの情報を取得するはずが、なぜか3行下の情報を取得してきます。
下のイメージの場合、ボタン①を押すと、本来は2)でセルA1~E1の値を取得したいのですが、実際にはA4~E4の値を取得してくるということになります。

((シート上の配置のイメージ))
ボタン① セルA1 セルB1 セルC1 セルD1 セルE1
ボタン② セルA2 セルB2 セルC2 セルD2 セルE2
ボタン③ ・ ・ ・ ・ ・



(使用しているコード)

Private Sub CommandButton1_Click()
Dim ActiveRow As Long
With ActiveSheet.Shapes(Application.Caller).TopLeftCell.Offset(0, 0)
lastRow = .Cells(.Rows.Count, 0).End(xlUp).Row
Me.項目A.Text = .Cells(lastRow, 8)
Me.項目B.Text = .Cells(lastRow, 9)
Me.項目C.Text = .Cells(lastRow, 10)
Me.項目D.Text = .Cells(lastRow, 11)
Me.項目E.Text = .Cells(lastRow, 12)

End With
End Sub


初心者のため、読み方も原理もわからず、コードのせいなのか、またはほかに原因があるのか、皆目見当がつかずとにかく困っています。

どなたか詳しい方、ご助言お願いいたします。

コードの意味が今一つわからないままネットで調べたコードを切り貼りして、とにかく動いたものをそのまま使っているため、意味をなさない構文になっているかもしれません。そのあたりもご助言いただけると幸いです。

よろしくお願いいたします。

補足補足
<シート上での配置について>
1行目から3行目までがヘッダーで、4行目以降がレコードになります。

<セルの値の取得について>
上記コードで情報を取得すると、レコードの3件目(シートの7行目)までは、想定しているようにその行のレコードの情報を取得できます。
シート8行目(レコード4件目)以降、質問に書いたような3行下のレコードの情報が取得される状態です。

閲覧数:
145
回答数:
3

違反報告

ベストアンサーに選ばれた回答

プロフィール画像

カテゴリマスター

tai********さん

2017/12/1509:55:41

そのコードだとオプションボタン一つ一つにマクロの登録が必要でオプションボタンを押したとき呼び出し元のボタンの位置をApplication.Callerで取得するような感じになります。
それには下準備が必要です。標準モジュールに

Sub 登録()
Dim ob As Object
For Each ob In ActiveSheet.OptionButtons
ob.OnAction = "ユーザーフォーム起動"
Next
End Sub

Sub ユーザーフォーム起動()
UserForm1.Show
End Sub

と記述しておいて
Sub 登録()を実行します。これでオプションボタンを押したときユーザーフォームが起動します。


またオプションボタンの位置のデータを取得するはずがいつも間にか最終行のデータを取得するコードになってしまってます。最終行でなければ
ユーザーフォームのコードに

Private Sub CommandButton1_Click()
Dim ActiveRow As Long
With ActiveSheet
ActiveRow = .Shapes(Application.Caller).TopLeftCell.Row
Me.項目A.Text = .Cells(ActiveRow, 8)
Me.項目B.Text = .Cells(ActiveRow, 9)
Me.項目C.Text = .Cells(ActiveRow, 10)
Me.項目D.Text = .Cells(ActiveRow, 11)
Me.項目E.Text = .Cells(ActiveRow, 12)
End With
End Sub


コマンドボタンを押すとオプションボタンの位置のデータをテキストボックスに入れます。ただしオプションボタンから呼び出さないで直接ユーザーフォームを呼び出してコマンドボタンを押すとエラーになります。モードレスでもエラーです。ActiveRowにうまくShapes(Application.Caller).TopLeftCell.Rowが入らないからですね。

これならActiveXのOptionButtonのクリックイベントを使った方がはるかにまし・・

という感じですが。

この回答は投票によってベストアンサーに選ばれました!

ベストアンサー以外の回答

1〜2件/2件中

並び替え:回答日時の
新しい順
|古い順

hel********さん

2017/12/1507:29:20

>一行ごとにオプションボタンを配置し

この1文よりマクロを使うメリットがないです。仮に、100行あれば100個作る必要が出てきますし、複数の行が削除された時に、しっかりとオプションボタンを削除しないといけません。

マクロは効率的に、より簡潔にすることもメリットがあります。

データを取得したい行であれば、その行にアクティブセルを置いて、ボタンを押せば良いですよね。ユーザーフォームにアクティブセルのあるAからE列までのデータがテキストボックスに入り、変更ボタンを押すと上書きして、ユーザーフォームが閉じれば簡潔になります。

シートにユーザーフォームを起動するボタンを作ります。以下が登録するマクロです。標準モジュールに作成ですね。

Sub ボタン1_Click()
Dim myRow As Long
myRow = ActiveCell.Row
With UserForm1
.項目A.Text = Cells(myRow, "A")
.項目B.Text = Cells(myRow, "B")
.項目C.Text = Cells(myRow, "C")
.項目D.Text = Cells(myRow, "D")
.項目E.Text = Cells(myRow, "E")
UserForm1.Show
End With
End Sub


次にユーザーフォームに変更(上書きする)ボタンを作り、そのコードが下になります。

Private Sub CommandButton1_Click()
Dim myRow As Long
myRow = ActiveCell.Row
Cells(myRow, "A") = Me.項目A.Text
Cells(myRow, "B") = Me.項目B.Text
Cells(myRow, "C") = Me.項目C.Text
Cells(myRow, "D") = Me.項目D.Text
Cells(myRow, "E") = Me.項目E.Text
Unload Me
End Sub

あと、キャンセルボタンも作ったほうが良さそうね。

今回のマクロは、通常のセル上で操作できるものです。あえてユーザーフォームを使うメリットは少ないようですが、学習としてならば、マクロを勉強してから行いましょう。

また、あなたの示したコードには先に回答されているように、意味が不明な無茶苦茶なコードです。これでA~E列のデータが取得できたとは?

Cellsは、Cells(行,列)で構成されます。行は変数を使いますが、列は8、9、10・・と書かれていますよね。これって8列目、9列目・・ということです。A列は1列目です。なので、A~E列までのデータは取得できないと思います。

コードを読めるようになれば、おのずと自分で書けるようになります。

yok********さん

2017/12/1502:13:58

>ユーザーフォームを使って、入力済みのセルの情報を簡単に書き換えられるような仕組みを作りたいと考えています。

なぜ本来書き換え可能なセルの情報をわざわざユーザーフォームに
持っていく必要があるのでしょうか?

ユーザーフォームは初心者が取り組むテーマではないと思いますよ。
EXCEL本来の処理とは別で操作する人へのサービス提供ですから
使う人がいて作る側専門の人が考えること。初心者を自認されるなら
自分で利用するためのEXCELのコードから始めて
EXCEL本来の処理を一通りマスターしてからでも
遅くはないと思います。

その上で疑問なコードだけご指摘させて頂きます。
行は押したボタンで決めているんですよね?
ではlastRow最終行は何の目的で使っているんですか
さらに最終行にそのボタンの行を加算ですよね実質。
これで本当にデータは入るんですか?

さらにA-EというけどCellsは8-12これって
何の意味でしょう?

そもそもWithでボタンのセル番地を出しているのに
そこにCellsで番地をずらせるという手法は
どうしてそれを採用したのでしょう?
ややこしいことこの上ないと思いますが。

あわせて知りたい

みんなで作る知恵袋 悩みや疑問、なんでも気軽にきいちゃおう!

Q&Aをキーワードで検索:

Yahoo! JAPANは、回答に記載された内容の信ぴょう性、正確性を保証しておりません。
お客様自身の責任と判断で、ご利用ください。
本文はここまでです このページの先頭へ

「追加する」ボタンを押してください。

閉じる

※知恵コレクションに追加された質問は選択されたID/ニックネームのMy知恵袋で確認できます。

不適切な投稿でないことを報告しました。

閉じる