スケジュール作成をもっと簡単に。内製アプリケーション「ScheduleCanvas」

早速ですが皆さん。

プロジェクトの計画を立てるとき、スケジュールの作成が面倒だと感じたことはありませんか?

汎用的なExcel等のツールを使って作成すると、まずは管理するためにフォーマットを決めなければならず、途中でのタスクの入れ替えやパスの変更はなかなか容易ではありません。

市販のツールを使おうにもただ試すだけにはハードルが高すぎたり・・・。

そういった悩みを解消するために社内開発に踏み切ったのが、内製アプリケーション「ScheduleCanvas(スケジュールキャンバス)」です。

f:id:sgtech:20200206212358p:plain

今回のBlogではこのツールの仕様と、スケジュール作成がどう変わったのかを紹介するとともに、ツール実装におけるノウハウの一部を少しだけ紹介します。

今回このブログを担当するのは、セガゲームス 第3事業部 第3開発2部 テクニカルサポートセクションの麓です。

まずは私からScheduleCanvasとはどんなアプリケーションなのかなど説明していきたいと思います。

ScheduleCanvasってどんなツールなの?

単体で使用できるアプリケーション

このツール開発は、スケジュール表の作成、タスクの入れ替えをExcelから脱却し、煩雑なフォーマットを統一するためにスタートしました。

また、WebサービスやDBを社内向けに作ってしまうと、外部協力会社との連携のときの障壁が多かったことと、とりあえずアプリケーションを作ってみることでどこまで効果があるのかを見てみるには大きなシステムは向かないということで、単体で動くexe、アプリケーションとして開発されました。

f:id:sgtech:20200206212540p:plain

アイコン

ガントチャートと各リストで構成

画面要素はガントチャートをベースにそこに表示されるデータがリスト形式になっています。

ガントチャートによって、スケジュールの可視化ができ、マウス操作を充実させることで、簡単にタスクの入れ替えや調整ができるように作られています。

主な動作をいくつか紹介します。

タスクの作成

f:id:sgtech:20200206213605g:plain



タスクをガントチャート上で簡単に登録でき、タスク名も即座に変更することができます。

担当者変更

f:id:sgtech:20200206215139g:plain

担当者の追加とタスクのアサイン変更もドラッグ&ドロップで手軽に行えます。

休日の自動調整

f:id:sgtech:20200207160420g:plain

タスクの長さは工数(日数)ベースで設定されていますので、休日を跨ぐと自動で長さを調節します。

オート整列機能

f:id:sgtech:20200207160951g:plain

複数のタスクを並べ直して総工数を確認する機能も充実しています。

 

また、ガントチャートに表示される情報は全てリスト形式で管理され、リストの編集性もできるだけExcelに近づくように(完全再現への道はまだ遠いですが)設計されています。

例えば、リスト項目のコピペや追加、削除、順番の入れ替えは簡単にできるように作られています。

リスト処理「タスク一覧」

f:id:sgtech:20200207185005g:plain

Excelのような外部アプリケーションのリストから、コピー&ペーストでタスク登録、一覧のセルの内容のコピーペースト、値も外部アプリケーションからコピーペーストで設定することもできます。

リストのフィルター機能

f:id:sgtech:20200207192447g:plain

各要素のフォーカスを切り替えられるようなフィルター機能は大量のタスクを管理するのには重要な機能です。

 

また、スケジュール作成の簡便化やフォーマットの統一等はScheduleCanvasを使ってもらうことで解決していますので、印刷や報告書などに活用できるようにExcel出力機能も用意しています。

f:id:sgtech:20200207193346p:plain

このように、主だった機能はゲーム開発者であるユーザーのニーズに常に答えるようにしてアプリケーションは開発されました。

外部連携

Excelの他にも各種チケット管理やバグトラッキングシステムなどと連携させて、ガントチャート視覚化も実装済みですが、今回は記事のボリュームを考慮して割愛させていたできます。

その効果は?

機能実装がある程度落ち着き、現在では多くのプロジェクトで試用してもらっています。

