ネットワーク経由でiPadの台数点検

GIGAスクール構想で、私の勤務校にはiPadが304台配備されました。

たくさんのiPadが入ってきて、大変嬉しい限りですが、教育委員会より月に1回台数の点検を行うようにという指示も同時に受けました。(中々面倒です)

クラスにお願いすればいいと思われるかもしれませんが、機器が増えたら仕事も増えたと思われたくありません。

何とか最小限の労力でかつ正確に台数点検できないかと考え、思いついたのがネットワーク経由での台数点検です。

① 同じネットワークにつながっている機器をすべて検出する。=MACアドレスも検出される

※MACアドレス:ネットワークにつないで使用する機器には全て割り振られている、重複しない固有のアドレス。

② 検出結果をcsvで保存する。

③ 教育委員会からもらったiPadの一覧表と照らし合わせる。(一覧表にはiPadのMACアドレスが記載されている)

※照らし合わせる部分をGoogleスプレッドシートにGASを使って自動化

動作イメージ編(実際の点検の様子)




システム作成編(スプレッドシートで照合作業を行う部分を作成)

GASのソースコード

// メニューの追加

function onOpen() {

SpreadsheetApp.getUi()

.createMenu('追加メニュー')

.addItem('CSVアップロード', 'csvDialog')

.addItem('照合作業開始','assColumn')

.addItem('照合結果保存','saveCSVmain')

.addToUi();

}


// csvファイルアップロードダイアログを表示

function csvDialog() {

// 各シートのデータをクリアする

const ss = SpreadsheetApp.getActiveSpreadsheet();


sheet1 = ss.getSheetByName('検出端末');

sheet2 = ss.getSheetByName('登録端末');

sheet3 = ss.getSheetByName('操作シート');


// 各シート最終行を取得

const lastRow = sheet1.getLastRow();

const lastColumn = sheet1.getLastColumn();

const lastRow2 = sheet2.getLastRow();

const lastRow3 = sheet3.getLastRow();


if(lastRow != 0 ){

sheet1.getRange(1,1,lastRow,lastColumn).clear();

}

sheet2.getRange(5,6,lastRow2,6).clear();

sheet3.getRange(15,1,lastRow3,5).clear();

sheet3.getRange(13,2).clear();

sheet3.getRange(13,4).clear();


// csvファイルアップロードダイアログを呼び出す

var html = HtmlService.createHtmlOutputFromFile('index');

SpreadsheetApp.getUi().showModalDialog(html, 'CSVアップロード');

}


// アップロード処理

function uploadProcess(formObject) {

var formBlob = formObject.myFile;

var csvText = formBlob.getDataAsString('shift-jis');

var values = Utilities.parseCsv(csvText);

const upCsv = SpreadsheetApp.getActiveSpreadsheet();


recSheet = upCsv.getSheetByName('検出端末');

recSheet.getRange(1, 1, values.length, values[0].length).setValues(values);


Browser.msgBox('検出端末タブを開いて、MACアドレスが何列目にあるか数えてから、\\n[② 照合作業開始]ボタンをクリックしてください。');

}


// アップロードcsvファイルで、Macアドレスの列番号を指定するダイアログを表示

function assColumn(){

var columnStr = Browser.inputBox("検出端末タブのMACアドレスが入っている列番号を入力してください。\\n 例えば、M列であれば13です。");


if(columnStr == "cancel"){

return;

} else {

// 入力された列番号を数値に変換し、Macアドレス小文字変換へ!

var columnNum = Number(columnStr);

Browser.msgBox('照合作業を開始します。\\n 時間がかかります。OKをクリックして続行してください。');

lowRewrite(columnNum);

}

}


// Macアドレス小文字変換

function lowRewrite(columnNum){

const ss = SpreadsheetApp.getActiveSpreadsheet();

csvSheet = ss.getSheetByName('検出端末');


const lastRow = csvSheet.getLastRow();


for(var k = 2; k <= lastRow; k++){

console.log(columnNum);

var csvCell = csvSheet.getRange(k, columnNum).getValue();

var lowerStr = csvCell.toLowerCase();

csvSheet.getRange(k, columnNum+1).setValue(lowerStr);

}


// そのまま照合作業へ!

macAddressMatching(columnNum);

}


// 照合

