2019年3月30日土曜日

私の少年 第28話 イルミネーション(ネタバレ感想)

【感想・考察】
聡子にとっても真修にとっても、止まっていた時間が一気に動き出した感じ。
お互いのことしか頭になかった時間が、社会の中でお互いの存在を大切に思う、そういう時間に変わっていく様子が描写されている。

クリスマスパーティでプレゼント交換することになったが、真修に喜んでもらえるものをあげたいので相談に乗ってほしい、という菜緒。「くじで相手を決めた」という発言を聞いてホッとしている自分に少し呆れているが、この時点ではまだそれ以上の描写はない。真修の友人関係を知りたいと思いつつ買い物に付き合う聡子は、菜緒の見せる反応から恋心を感じ取る。そして、自分には踏み出せずにいる一歩を踏み出している姿を見て、嫉妬しているのかな。
アクセサリーに使う石にターコイズを手にとったのは、それまでの2年で真修がそう思わせる言動をしていたのだろうか。聡子が手にとったのかとも思うけど、ちょっとわからないな。

帰路、真修の周りのことを「知ってしまった」と表現している聡子は、真修が自分にはもう過ぎてしまった青春の只中にいることを改めて自覚したんだろう。痛い、とこぼしているのは、真修にこうあってほしいと思うことと、自分がこうなりたいと思うことが噛み合っていないことに気づいているからじゃないだろうか。

そこに真修からのライン、「ダメなところを思いつかないので聞いていいですか」って、それ聞いちゃダメな奴だから。
自分のだめなところをつぶやく聡子、靴下が左右バラバラなんてしょっちゅう、とかいいつつブーツは脱ぎっぱなし。これはいいのか。
あれこれ悩まないでプレゼントでも買ってしまえばよかったかも、なんて思っているが、どういう口実でプレゼントを渡すつもりなのか。クリスマスに会うことを自分から断ったのに。
そして真修の近い将来、おそらくは高校生になった真修とその隣りにいる菜緒を想像して、変な声を出している。プレゼント選びのときには自然な想像だったのに今度は声を上げているのは、真修が相手の方を向いているからだろうか。
買い物中帰宅後

気になったので第10話を読み返してみたら、ここの将来像でも(ハッキリとは書かれてないけど)真修は聡子の方を見ているのだな。
プレゼント選びのときは、真修が菜緒に意識を向けることを考えていなかったけれど、冷静になってそれに気づいたということか。

ついでに10話のそのシーン(聡子が真修の未来を想像するところ)で、よく見たら聡子は少し目に涙を浮かばているのね。

クリスマスパーティでは周囲のことなど全然見てなくて聡子のことばかり考えている真修と、そんな日に歯医者通いという思い切り日常を過ごしている聡子。一応真修のことを考えてはいるけれど、菜緒に対する真修の反応はどうだろうとか、そういうことは一切期にしている素振りはない。もう忘れちゃったのか。
聡子のことが気になりすぎて、パーティの途中で帰ってしまう真修に対し、駆け寄ってプレゼントを渡す菜緒。周りから見てもバレバレの好意に、他人事のような真修がいい。菜緒はスパイスではあるけれど、真修の心が動くことなんてきっとないから、早く見切りをつけたほうが傷が浅くて済むよ。

結局わざわざ三鷹まで、聡子がいるとも限らないのに駆けつけた真修。聡子は真修をすぐに発見し、真修もすぐに聡子を発見する。それは、お互いが相手のことしか見えてないから。
ここから背景の描写が消えるのは、高野先生のtwitterによると、周囲が見えていないことの暗示らしい。

幸せな二人だけの世界は、真修の世界を閉じることで生まれる世界と認識した聡子は、「一番だめなところ」と考えている。どういう意味だろう。
素直に読めば真修を独占しようとしてしまう、という意味に思えるけど、その後の言動を見ていると「自分の感情に素直じゃない」ことがダメなところだと考えているのかもしれない。

駆け寄ってくる真修に、私ばかり見てちゃダメでしょ、もっと周りも見ないと、と諭す聡子。
真修のことを見てくれる人を大切にしなさい、と言い聞かせ、次は聡子から連絡するからと約束して別れる。その後姿を見て、私は真修の世界を開いていきたいんだ、と考える、その時真修の周りに風景が見えているけれど、聡子の周りにはない。真修から再び電話がかかってきて、後ろを見てください、と言われるまでクリスマスツリーの存在にすら気づいていない。真修の周りには目が行くようになっても、自分の周りには目が行っていなかった、という演出なのかな。

