質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
VBA

VBAはオブジェクト指向プログラミング言語のひとつで、マクロを作成によりExcelなどのOffice業務を自動化することができます。

Q&A

解決済

4回答

6017閲覧

エクセル(2010)でリストボックス内のテキストを、ワークシート上の任意のセルにドラッグアンドドロップで表示

kate-zak

総合スコア13

VBA

VBAはオブジェクト指向プログラミング言語のひとつで、マクロを作成によりExcelなどのOffice業務を自動化することができます。

0グッド

0クリップ

投稿2019/02/14 02:38

前提・実現したいこと

###エクセル(2010)でリストボックス内のテキストを、ワークシート上の任意のセルにドラッグアンドドロップで表示

表題につきまして、VBAを使用して実現できないかご質問です。

リストボックスをユーザーフォームに配置し、任意のテキストを複数入力しておきます。
テキストの一つを選択し、ドラッグしてワークシート上の任意のセル上でドロップすることで、
選択したテキストがセル上に反映する、といったことは実装可能でしょうか。

リストボックス内の多数のテキスト情報を、決められたフォームのスケジュール表に落とす作業がありまして、
今まではセル選択⇒テキスト選択⇒入力ボタン押下、で処理するようにしていましたが、1工程でも
操作性を改善できないか模索しております。

そこで表題のような方法を考えているのですが、
エクセルのみを使用する場合、理屈上実行可能なものなのか知りたく思います。
VBA関連で似たような情報を探しておりましたがなかなか回答が見つからず、
自作で試行しておりますが、最初から躓いており、まだ上手くいっておりません。

大まかな記述で恐縮ですが、
何卒ご教示の程よろしくお願いいたします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答4

0

ベストアンサー

ちょっと適当ですが簡単な実装例を。

まず、Window.RangeFromPoint メソッド (Excel)を使用すると、画面上の座標から、Excelのウィンドウ上のオブジェクト(セル or 図形 or なし)を取得できます。

あとはマウスのボタンが放されたときに、その位置を元にセルを取得できれば良さそうということになります。

ListBoxなどには、MouseDown、MouseUp イベントがあります。
このイベントはドラッグ開始点がそのコントロール上であれば、コントロール外でボタンを放したとしてもその時点でMouseUpイベントが発生します。
そのため、これでマウスのボタンが放されたタイミングも捕捉できます。
もう一つ必要な情報のマウスの位置ですが、こちらはMouse関連のイベントだけでは取得がちょっと難しいです。
イベントの引数のX、Yはありますが、これら相対位置になるので、絶対位置への変換&画面上への座標系の変換が必要になります。

とりあえず最低限必要そうな部品は以上になります。

上記のことを踏まえて私が適当に実装してみたのが以下のコードになります。

リストボックスの名前はListBox1としています。

vba

