packしないPerlの数値変換

16進文字列を整数値に

お約束。

my $num10 = hex("FF") #=255
my $num10 = hex("0xFF") #=255

8進文字列を整数値に

8進数…あまりお目にかからないですが、「0」から始まる数値文字列をoct()に渡すと処理してくれます。

my $num = oct("046"); #=38
#oct("0"."46")と考えるといいかも

2進数を整数値に

これもoct()が使えます。"0b"で始まる文字列を渡すと、2進数文字列として数値に変換されます。

my $num=oct("0b0010"); #=2
my $num2=oct("0b”.$str); #2進文字列がある場合

oct()は"0x"で始まる文字列も処理できます*1が、hex()があるのでそちらのほうが明示的だと思います。

oct関数で16進を作る、ってわかりにくいので。

数値から文字列にする

sprintfが使えます(と思っているのですがあまり見かけない*2 )。 0詰めもできます。ただし、通常のprintf同様、渡された文字列が文字数指定より長いと、0詰めに失敗します。

packと違って長さ無制限(?)です。(違うかも)

my $str_bin = sprintf ("%012b", 4) ; #="000000000100"
my $str_bin2 = sprintf ("%03b", 255) ; #="11111111" (3桁指定がうまくいかない例)

my $str_hex = sprintf ("%02x", 255) ; #="ff" (小文字)
my $str_hex2 = sprintf ("%02X", 255) ; #="FF" (大文字)

2進数文字列から16進数文字列へ

組み合わせ技。

my $str_hex=sprintf("%04x",oct("0b".$str_bin)); #4桁の16進数になる
#ただし、$num_binが大きすぎると4桁にならない

まとめ(?)

  • packはバイトオーダーやテンプレートの長さなど、慣れないとわからないことが多いです。文字列操作関数を使ったほうがわかりやすい時があるかもしれません。
    • spirntfのフォーマットもpackのテンプレートも覚える労力は同じ、かもしれませんが…。
  • かならず固定文字数で結果を得たいときにはpackが有利です。ただし、「桁数が切り捨てられてもいい」という場面は限られると思います。切り捨てられた桁数のために、複数回pack/unpackするなら、メンテナンス性などの点を考慮し*3、1度で書けるコードに変えることも検討していいと思います。
  • バイナリ処理であるpack/unpackのほうが速度面では有利かもしれません。ただ、短いスクリプトで1~3回使うだけのときや、繰り返し実行しないときには、そこまで気にする速度差は出ないと考えています。
  • とはいえ、packを使ったコードはよく見かけるので、使わなくても読むための知識は必要だと感じています。

*1: ただし、perlfuncのhex()解説によると、不正な文字列や空白文字で始まった時の扱いなどに差があるようです。

*2:%bはC言語と互換性がないせいかもしれません。ただし、多くの言語では%bが使えます。

*3:「プログラムの行数が長いほどバグが増える」というあるある法則。

Excelマクロでグラフの行/列を変更する

公式リファレンス

xlRows(行がデータ系列)とxlColumns(列がデータ系列)のどちらかを使います。マクロでグラフ操作をして、思った通りの系列が作成されないときなどに。

Sub 行列の変更()
    ActiveChart.PlotBy = xlRows
    ActiveChart.PlotBy = xlColumns
End Sub

Setup.exeの中身がおかれるフォルダ

Setup.exeの中身を調査する - misc.log

windows10では、C:\Users(ユーザ名)\AppData\Local\Temp\になっている様子。

また、c:\tempやC:\Windows\Temp\ *1以下に自己解凍したファイルを置くものもあるみたい。https://www.billionwallet.com/goods/windows10/windows10_gpedit.html

*1:WindowsのTEMPフォルダの設定による

WindowsのISOからファイルを取り出す

!!注意!!

  • dismコマンドを使用しています。間違ったパラメータで実行した場合、Windowsシステムを上書きするなど最悪のことが起こります。
  • 誤字の無いよう努めていますが、 タイプミスでおかしなコマンドになっているかもしれません。 コピペ即実行は控えて、パラメータを理解の上実行してください。
  • 自己責任でお願いします。 本当に気を付けて。

ISOをダウンロード

Windows 10 のダウンロード

インストールイメージの確認

ISOをDVDに焼く。もしくは右クリックから「マウント」でDVDドライブとして操作できる。

ドライブのsourcesフォルダからinstall.wim(install.esdかもしれない)を見つけ、適当なフォルダへコピーする。今回は簡単のためc:\とする*1

dismを使い、wimの中身を確認する。

%> dism /get-wiminfo /wimfile:c:\install.wim
展開イメージのサービスと管理ツール
バージョン: 10.0.17134.1

イメージの詳細: install.wim

インデックス: 1
名前: Windows 10 Home
説明: Windows 10 Home
サイズ: 15,883,203,288 バイト

インデックス: 2
名前: Windows 10 Education
説明: Windows 10 Education
サイズ: 16,101,770,287 バイト

インデックス: 3
名前: Windows 10 Pro
説明: Windows 10 Pro
サイズ: 16,101,649,315 バイト

インデックス: 4
名前: Windows 10 Pro Education
説明: Windows 10 Pro Education
サイズ: 16,101,697,675 バイト

インデックス: 5
名前: Windows 10 Pro for Workstations
説明: Windows 10 Pro for Workstations
サイズ: 16,101,733,747 バイト

上記の場合、インデックス1から5まで、5種類が1ファイルに収まっているということになる。

wim(esd)ファイルからファイルを展開する

ファイルを展開するフォルダをつくる。今回は仮に「c:\mount」とする。

dismを使用して、wimからファイルを展開する。 取り出したいバージョンに合わせ、/indexオプションの数値は先ほど調べた値に変更する。実行から完了まで数分単位でかかるため、時間には余裕をもって。 あと、ファイルを上書きしたら大変なことになる*2ので、絶対に絶対に/applydirの指定を忘れないこと。また空フォルダを指定すること。

%>dism /apply-image /imagefile:c:\ /applydir:c:\mount /index:3

上記ならインデックス3、つまりWindows 10 Proになる。インデックス1ならWindows 10 Home。

展開イメージのサービスと管理ツール
バージョン: 10.0.17134.1

イメージを適用しています
[==========================80.0%==================        ]
操作は正常に完了しました。

進捗が100%になるまで待つ*3

完了すると、mountフォルダにwindowsフォルダやprogram filesフォルダができているので、好きなファイルを取り出す。

*1:例示のためドライブ直下としていますが、デスクトップやマイドキュメントなどのほうがいいかもしれない

*2:Windowsフォルダを上書きするかもしれない

*3:念のため、余計な操作は控える

PCが壊れた→復旧した(簡易版)

要約すると

  • 古いPCを「たまにブルースクリーンが出る」状態で放置していたら、数日で完全に壊れた。場面構わず、突然ブルースクリーン。修復インストールもブルースクリーンで止まり失敗、お手上げ。
  • エラーコードからドライバ・HW周辺の不調を推定してPCを新調。ブルースクリーンは消えた。
  • HDDをディスクコピーツールでコピーしてデータも無事。
  • でもWindowsのシステムがめちゃくちゃに壊れていた。システムアプリやコンパネの項目が動かない。
  • Webで調べていろいろ修復作業したけど治らなかった。
  • MediaCreationTool使ってダメだった。(ISO焼き、上書きインストール両方)
  • Web情報を参考に、MSサイトでISOを直接ダウンロード、上書きインストール(個人用ファイルとアプリを引き継ぐ)で復旧できた。
  • 使用不能になってから解決するまで1週間。代金は新PC1台分。
  • 長くPCを使うのはほどほどにしましょう、不調はすぐ対応しましょう。無事なうちにインストールディスクは作っておきましょう。

PCの交換で動作は安定しましたが、Windowsシステムがおかしく、スタートメニューが使えない、コンパネの項目が「クラスの登録がありません」などで動かないなど、元通りに使える状態ではありませんでした。

MediaCreationToolを使った上書きインストールやISOダウンロードが失敗して、もうだめかと思っていたのですが、ISOをMSのサイトから直接DL、インストールすることで解決できました。Mac環境かブラウザUAを変えないとダウンロードできない、という点は正攻法でない感じで気になりますが…。

MediaCreationToolはWindowsUpdateの機能を使っているらしく、Windowsの機能が壊れているとデータのダウンロードがおかしかったり、生成するISOデータが正常でなかったりするようです。DVDの焼きに失敗していたのかもしれません。公式ツールなら絶対大丈夫と思っていたのですが、壊れたWindows上で正しく動く保証はないようです*1。 事実として、ISOの中のinstall.esdを取り出してdism /apply-imageしようとしたら90%くらいでエラー発生しました。

「壊れてから買いなおせばいい」では取り返しがつかないかもしれない、という経験でした。

*1:当然

シート内のグラフ(画像)を等間隔に並べる

標数値は直書きです。本当はユーザーフォームを作ったほうが良い。 並べる順番は、「オブジェクトの選択と表示」で表示されるリスト順です。並び順を変えたい場合は、事前にソートしておいてください。

Sub 画像を並べる()
'大体で並べる(重なり回避程度)
'Shapes全部に行うので、画像グラフ混在シートでは不可
'
'Excel2013の場合、セルB1の座標は top=13.5、Left=54
    Dim i As Long
    Dim x As Long
    Dim y As Long
    Const start_top As Long = 13.5
    Const start_left As Long = 54
    Const offset_h As Long = 550 'グラフサイズにに合わせて設定
    Const offset_w As Long = 900 'グラフサイズに合わせて設定
    
'シート内のグラフ全部に同じ処理をする(グラフ選択不要)
    
    Dim myShape As Shape
    
    x = start_left
    y = start_top
    
    For i = 1 To ActiveSheet.Shapes.count
        Set myShape = ActiveSheet.Shapes(i)
            
        myShape.Left = x
        myShape.top = y
        y = y + offset_h    
                
        If i Mod 4 = 0 Then 'X方向に4個並べたらY方向を移動させる
            y = start_top
            x = x + offset_w
        End If
             
    Next i


End Sub

また、グラフオブジェクトをセルの枠に合わせたい場合は、下記を追加します。

        'オブジェクトの左上セルの枠線に位置をあわせる(画像が重なる場合がある)
        myShape.Left = myShape.topLeftCell.Left
        myShape.top = myShape.topLeftCell.top
  

改良の余地はたくさんあるのだけれど、とりあえずの間に合わせ、ということで。