OpenOffice.org Basicでガントチャート
OpenOffice.org Basicを使ってガントチャート作成用マクロ ガントチャートforOOoを開発する手順を紹介していきます。
スポンサーサイト
上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。
あとがき その1

初めは一年かけて完成させるつもりだったのが、ずいぶん急ぎ足で書いたので、ここで一段落して一旦終わりにします。

もちろん、皆さんが感じられるように僕も中途半端だという思いは否定できません。ですが、このブログを書いていて、途中から疑問を感じずにはいられなかったのです。その疑問は「果たしてこのマクロの解説は必要なことなんだろうか?誰かの役に立つのだろうか」というものです。

プログラミングもパズルのように小さな部品を組上げていけば、それが最後には大きな絵を完成させることになるのですが、このマクロは初心者に対してそれほど小さなパズルとは言えません。作っていても先が見えないというのが実情ではないでしょうか。そこに完成品があって、出来上がるとこうなるというのがわかっていても、小さな関数を連ねる僕の作風では「何をしているのかな?」という疑問を感じるばかりではないかという気がしてなりません。
では上級者向けかというと、このマクロは稚拙な処理の繰り返しであってとてもセンスのいいコードとは言えませんから、上級者がこれを読んでも得られることなどほとんどないと思います。

ということで、ちょっと題材が悪かったと言わざるをえないと感じています。Excelのマクロを解説したときは、簡易版を解説しました。大幅に機能を削減して必要最低限の機能しか作らないことで、コードの量も激減し、まさに素人向けとしてちょうどいい題材だったことを思うと、同じようなアプローチをとっておけば良かったと後悔してなりません。
また、解説もいい加減でした。自分が作り馴れてくると、一般の人がわかる範囲とわからない範囲の区別が難しくなってきて、これではいけないなと感じる部分も多々あります。

こうした幾多の反省を感じながら、初期の記事を直したくて仕方の無い衝動に何度も駆られ、でも直していれば先に進めないというジレンマをずっと抱えながら書いていて、いつの間にかやってる意味がわからなくなってきていました。

一旦筆を置きますが、今後は各部の修正に努めます。OOoBasicのTipsも不定期で追記して行きたいと思っていますし、コメントなどでお問い合わせをいただければ、きちんと対応させて頂きたいと考えています。

これまでご愛読頂いた方に感謝すると共に、がさつな記事を書き続けてきた事をお詫びします。後日、コンテンツを再整備して、胸を張って人に紹介できるような内容になったら、改めて「あとがき その2」を書きたいと思います。

スポンサーサイト

テーマ:OpenOffice.org - ジャンル:コンピュータ

工程表シート作成 その3

作成したマクロをシート上のフォームに割り当てる操作を行います。

フォームを編集可能な状態にしてから、フォーム上で右クリックをして「コントロール」を選択すると、下図のようなダイアログが表示されます。


イベントタブを選択すると、割り当てる事のできるイベントが列挙されるので、「動作時」の右端にある「...」というボタンをクリックします。クリックすると下図のダイアログが表示されます。





そこで、表示されたダイアログの下部にあるマクロから目的の関数があるモジュールを探し、表示されたリストから関数を選択します。そして、「割り当て」ボタンを押すと登録完了です。以降は、このボタンを押す事で目的のマクロを実行する事ができるようになります。

同様に、全てのボタンに必要なマクロを登録します。

実は、これで終わりのように感じられるかもしれませんが、このままファイルを保存して開き、ボタンでマクロを実行させようとするとエラーが出ます。エラーの「OK」ボタンを押してから、再度ボタンでマクロを実行させようとすると今度は正常に動作します。
これは、OpenOffice.orgの自作ダイアログは読み込みを指示しなくては読込まれないために発生する現象で、エラーの後にIDEが表示される事で自作ダイアログが読込まれるので、次からエラーが発生しないのです。そこで、このエラーを回避するため、ファイルを開いた時に自作ダイアログを読込むようなマクロを自動で実行するよう設定します。
ダイアログを読み込むコードは下記となります。

Sub Auto_Open
    DialogLibraries.LoadLibrary("Standard")
End Sub