1Option Explicit 2 3'Windows API用定義 4Private Type ApiPoint 5 X As Long 6 Y As Long 7End Type 8 9Private Declare PtrSafe Function _ 10 GetCursorPos Lib "User32" (lpPoint As ApiPoint) As Long 11 12'リストボックスの値 13Private currentValue_ As String 14'ドラッグ中かどうか 15Private onDragMove_ As Boolean 16 17'マウス関連のイベントの左ボタン押下時の値 18Const LeftButton = 1 19 20 21Private Sub ListBox1_Change() 22 'ドラッグ中でなければ値を変更する(ドラッグ中でも値が変わってしまうことの対策) 23 If Not onDragMove_ Then 24 currentValue_ = Me.ListBox1.Text 25 Me.Caption = currentValue_ '選択したものをわかりやすくするためフォームのタイトルにも表示 26 End If 27End Sub 28 29 30Private Sub ListBox1_MouseMove(ByVal Button As Integer, ByVal Shift As Integer, ByVal X As Single, ByVal Y As Single) 31 '左ボタンでドラッグ&Shift,Ctrl,Altなどが押されていない時をドラッグ中とする(Shiftなどはキャンセル用) 32 onDragMove_ = (Button = LeftButton) And (Shift = 0) 33 34 'ドラッグ中じゃなければ抜ける 35 If Not onDragMove_ Then Exit Sub 36 'フォーム上なら誤爆防止のため抜ける 37 If mouseEventIsOnForm(Me.ListBox1, X, Y) Then Exit Sub 38 39 'セルの上にカーソルがあれば、そのセルを選択する(対象のセルをわかりやすくするため) 40 Dim r As Excel.Range 41 If TryGetRangeOfOnCursor(r) Then 42 r.Activate 43 End If 44End Sub 45 46Private Sub ListBox1_MouseUp(ByVal Button As Integer, ByVal Shift As Integer, ByVal X As Single, ByVal Y As Single) 47 'フォーム上なら誤爆防止のため抜ける 48 If mouseEventIsOnForm(Me.ListBox1, X, Y) Then Exit Sub 49 50 'セルの上にカーソルがあれば、そのセルに値を入れる 51 Dim r As Excel.Range 52 If TryGetRangeOfOnCursor(r) Then 53 If currentValue_ <> VBA.vbNullString Then 54 r.Value() = currentValue_ 55 End If 56 End If 57End Sub 58 59 60'カーソルがRangeの上にあればそのRangeを取得してみる 61Private Function TryGetRangeOfOnCursor(ByRef outOnCursorRange As Excel.Range) As Boolean 62 'Windows API無しでも取れるはずだけど、補正が面倒だったので 63 'Windows APIで位置を取得 64 Dim pt As ApiPoint 65 If CBool(GetCursorPos(pt)) = False Then Err.Raise 5, , "Fail GetCursorPos" 66 67 'ディスプレイ上の座標をもとに、Excelの最前面のウィンドウからその位置のものを取得 68 Dim obj As Object 69 Set obj = Excel.ActiveWindow.RangeFromPoint(pt.X, pt.Y) 70 71 If TypeOf obj Is Excel.Range Then 72 Set outOnCursorRange = obj 73 Let TryGetRangeOfOnCursor = True 74 End If 75 76End Function 77 78 79'マウス関連イベントがフォーム上で起こったかどうか 80Private Function mouseEventIsOnForm(Sender As MSForms.Control, X As Single, Y As Single) As Boolean 81 'マウス関連イベントは、イベント発生コントロールの左上を起点にX・Yが出力される 82 83 Select Case X + Sender.Left 84 Case 0 To Me.Width 85 'Next 86 Case Else 87 Exit Function 88 End Select 89 90 Select Case Y + Sender.Top 91 Case 0 To Me.Height 92 'Next 93 Case Else 94 Exit Function 95 End Select 96 97 Let mouseEventIsOnForm = True 98End Function

一部挙動が微妙なところはありますが、恐らくイメージに近いものだと思われます。

投稿2019/02/14 14:06

編集2019/02/14 14:14
imihito

総合スコア2166

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

kate-zak

2019/02/14 17:24

ご回答と具体的な例のご提案をいただきありがとうございます! 私はまだ勉強途中ですが、非常にご丁寧に記述頂きまして、学びつつ順を追って追いかけられそうです。 こちらでご提案いただいたものを元に、一度組み込みを試行させていただければと思います。 貴重なお時間をいただき本当にありがとうございます。
guest

0

そこで表題のような方法を考えているのですが、
エクセルのみを使用する場合、理屈上実行可能なものなのか知りたく思います。

可能か不可能かというと「たぶん」可能です。
ただし、実現しようとすると、
かなり困難でしょう。
僕の知識量では、実現できません^^;(代替案でそのように「見せる」ことは可能かなと思います。)

