プロが教えるわが家の防犯対策術!

Word2007で数式入力開始時に,IMEを自動的に半角英数にしたいので次のようなマクロを作ってみました.(Word2003以前は自動でIMEがオフになったのに)
Sub EquationPlus()
If IMEStatus <> vbIMEModeHiragana Then
'SendKeys "{kanji}"
SendKeys "%{kanji}" '漢字キーの代わりに変換キーを使っているので
WordBasic.EquationEdit
Else
WordBasic.EquationEdit
End If
End Sub
問題は,数式モードを抜けたらIMEを全角ひらがなに戻したいのですが,WordBasic.EquationEditの直後にSendKeys "%{kanji}"を付けると,数式モードを抜ける前に全角ひらがなに戻ってしまいます.

数式モードを抜けたことを検出してIMEを全角ひらがなに戻すことは可能なのでしょうか.

A 回答 (5件)

こんばんは。



本来、私はコードを書くべきなんですが、確実といえるものがひとつもないのです。今のところ、Win32API のSendKey がありますが、そこからキーを送る方法があります。CreateObject("Wscript.Shell").SendKeys は、VBAと同じキーコードですが、これは、外部からキーコードを送りますから、一旦命令を送れば、その後のWord内の内部オブジェクトに影響されません。

それと、
>RunでOLEを指定すると思うのですが,それが無い?
Run で動かすのは、Exe ファイルです。OLEは、タイプテーブルかダイナミックリンクですから、Run では呼び出せません。

どうやら、ご自身で、調べながらでもコードを作ることが出来そうですね。

ただ、もう一度、最初の質問のコードを良くみると、良く分からない部分がまだありますね。
そのコードのロジックで、IMEのオンオフは可能だったのでしょうか。

たぶん、トグルになっているのだと思いますが、
'-------------------------------------------
If IMEStatus <> vbIMEModeHiragana Then 
ひらがなモードでなければ、[Alt+ 漢字] キーを押せば、IMEはOn になるはずです。
その後で、Equation Editor を起動する/Off にする
'-------------------------------------------
起動していれば、
そのまま、 Equation Editor を起動する/Offにする
'-------------------------------------------
と読んでいます。

以下は、ためしに作ったもので、思ったよう動かないかもしれません。

'標準モジュール

'Option Explicit

Public Declare Sub keybd_event Lib "user32" (ByVal bVk As Byte, ByVal bScan As Byte, ByVal dwFlags As Long, ByVal dwExtraInfo As Long)
  
  Public Const VK_SHIFT As Long = &H10
  Public Const VK_LMENU As Long = &HA4
  Public Const VK_KANJI As Long = &H19
 
  Public Const KEYEVENTF_EXTENDEDKEY = &H1
  Public Const KEYEVENTF_KEYUP = &H2
Public Sub IMEControl_Prc()
'Word 2007 VBA Only
 If IMEStatus = vbIMEModeOn Then
   'IMEMode Off
   keybd_event VK_LMENU, 0, KEYEVENTF_EXTENDEDKEY Or 0, 0
   keybd_event VK_KANJI, 0, 0, 0
   keybd_event VK_LMENU, 0, KEYEVENTF_EXTENDEDKEY Or KEYEVENTF_KEYUP, 0
   WordBasic.EquationEdit
  Else
   'rid of 'Equation Editor'
   If Selection.OMaths.Count >0 Then
     Selection.HomeKey Unit:=wdStory '数式エディタを外す
   End if
   'IMEMode On
   keybd_event VK_LMENU, 0, KEYEVENTF_EXTENDEDKEY Or 0, 0
   keybd_event VK_KANJI, 0, 0, 0
   keybd_event VK_LMENU, 0, KEYEVENTF_EXTENDEDKEY Or KEYEVENTF_KEYUP, 0
 End If
End Sub

この回答への補足

ありがとうございます.
If IMEStatus <> vbIMEModeHiragana Then 
について,スレッド作成時に恥ずかしい間違いをしてしまいました.^^;
最初の補足内容で書いてはいたのですが見づらくて申し訳ありませんでした.
以下が要件でございます.
数式入力時にはIMEを必ずオフにしておきたい.
数式入力終了後は(数式入力)以前のIME状態に戻したい.
でございます.
サンプルをお教えいただいて,Word2007における,
(1) VBAからWin32APIの呼び出し方.
(2) keybd_eventの使い方.(winuser.hにコード表有り)
VK_LMENUなどの拡張キーに必要なフラグ
キーを戻すときは,| KEYEVENTF_KEYUPも付けるなど.
(3) Selection.OMaths.Countで数式状態かが判別できる.
(4) Selection.HomeKey Unit:=wdStoryで文頭に移動できる.
(Selection.EndKeyにして使用しています)
といった大事なことが理解できました.

