子育てエンジニアブログ

子育てに励むシステムエンジニア(SE)のブログ

EVMについて調べてみた

プロジェクトマネジメントをする上で何か、効率的にできないかと思いいろいろと調べていくとEVMというものがあることを知ったので自分用にまとめてみる。

EVMとはEarned Value Management(アーンドバリューマネジメント)の略であり、プロジェクト全体の進捗を実際にかかったコストなどの価値で分析する手法のこと。
プロジェクトの実績と進捗を可視化できる。
プロジェクト管理の単位に時間だけでなく、コストを加えている。

PV
Planned Valueの略であり、計画予算の事。
プロジェクトの計画時に作成された予算のうち特定の時点までに完了すべき作業の予算コストのこと。

EV
Earned Valueの略であり、出来高の事。
特定の時点で完了している工程の予算コストの合計値を表す。
EVとPVを比べることで計画と実際のスケジュールの差異を算出できる。

AC
Actual Costの略であり、実コストのこと。
特定の時点までに投入された実際に発生したコストの合計値。
EVとACはどちらもある時点でのコストの合計値だが、EVが予算に対してで、
ACは実際にかかったコストを表す。

BAC
Budget at Completionの略であり、プロジェクトに必要な予算の合計値を示す。
プロジェクトの計画立案時に算出される数値で、EVを算定する際の根拠となる数字。

SV
Schedule Varianceの略であり、スケジュール際の事。
現時点で完了した実績作業分の予算コストのEVと、計画段階の予算コストPVが必要。
EVーPV=SV
SVがマイナスの数値だと、計画より遅延しているということになる。

CV
Cost Varianceの略であり、コスト差異のこと。
特定の時点までに実際に発生したコストACと、現時点までに完了した実績作業分の予算EVの差。
EVーAC=CV
CVがプラスであればその時点までのコストが予算内である。
逆にマイナスの場合だと、その時点までのコストが予算を超過していることになる。

SPI
Schedule Performance Indexの略であり、スケジュール効率指数のこと。
スケジュールの進み具合を示す数値で、現時点で完了した作業の予算コスト「EV」を、計画時に見積もった予算コスト「PV」で割り算出できる。
EV/PV=SPI
SPIが1よりも大きければ当初の計画よりも進んでいる。
1であれば計画どおりに進んでいる。
1よりも小さい場合は計画よりも遅れていることを意味する。

CPI
Cost Performance Indexの略であり、コスト効率指数のこと。
プロジェクトの進捗に対して、計画と比べてどのくらいのコストがかかっているかを算出する。
現時点で完了した作業の予算コストEVを、実際に発生したコストACで割り算出する。
EV/AC=CPI
CPIが1であれば予算どおり。
1より大きければ計画していたよりもコストが発生していない。
1よりも小さければ計画よりもコストを多く使っている。

ETC
Estimate To Completionの略であり、残作業コスト予測のこと。
現時点で完成までに残っている作業の予算コストを指す。
プロジェクト完了までに必要な当初の総予算であるBACから、現時点までに完了した作業の予算コストEVを引き、
コスト効率を示すCPIで割り算出する。
(BACーEV)/CPI=ETC
ETCは費用があといくら必要なのか分かる。

EAC
Estimate At Completionの略であり、完了時コスト予測のこと。
現時点でのプロジェクト完了時の総予算を指す。
現在の作業ペースでいくと、最終的にどの程度コストがかかりそうか分かる。
実際に発生したコストACと、残作業に予測されるコストETCを足して算出する。
AC+ETC=EAC
現時点でどのように対応すべきかの判断に利用できる。

VAC
Variance At Completionの略であり、完了時コスト差異のこと。
プロジェクト完了までに必要な当初の総予算BACから、現時点で見積もった最終的な総予算EACを引いて算出する。
BACーEAC=VAC
VACがプラスであれば予算内におさまっている。
マイナスであれば予算を超過している。

【GAS】GoogleスプレッドシートでHTML画面を表示してスプレッド上の値を画面上に表示する方法

GoogleスプレッドシートでHTML画面を表示してスプレッド上の値を画面上に表示する方法についてです。

画面を表示するだけなら下記の記事に詳しく書いています。
stsa.hatenablog.com

今回はそこからさらにスプレッド上の値を画面上に表示するというところをやってみます。

スプレッドの入力してある値はこんな感じ。

ファイル構成はこんな感じ。gasプログラムとindex.html。

今回やることは、カーソルのある行の値を取得してHTML側に描画してみようと思います。

出来上がりはこんな感じでシンプル。
HTML側はCSSなどをしっかり使えばもっと綺麗になりますが、今回は最小限で。