実現したいなら、まず、
操作対象のリストボックスなどのユーザーフォームの部品(ActiveXコントロール)が、
そういった機能をもっているかどうか(今ドラッグしているというのを検知する機能)があるかないかが
問題です。
幸いにもリストボックスには、
BeforeDragOverイベント
BeforeDropOrPasteイベント
というものが用意されてますので、
同じユーザーフォーム上のリストボックス↔リストボックスのやり取りなら、
比較的容易にドラッグ&ドロップで、値をコピーしたりのやりとりは出来そうです。
ただし、
シート上では、そのようなイベントが用意されてないし、
ましてや、マウスから指を離したというMouseUpイベントもないので、
VBAのみでは実現不可能でしょう。

ただし、
リストボックスにない機能(マウスホイール回転によるスクロール)も、
ネット上では実現できているようですので、
実現が不可能ではないだろうと推測します。
個人的には不便をものすごく感じていますが、
そういうものを作ることにはチャレンジしてません。
勉強する暇と気力がないので^^;
もし、そういうことを勉強して自在にエクセルを制御してやろうと考えているのなら、
まずは、マウスホイールによるスクロールという機能を追加してみるところから、
勉強してみてはいかがでしょうか?
そうすることで、今したいことを実現するにはどんな情報が必要かがわかるのでは?と、
推測します。わからなくても手掛かりくらいは掴めると思います。

それともう一つ気がかりなのは、
ユーザーフォーム上からドラッグしていって、
シート上にマウスカーソルが来たときに、
どうやって、エクセルの画面をアクティブにするのか?
ということが、パっと、思いつきません。(まぁ、代替案がなくはないですが。)

そういったことを考えると、この件は、素人が取り組む課題ではないかなぁと思います。

表題につきまして、VBAを使用して実現できないかご質問です。

まず、エクセルVBAで何か機能を作るということは、
「エクセルをカスタマイズ」しているんだということを自覚する必要があります。
ということは、何か不都合が出てきたときに、自分でメンテナンスする必要があるということです。
ユーザーは思いも寄らない操作をします。
(例えば僕なんかは、無意味に画面のあいているところで、右クリックをするくせがあります。)
それら、アプリケーション作成時に予想できなかった事態に、自分で対応する
(掲示板でアドバイスを求めるのも含む)覚悟をもって取り組まないと、
使えるアプリケーションにならないかなと思います。

話しが変わりますが、

リストボックス内の多数のテキスト情報を、

多数とはどれくらいの数を想定してますか?
僕が言葉をそのまま受け取ると、100とか200かなぁと思ってますが、
そんだけのリストの中から思ったデータを見つけるのは、非常に困難かなと、
思うのですが、最終的には10~20くらいに絞り込んでその中から選ぶという事でしょうか?
その辺の想定している数を説明した方が良いと思います。

テキスト情報を、決められたフォームのスケジュール表に落とす作業がありまして

あぁ、そういうことは僕もやったことがあります。

今まではセル選択⇒テキスト選択⇒入力ボタン押下、で処理するようにしていましたが、1工程でも
操作性を改善できないか模索しております。

ならば、リストボックスをダブルクリックすることで、
アクティブセルに文字列を転記するようにしたら、
入力ボタン押下の手間は省くことが可能でしょう。

参考URL>>
https://www.petitmonte.com/excel/excel_vba_30.html
http://kabu-macro.com/word/a-o/event_procedure.html

今、コマンドボタンのクリックイベントに書いているものを、
リストボックスのダブルクリックイベントに書き直すだけで対応可能でしょう。
これなら、少し試行錯誤したら出来るんじゃないでしょうか?

で、ながなが書きましたがここから本題(?)
(代替案の話です。)
僕も昔、同じことを思って(既定の文言を、ドラッグ&ドロップでセルに入れたい)
掲示板でアドバイスを求めました。
そうしたら、サンプルコードを書いてくれた人がいました。
ただし、僕の場合は最大でも20個くらいの選択肢でしたし、
スクロールは絶対したくなかったので、ユーザーフォームなんて
エクセルとは別物ではなく、シート上で全てを用意する仕様でした。
そのアドバイスを元に、
(サンプルをくれた人の案をほぼ訳もわからず転用させてもらっただけですが^^;)