次に、このマクロをファイルが開かれたら自動的に実行させるため、メニューバーの「ツール」から「ユーザー設定」を選択します。すると、下図のダイアログが表示されるので、イベントタブを選び、イベントの一覧から「ドキュメントを開く時」を選択します。その状態で、下部のリストから目的のモジュール(ここではmdlMain)とマクロ(ここではAuto_Open)を探し、選択してから「割り当て」ボタンを押します。


以上で、1ヶ月工程のシートは完成です。このシートに合わせてプロパティを書けば工程表を更新することが可能となります。また、他の期間も公開されているファイルを参考にすれば、簡単に作成できるものと考えます。

テーマ:OpenOffice.org - ジャンル:コンピュータ

工程表シート作成 その2

次に工程の開始日を変更するマクロを作成します。マクロの流れは、Initialize関数で初期化した後、mdlPropertyモジュールのChangeBeginDate関数を実行し、変更されたならば変更を保存してチャートを更新するというもので、コードは下記となります。

Sub ChangeBeginDate
    Initialize
    If mdlProperty.ChangeBeginDate Then
        mdlProperty.SaveAll
        mdlDraw.Update
    End If
End Sub

ここで、ChangeBeginDate関数はmdlProperty内で下記のように実装されています。簡単に処理の内容を説明すると

  1. データを読込み、選択中のシートに対応したプロパティを選択する
  2. 現在のデータをBeginDateに保存しておく
  3. カレンダーを表示して、日付を選択してもらう
  4. 選択した日付がBeginDateと等しくなく、不適切な日付でなければデータを更新して真を返す
となります。

Private Function ChangeBeginDate As Boolean
    
    LoadAll
    getActiveId
    
    If ActiveId < 1 Or Count < ActiveId Then Exit Function
    
    Dim BeginDate As Date
    Dim wk As Date
    
    BeginDate = Properties(ActiveId)._BeginDate
    wk = mdlCalendar.Show(BeginDate, CALENDARTYPE_SELECT)
    If FirstDate < wk And wk <> BeginDate Then
        Properties(ActiveId)._BeginDate = wk
        ChangeBeginDate = True
    Else
        ChangeBeginDate = False
    End If
    
End Function

テーマ:OpenOffice.org - ジャンル:コンピュータ

工程表シート作成 その1

とりあえず、1ヶ月工程用のシートを作成します。作成したシートは下図となります。


フォーム機能でボタンを4つ配置し、それぞれの表示用の名前を変更します。次に、それぞれのボタンに登録するマクロを作成します。ここで作成するマクロは全てmdlMainモジュールに記載します。

まずは、工程表の更新としてChartUpdate関数を作成します。マクロの流れは、Initialize関数で初期化した後、mdlDrawモジュールのUpdate関数を実行するというもので、コードは下記となります。

Sub ChartUpdate
    Initialize
    mdlDraw.Update
End Sub

次に、データの編集用のEditData関数を作成します。マクロの流れは、Initialize関数で初期化した後、mdlDataManagerモジュールのShow関数を実行するというもので、コードは下記となります。

Sub EditData
    Initialize
    mdlDataManager.Show
End Sub

次に、休日の編集を行うEditHoliday関数を作成します。マクロの流れは、Initialize関数で初期化した後、mdlCalendarモジュールのShow関数を実行して休日の編集を行い、編集終了後にmdlDrawモジュールのUpdateHoliday関数を実行するというもので、コードは下記となります。

Sub EditHoliday
    Initialize
    mdlCalendar.Show(Now(), CALENDARTYPE_Edit)
    mdlDraw.UpdateHoliday
End Sub

ちなみに、mdlDrawモジュールのUpdateHoliday関数とは、Update関数から休日の色分け部分のみを切り出したもので、コードは下記となります。

Sub UpdateHoliday

    LoadAll
    
    If Not getProperty Then Exit Sub
    
    oSheet = mdlMain.Sheets(oProperty._SheetName)
    
    setScreenUpdating(False)
    setMaxRows
    paintHoliday
    setScreenUpdating(True)
    
End Sub

テーマ:OpenOffice.org - ジャンル:コンピュータ

チャートの描画 その8

最後にこれまで解説してきた処理や作成してきた関数を組み合わせて、工程表を更新するUpdate関数を作成します。

