インストールレスプログラミング( ´ー`)

VBA , JavaScript , HTAなど 365アプリはインストール必要ですが、仕事に無いケースはほぼないから(・_・;)

連続数字を表に入れるときのメモ

データを文字列を介していろいろな形に加工するという作業をよくやります。

わかってしまえば,たやすい事なんですが,思いつかないとしばらく悩まないといけないポイントがあり,

見事にはまった後解決した記憶がありましたので,たぶん多くの方にはつまんないことですが,メモとして書きます。




1,2,3,4,5,6,7,8,9,10,11,12,13,14,15


  ↓ 5列の表にしたい

1 2 3 4 5
6 7 8 9 10
11 12 13 14 15

こういうことをやりたいことがあるんです。けっこう頻繁に。。


商と余りを使えばいい。

とても簡単なんですが,元の数字をそのまま商と余りで処理しようとすると,意外に難しいことになります。

1 2 3 4
5 6 7 8 9
10 11 12 13 14
15

わたしみたいにあんまり物を考えない人はごり押しします。If文でごりごり書き出したり,

do loopなどでカウンタを条件に合わせてリセットすることで対処したり。。

(;´▽`A``ホントコマッタモノデス。


さて,引っ張りすぎですね。答えは簡単

0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15

0から始まる数値なら,5で割り算をした商と余りを用いれば

0 1 2 3 4 5 6 7 8 9 10 11 12 13 14
0 0 0 0 0 1 1 1 1 1 2 2 2 2 2
余り 0 1 2 3 4 0 1 2 3 4 0 1 2 3 4

きれいにできあがります。
気づいた時の自分に対するあきれようはすごいですが,しばらくするとすぐ忘れるモノデス(;´▽`A``

さて,パワーポイントのVBAをだいぶ忘れているので,思い出すためにパワーポイントのVBAコードで試します。

f:id:chemiphys:20170410224414p:plain
パワーポイントのスライド1に3つの表をこのSSのように並べます。それぞれに付けた名前はマクロで使用します。
場所や大きさは適当ですが,列数は守る必要があります。または,コードのほうを好きに変えるのもいいですね。

標準モジュールはこちら

Sub test()
    
    Dim TargetSlide As Slide: Set TargetSlide = ActiveWindow.View.Slide
    
    Dim SourceTable As Table: Set SourceTable = TargetSlide.Shapes("元表").Table
    Dim PasteTable As Table: Set PasteTable = TargetSlide.Shapes("貼付表5列").Table
    Dim PasteTable2 As Table: Set PasteTable2 = TargetSlide.Shapes("貼付表3列").Table
    
    Dim DataCollection As Collection: Set DataCollection = New Collection
    
    Dim r As Cell
    For Each r In SourceTable.Rows(1).Cells
        DataCollection.Add r.Shape.TextFrame.TextRange.Text
    Next
    
    Dim i As Long, tmp As String
    For i = 0 To DataCollection.Count - 1
        tmp = DataCollection(i + 1)
        PasteTable.Cell(Int(i / 5) + 1, i Mod 5 + 1).Shape.TextFrame.TextRange = tmp
    Next
    
    For i = 0 To DataCollection.Count - 1
        tmp = DataCollection(i + 1)
        PasteTable2.Cell(Int(i / 3) + 1, i Mod 3 + 1).Shape.TextFrame.TextRange = tmp
    Next

End Sub

実行すると,
f:id:chemiphys:20170410224645p:plain

このとおりです。

コードの補足を少しします。

    Dim TargetSlide As Slide: Set TargetSlide = ActiveWindow.View.Slide

対象のスライドからオブジェクトの指定が始まることがほとんどなので,対象のスライドをオブジェクト変数に入れます。
いろいろな方法がありますが,アクティブなスライドを捕まえる書き方の一つです。imihitoさんから教えていただいたヤツデス。

    Dim SourceTable As Table: Set SourceTable = TargetSlide.Shapes("元表").Table
    Dim PasteTable As Table: Set PasteTable = TargetSlide.Shapes("貼付表5列").Table
    Dim PasteTable2 As Table: Set PasteTable2 = TargetSlide.Shapes("貼付表3列").Table

表に名前がついているように感じますが,パワーポイントの場合いろいろなものはShapeオブジェクトとして扱われます。
各Shapeオブジェクトの中のTable のように指定するわけです。

    Dim DataCollection As Collection: Set DataCollection = New Collection

要素数を決めないで値を放り込むのに使えるということで,Collectionを使いました。配列を使ってもいいかもしれません。

    Dim r As Cell
    For Each r In SourceTable.Rows(1).Cells
        DataCollection.Add r.Shape.TextFrame.TextRange.Text
    Next

パワーポイントの表については,For Eachステートメントはとても使いにくいんですが,
Rowオブジェクト,Columnオブジェクト内にはCellsコレクションがあるので,そこを利用すれば強引にFor Eachが使えます。
二回 For Eachを使えば表全体を扱えるということですね。

    Dim i As Long, tmp As String
    For i = 0 To DataCollection.Count - 1
        tmp = DataCollection(i + 1)
        PasteTable.Cell(Int(i / 5) + 1, i Mod 5 + 1).Shape.TextFrame.TextRange.Text = tmp
    Next
    
    For i = 0 To DataCollection.Count - 1
        tmp = DataCollection(i + 1)
        PasteTable2.Cell(Int(i / 3) + 1, i Mod 3 + 1).Shape.TextFrame.TextRange.Text = tmp
    Next

それぞれの表に流し込んでいます。
表のセルは (1,1) ~ なので, 0を利用していることから1を足して利用しています。
Int(i/5)で 5で割った商 , i mod 5 で5で割った余り という意味です。

ちなみに表の各セルのテキストは
Cell(行,列).Shape.TextFrame.TextRange.Text
と階層が深いのはパワポVBAの仕様なのであきらめるしかありません。。

以上でした(ΦωΦ)