そこで今後の開発継続に向けて参考にするために、ちょっとしたアンケートをとって見ました。

集計結果は…。

質問:ScheduleCanvasを利用するメリットを感じますか?

f:id:sgtech:20200207194313p:plain

質問:ScheduleCanvasを利用して、効率化した部分はありましたか?

f:id:sgtech:20200207194316p:plain

ここでは概ねポジティブな印象です。

また、意見として以下のようにもいただいていますので、ひとつひとつを参考にさらに使いやすいツールにするために開発を続行していきます。

良い意見
  • スケジュールの入れ替え、パスの調整等にかかる時間が短縮した。
  • ユーザーのタスク負担度が一目でわかる。
  • 今までバラバラだったスケジュールのフォーマットが統一され、見やすくなった。
改善が必要な意見
  • タスクの検索がExcelの検索より一覧性がない。
  • 開発会社に委託する業務が多く、他社提出のスケジュール(Excel)との共存が難しい。
  • 動作をとにかく軽くしてほしい。

他にもアンケートとは別にExcelで管理してたときよりも確実に30%は効率化できているという声もありました。

社内ツールを開発する上で定期的なアンケートはとても有用で、現在主にどう使われていて、何が一番ボトルネックになっているのかのスコープを探るときに活用しています。

今後も・・・

内製アプリケーションということで、手軽なカスタマイズや要望に応じて機能実装を即時対応できるというのが大きなメリットとなります。

単純なスケジューラーは数あれど、ゲーム開発の現場でゲーム開発の状況に応じて作られているアプリケーションは他の会社だったとしても同じような問題に行き当たることが多いと思います。

こういったゲーム会社に特化した内製ツールだからこそ、会社の枠を超えていつか提供できるようにして、業界に貢献できたらという願いで製作しています。

ご興味ある方は…と言いたいですが、現時点ではそういった準備が整っていないので今しばらくお待ち下さい。

実装ノウハウをちょっとだけ

ここからは実装担当の清水から、このアプリケーションの実装について軽く触れてもらおうと思います。

 

というわけで本パートを担当させていただきます、セガゲームス 第3事業部 第3開発2部 テクニカルサポートセクションの清水です。

 

