Excel VBA質問箱 IV

当質問箱は、有志のボランティア精神のおかげで成り立っています。
問題が解決したら、必ずお礼をしましょうね。
本サイトの基本方針をまとめました。こちら をご一読ください。

投稿種別の選択が必要です。ご注意ください。
迷惑投稿防止のため、URLの入力を制限しています。ご了承ください。


3747 / 13645 ツリー ←次へ | 前へ→

【60365】日本語入力の制御 山ちゃん 09/2/13(金) 16:22 質問[未読]
【60368】Re:日本語入力の制御 ichinose 09/2/14(土) 14:48 発言[未読]
【60374】Re:日本語入力の制御 山ちゃん 09/2/15(日) 10:06 発言[未読]
【60375】Re:日本語入力の制御 neptune 09/2/15(日) 11:46 発言[未読]
【60381】Re:日本語入力の制御 Abyss 09/2/15(日) 16:14 回答[未読]
【60383】Re:日本語入力の制御 ichinose 09/2/15(日) 20:18 発言[未読]
【60385】Re:日本語入力の制御 山ちゃん 09/2/16(月) 1:27 お礼[未読]
【60386】Re:日本語入力の制御 訂正 ichinose 09/2/16(月) 6:48 発言[未読]

【60365】日本語入力の制御
質問  山ちゃん  - 09/2/13(金) 16:22 -

引用なし
パスワード
   ブックのオープンイベントに
Private Sub Workbook_Open()
UserForm1.Show
End Sub

ユーザーフォームにコマンドボタンを置く。そのボタンに
Private Sub CommandButton1_Click()
Range("A1").Value = "名前を入力してください"
IMEon
GetName = Range("A1").Value
Range("A1").Value = ""
UserForm1.Hide
'取得したGetNameで以下の処理
End Sub

サブルーチンIMEonは
Sub IMEon()
  Application.ScreenUpdating = False
  With Workbooks.Add
    With ActiveCell.Validation
      .Add Type:=xlValidateInputOnly
      .IMEMode = xlIMEModeOn
    End With
    InputString = Sheet1.Range("A1").Value
    buf = Application.InputBox(InputString)
    .Close SaveChanges:=False
  End With
  Application.ScreenUpdating = True
  Sheet1.Range("A1") = buf
End Sub

これらでブックのその時の日本後モードのいかんにかかわらず、名前入力の際自動的に日本語モードにしようとしています。さて、ブックをオープンしても思い通りの日本語モードにならない。

ところがファンクションキーF8でステップ毎にマクロを動かすと思惑通りになる。

また、ユーザーフォームでなくシート上のアクティブXにコードを組めばやはり日本語モードになる。

マクロの間違えを指摘してください。

【60368】Re:日本語入力の制御
発言  ichinose  - 09/2/14(土) 14:48 -

引用なし
パスワード
   こんいちは。


>ブックのオープンイベントに
>Private Sub Workbook_Open()
>UserForm1.Show
>End Sub


>サブルーチンIMEonは

>Sub IMEon()
>    InputString = Sheet1.Range("A1").Value
    SendKeys "{kanji}"
>    buf = Application.InputBox(InputString)
>  Sheet1.Range("A1") = buf
>End Sub

とするか・・・、

IMEonは、従来どおりのコードで、

>Private Sub CommandButton1_Click()
>Range("A1").Value = "名前を入力してください"
me.hide
>IMEon
>GetName = Range("A1").Value
>Range("A1").Value = ""
>'取得したGetNameで以下の処理
>End Sub

とするか・・・、で試してみてください。

因みにIMEonという名前からすると、
私なら
ここは、あくまでもIMEをonにするだけの処理を行い、
入力要求は、呼び出しもとのプロシジャーで行いますけけどね

【60374】Re:日本語入力の制御
発言  山ちゃん  - 09/2/15(日) 10:06 -