function macAddressMatching(columnNum){

const ss = SpreadsheetApp.getActiveSpreadsheet();


sheet1 = ss.getSheetByName('検出端末');

sheet2 = ss.getSheetByName('登録端末');

sheet3 = ss.getSheetByName('操作シート');


// 最終行を取得

const lastRow = sheet1.getLastRow();

const lastRow2 = sheet2.getLastRow();


var l = 15; // 見つからなかった端末リストを作る際の開始行番号

// 今日の日付

var date = new Date();

sheet3.getRange(13,2).setValue(Utilities.formatDate( date, 'Asia/Tokyo', 'yyyy/MM/dd HH:mm:ss'));


// 照合作業

for (var j = 5; j <= lastRow2; j++){

var s2Cell = sheet2.getRange(j,4); // 登録端末のMacアドレス

var s2Val = s2Cell.getValue();


for (var i = 2; i <= lastRow; i++){

var s1Cell = sheet1.getRange(i,columnNum+1); // 検出端末のMacアドレス

var s1Val = s1Cell.getValue();

var s1State = sheet1.getRange(i,1);

var s1State = s1State.getValue();

// 検出端末のMACアドレスと登録端末のMACアドレスが一致したら

if ( s1Val == s2Val && s1State == 'On'){

sheet2.getRange(j,6).setValue('OK');

break;

}

}

// 検出端末の中に登録端末が無かったら

if ( sheet2.getRange(j,6).isBlank()){

// 操作シートにリスト化していく

var s2No = sheet2.getRange(j,1).getValue();

var s2Name = sheet2.getRange(j,2).getValue();

var s2Sirial = sheet2.getRange(j,3).getValue();

var s2Location = sheet2.getRange(j,5).getValue();

sheet3.getRange(l,1).setValue(s2No);

sheet3.getRange(l,2).setValue(s2Name);

sheet3.getRange(l,3).setValue(s2Sirial);

sheet3.getRange(l,4).setValue(s2Val);

sheet3.getRange(l,5).setValue(s2Location);

l++;

}

}


sheet3.getRange(13,4).setValue(l-15); // 見つからなかった台数

Browser.msgBox('照合作業が終わりました。');

}


// 照合結果保存

function saveCSVmain() {

// dialog.html をもとにHTMLファイルを生成

// evaluate() は dialog.html 内の GAS を実行するため( <?= => の箇所)

var html = HtmlService.createTemplateFromFile("csvdialog").evaluate();

// 上記HTMLファイルをダイアログ出力

SpreadsheetApp.getUi().showModalDialog(html, "CSVファイルダウンロード");

}


function saveCSV() {

// スプレッドシート上の値を二次元配列の形で取得

const ss = SpreadsheetApp.getActiveSpreadsheet();

var sheet3 = ss.getSheetByName('操作シート');

var lastRow = sheet3.getLastRow();

var values = sheet3.getRange(13,1, lastRow,5).getValues();


// 二次元配列をCSV形式のテキストデータに変換

var dataArray = [];

for (var i = 0; i < values.length; i++) {

dataArray.push(values[i].join(","));

}

return dataArray.join("\r\n"); // 改行コードは windows を想定

}


// CSVファイル名の設定はここで!!

function getFileName() {

var now = new Date();

var datetime = Utilities.formatDate( now, 'Asia/Tokyo', 'yyyy/MM/dd/HH:mm:ss');

// アクティブシート名+現在日時

return 'iPad台数照合結果' + '(' + datetime + ')' + '.csv';

}


index.html

<!DOCTYPE html>

<html>

<head>

<base target="_top">

<script>

// アップロードボタンが押された時の処理

function csvUpload(formObject) {

google.script.run.withSuccessHandler(closeDialog).uploadProcess(formObject);

document.getElementById('myForm').style.display = 'none'; // フォームを非表示

document.getElementById('message').innerHTML = '処理中...'; // 処理中の文字を表示

}

// 処理が終わった時にダイアログを閉じる

function closeDialog() {

google.script.host.close();

}

</script>

</head>

<body>

<form id='myForm'>

<input name="myFile" type="file" />

<button onclick="csvUpload(this.parentNode);">アップロード</button>

</form>

<div id='message'></div>

</body>

</html>

csvdialog.html

<!DOCTYPE html>

<html>

<head>

<base target="_top">

<script type='text/javascript'>

function handleDownload() {

var content = <?= saveCSV(); ?>; // 出力データを GAS から取得する

var blob = new Blob([ content ], { "type" : "text/csv"});

document.getElementById("download").href = window.URL.createObjectURL(blob);

}

</script>

</head>

<body>

<a id="download" href="#" download=<?= getFileName(); ?> onclick="handleDownload()">ダウンロード</a>

</body>

</html>