これまで同様、処理を簡単に説明すると

  1. データの読み込む
  2. 描画するシートの取得する
  3. チャートの最終日を計算する
  4. チャートを描画するためにデータの予備処理を行う
  5. 分類区分により必要なBinデータを生成する
  6. 描画に必要な最大行数を計算する
  7. 以降、画面の描画を伴うので更新処理を一時停止させる
  8. 日付欄を更新する
  9. 休日の塗り分けを行う
  10. チャートを描画するための図形を準備する
  11. 入力済みのセルの内容を消去する
  12. 分類、項目、工程のデータに合わせて、チャートを描画する
  13. 停止した描画処理を再開させる
となります。

Sub Update
    
    LoadAll
    
    If Not getProperty Then Exit Sub
    
    oSheet = mdlMain.Sheets(oProperty._SheetName)
    
    CulcEndDate
    checkData
    
    Select Case oProperty._CategorizeType
        Case CATEGORIZETYPE_CATEGORY
            mdlBin.CreateBins(False)
        Case CATEGORIZETYPE_Person
            mdlBin.CreateBinsByPerson(False)
    End Select
    
    setMaxRows
    
    setScreenUpdating(False)
    
    printDateHeader
    paintHoliday
    
    setChartBars
    setProgressBars
    
    '*** Clear Contents ***
    oSheet.getCellRangeByPosition( _
        oProperty._LeftColumn - 1, _
        oProperty._TopRow + ChartHeaderRows - 1, _
        oProperty._LeftColumn + oProperty._DrawColumns + _
            ChartHeaderColumns - 1, _
        oProperty._TopRow + oProperty._DrawRows + _
            ChartHeaderRows - 2 _
    ).clearContents( _
        com.sun.star.sheet.CellFlags.STRING + _
        com.sun.star.sheet.CellFlags.VALUE _
    )
    
    Dim i As Integer
    
    RectPos = 0
    LinePos = 0
    PrgsPos = 0
    
    For i = 1 To mdlBin.Count
        DrawChart(Bins(i))
    Next i
    
    For i = 1 To 20
        DrawProgressLine(i)
    Next i
    
    setScreenUpdating(True)
    
End Sub

ここで作成したUpdate関数をシート上に配置したフォームのボタンに割り当てれば、この工程表マクロは完成です。

テーマ:OpenOffice.org - ジャンル:コンピュータ

チャートの描画 その7

次に項目名の表示で作ったDrawChart関数で使用しながら、全く解説していなかったDrawChartBar関数を作成します。

これは項目データのIDに割り当てられた工程データを探し、それをsetSchdule関数(後述)に送ります。その処理を項目ID回数繰り返す事で、それぞれの項目に割り当てられた工程のチャートを描画することができます。多少非効率的な処理ですが、単純な作業なのでそのままコードにしてみました。

Sub DrawChartBar(ItemId As Integer, Row As Integer)
    
    Dim i As Integer
    
    For i = 1 To mdlSchedule.Count
        
        If Schedules(i)._ItemId = ItemId Then
            
            setSchedule(Schedules(i), Row)
            
        End If
        
    Next i
    
End Sub

上述のsetSchedule関数は下記となります。渡された工程データから予定と実績のそれぞれについて、描画処理が必要か否かのフラグを確認し、必要ならば前回作成したsetChartBar関数に渡します。また工程の名称を表示する設定になっていれば、工程の左端のセルにその名称を入力するというものです。

Sub setSchedule(Schedule As Object, Row As Integer)
    
    Dim flgPrintLabel As Long
    
    If oProperty._PrintLabel Then
        flgPrintLabel = True
    Else
        flgPrintLabel = False
    End If
    
    If Schedule._DrawPlan Then
        setChartBar("Plan", Schedule, Row)
        If flgPrintLabel Then
            Cells(oSheet, _
                Int(getColumnIndexByDate(Schedule._PlanBegin)+1), _
                Row).String = Schedule._Name
            flgPrintLabel = False
        End If
    End If
    
    If Schedule._DrawAct Then
        setChartBar("Act", Schedule, Row)
        If flgPrintLabel Then
            Cells(oSheet, _
                Int(getColumnIndexByDate(Schedule._PlanBegin)+1), _
                Row).String = Schedule._Name
            flgPrintLabel = False
        End If
    End If
    