引用なし
パスワード
   ichinose さんの回答はいつも分かり易く、的を得ており、感銘を受けていました。お答え頂き、ありがとうございます。

さて、いくつか分けて疑問を呈します。お答え頂けたら嬉しいです。

そもそも、こんなまどろっこしい手法に至ったのは、InputBox関数自体にIMEを制御する機能がないからなのです。

SendKeys "{kanji}"はIMEをオン/オフするだけですよね?ブックのオープン当初では、これでうまくいきます。ところが私のこのUserForm1は何度も使用されるのです。対になったサブルーチンIMEoffがあり、メールアドレスなどを要求させるのです。

Me.Hideを入れただけで、うまく行くのはなぜなのか釈然としない。ちょっと説明が欲しいなあ。

一番大きな疑問はこれなんです。私のコードでどこかにブレークポイントを設定し、そこからステップ毎に動かすと思い通りの結果が得られるのです。

私のコードでうまく行かないのはオープン当初だけで、後には全て思い通りに行くのです。

まるっきしサラにして、InputBox関数のIMEを制御するような手法を出して頂けたら。

【60375】Re:日本語入力の制御
発言  neptune  - 09/2/15(日) 11:46 -

引用なし
パスワード
   ▼山ちゃん さん:
こんにちは

ichinose さんではありませんが。

>そもそも、こんなまどろっこしい手法に至ったのは、InputBox関数自体にIMEを制御する機能がないからなのです。
なら、ご自分の好みのinputboxをuserformで自作する事をお勧めします。

sendkeyは動作を保障されたコマンドではないので100%を求めるのはそもそも
酷と思います。ActiveなWindowに送るコマンドですから。

>一番大きな疑問はこれなんです。私のコードでどこかにブレークポイントを設定し、そこからステップ毎に動かすと思い通りの結果が得られるのです。
>私のコードでうまく行かないのはオープン当初だけで、後には全て思い通りに行くのです。
自信は無いですが、IMEってのは現在ActiveなWindowに対して制御されるため
の挙動ではないでしょうか?コンパイル時の挙動と、コンパイル後の挙動では
違ってきても不思議ではないと思います。

>
>まるっきしサラにして、InputBox関数のIMEを制御するような手法を出して頂けたら。
InputBox関数の仕様としてIME操作の機能を持ってないのですから、
100%を求めるとなると、やはりmessageをフックするとかの手法になるかと
思います。
が、ExcelVBAではサブクラスという手法そのものが実用に耐えません。
・・・理由は割愛します。
(InputBox関数で出来るかどうかは試した事ありませんので可不可は判りません)

最初に書いたようにUserFormで自作するのが一番楽チン簡単と思います。

参考
プラットフォーム SDK
Input Method Editor (IME)
ht tp://msdn.microsoft.com/ja-jp/library/cc422019.aspx
[XL95]日本語入力システムのオン/オフを制御する方法
ht tp://support.microsoft.com/kb/407890/ja

【60381】Re:日本語入力の制御
回答  Abyss  - 09/2/15(日) 16:14 -

引用なし
パスワード
   > まるっきしサラにして、InputBox関数のIMEを制御するような手法を出して頂けたら。

InputBoxはExcelアプリに対してModal動作をしますから、
InputBox状態に入る前にExcelのIME状態を希望の状態に
設定し、処理後に前の状態に戻す。

この手順でよろしいかと思います。
とりあえず、標準モジュールでのテストです。

(Sample)

Declare Function ImmGetContext Lib "Imm32" _
  (ByVal Hwnd As Long) As Long
  
Declare Function ImmReleaseContext Lib "Imm32" _
  (ByVal Hwnd As Long, _
   ByVal Himc As Long) As Long

Declare Function ImmGetOpenStatus Lib "Imm32" _
  (ByVal Himc As Long) As Long

Declare Function ImmSetOpenStatus Lib "Imm32" _
  (ByVal Himc As Long, _
   ByVal fOpen As Long) As Long
 