真修の世界を開いていきたい、という前段に、真修に会いたいと思っている人のことをちゃんと見てあげて、と言っているのは明らかに菜緒のことを指しているのだろう。聡子は、真修と菜緒の関係がどうなってほしいと思っているのだろうか。
おそらくは、今真修が聡子のことを好きなのは聡子以外が見えてないからであって、聡子以外の女性もちゃんと認識した上で、それでも聡子のことを好きでいてほしいんじゃないだろうか。「男は最初の男になりたがり、女は最後の女になりたがる」という言葉もあるくらいだし。そこまで考えてないかもしれないけど。
ちゃんと見てあげてと言われて不満げな真修は、これをくれたのが聡子だったら良かったのに、とか思ってるんだろうな。

今回は結構キリがいい終わり方だけど、次回どこから始まるんだろう。
一気に高校生という予想もあるみたいだけど、まずは正月をどう乗り切るかというのは結構重要だと思う。真修父は帰省してくる可能性があるし、そうなると少なくともばあちゃんは真修父に聡子のことを話す可能性が高い。真修が口止めしていれば別だけど、真修はまだ聡子が仙台に行った理由を知らないのだから、口止めするかなあ。となると、聡子としては年内の早いうちに真修と話をして、少なくとも聡子と会うためには聡子の存在を秘密にしておくべきことを伝えなくてはならない。あるいは隠さずに、父と対峙するか。どちらの判断をするにしても大きなポイントだから、ちゃんと描くんじゃないかなあ。真修が高校生になるまで父親が帰宅しないとも思えないし。真修にどう伝えて、そしてばあちゃんにどう話をするのか、これが次巻のポイントじゃないかなあ。時系列的には次の話で取り上げられるタイミングだけど、そうなるとせっかく温かいムードで終わった6巻から、7巻はいきなりハードモードでのスタート。電話があって「正月も忙しくて帰れないって」とかばあちゃんから聞いて、その後真修が菜緒の気持ちに気づく(そして遅かれ早かれ振る)という展開かなあ。

28話が収録されているヤンマガはこちら。

2019年3月5日火曜日

VBA; 005 画像をセルのサイズに合わせて貼り付ける

自分用メモ。
画像を貼り付けるとき、セルに合わせてサイズ調整するのを手作業でやるのは面倒なのでその方法。
罫線を書いているときなど、セルぴったりにしてしまうと罫線よりも画像が上に描写されてしまうので、マージン有無の設定もできるように。

Private Sub pasteImageFromFile(targetRange As Range, imageFilePath As String, margin As Integer, isLink As Boolean)
    Dim image As Shape
    Dim zoom_scale As Double
    Dim margin_point As Double
    Dim ht As Integer
    Dim wd As Integer
    Dim isSave As Boolean
    
    margin_point = (margin * (72 / 25.4)) * 2
    
    If isLink = False Then
        isSave = True
    Else
        isSave = False
    End If

    Set image = targetRange.Worksheet.Shapes.AddPicture( _
        Filename:=imageFilePath, _
        LinkToFile:=isLink, _
        SaveWithDocument:=isSave, _
        Left:=targetRange.Left, Top:=targetRange.Top, _
        Width:=-1, Height:=-1)
    
    With image
        .LockAspectRatio = msoTrue
        ht = targetRange.Height - margin_point
        wd = targetRange.Width - margin_point
        If wd / .Width < ht / .Height Then
            zoom_scale = Application.WorksheetFunction.RoundDown(wd / .Width, 2)
        Else
            zoom_scale = Application.WorksheetFunction.RoundDown(ht / .Height, 2)
        End If
        
        .ScaleWidth zoom_scale, msoFalse, msoScaleFromTopLeft
        
        .Left = .Left + (targetRange.Width - .Width) / 2
        .Top = .Top + (targetRange.Height - .Height) / 2
    End With

End Sub

引数としては貼り付け先のrangeオブジェクト、イメージのファイルパス、マージン(mm)、リンクにするか貼り付けるか。
リンクにすると、ファイルにはリンク先の情報が保存されるので、ファイルサイズは小さくなるけど画像データを毎回読み込む必要あり。なのでexcelファイルだけでは配布できなくなる。
マージン(というより画像サイズ)は本来ポイント単位での指定だけど、いちいちmmに換算してられないので引数をmmで設定。上下左右のマージンなので、引数を2倍にして使う。
LockAspectRatioで縦横比を固定。
対象レンジの幅・高さとイメージのサイズから倍率を決定。このとき、縦横のどちらが大きいかを見て調整。最後にイメージの配置場所を、セルの中心に移動。

もともとどこかのサイトのコードを参考(というかほぼコピペ)で書いたんだけど、どこだったか探しても見つからなかったのでリンクが張れない。残念。