私の環境では,
Change KeyというソフトやIMEの設定で,
キーを入れ替えたりしているので独自の記述が必要になったのですが,すべてOKでした.

VBAにフックの概念はあるのか?,オブジェクトの状態をバックアップしてどこかに記憶させておくことは可能なのか?などが今後の調査課題ですが,とりあえず不自由はなくなったので必要になったときにまた考えるようにします.

本当にありがとうございました.

補足日時:2009/10/08 12:07
    • good
    • 0

こんにちは。



>MFCと.NetFrameWorkの対応が良く分からないことにかなり戸惑いました.もうひとつ私にとって痛いのは,そもそもプログラムが必要となるような対象がほとんどなくなってしまったことなのですが

分かっている話なのかもしれませんが、.Net FrameWork のプログラミングというのは、つまるところ、VS2008 とか、Microsoft が供給するVSシリーズになるのではありませんか。これを、まったく知らないというわけには行かないとは思うのですが、*

Office VBAに、この.Net の波が来るのはだいぶ後になりそうです。Office 2003 以降は、.Net FrameWork はある程度対応しているようです。**

(*前回と今回のCと.Net FrameWork の関係の根拠)
Microsoft Win32 と Microsoft .NET Framework API との対応
http://msdn.microsoft.com/ja-jp/library/aa302340 …

(**Office VBAで、オートメーション・オブジェクトから、.Net FrameWork の一部を利用する)
CreateObject("System.Collections.ArrayList")

ただ、私個人からすると、Office VBAの Excel, Access は、研究尽くされてはいても、それ以外の情報は、あまり良く得られません。日本語の情報にはかなり限界があります。それに、Word VBAに関しては、Excel VBAより仕様が先に行っているようです。それだけに、高い技術が必要とされるようです。

私自身の後の残りの人生のことを考えると、今のところ、C言語に関係するものは、特別にMicrosoft 側の新しい技術に追従する必要性がないような気がしています。たぶん、いつまで経っても、追いつかずに振り回されるだけのような気がします。Microsoft というのは、そういう仕組みになっているのではないでしょうか。もっと、ベースの部分を固めていれば、ほとんどのことは対応できるのではないかと思っています。
 
プログラム言語でも、必要のあるなしに関係なく、最終目的を置かないことかもしれませんね。
目的はなくても、淡々と先を求めていけば、いずれは形になるのではないかと思ったりします。

適切な答えになっているか分かりませんが、そう思いました。

この回答への補足

返信が遅くなってしまい申し訳ありません.
VBA, .Net Frameworkの全体像を教えていただきありがとうございます.

> 今のところ、C言語に関係するものは、特別にMicrosoft 側の新しい技術に追従する必要性がないような気がしています。

私は,C/C++でプログラムを書くときに,(これでいいのかな?と)リソースの開放が気になってしまいます.C言語はハードの動きをイメージすると理解しやすいので,逆にハードの動きが見えなくなると不安を感じます.
なるべく多くのプログラミングに挑戦しながら一つ一つ理解していきたいと思います.今後ともよろしくお願い申し上げます.

補足日時:2009/10/13 12:28
    • good
    • 0

こんばんは。



>最初の補足内容で書いてはいたのですが見づらくて申し訳ありませんでした.

そうでした。最初に見ていた時点では、別のことを考えていたので、頭に残っていませんでした。失礼しました。

良く研究されていますね。そこで、ひとつ・ふたつのアドバイスと、本質的な今後の問題に関して大事なことを書かせていただきます。

>VBAにフックの概念はあるのか?,
何に対するフックか分かりませんが、Win32APIに関してはいくつかあります。

>オブジェクトの状態をバックアップしてどこかに記憶させておくことは可能なのか?
それは、良く分かりません。しかし、目算のない考えですが、数式エディタに関しては、あらかじめ作るという方法は可能だと思います。

今後の課題ということをお書きになっていましたが、大きな問題は、私は、Win32API自体は、C++に戻っていくものだと思います。Microsoft 側では、.Net FrameWork を使う方向に進んでいます。だから、Win32API + VBの有名なサイトが、ひとつ消えました。別途、WMIを使用することが増えてきています。C言語は、あくまでも、独自路線だと思います。