Sub aTest()

  Dim Hwnd As Long
  Dim IMC As Long
  Dim Flag As Long
  
  Hwnd = Application.Hwnd
  IMC = ImmGetContext(Hwnd)
  
  ' 現在のIMEOnOff状態を取得...
  Flag = ImmGetOpenStatus(IMC)
  
  ' IME Onの状態に設定...
  ImmSetOpenStatus IMC, 1&
  ImmReleaseContext Hwnd, IMC
  
  Application.InputBox "名前を入力してください。"
  
  ' 当初のIME状態に復帰 ...
  IMC = ImmGetContext(Hwnd)
  ImmSetOpenStatus IMC, Flag
  ImmReleaseContext Hwnd, IMC
  
End Sub

【60383】Re:日本語入力の制御
発言  ichinose  - 09/2/15(日) 20:18 -

引用なし
パスワード
   こんばんは。


>
>そもそも、こんなまどろっこしい手法に至ったのは、InputBox関数自体にIMEを制御する機能がないからなのです。
これは、私もUserformを使って、Inputboxを自作する方法が適当だと思いますねえ!!


>
>SendKeys "{kanji}"はIMEをオン/オフするだけですよね?ブックのオープン当初では、これでうまくいきます。ところが私のこのUserForm1は何度も使用されるのです。対になったサブルーチンIMEoffがあり、メールアドレスなどを要求させるのです。

{kanji}では、そうなりますね!!


>
>Me.Hideを入れただけで、うまく行くのはなぜなのか釈然としない。ちょっと説明が欲しいなあ。

ユーザーフォームがモーダルで表示されている状態では、入力規則の設定では、
IMEのモード変更は簡単なテストコードでは出来ませんでした。
Me.Hideの実行する順序の変更は、このテスト結果からの推測に過ぎません。


>私のコードでうまく行かないのはオープン当初だけで、後には全て思い通りに行くのです。
このうまくいくという手順がわかりませんが、私の環境では、
何度繰り替えしても、出来るものは出来るし、出来ないものはできないと言う結果でした。
これを明確にするには、もっと山ちゃんさんと私の扱っているUserformの同期を
取る必要があるかもしれません。Win2000&Excel2002

因みにUserformとIMEではテキストボックスのImemodeだって、うまく作動しない場合が
ありますよ!!
Frameに配置すると、IME関連は、是正されますが、これはこれで
別の問題が生じたりして、厄介です。


>まるっきしサラにして、InputBox関数のIMEを制御するような手法を出して頂けたら。

これは、繰り返しますが、私も Userformで自作して----アドイン登録し、汎用的に使えるようにする

ですね!!


今回の事との因果関係はないと思いますが、
モーダルモードのUserformを表示した状態で
Application.Inputboxメソッドを使用すると、

実行後のUserformがモーダルモードになっていると言う現象を確認しています。
(今回は、Inputbox実行後に hideなので直接関係ないですけど)

【60385】Re:日本語入力の制御
お礼  山ちゃん  - 09/2/16(月) 1:27 -

引用なし
パスワード
   皆さん、丁寧に解説していただきまして、ありがとうございます。

お陰様で、今回の件でもたくさんのことを学びました。この板の素晴らしさを再確認いたしました。

ユーザーフォームを使って、InputBoxを自作しましょう。

【60386】Re:日本語入力の制御 訂正
発言  ichinose  - 09/2/16(月) 6:48 -

引用なし
パスワード
   おはようございます。

>モーダルモードのUserformを表示した状態で
>Application.Inputboxメソッドを使用すると、
>
>実行後のUserformがモーダルモードになっていると言う現象を確認しています。
          ↑モーダレスモードの間違いです

>(今回は、Inputbox実行後に hideなので直接関係ないですけど)

3747 / 13645 ツリー ←次へ | 前へ→
ページ:  ┃  記事番号:
2610219
(SS)C-BOARD v3.8 is Free