End Sub

テーマ:OpenOffice.org - ジャンル:コンピュータ

チャートの描画 その6

これまで作成した関数を組み合わせて、工程データと列番号からチャート用の横線を描画する関数を作成します。

この関数の処理の流れを簡単に説明すると

  1. getChartBarObject関数(後述)を使って、描画に使う図形オブジェクトを取得する
  2. 列番号から列オブジェクトを取得する
  3. BarTypeには"Plan"または"Act"を指定し、それぞれ予定か実績を区別する
  4. 予定または実績のデータから図形の位置と幅を計算し、合わせて色を取得する
  5. プロパティから図形の厚みを計算し、縦位置を補正する
  6. 描画する図形が直線か長方形であるかで分岐し、それぞれにあった図形の設定を行う
  7. setDrawSize関数で図形の位置と大きさを指定する
となります。

実際のコードを下記に示します。

Sub setChartBar(BarType As String, _
    Schedule As Object, Row As Integer)
    
    Dim X As Long
    Dim Y As Long
    Dim Width As Long
    Dim Height As Long
    Dim LineColor As Long
    Dim FillColor As Long
    
    Dim oDraw As Object
    Dim oRow As Object
    
    oDraw = getChartBarObject(Schedule)
    oRow = oSheet.Rows.getByIndex(Row - 1)
    
    Select Case BarType
        
        Case "Plan"
            X = getPositionXByDate(Schedule._PlanBegin)
            Y = oRow.Position.Y + oRow.Size.Height * _
                oProperty._ChartBarPlanPos / 100
            Width = getPositionXByDate(Schedule._PlanEnd) - X
            
            LineColor = oProperty._ChartBarPlanLineColor
            FillColor = Schedule._PlanColor
        Case "Act"
            X = getPositionXByDate(Schedule._ActBegin)
            Y = oRow.Position.Y + oRow.Size.Height * _
                oProperty._ChartBarActPos / 100
            Width = getPositionXByDate(Schedule._ActEnd) - X
        
            LineColor = oProperty._ChartBarActLineColor
            FillColor = Schedule._ActColor
    End Select
    
    Height = oProperty._ChartBarWeight * 50
    Y = Y - Height / 2
    
    Select Case Schedule._LineType
        Case LineType_Rectangle
            oDraw.lineColor = LineColor
            oDraw.fillColor = FillColor
            oDraw.lineWidth = 0
        Case LineType_Line
            oDraw.lineColor = FillColor
            oDraw.lineWidth = Height
            Height = 0
    End Select
    
    setDrawSize(oDraw, X, Y, Width, Height)
    
End Sub

getChartBarObject関数では、RectPosとLinePosというグローバル変数によって次々と使用していないオブジェクトを返すという処理をするものです。実際のコードは下記となります。

Function getChartBarObject(Schedule As Object) As Object
    
    Select Case Schedule._LineType
        Case LineType_Rectangle
            RectPos = RectPos + 1
            getChartBarObject = ChartBarRect(RectPos)
        Case LineType_Line
            LinePos = LinePos + 1
            getChartBarObject = ChartBarLine(LinePos)
    End Select
    
End Function

テーマ:OpenOffice.org - ジャンル:コンピュータ

チャートの描画 その5

図形の位置とサイズの調整が頻繁に出現するので、これを簡便にするためsetDrawSize関数を作成します。

Sub setDrawSize(oDraw As Object, _
    X As Long, Y As Long, _
        Width As Long, Height As Long)
    
    Dim aPos As New com.sun.star.awt.Point
    Dim aSize As New com.sun.star.awt.Size
    
    aPos.X = X
    aPos.Y = Y
    aSize.Width = Width
    aSize.Height = Height
    
    oDraw.setPosition(aPos)
    oDraw.setSize(aSize)
    
End Sub

こうして作っておくと、今後のチャート描画が非常に楽になります。

テーマ:OpenOffice.org - ジャンル:コンピュータ

チャートの描画 その4

次に、getColumnIndexByDate関数を使って、日付からX座標を取得するgetPositionXByDate関数を作成します。