シート上に図形のテキストボックスを人数分用意し、
それぞれに名前を書き、
その図形をクリックした時から、その図形がマウスカーソルに追随し、
意図するセル上でもう一回クリックしたら(実際には図形が追随してますのでその図形をクリックしているのですが)、
テキストボックスの内容をそのセルに転記し、図形は元の位置に戻る。

というような仕様でした。(イメージが伝わりますでしょうか?)
まぁ、遊びの延長なので最終的には使用することはなかったですが、
一応、そういったことは可能でした。
ですが、無限にループしてVBAでマウスカーソルの位置を監視することになるので、
そのことが他にどのような影響があるかまではわかりません。
結局、そのアプリは遊びの延長で作っただけで、実際に運用したわけではないので、
どれくらい使い物になるかはわかりません^^;
ということで、代替案は一応あるよということです。
できれば、その質問のログを見せてあげたいところですが、
そのサイトは既に閉鎖していて、現在みることは不可能です。
(どうしても見たいということなら、誰かがログを保存してるとは思いますが、
「探して」なんて頼めるわけないですしね^^;)
すごい暇してたら、思い出しながらサンプルコード考えてもいいかなと思いますが、
ちょっと最近は時間がなくて、気分転換にちょいちょい横槍入れるのが精いっぱいなので、
ちょっとサンプルとか書ける暇がないですm(_ _)m

興味があれば、マウスカーソルの位置を取得する方法はネット上にあるので、
それを参考に、無限ループをしながらマウスカーソルの位置を監視して、
図形を追随させることに掲示板で質問しながら挑戦してみてはいかがでしょうか?
今の仕様で代替案が無いわけでもないですが、
本当に出来るか、コードを書いたり実験して動かしてテストすることができないので、
この程度の情報のみでご勘弁を ^^)ノシ

投稿2019/02/14 12:06

mattuwan

総合スコア2136

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

kate-zak

2019/02/14 17:10

ご回答ありがとうございます! 私は初学者ですが、考え方を筋道立ててご説明いただき理解が進みました。 たしかにユーザーの振る舞いは予測できないものですので、私自身が道具立てを理解していないといけないことを痛感しております。 ダブルクリックでの入力も確かに工程削減になるので、自身の制約も考慮してなにを優先するか考えていきます。 最後に頂いた代替案ですが、新しく閃くものがあり、純粋に興味深く思いました。 こちらは私も試行して行きます。 丁寧に教えていただきありがとうございます。
guest

0

リストボックスではなくリストビュー(ListView)を使うと、OLEドラッグ&ドロップが使えるようです。
で、試してみてたのですが、うまく実装できませんでした。
もう少し試したかったのですが時間がなくここまでです。
何の解決にもなってませんが、情報として残しておきます。

投稿2019/02/14 05:45

ttyp03

総合スコア16996

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

kate-zak

2019/02/14 09:39

ご回答ありがとうございます! 別の視点から試してみることで可能性があると気づけました。 参考にさせていただきつつ、試行してみます。
guest

0

そういったインタラクティブな操作はVBAだけ実行するのは困難なので、次の方法はいかがでしょうか?

  1. Excelのリストボックスの設定プロパティから、設定に用いている選択文字列すべてを抽出し、エディタに貼り付ける
  2. おそらく、カンマかなにかで区切られているので、それを改行コードに置き換えて一覧にする

あとは、その一覧の文字を使って任意のシートに貼り付ければいいのではないかと思います。

投稿2019/02/14 05:09

FKM

総合スコア3608

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

kate-zak

2019/02/14 09:42

ご回答ありがとうございます! 具体的な方法をご教授いただき幸いです。 たしかにVBAのみと言うのはハードルが高いのかも知れないと考えておりました。 他の手段も視野に入れて取り組んでみます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問