今の段階では、これらは選択肢のひとつに過ぎません。私個人は、どうするかは、ある程度決めています。

この回答への補足

今後の課題にまで光明を与えていただきまして本当にありがとうございます.先輩方の「可能だと思う」という進言は本当に心強いです..Net FrameWorkの方は,かつてXMLをかじったときに便利に感じました.(XMLはかじっただけです)一方で,他のウインドウをキャプチャするプログラムを作ろうとしたときにhWndを取得する方法がわからずに挫折したような記憶があります.MFCでプログラミングを始めた人間なので,MFCと.NetFrameWorkの対応が良く分からないことにかなり戸惑いました.もうひとつ私にとって痛いのは,そもそもプログラムが必要となるような対象がほとんどなくなってしまったことなのですが.
一般人でもプログラミングを楽しめるような秘策があると良いのですが.(最後はかなり脱線してしまいました.すみません.)
今後ともよろしくお願いいたします.

補足日時:2009/10/08 23:33
    • good
    • 0

こんにちは。



私の疑問は解けました。
>Word2003以前は自動でIMEがオフになったのに
と書かれていたので、Word2003 で、お使いになっていたコードだと思っていました。
それは、Word2007 のコードで、Word2007のみのものだったのですね。

>ちょっと厄介そうに感じてきました.

うまく行かないのは、内部オブジェクトを呼び出す、そのタイムロス(正しくはオーバーヘッド)があるからですから、やはり、IMEに対しては、WordBasic.EquationEdit を操作する前に、IMEに命令を先にしてあげるか、CreateObject("Wscript.Shell").SendKeys で命令を送るという方法があります。

そうでなければ、Win32APIを使ってみる価値はあります。

この回答への補足

ありがとうございます.キーワードをいろいろと教えていただいてとても勉強になりました.
(でも,私の力不足で解決できなくてすみません.)

1.CreateObjectでWscript.Shellオブジェクトの生成を完了してからSendKeysを送る方法について
(createobject wscript.shell sendkeys)で検索し,@ITのページを知ることができました.
@ITでは,
(1)Wscript.Shellオブジェクトへの参照objShellを得る.
(2)objShell.Run "外部アプリケーション"
(3)objShell.SendKeysでその外部アプリケーションにキーを送る.
のようでした.OLEオブジェクトをVBAで扱う際に参考になりそうです.
(ただ,SendKeysを送りたいのが,
CreateObjectを実行したオブジェクトそのものなので,
どう指定してよいのか分かりませんでした.
RunでOLEを指定すると思うのですが,それが無い?)

2.VBAからWin32APIを呼び出す.
Declare FunctionでDLLとAPI関数を指定することを検索で知ることができました.IMEは,ImmSetConversionStatus APIが使えそうに思いました.

現在の状況として,
○ 数式入力モードになった時点で,IMEを半角直接入力にすることは,
SendKeys "%{kanji}" (私は,変換キーを漢字キーと入れ替えています)
で,OK.
○ 数式モードを抜けた時点で,IMEを元の全角ひらがなに戻す方法は未解決.
でございます.
とりあえず,数式モードを抜けた時点でマニュアル入力で全角ひらがなに戻して使っております.

従来,数式モードに入った時点で全角のまま入力すると,それに気づいてBSキーを押しただけで勝手に数式モードを抜けてしまって困っておりました.それが無くなっただけでだいぶ楽になりました.

いろいろとありがとうございました.

補足日時:2009/10/07 13:12
    • good
    • 0

こんばんは。



うまく行かない場合は、IMEの命令とオブジェクトの設定を逆にすると良いようです。また、Win32APIを使ってみたらどうかということも考えます。

ただ、以下の部分が良く分からないのです。

> WordBasic.EquationEdit

これは、数式エディタを呼び出すものだとは思うのですが、数式エディタは、OLE Object ですから、WordBasicオブジェクトにはないはずで、呼び出せないと思います。どういうテクニックなのでしょうか?

この回答への補足

お世話になります.
(Word2007 数式 OLE)でGoogle検索したところ,2007以降の数式はOLEではないような主旨の情報が見つかりました.
ちょっと厄介そうに感じてきました.

質問の本質ではないのですが,恥ずかしいことに
If IMEStatus <> vbIMEModeHiragana Thenは,
If IMEStatus = vbIMEModeHiragana Thenの誤りでございます.
どうやら,XP SP3の言語設定で,詳細なテキストサービスをオフにしておかなかったので,IMEStatusの返り値が常にvbIMEModeOffでした.

補足日時:2009/10/07 10:22
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!