Function getPositionXByDate(TargetDate As Date) As Long
    
    Dim oColumn As Object
    
    Dim wk As Double
    Dim Left As Long
    Dim Width As Long
    
    wk = getColumnIndexByDate(TargetDate)
    
    oColumn = oSheet.Columns.getByIndex(Int(wk))
    
    Left = oColumn.Position.X
    Width = oColumn.Size.Width
    
    wk = wk - Int(wk)
    
    getPositionXByDate = Left + Width * wk
    
End Function

getColumnIndexByDate関数の戻り値を整数に丸め、列オブジェクトを取得し、その幅と戻り値の少数部をかけ合わせてX座標を取得しています。

この関数はこれから作成するチャート描画のプログラムを非常に簡単にしてくれます。

テーマ:OpenOffice.org - ジャンル:コンピュータ

チャートの描画 その3

今後の図形の操作を簡単にするため、日付から対象となる列の番号+αを取得するgetColumnIndexByDate関数を作成します。

この関数の戻り値はDouble型となっていて、整数部には列番号、少数部には引数の日付にてセルの単位に満たない部分に関するセル幅の割合を示します。
実際の例を使って説明します。セル単位が一日の場合の「4/8 12:00」を考えてみると、この工程表が4/1から始まっているならば、4/8は左端から数えて7番目の列になります。そして、12:00はちょうど一日の半分なので、セルの半分となります。そこで、戻り値は左端の列番号+7.5ということです。

なぜこんな面倒なことをするのかと言うと、このガントチャートはセルの幅を変更してもその変更に合わせてチャートを描画できるようにするためです。前にいた職場で3週間の工程表を描画する際、真ん中が重要で前後は幅が狭くなっている工程表を利用していました。この経験から、このような工程表を描画することもあり得ると思い、セル幅を変更しても体裁の崩れない構造が必要だと考えています。

Function getColumnIndexByDate(TargetDate As Date) As Double
    
    Dim wk As Double
        
    If TargetDate < oProperty._BeginDate Then
        wk = 0
    ElseIf TargetDate > oProperty._EndDate Then
        wk = oProperty._DrawColumns
    Else
        
        Select Case oProperty._CellUnit
            Case CELLUNIT_DAY
                wk = TargetDate - oProperty._BeginDate
            Case CELLUNIT_WEEK
                wk = (TargetDate - oProperty._BeginDate) / 7
            Case CELLUNIT_10DAYS
                If Day(TargetDate) < 21 Then
                    wk = DateDiff("m", _
                        oProperty._BeginDate, TargetDate) * 3 + _
                        (Day(TargetDate) - 1) / 10
                Else
                    wk = DateDiff("m", _
                        oProperty._BeginDate, TargetDate) * 3 + 2 + _
                        (Day(TargetDate) - 21) / _
                        (Day(getNextMonth(TargetDate) - 1) - 21)
                End If
            Case CELLUNIT_MONTH
                wk = DateDiff("m", _
                    oProperty._BeginDate, TargetDate) + _
                    Day(TargetDate) / _
                    Day(getNextMonth(TargetDate) - 1)
        End Select
    End If
    
    getColumnIndexByDate = wk + _
        oProperty._LeftColumn + ChartHeaderColumns - 1
    
End Function

セルの単位で分岐し、日付から列数を取得する処理を行っています。余りの日数をセルの日数で割ることで、セル幅の割合を計算し、チャートを描画する領域の左端の列を足して、それを戻り値にしています。

テーマ:OpenOffice.org - ジャンル:コンピュータ

チャートの描画 その2

次にsetChartBars関数を作成し、この中で描画に必要な図形の数を数え、足りない図形を追加したり、描画済みで不要な図形を削除したりします。

処理の流れを簡単に説明すると

  1. ドローページの取得および、図形記録用変数の初期化
  2. シート上の図形の名称を確認し、ChartBarNameと等しい場合は図形の種類を確認し、直線と長方形に区分けして変数に記録する
  3. 直線の図形数が描画に必要な数より少ない場合は図形を追加し、多い場合は図形を削除する
  4. 長方形の図形数が描画に必要な数より少ない場合は図形を追加し、多い場合は図形を削除する
となります。実際のコードを下記に示します。