今回は、いろいろと応用ができそうなExcel出力に関する実装について紹介しようと思います。

 ScheduleCanvasのExcelファイルの出力にはClosedXMLというオープンソースライブラリを使用しています。(https://github.com/ClosedXML/ClosedXML

f:id:nobutoshi_shimizu:20200213162255p:plain

簡単なコードでExcelワークシートを作成することができ、Excelファイル(.xlsx)で保存することができます。

また、PCにExcelのソフトウェアがインストールされていなくてもExcelファイルを作成することができます。これは、スタンドアロンツールであるScheduleCanvasにとって、とてもありがたい特徴でした。

NuGetからインストールできるのでVisual Studioを使用しているならば、インストールも簡単にできます。 

 

ClosedXMLを用いてExcelファイルを作成するには以下のようなコードを書きます。

//新規ワークブックを作成
var workbook = new XLWorkbook();

//新規ワークシート「Sample Sheet」を作成し、先ほど作成したワークブックに追加
var worksheet = workbook.Worksheets.Add("Sample Sheet");

//作成したワークブックを"HelloWorld.xlsx"として別名で保存
workbook.SaveAs("HelloWorld.xlsx");

このコードでは、初めに新規ワークブックを作成し、そのワークブックに新たなワークシート「Sample Sheet」シートを作成、ワークブックを「HelloWorld.xlsx」として保存しています。

f:id:sgtech:20200223205604p:plain

作成されたHelloWorld.xlsx

では次に、ワークシートに何か値を入れてみましょう。

//新規ワークブックを作成
var workbook = new XLWorkbook();

//新規ワークシート「Sample Sheet」を作成し、先ほど作成したワークブックに追加
var worksheet = workbook.Worksheets.Add("Sample Sheet");

//「Sample Sheet」シートのA1セルの内容に"Hello World!"を記入
worksheet.Cell("A1").Value = "Hello World!";

//作成したワークブックを"HelloWorld.xlsx"として別名で保存
workbook.SaveAs("HelloWorld.xlsx");

このコードでは、初めに新規ワークブックを作成し、そのワークブックに新たなワークシート「Sample Sheet」シートを作成、「Sample Sheet」シートのセルA1に「Hello World!」を記入して、ワークブックを「HelloWorld.xlsx」として保存しています。

f:id:sgtech:20200223205713p:plain

A1セルにHello World!を入力した出力結果

//「Sample Sheet」シートのA1セルの内容に"Hello World!"を記入
worksheet.Cell("A1").Value = "Hello World!";

この部分がセルに値をセットする部分です。

セルの指定方法は、複数あります。
以下のコードはいずれもA1セルを指定しています。

//セルのアドレスの文字列で指定
worksheet.Cell("A1").Value = "Hello World!";

//セルの行と列の数字で指定 ※最小は1、0だとエラーになる
worksheet.Cell(1, 1).Value = "Hello World!";

//セルの行は数字、列は文字列で指定
worksheet.Cell(1, "A").Value = "Hello World!";

実際にプログラムを組む際は一番よく使うのは、行と列ともに数字で指定する方法になるかと思います。

 

セルには値だけでなく、背景色、フォント、文字列の配置位置、数値の書式、枠線のタイプ、枠線の色なども設定できます。

//「Sample Sheet」シートのA1セルを変数に入れる
var cell = worksheet.Cell("A1");
 

//セルの背景色(R=255,G=0,B=0)に設定
cell.Style.Fill.BackgroundColor = XLColor.FromArgb(255,0,0);

//セルの文字のフォントをHGS創英角ポップ体に設定
cell.Style.Font.FontName = "HGS創英角ポップ体";

//セルの文字の水平方向の配置位置を中央に設定
cell.Style.Alignment.Horizontal = XLAlignmentHorizontalValues.Center;

//セルの文字の垂直方向の配置位置を中央に設定
cell.Style.Alignment.Vertical = XLAlignmentVerticalValues.Center;

//セルの数値の書式を"yyyy/mm"に設定 任意のフォーマットに指定可能
cell.Style.DateFormat.Format = "yyyy/mm";

//セルの周りの枠線を点線に設定
cell.Style.Border.OutsideBorder = XLBorderStyleValues.MediumDashDotDot;

//セルの周りの枠線の色を黒色に設定
cell.Style.Border.OutsideBorderColor = XLColor.Black;

 

//文字の配置位置をわかりやすくするためにセルの大きさを変更
worksheet.Column(1).Width = 50;
worksheet.Row(1).Height = 50;

f:id:sgtech:20200223205717p:plain

セルにいろいろ設定した出力結果

手作業でExcelを編集するときと同じように、セル単体ではなく範囲を対象に設定することもできます。

//「Sample Sheet」シートのA1セルからC5セルの範囲を変数に入れる
//範囲の指定は左上のセルと右下のセルを指定する
var range = worksheet.Range(worksheet.Cell("A1"), worksheet.Cell("C5"));
 
//範囲内の全てのセルの背景色を青色に設定
range.Style.Fill.BackgroundColor = XLColor.Blue;

f:id:sgtech:20200223205722p:plain

複数のセルを範囲指定して背景色を設定した出力結果

このほかにも、

複数のセルを一つのセルにする「セルの結合」

//結合したいセル範囲を指定して...
var mergerange = worksheet.Range(worksheet.Cell("B2"), worksheet.Cell("D4"));

//Merge()で範囲のセルを結合する
mergerange.Merge();

 

//値を設定してみる
mergerange.Value = "結合セル";
//文字の配置位置を中央に設定
mergerange.Style.Alignment.Horizontal = XLAlignmentHorizontalValues.Center;
mergerange.Style.Alignment.Vertical = XLAlignmentVerticalValues.Center;

f:id:sgtech:20200223205727p:plain

セルの結合を設定した出力結果

ワークシート上のデータを抽出して表示できるようにする「オートフィルタの設定」

//例示のために


セルにデータを入力

worksheet.Cell("B2").Value = "名前";
worksheet.Cell("C2").Value = "味";
worksheet.Cell("D2").Value = "知名度";
worksheet.Cell("E2").Value = "値段";
 
worksheet.Cell("B3").Value = "リンゴ";
worksheet.Cell("C3").Value = "甘い";
worksheet.Cell("D3").Value = "一般的";
worksheet.Cell("E3").Value = "500";

worksheet.Cell("B4").Value = "みかん";
worksheet.Cell("C4").Value = "甘い";
worksheet.Cell("D4").Value = "一般的";
worksheet.Cell("E4").Value = "300";
 
worksheet.Cell("B5").Value = "チリドッグ";
worksheet.Cell("C5").Value = "辛い";
worksheet.Cell("D5").Value = "低い";
worksheet.Cell("E5").Value = "700";

//オートフィルタを設定したいセル範囲を指定して...
var filterrange = worksheet.Range(worksheet.Cell("B2"), worksheet.Cell("E5"));

//SetAutoFilter()でオートフィルタを設定する
filterrange.SetAutoFilter();

 

//見やすいように範囲内のセルに枠線を設定
filterrange.Style.Border.OutsideBorder = XLBorderStyleValues.Thin;
filterrange.Style.Border.InsideBorder = XLBorderStyleValues.Thin;
//見やすいようにセルの幅を設定
worksheet.ColumnWidth = 20;

f:id:sgtech:20200223205732p:plain

オートフィルタを設定した出力結果

特定の行や列を固定表示したままシートをスクロールできるようにする「ウィンドウ枠の固定」

//固定するワークシートの1~2行目とA列B列をピンク色に設定
worksheet.Column(1).Style.Fill.BackgroundColor = XLColor.Pink;
worksheet.Column(2).Style.Fill.BackgroundColor = XLColor.Pink;
worksheet.Row(1).Style.Fill.BackgroundColor = XLColor.Pink;
worksheet.Row(2).Style.Fill.BackgroundColor = XLColor.Pink;

 

//行と列の数字を指定して「ウィンドウ枠の固定」を行う
//Freeze(2, 2)だとC3セルを指定して「ウィンドウ枠の固定」したときと同じ状態になる
worksheet.SheetView.Freeze(2, 2);

 

//セルの指定では0を指定するとエラーになったが、この処理は0が指定できる
//0を指定すると、行方向だけ、または、列方向だけにウィンドウ枠の固定ができる
worksheet.SheetView.Freeze(2, 0);

 

//行方向だけ、または、列方向だけウィンドウ枠の固定をするための別メソッドもある
worksheet.SheetView.FreezeColumns(2);
worksheet.SheetView.FreezeRows(2);

f:id:sgtech:20200223205738p:plain

ウィンドウ枠の固定を設定した出力結果

上記のとおり、Excel上で設定できるものは基本的にコード上で設定することができます。

 

ScheduleCanvasでは、これらを使ってツール上で表示している見た目と同じようなExcelファイルの出力を実現しています。

以下の2つの図はScheduleCanvas上での見た目と出力したExcelの見た目をそれぞれキャプチャしたものです。

f:id:sgtech:20200223205743p:plain

ScheduleCanvasの見た目

f:id:sgtech:20200223205750p:plain

ScheduleCanvasから出力したExcelファイルの見た目

なかなかの再現度ではないでしょうか。

ここまで見た目にこだわるとコードも結構複雑になりますが、データを出力する際に見出しの行に色を付けたり、オートフィルタを設定するだけならば簡単に実装できます。

皆さんも試してみてはいかがでしょうか。

 

ひとまずはツールの実装の一例としてExcelファイルとの連携をご紹介しましたが、ユーザーの要件に応えるために一つのツールには他にも多くの技術が盛り込まれて実装されています。

このようなゲームを作るための周辺ツールやワークフロー、ゲームエンジンのノウハウが豊富で、情報共有が盛んな職場で働いてみたいという方はぜひ、以下をチェックしてみてください。

 

www.sega.co.jp

(C) SEGA

Powered by はてなブログ