まずはgas側。こちら全量です。値を渡すところ以外の処理も入った状態を載せています。
ポイントは2ヶ所。
1つ目は、showScreen()で画面の呼び出しをしているところ。
2つ目は、getValue() でこれは画面側のJSから呼び出されるのですが、hashValueを返しているところ。

var app = SpreadsheetApp;

function onOpen() {
    var ui = SpreadsheetApp.getUi()
    //メニュー名を決定
    var menu = ui.createMenu("メニュー名");
    menu.addItem("関数1", "showScreen");
    menu.addItem("関数2", "showScreen"); 
    menu.addSeparator(); 
    menu.addSubMenu(ui.createMenu("サブメニュー名").addItem("サブアイテム1", "showScreen") );
    //スプレッドシートに反映
    menu.addToUi();
}

function showScreen() {
    var html = HtmlService.createHtmlOutputFromFile('index').setWidth(500).setHeight(500);
    app.getActiveSpreadsheet().show(html);
}

function getValue() {
    //現在のスプレッドシートを取得
    var activeSpreadSheet = SpreadsheetApp.getActiveSpreadsheet();
    var sheet = activeSpreadSheet.getActiveSheet();
    let myActiveCell = sheet.getActiveCell();

    //アクティブなセルからRow:行を取得する
    let selectedRow = myActiveCell.getRow();

    //行の最終列から左方向に取得する
    var lastCol = sheet.getRange(selectedRow, sheet.getMaxColumns()).getNextDataCell(SpreadsheetApp.Direction.PREVIOUS).getColumn();
    
    // 配列の初期化
    var hashValue = {};

    // 1列目から取得
    for (var i = 1; i <= lastCol; i++) {
        if (true) {      
                hashValue["Key:" + sheet.getRange(selectedRow, i).getValue() ] = "Value:"+sheet.getRange(selectedRow, i).getValue();
        }
    }
    return hashValue;
}

次に画面(HTML側)。
index.htmlという名前にしています。
こちらも全量載せておきます。
こちらは、HTMLは大したことは書いていなくて、JSで動的に生成するDOMを入れ込むinsert-contentというidがポイントです。
で、上の方に書いているscriptの部分が大事。
google.script.run.withSuccessHandlerでgasの関数getValueを呼んで、取得値をdtに渡して受け取っています。
その後は、ループ処理でhashValueの値を取得して、contentに詰めています。
そして、insertContent.innerHTMLで埋め込んでいます。

<!DOCTYPE html>
<html>
  <head>
    <base target="top">
    <script>
    window.onload = function () {
        var content = '';  //作成するDOM
        google.script.run.withSuccessHandler(function (dt) { //取得値をdtに渡す

            for (let key in dt) {
                content = content + key + " ";
                content = content + dt[key];
                content = content + '<br>';
            }
            var insertContent = document.getElementById('insert-content');
            insertContent.innerHTML = content;
        }).getValue();
    }
</script>
  </head>
  <body>
    <div id ="insert-content"></div>
  </body>
</html>

関数を呼び出すときは、 onOpen()によりメニューに追加されるので、そこから実行します。

詳しくは下記の記事から。
stsa.hatenablog.com


以上、GoogleスプレッドシートでHTML画面を表示してスプレッド上の値を画面上に表示する方法でした。

【GAS】Googleスプレッドシートでオリジナルのメニューを追加する方法

Googleスプレッドシートでオリジナルのメニューを追加する方法についてです。

Googleスプレッドシートを使っていると、関数を作り処理を自動化したりする。

しかし、スプレッド上にボタンを配置して実行するのがなんとなくダサく感じていた。
わざわざスプレッド部分に置かないといけないし、そもそもオブジェクトが見た目がダサい気がしていた。

ちなみにボタンを押したときに処理させる方法は下記。
stsa.hatenablog.com


そこで、Googleスプレッドシートでオリジナルのメニューを追加する方法があるらしいので試してみた。

追加してみたのはこんな感じのオリジナルのメニュー

さらにこれの素晴らしいところはサブメニューまで追加できる。

さて、早速やり方についてですが、やり方は簡単。
下記のようなものを追加するだけで勝手にメニューに追加される。

function onOpen() {
    var ui = SpreadsheetApp.getUi()
    //メニュー名を決定
    var menu = ui.createMenu("メニュー名");
    menu.addItem("関数1", "実際の関数名1");
    menu.addItem("関数2", "実際の関数名2"); 
    menu.addSeparator(); 
    menu.addSubMenu(ui.createMenu("サブメニュー名").addItem("サブアイテム1", "実際の関数名2") );
    //スプレッドシートに反映
    menu.addToUi();
}

Googleスプレッドシートでオリジナルのメニューを追加する方法についてでした。