Sub setChartBars
    
    Dim oDrawPage As Object
    Dim oDraw As Object
    
    oDrawPage = oSheet.getDrawPage
    
    Dim cntLine As Integer
    Dim cntRect As Integer
    
    cntLine = 0
    cntRect = 0
    
    Redim Preserve ChartBarLine(0)
    Redim Preserve ChartBarRect(0)
    
    Dim i As Integer
    
    For i = 0 To oDrawPage.getCount - 1
        oDraw = oDrawPage.getByIndex(i)
        
        If oDraw.Name = ChartBarName Then
            
            Select Case oDraw.ShapeType
                Case "com.sun.star.drawing.LineShape"
                    cntLine = cntLine + 1
                    Redim Preserve ChartBarLine(cntLine)
                    ChartBarLine(cntLine) = oDraw
                Case "com.sun.star.drawing.RectangleShape"
                    cntRect = cntRect + 1
                    Redim Preserve ChartBarRect(cntRect)
                    ChartBarRect(cntRect) = oDraw
                Case Else
            End Select
            
        End If
        
    Next i
    
    If cntLine < LineCount Then
        Do
            cntLine = cntLine + 1
            Redim Preserve ChartBarLine(cntLine)
            ChartBarLine(cntLine) = _
                AddShape("com.sun.star.drawing.LineShape", _
                    ChartBarName)
            If cntLine = LineCount Then Exit Do
        Loop
    ElseIf cntLine > LineCount Then
        Do
            oDrawPage.Remove(ChartBarLine(cntLine)
            cntLine = cntLine - 1
            Redim Preserve ChartBarLine(cntLine)
            If cntLine = LineCount Then Exit Do
        Loop
    End If
    
    If cntRect < RectCount Then
        Do
            cntRect = cntRect + 1
            Redim Preserve ChartBarRect(cntRect)
            ChartBarRect(cntRect) = _
                AddShape("com.sun.star.drawing.RectangleShape", _
                    ChartBarName)
            If cntRect = RectCount Then Exit Do
        Loop
    ElseIf cntRect > RectCount Then
        Do
            oDrawPage.Remove(ChartBarRect(cntRect)
            cntRect = cntRect - 1
            Redim Preserve ChartBarRect(cntRect)
            If cntRect = RectCount Then Exit Do
        Loop
    End If
    
End Sub

テーマ:OpenOffice.org - ジャンル:コンピュータ

チャートの描画 その1

まず、図形を追加する関数を作成します。コードを示すと

Function AddShape(ShapeType As String, ShapeName As String) As Object
    
    Dim oDraw As Object
    
    oDraw = ThisComponent.createInstance(ShapeType)
    
    oDraw.Name = ShapeName
    oSheet.getDrawPage.Add(oDraw)
    
    AddShape = oDraw
    
End Function

となります。これは図形の種類と図形に付ける名前を指定すると、シートに図形を追加して追加した図形オブジェクトを返すという関数です。

これを利用して直線を描画するなら

AddShape("com.sun.star.drawing.LineShape", ChartBarName)
となり、長方形を描画するなら
AddShape("com.sun.star.drawing.RectangleShape", ChartBarName)
となります。

ここで、ChartBarNameはmdlMainにて宣言しておき、

ChartBarName = "ChartBar"
と定義されています。こうして名称を利用するのは、ユーザーが書き加えた図形であるかマクロで描画したものかを識別するためのものです。

テーマ:OpenOffice.org - ジャンル:コンピュータ

項目名の表示

長くなりますが、処理はただ条件を判断し分岐させながら実行するだけなので、とても簡単です。流れを要約すると

  1. 与えられたBin型データから、分類・担当者・項目のいずれかであるかを判断する
  2. 分類または担当者ならば、NOの欄にIDを表示する
  3. 項目ならば分類方法により、名称の隣に入力する文字列を分類または担当者を判断して記入する
    予定に必要な作業量を記入する
    処理状況は入力値を使うか、実績から計算するかを判断し、記入する
    備考を記入する
    必要なチャートバーを描画する(後述します)
  4. 与えられたBinに対応する名称を記入し、セル幅に合わせて文字の大きさを縮小するオプションを設定し、Binに設定されたインデントを付加する
となります。実際のコードを下記に示しますが、ページ幅の関係上改行を繰り返しており見づらくなっています。実際のマクロをダウンロードして、OpenOffice.orgにて確認してみて下さい。

Sub DrawChart(bin As Object)
    
    Dim wk As Object
    
    Select Case bin._Type
        Case BINTYPE_CATEGORY
            wk = Categories(bin._Id)
            mdlMain.Cells(oSheet, _
                oProperty._LeftColumn, _
                bin._Row).Value = wk._Id
        Case BINTYPE_PERSON
            wk = Persons(bin._Id)
            mdlMain.Cells(oSheet, _
                oProperty._LeftColumn, _
                bin._Row).Value = wk._Id
        Case BINTYPE_ITEM
            
            wk = Items(bin._Id)
            
            Select Case oProperty._CategorizeType
                Case CATEGORIZETYPE_CATEGORY
                    Cells(oSheet, _
                        oProperty._LeftColumn + 2, _
                        bin._Row).String = _
                            Persons(wk._PersonId)._Name
                Case CATEGORIZETYPE_Person
                    Cells(oSheet, _
                        oProperty._LeftColumn + 2, _
                        bin._Row).String = _
                            Categories(wk._CategoryId)._Name
            End Select
            
            Cells(oSheet, _
                oProperty._LeftColumn + 3, _
                    bin._Row).Value = wk._Plan
            
            If oProperty._CalculateStatus Then
                If wk._Plan = 0 Then
                    Cells(oSheet, _
                        oProperty._LeftColumn + 4, _
                        bin._Row).Value = 0
                Else
                    Cells(oSheet, _
                        oProperty._LeftColumn + 4, _
                        bin._Row).Value = _
                            (wk._Act / wk._Plan) * 100
                End If
            Else
                Cells(oSheet, _
                    oProperty._LeftColumn + 4, _
                    bin._Row).Value = wk._Status
            End If
            Cells(oSheet, _
                oProperty._LeftColumn + ChartHeaderColumns + _
                    oProperty._DrawColumns, _
                bin._Row).String = wk._Note
                
            DrawChartBar(bin._Id, bin._Row)
            
    End Select
    
    With mdlMain.Cells(oSheet, oProperty._LeftColumn + 1, bin._Row)
        .String = wk._Name
        .HoriJustify = 1
        .ParaIndent = 353 * bin._Depth    '1[point] = 0.3528[mm]
    End With
    
End Sub

テーマ:OpenOffice.org - ジャンル:コンピュータ

休日の色分け

これまでにしっかりと環境を整えてきたので、休日の色分けは非常に簡単です。処理の流れは、

  1. 上端、左端、行数のデータを取得
  2. (1)で取得した数値から塗り分けする部分の列をオブジェクトとして取得
  3. セルの単位が一日単位で、且つ休日であれば色を塗り、そうでなければ無色にする
  4. (2)を次の列で行い(3)を実行し、この処理を描画する列数回繰り返す
というものです。実際のコードを下記に示します。

Sub paintHoliday
    
    Dim i As Integer
    
    Dim Top As Integer
    Dim Left As Integer
    Dim Row As Integer
    
    Dim oCells As Object
    
    Top = oProperty._TopRow + 1
    Left = oProperty._LeftColumn + ChartHeaderColumns - 1
    Row = MaxRows + Top
    
    For i = 0 To oProperty._DrawColumns - 1
        
        oCells = oSheet.getCellRangeByPosition(Left + i, Top, Left + i, Row)
        
        If oProperty._CellUnit =CELLUNIT_DAY And _
            IsHoliday(oProperty._BeginDate + i) Then
            oCells.CellBackColor = oProperty._ChartHolidayColor
        Else
            oCells.CellBackColor = -1
        End If
        
    Next i
    
End Sub

IsHoliday関数はmdlHolidayで宣言してあり、休日であれば真、休日でなければ偽を返す関数です。

テーマ:OpenOffice.org - ジャンル:コンピュータ

日付欄の更新 その3

実際に日付欄を書き換えるコードを下記に示します。

Sub printDateHeader
    
    Dim Row As Integer
    Dim Column As Integer
    Dim i As Integer
    
    Row = oProperty._TopRow + 1
    Column = oProperty._LeftColumn + ChartHeaderColumns
    
    Dim wk As Date
    Dim buff As Date
    
    buff = oProperty._BeginDate
    
    For i = 0 To oProperty._DrawColumns - 1
        
        wk = getDateByColumn(i)
        Cells(oSheet, i + Column, Row).Value = wk
        
        Select Case oProperty._CellUnit
            Case CELLUNIT_MONTH
                If i = 0 Or Year(wk) <> Year(buff) Then
                    Cells(oSheet, i + Column, Row - 1).String = Year(wk)
                    setLeftBorder(Cells(oSheet, i + Column, Row - 1), True)
                Else
                    Cells(oSheet, i + Column, Row - 1).String = ""
                    setLeftBorder(Cells(oSheet, i + Column, Row - 1), False)
                End If
            Case Else
                If i = 0 Or Month(wk) <> Month(buff) Then
                    Cells(oSheet, i + Column, Row - 1).String = Year(wk) & "/" & Month(wk)
                    setLeftBorder(Cells(oSheet, i + Column, Row - 1), True)
                Else
                    Cells(oSheet, i + Column, Row - 1).String = ""
                    setLeftBorder(Cells(oSheet, i + Column, Row - 1), False)
                End If
        End Select
        
        buff = wk
        
    Next i
    
End Sub

必要な変数を宣言した後、プロパティから日付を書き換える行番号と左端の列番号を取得します。また、工程表の開始日を取得し、バッファ用変数に記録します。

For...Next文で描画する列数回処理を繰り返します。処理の内容として、前々回作成したgetDateByColumn関数により、日付データを取得し、日付欄に入力します。次に、セルの単位で処理を分岐し、月単位ならば年が変わった時点で罫線を引くという処理を行い、それ以外であれば月が変わった時点で罫線を引くという処理を行います。

テーマ:OpenOffice.org - ジャンル:コンピュータ

日付欄の更新 その2

年月の欄は、年月を記載したセルの左側に罫線を引き、そうでないセルの左側は罫線を消す必要があります。このコードを直接記載してもかまわないですが、関数を作って利用する事にします。

Sub setLeftBorder(oCell As Object, flg As Boolean)
    
    Dim LeftBorder As New com.sun.star.table.BorderLine
    
    If flg Then
        LeftBorder.OuterLineWidth = 2
    Else
        LeftBorder.OuterLineWidth = 0
    End If
    
    oCell.LeftBorder = LeftBorder
    
End Sub

この関数は引数にセルオブジェクトと真偽の2つを持ち、フラグが真ならばセルの左側に罫線を引いて、偽ならば罫線を消しています。

テーマ:OpenOffice.org - ジャンル:コンピュータ

日付欄の更新 その1

日付の更新を容易にするため、列番号から日付を取得する関数を作成します。

Function getDateByColumn(Column As Integer) As Date
    
    Dim y As Integer
    Dim m As Integer
    Dim d As Integer
    Dim wk As Date
    
    wk = oProperty._BeginDate
    y = Year(wk)
    m = Month(wk)
    d = Day(wk)
    
    With oProperty
        
        Select Case ._CellUnit
            Case CELLUNIT_DAY
                wk = ._BeginDate + Column
            Case CELLUNIT_WEEK
                wk = ._BeginDate + Column * 7
            Case CELLUNIT_10DAYS
                
                d = Column mod 3
                m = m + (Column / 3 - 0.5)
                y = y + ((m - 1) / 12 - 0.5)
                m = (m - 1) mod 12 + 1
                
                If Column = 0 Then
                    
                ElseIf d = 0 Then
                    wk = DateSerial(y, m, 1)
                Else
                    wk = DateSerial(y, m, d * 10) + 1
                End If
                
            Case CELLUNIT_MONTH
                
                m = m + Column
                y = y + Int((m-1) / 12)
                m = (m - 1) mod 12 + 1
                wk = DateSerial(y, m, 1)
                
        End Select
        
    End With
    
    getDateByColumn = wk
    
End Function

以前作成したCalcEndDate関数と同様に、セルの単位別に日付を計算しています。

テーマ:OpenOffice.org - ジャンル:コンピュータ

COPYRIGHT(C) 2004 POWERD BY FC2 ALLRIGHT RESERVED.
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。