hiroshi akutsuの日記

主にプログラミング関係のこと

vba【大量の複数の印刷範囲の設定の仕方】

忘れやすいのでメモ。

vbaのPageSetup.PrintAreaプロパティはセル範囲をA1形式の文字列で設定し、複数の範囲にしたい場合はカンマで区切れば複数範囲の印刷設定が可能である。

こんな風に...

ActiveSheet.PageSetup.PrintArea = "A1:G5,A8:G13"

しかし、なぜそんな制限(というか仕様)にしてしまったのかよくわからないが、残念なことに設定値の文字列が255文字を超えたらエラーになる。

どうすべきかと言えば、一旦印刷範囲をUnionでrangeオブジェクトにして、Nameプロパティでセルに名前を付けて、PrintAreaプロパティに付けた名前を渡せばいい。

Dim ra As Range
Set ra = Range("A1:G5")
Set ra = Union(ra,"A8:G13")

'''ループでどんどんUnionしていくイメージ

ra.Name = "印刷範囲"
ActiveSheet.PageSetup.PrintArea = "印刷範囲"

excel 2013,2010では動くのを確認できたが、それ以前のバージョンは不明。

vba【コールバックぽく処理を記述】

たとえば、findnextを使って、検索にヒットするすべてのセルに処理を行いたいとします。

こういう時は、コールバックが使えたら便利だなと思っていました。

ただvbaにコールバック関数的なものがあるのか分かりませんが、callbyname関数があってこれを使うとそれっぽくできるとのことなのでやってみたメモを残します。


コールバックする関数はクラスモジュールのCommonMethodsというクラスを作って、そこにパブリックメソッドとして記述します。

第1引数に検索でhitしたセル(findAll関数から渡される)
第2引数にコールバックの大元から送った引数(mainサブルーチンから渡される)

Public Sub changeColor(ByVal fcell As Range, ByRef co As Collection)
    fcell.Interior.ColorIndex = co(1)
End Sub


findnextのループを行う関数はつぎのようになります。
標準モジュールや、クラスモジュールの場合はメソッドとして記述します。

第1引数に検索範囲
第2引数に検索テキスト
第3引数にコールバック関数名のstring
第4引数にコールバック関数に渡す引数のCollection

Private Sub findAll(ByVal ra As Range, ByVal whattxt As String, ByVal callback As String, ByVal callback_args As Collection)
    Dim fcell As Range
    Dim fadd As String

    
    Set fcell = ra.Find(what:=whattxt, LookIn:=xlValues, lookat:=xlWhole, MatchCase:=True)
    If Not fcell Is Nothing Then
        fadd = fcell.Address
        Do
            CallByName New CommonMethods, callback, VbMethod, fcell, callback_args
            
            
            Set fcell = ra.FindNext(fcell)
            If fcell Is Nothing Then
                Exit Do
            End If
            If fcell.Address = fadd Then
                Exit Do
            End If
        Loop
    End If
End Sub

あとはmainから呼び出します。

Sub main()
    Dim callback_args As New Collection
    callback_args.Add 10

    Call findAll(Cells, "test", "changeColor", callback_args)
End Sub


コールバック関数をクラスモジュールに書いているのが若干気持ち悪いです。
javascriptのように無名関数を渡せると非常に勝手がいいなと思いますが、まあそこまでなくても希望の動きはできました。

Virtualbox【guest additionsを入れてもFHD(1920*1080)にならない】

ついこないだまでは、普通にGuest AdditionsをCentOSのデスクトップにインストールすることで、FHDの画面が表示できていた。

しかしこないだVirtualboxのバージョンアップしたところ、FHDにならなくなってしまった。
アイコンもデカいし、文字もデカい。これでは開発環境として使い物にならない。

まあなんかの不具合なんだろうが、対処法が分かったのでメモ。

現在の問題のVirtualboxのバージョンは4.3.28 r100309。
ホストはwindows 7

色々調べた結果、問題の現象は、仮想マシンのshutdown時にホスト側の仮想マシンのウィンドウをFHD画面で最大化していると、次回仮想マシン起動時に起こると判明。

対処法は、仮想マシンのshutdown時に、ホスト側で、仮想マシンのウィンドウを縮小すること。
縮小して仮想マシンをshutdownすることで、次回起動時は縮小されたウィンドウの状態で仮想マシンが立ち上がる。

そうすると、仮想マシンがいい感じの解像度で立ち上がってくれるので、アカウントにログインした後でホスト側でFHDに最大化する。

何ともアナログな方法だが、今のところこうするしかなさそう…。

リモートアシスタンス【teredoで「サーバー名を解決できませんでした」のエラー】

これまでリモートアシスタンスを使って遠隔地と毎日1回はデスクトップの共有を行っていたのですが、2015年の5月初週ぐらいから急に接続ができなくなりました。

原因は、dnsが名前解決してくれないことのよう。


環境はアシスタンスを受ける側とする側ともにwindows 7

リモートアシスタンスはNAT越えにipv6トンネリング技術の1つteredoを利用する。
ネットワークの設定を見ても、ipv6も有効にしているし、インターネットにも接続できている。


アシスタンスを受ける側のPCのコマンドプロンプト(管理者として実行)で

>netsh interface ipv6 show teredo

とやると

エラー:サーバー名を解決できませんでした

と表示される。
以前までは普通にteredo動いていたんだけど、どういう原因かわからないが、windows7デフォルトで指定のあるteredoサーバ(teredo.ipv6.microsoft.com.)の名前解決が死んでいる模様。

pingを打ってみるも

>ping teredo.ipv6.microsoft.com
ping要求ではホスト teredo.ipv6.microsoft.com が見つかりませんでした。ホスト名を確認してもう一度実行してください。

DNSサーバを変えてみるもダメ...
ネットワークアダプタの再起動、PCの再起動、teredoの再起動といろいろやってみましたが状況が変わりませんでした。
社内のwindows7のPCにおいてはまさに全PCそんな状況でした。
途方に暮れかけそうになったのですが、幸い1台だけwindows8.1でテストしていて、そこで

>netsh interface ipv6 show teredo

とやるとこっちは正常にteredoが動いていて、なんでかなと眺めてみるとteredoサーバがwindows7のものと違っていました。
windows8.1のteredoサーバは「win8.ipv6.microsoft.com」。

win8からデフォルトで違うサーバを見ているようです。

もしかしてこのサーバ使えばいけんじゃないかと思って、ためしにwindows7側のteredoサーバを

>netsh interface ipv6 set teredo type=client win8.ipv6.microsoft.com

として変更し、OKが表示されたら再度

>netsh interface ipv6 show teredo

をやるとアシスタンスを受ける側のteredoが復活しました。

アシスタンスを行う側も同様にteredoサーバをwin8...のものを利用し、ようやくリモートアシスタンスが復活しました。

このままwin8サーバを使い続けていいのかどうかはよくわかりませんが、当面これでしのげればいいです。

vba【powerpointのテキストボックスの日本語フォントの変更方法】

PowerPoint VBAでフォントの名前を変更しようとした際、ハマったのでメモ。

環境は以下。

MS office 2013 64bit
Win7

Meiryo UIをテキストボックスのフォントにしようとして、

Slide(1).Shape("textbox").TextFrame.TextRange.Font.Name = "Meiryo UI"

としたんだけど、英数字のみMeiryo UIになって、日本語の文字列にフォント名が反映されなかった。

これは、
Excel 2007 のテキスト ボックスで使用するフォントの種類をマクロで変更できない
に記載があるように、

Slide(1).Shape("textbox").TextFrame.TextRange.Font.Name = "Meiryo UI"
Slide(1).Shape("textbox").TextFrame.TextRange.Font.NameFarEast = "Meiryo UI"

と2行にわたって指定しないといけないらしい。

kvm【qemu-kvm コマンドが見つかりません】

qemu-kvmなどをcentos6.5へインストールしてコマンドからkvmを利用しようとしたときのメモ

$ qemu-kvm -monitor stdio

と打ってみたがどうもコマンドが見つからないらしい。

いやいやそんなはずはない、きちんとインストールしたのに。
念のためyumでもう一回インストールしようとしてみたけどやはりインストール済みになっている。

色々調べたら

/usr/libexec/qemu-kvm

にあるらしい。
基本的には一般ユーザーからではなくスーパーユーザーから操作しないといけないようだ。

パスになかったので

# su
# echo 'export PATH=$PATH:/usr/libexec' >> ./bash_profile

として解決した。

vagrant【git cloneしてきたがvagrant upできなかった】

git cloneでとってきたVagrantfileがあるのにvagrant upできなかった。

inspected result must be ASCII only or use the same encoding with default external (Encoding::CompatibilityError)

のようなエラーが出たが、原因はどうもgit cloneしたディレクトリのパスにマルチバイト文字が含まれていたせいだった。

マルチバイト文字をパスからとってやったら、うまいこといった。