VBA; 004 行の高さをミリメートル単位で指定する

自分用メモ。
行の高さはポイント単位での指定なので、列の幅と違って素直に設定可能。

Private Sub setRowHeightByMillimeter(targetRange As Range, targetHeight As Integer)
    targetRange.RowHeight = Application.CentimetersToPoints(targetHeight / 10)
End Sub

VBA; 003 列の幅をミリメートル単位で指定する

自分用メモ。
excelでは列の幅指定はフォント依存。標準フォントで半角数字の'0'が何文字表示できるか、というわけのわからん単位なので、これをミリメートル単位で設定する方法。

列の幅はColumnWidthプロパティで設定する。前述のとおり、これがフォントに依存する単位なので、こいつを「ポイント」に変換する。1ポイントは0.35mm。
Widthプロパティはポイント単位の数値なので(統一しろや・・・)これを使う。

ColumnWidth / Width

で、1ポイントが文字単位に換算するといくつになるかがわかる。
ミリメートルをポイントに変換する必要もあるので、これはCentimetersToPointsメソッドを使う。名前の通り単位はセンチメートルなので、ミリメートルに変換するのを忘れない。

Private Sub setColumnWidthByMillimeter(targetRange As Range, targetWidth As Integer)
    Dim columnCount As Integer
    Dim i As Integer
    Dim j As Integer
    Dim col As Integer
    Dim objectWidth As Double
    
    columnCount = targetRange.Columns.Count - 1
    objectWidth = Application.CentimetersToPoints(targetWidth / 10)
    
    For i = 0 To 1
        For j = 0 To columnCount
            col = targetRange.Column + j
            With Columns(col)
                .ColumnWidth = objectWidth * (.ColumnWidth / .Width)
            End With
        Next
    Next
End Sub

ColumnWidthでは、複数列の幅を正しく取得できないっぽいので、指定したレンジの範囲で1列ごとに設定する。
また変換誤差が発生するのか、同じ処理をしても1回めと2回めとで結果が変わってしまうのでループで2回設定する。2回めで設定された幅は変わらない模様。

2019年3月3日日曜日

VBA; 002 テキストボックスの内容を変更する

自分用メモ。
マクロのフォームではなく、挿入→テキストボックスで入れたものの内容を変更する方法。

画像挿入で貼り付けた地図に番号を振って、あとでシャッフルするときなどに使用。

前準備として、テキストボックスの名前を連番にしておく。
ページレイアウト→配置→オブジェクトの選択と表示をクリックして、オブジェクトの一覧を表示。ここで名前を変更して、連番にする。
同じ名前も存在できるので、ユニークな情報ではなさそうだけど、とりあえず動くからこれ以上は調べない。


以下の例では0パディングしてない名前を前提にしているので、0パディングした場合はformat関数あたりを使って調整。
tbox_0 - tbox_19 まで20個のテキストボックスに、⑳ - ①までの丸数字(機種依存文字)を逆順に設定。
ちなみに21以降は文字コードが違うようで、いろいろ試したけどうまく振れなかったので今回は断念。
あと、テキストボックスの他、吹き出しを混ぜても問題なく動作した。


Option Explicit

Const HEADER_NAME = "tbox_"
Const MAX_NUM = 19

Private Sub setTboxesNumber()
    Dim i As Integer
    Dim box_name As String
    
    For i = 0 To MAX_NUM
        box_name = Trim(HEADER_NAME & Trim(str(i)))
        ActiveSheet.Shapes.Range(box_name).TextFrame.Characters.Text = Chr(Asc("⑳") - i)
    Next
End Sub

実行前実行後
しかしBASICだから当然なんだろうけど、for文が最後の数字までカウントされるの、cに慣れると気持ち悪いな。
ループカウンタを1から始めればMAX_NUMを20にできるんだけど、それはそれで0番目の要素が飛ばされるから気持ち悪い。

2019年3月2日土曜日

VBA; 001 オブジェクト変数または With ブロック変数が設定されていません

自分用メモ。
VBAは年に数回しか触らないので、以前調べたこともすぐ忘れちゃうからここにメモしよう。



実行時エラー '91':
オブジェクト変数または With ブロック変数が設定されていません。

と出たときは、大抵はオブジェクト変数に代入するときsetステートメントを忘れている。
integerとかstringとかはオブジェクト型じゃないので、そのまま代入可能。
でもrangeだとかworksheetだとかはオブジェクト型なので、setステートメントがないと代入不可。

    Dim i As Integer
    Dim rng As Range
    
    i = 0
    Set rng = Range("a:a")