るぴブロ

備忘録とかです(*'ω'*)

Visual Studio for MAC 2019 GA

こんばんは。

久しぶりのアップです。

 

昨日Visual Studio 2019のLaunchイベントで以下がGAされました。

visualstudio.microsoft.com

 

今回GAされるかと思っていた、IntellicodeとC# 8.0はPreviewのままでしたね。

きっと2019年後半くらいに.NET Core 3.0と一緒にGAされるのかもしれません…わかりませんがw

 

 

さて、今回はMacBookProに入っているVisual Studio 2017 for MACをアンインストールして…

 

…ってどうやってアンインストールするのっ!?

 

まだMACがよくわかってない初心者なのでggってみると公式に書いてましたw

スクリプト叩いてアンインストールするんですね。

docs.microsoft.com

 

サクッとアンインストールしてダウンロードしましょう!

 

visualstudio.microsoft.com

f:id:rupic:20190403231421p:plain

ダウンロードした.dmgファイルをダブルクリックするといつものアレが出てきますので続けてアイコンをダブルクリックしましょう。

f:id:rupic:20190403231647p:plain

途中こんなやつやパスワード入力を求められる事があるので指示に従って進めていきます。

f:id:rupic:20190403231804p:plain

続いて何をインストールするか聞かれますので用途にあったものをインストールしましょう。

f:id:rupic:20190403231913p:plainf:id:rupic:20190403231920p:plain

ダウンロードしながらインストールが進んでいきます。

f:id:rupic:20190403232200p:plain

おおw早い!!

Visual Studio 2017をインストールした時はめっちゃ時間がかかったイメージがありましたので、今回のインストールは随分早くなったと感動しました。

f:id:rupic:20190403232217p:plain

だがしかしです。

ここからがめっちゃ長かったーw

f:id:rupic:20190403232233p:plain

という事で…インストールも終わり(白目

スタートアップ画面です。驚きの白さです。。

オサレでかっこいいですね!!

f:id:rupic:20190403232655p:plain

プロジェクトを作成してみます!

.NETCoreは2.2まで選択可能です。

f:id:rupic:20190403232701p:plainf:id:rupic:20190403232709p:plain

相変わらずシンプルですねー。

普段WindowsVisual Studioを使っていて、テーマも濃紺にしているのでなおさらシンプルに見えてしまいます。

f:id:rupic:20190403233117p:plain

 

今回のVisual Studio for MACでの改善点

docs.microsoft.com

 

毎日会社ではWindows版を使っていることもあり、まだあまり慣れないですが、慣れるために暫くこちらで遊んでみることにします。

来週の福岡で開催されるLaunchイベントでこれ持って行ってみようかしらw

スプレッドシートをWebアプリから参照する 

こんばんは。
何回かにわけて投稿してきたGoogle Form備忘録ですが、ようやく最終回です。

実現したい事

  • Google Formで時間帯予約フォームを作成
  • 予約データをスプレッドシートと連携
  • 各時間帯には上限があり残席数を知らせたい(予約できなくする等の制限は不要)
  • 登録時にユーザーIDを入力してもらい予約のキャンセル/変更ができる
  • スプレッドシートのデータを検索し現在の登録状況を検索/表示する事ができる
  • ユーザーはスマホWebブラウザからのアクセスのみ(ガラケは無視でおk)
  • 尚、ユーザーはGoogleアカウントでログインしない事とする(震

 

最後の機能はGoogle Formに登録した回答内容をどうにかして確認する術を探すというものですw

基本的にこちらもGoogleアカウントでログインしていただければ簡単に確認する事ができますのでこんな面倒な方法は不要かと思いまが、色々失敗してスプレッドシートをWebアプリケーションから呼び出す仕様になったので、そこはは別の用途で使えそうですね。

はじめは…

スプレッドシートにデータを保存しているので、単純に確認用のスプレッドシートを準備してユーザーの方にIDを入力→GASで必要事項を表示するといった仕様でした。

 

f:id:rupic:20190307235617p:plain

とりあえずこんな感じのTHEエクセルチックなシートを準備して、ユーザーIDを入力し図形描画で作った検索ボタン(GASを割付)をクリックしたらスプレッドシートの中身を検索というものを作成してみました。

なんとなくGASの使い方にも慣れ10分くらいで完成し、動作確認もバッチリです😊

www.atmarkit.co.jp

 

しかし…

上記で作成したスプレッドシートを公開してユーザーの方にページにアクセスしてもらうという算段でしたが、Googleアカウントでログインしない時点でスプレッドシートは読み取り専用となり、ユーザーには何やら検索できそうな画面を見るだけという謎仕様のものが見えるのみとなってしまいましたwwwwww

 

スプレッドシートをWebアプリから参照する 

もうダメかと思ってネットサーフィンしてたらこんな記事を見つけました。

qiita.com

 

どうやらスプレッドシートをDBの様に見立てて、Webアプリから参照する事ができる様です。

developers.google.com

 

公式によるとWebアプリとして公開するには以下の条件を満たしている必要があるらしいです。

  • doGet() または doPost() 関数を実装する
  • HTML service HtmlOutput オブジェクト または Content service TextOutput オブジェクト を返す

作ってみよう

とりあえず、gsファイルとHTML、javascriptを書きます。

index.gs

function getData(userid,week) {
  
  const fw_id = "***スプレッドシートのIDを入力***";
  const sw_id = "***スプレッドシートのIDを入力***";
  
  var spreadsheet;
  if(week === '1'){
    spreadsheet = SpreadsheetApp.openById(fw_id);
  } else {
    spreadsheet = SpreadsheetApp.openById(sw_id);
  }  
  
  var sheet = spreadsheet.getActiveSheet();
  
  const inventory = sheet.getDataRange().getValues()
  .filter(function(row){return row[1] === userid})
  .map(function(e){
    const columns = [0,1,2,3,4,5,6,7,8,9,10,11],row = [];
    for(var i = 0; i < columns.length; i++) row.push(e[columns[i]]);
    return row;
    
  });
  
  if(inventory.length === 0){
    return inventory;
  }
  
  return inventory[inventory.length -1];
}

function doGet(e) {
  var data = getData(e.parameter.name,e.parameter.id);
  return ContentService.createTextOutput(JSON.stringify(data, null, 2))
  .setMimeType(ContentService.MimeType.JSON);
}

index.html

<!DOCTYPE html>
<html lang="en">

    <head>
        <meta charset="utf-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <!-- The above 3 meta tags *must* come first in the head; any other head content must come *after* these tags -->
        <title>バス予約確認</title>
        <link rel="icon" href="img/fav.png" type="image/x-icon">
    
        <!-- Bootstrap -->
        <link href="css/bootstrap.min.css" rel="stylesheet">
    
        <!-- main css -->
        <link href="css/style.css" rel="stylesheet">      
    
        <!-- modernizr -->
        <script src="js/modernizr.js"></script>           

    </head>
    <body>        
        <div class="container main-container">
            <div class="header">
                <a class="h2" href="#" onclick="location.reload();">バス予約確認</a>
            </div>
            <br>            
            <div class="row col-md-12">
                <div class="input-contact col-md-4" style="width: 200px">
                    <input type="text" id="jcode" placeholder="ユーザーIDを入力">
                    <br>
                    <div class="btn-group" data-toggle="buttons" style="margin-top: 10px">
                        <label class="btn btn-default active">
                            <input name="week" type="radio" autocomplete="off" checked> 1週目
                        </label>
                        <label class="btn btn-default">
                            <input name="week" type="radio" autocomplete="off"> 2週目
                        </label>
                    </div>                    
                </div>
            </div>
            <div class="row col-lg-12">
                <div>
                        <input type="submit" id="search" class="btn btn-box" value="検索">
                </div>                
            </div>            
            <div class="row col-md-12">
                <div id="fw" class="col-md-6 values">
                    <h2>1週目</h2>
                    <table class="table table-borderd table-striped">
                        <th></th>
                        <th>行き</th>
                        <th>帰り</th>
                        <tr>
                            <th>3月4日(月)</th>
                            <td id="fw_go_mon"></td>
                            <td id="fw_rtn_mon"></td>
                        </tr>
                        <tr>
                            <th>3月5日(火)</th>
                            <td id="fw_go_tue"></td>
                            <td id="fw_rtn_tue"></td>
                        </tr>
                        <tr>
                            <th>3月6日(水)</th>
                            <td id="fw_go_wed"></td>
                            <td id="fw_rtn_wed"></td>
                        </tr>
                        <tr>
                            <th>3月7日(木)</th>
                            <td id="fw_go_thu"></td>
                            <td id="fw_rtn_thu"></td>
                        </tr>
                        <tr>
                            <th>3月8日(金)</th>
                            <td id="fw_go_fri"></td>
                            <td id="fw_rtn_fri"></td>
                        </tr>
                    </table>
                </div>
                <div id="sw" class="col-md-6">
                    <h2>2週目</h2>
                    <table class="table table-borderd table-striped">
                        <th></th>
                        <th>行き</th>
                        <th>帰り</th>
                        <tr>
                            <th>3月11日(月)</th>
                            <td id="sw_go_mon"></td>
                            <td id="sw_rtn_mon"></td>
                        </tr>
                        <tr>
                            <th>3月12日(火)</th>
                            <td id="sw_go_tue"></td>
                            <td id="sw_rtn_tue"></td>
                        </tr>
                        <tr>
                            <th>3月13日(水)</th>
                            <td id="sw_go_wed"></td>
                            <td id="sw_rtn_wed"></td>
                        </tr>
                        <tr>
                            <th>3月14日(木)</th>
                            <td id="sw_go_thu"></td>
                            <td id="sw_rtn_thu"></td>
                        </tr>
                        <tr>
                            <th>3月15日(金)</th>
                            <td id="sw_go_fri"></td>
                            <td id="sw_rtn_fri"></td>
                        </tr>
                    </table>
                </div>
            </div>

        </div>
        <footer>
            <div class="container-fluid">
                <p class="copyright">© Rupic</p>
            </div>
        </footer>

        <!-- jQuery -->
        <script src="js/jquery-2.1.1.js"></script>
        <!--  plugins -->
        <script src="js/bootstrap.min.js"></script>
        <script src="js/sheet.js"></script>
    </body>
</html>

seet.js

$(function(){
    $("#fw").css("display", "none");
    $("#sw").css("display", "none");

    $('#search').click(function(){
        var jcode = $('#jcode').val();
        var week = 0;
        $("#fw").css("display", "none");
        $("#sw").css("display", "none");

        if($('input[name=week]:eq(0)').prop('checked')){
          $("#fw").toggle();
          week = 1;
        }else{
          $("#sw").toggle();
          week = 2;
        };

        var url = 'https://script.google.com/macros/s/AKfycbyolai-14OF6N_jWKCnykga3WpVcCX06LYvRBn23W1gjkyYDFU/exec?name='+jcode+"&id="+week;

        $.ajax({ // json読み込み開始
            type: 'GET',
            url: url,
            dataType: 'json'
          })
          .then(
            function(json) { // jsonの読み込みに成功した時
              if(week===1){
                $('#fw_go_mon').text(json[2]);
                $('#fw_go_tue').text(json[3]);
                $('#fw_go_wed').text(json[4]);
                $('#fw_go_thu').text(json[5]);
                $('#fw_go_fri').text(json[6]);
                $('#fw_rtn_mon').text(json[7]);
                $('#fw_rtn_tue').text(json[8]);
                $('#fw_rtn_wed').text(json[9]);
                $('#fw_rtn_thu').text(json[10]);
                $('#fw_rtn_fri').text(json[11]);
              }else{
                $('#sw_go_mon').text(json[2]);
                $('#sw_go_tue').text(json[3]);
                $('#sw_go_wed').text(json[4]);
                $('#sw_go_thu').text(json[5]);
                $('#sw_go_fri').text(json[6]);
                $('#sw_rtn_mon').text(json[7]);
                $('#sw_rtn_tue').text(json[8]);
                $('#sw_rtn_wed').text(json[9]);
                $('#sw_rtn_thu').text(json[10]);
                $('#sw_rtn_fri').text(json[11]);
              }
            },
            function() { //jsonの読み込みに失敗した時
              alert('予期せぬ不具合が発生しました');
            }
           );
    });
});

 

適当にWebサーバーにデプロイして接続してみます。

f:id:rupic:20190309012921p:plain

まとめ

  • 急ぎで作成したので雑で申し訳ないです
  • 簡単にWebアプリから呼び出し可能なのでサクッと作りたい時に重宝しそう?
  • UIは自分の好きな感じで作成できるので融通が効きますね

 

今回のGoogle Formシリーズはこれにて終了ですが、また機会があれば、色々触ってみようかと思いますm(_ _)m

Google Formでログインなしで登録時に重複を削除する

こんばんは。

昨日の続きです!

実現したい事

  • Google Formで時間帯予約フォームを作成

  • 予約データをスプレッドシートと連携

  • 各時間帯には上限があり残席数を知らせたい(予約できなくする等の制限は不要)

  • 登録時にユーザーIDを入力してもらい予約のキャンセル/変更ができる

  • スプレッドシートのデータを検索し現在の登録状況を検索/表示する事ができる

  • ユーザーはスマホWebブラウザからのアクセスのみ(ガラケは無視でおk)

  • 尚、ユーザーはGoogleアカウントでログインしない事とする(震

 

はじめに・・・

正直今回は苦肉の策と言いますか、ユーザー次第的なところが強いので、あまりオススメできません。(泣

一度登録した内容を編集したい場合や、回答の重複を避けたい場合はGoogleアカウントでログインして頂く事を強くオススメします。

hep.eiz.jp

 

どうしよう・・・

今回、要件にユーザーの方にはGoogleアカウントでログインしないとあったので、どうしたものか考えに考えた結果、ユーザの方には予め決められたユーザーIDを入力してもらい、GASを使ってGoogle Formのリクエスト送信時に同じIDが過去に登録されていた場合は古いIDのレコードを削除するといったものにしました。

Google Formはスプレッドシートと連携必須

 

懸念事項

スプレッド上のレコードを削除する為、Google Formの回答とスプレッドシートのレコードがアンマッチになる

ユーザーIDを少しでも間違えて入力したら積む

 

とりあえず実装してみる

function myFunction() {

  var id = '***ここにスプレッドシートのIDを入力***';
  var answer_sheetname = '回答';
  var cansel_sheetname = 'キャンセル';
  
  //シートの読み込み
  var spsheet = SpreadsheetApp.openById(id)
  var answer_sheet = spsheet.getSheetByName(answer_sheetname);
  var cansel_sheet = spsheet.getSheetByName(cansel_sheetname);  
  //最終行の取得
  var answer_lastrow = answer_sheet.getLastRow();
  var cansel_lastrow = cansel_sheet.getLastRow()+1;
//直前に入力したレコードよりユーザーIDを取得 var userid = answer_sheet.getRange("B"+answer_lastrow).getValue(); //対象useridの行を取得 var rowPosition = findRow(answer_sheet,userid,2); //最終行と一致する場合は重複なしとみなす if(rowPosition === answer_lastrow){ return; } //取得した回答データをキャンセルシートに貼り付け answer_sheet.getRange('A'+rowPosition+':L'+rowPosition).copyTo(cansel_sheet.getRange('A'+cansel_lastrow+':L'+cansel_lastrow)); //元データを行ごと削除 answer_sheet.deleteRow(rowPosition); } function findRow(sheet,val,col){ var dat = sheet.getDataRange().getValues(); for(var i=1;i<dat.length;i++){ if(dat[i][col-1] === val){ return i+1; } } return 0; }

 

こんな感じです。

データを削除しようと思ったのですが、後から削除したデータはどんなものだったのか?と言うのを確認できる様にキャンセルシートを用意し、レコードを移動するイメージで作成してみました。

苦しい感じですが、以下の様な処理を行なっています。

  1. 自身のスプレッドシートから回答シートとキャンセルシートを取得
  2. 直前に入力したレコードよりユーザーIDを取得
  3. findRow関数で対象のユーザーIDを含むレコードが存在するかチェック
  4. 対象レコードが存在した場合、キャンセルシートにレコードをコピペ
  5. 回答シートよりコピペしたレコードを削除

2の直前に入力したレコードよりユーザーIDを取得したところで、複数ユーザーが同時にフォームに入力した場合はどうなるのか同僚にお願いして何度かテストしましたが、40回ほど実験して100%自身の入力したレコードだったので大丈夫かと怪しい処理を書いてますwww

 

まとめ

  • 今回の方法は絶対にオススメしません
  • 重複を削除したい場合はGoogleアカウントでログインしましょう

 

まぁ結果はともあれ、良く頑張った!!と思うwwww

 

Google Formでリクエスト送信時Formの表示を変更する

こんばんは。

前回に引き続きGoogle Formでやった案件のメモを残しておきます。

rupic.hatenablog.com 

実現したい事

  • Google Formで時間帯予約フォームを作成

  • 予約データをスプレッドシートと連携

  • 各時間帯には上限があり残席数を知らせたい(予約できなくする等の制限は不要)

  • 登録時にユーザーIDを入力してもらい予約のキャンセル/変更ができる

  • スプレッドシートのデータを検索し現在の登録状況を検索/表示する事ができる

  • ユーザーはスマホWebブラウザからのアクセスのみ(ガラケは無視でおk)

  • 尚、ユーザーはGoogleアカウントでログインしない事とする(震

 

各時間帯毎の予約件数をフォームに表示する

 そもそもそんな事が出来るのか謎なままネットサーフィンしていたら、非常に分かりやすいブログを発見しました。

 

どうやらGoogleではGoogleが提供するGoogle Formやカレンダー、スプレッドシート等のサービス上で動作するスクリプトを使ってアプリの機能を拡張したり連携したり出来るらしいデス。便利ですねw

developers.google.com

 

スクリプトを書いていきましょう

Google Formデザイナー画面右上のメニューより「スクリプトエディター」を選択します。

f:id:rupic:20190303233556p:plain

 

こんな感じでJavaScriptで書きましょう。

今回は前回の記事でスプレッドシートに回答結果を同期させているので、スプレッドシートよりデータを取得する事にしました。(実はちょっとした事情があってw

フォームの説明の箇所に取得したデータを表示するには以下でOKみたい。

 var form = FormApp.getActiveForm();

 form.setDescription(joinStr);

 

本当はセクション毎に表示したかったのですが、どうやってもセクション毎の説明を取得する方法がわからなくて致し方なく全てTopに表示です。

function endFormCheck_Ontheway(){
  var description = [];
  var weeks = CreateWeeks(1);
  var target = CreateTarget(1);
      
  description.push('■■■■■■行き便の空席状況■■■■■■\n');
  description.push('\n')
  
  description.push.apply(description,CreateDescription(weeks,target));

  return description;
}

function endFormCheck_Onthewayback(){
  var description = [];
  var weeks = CreateWeeks(2);
  var target = CreateTarget(2);
    
  description.push('■■■■■■帰り便の空席状況■■■■■■\n');
  description.push('\n')
  
  description.push.apply(description,CreateDescription(weeks,target));

  return description;
}
function CreateTarget(mode){  
  if(mode === 1){
    return ["5時","6時"];
  }else{
    return ["17時","18時"];
  }
}

function CreateDescription(weeks,target){
  var LIMIT_COUNT = 50;
  
  var id = '***ここはスプレッドシートのシートIDを入力しましょう***';
  var sheetname = '回答';
  
  //シートの読み込み
  var spsheet = SpreadsheetApp.openById(id)
  var sheet = spsheet.getSheetByName(sheetname);

  var description = [];
  
  for(var i = 0; i < weeks.length; i++){
    const list = sheet.getDataRange().getValues();
   
    description.push("・" + weeks[i][1]+'の予約状況\n')
    for(var j = 0; j < target.length; j++){
      description.push(GetSeatCount(list,i,weeks,target[j],LIMIT_COUNT));
    }
    description.push('\n')
  }
  return description;
}

function GetSeatCount(dat,count,weeks,target,LIMIT_COUNT){
  const tmp = dat.filter(function(item){return item[weeks[count][0]] === target});
  var seat = LIMIT_COUNT-tmp.length;
  return '  ' + target + ' → 残り' + seat + '席です\n';
}

function CreateWeeks(mode){
  if(mode === 1){
    return [[2,"3月4日"],[3,"3月5日"],[4,"3月6日"]];
  }else{
    return [[5,"3月4日"],[6,"3月5日"],[7,"3月6日"]];
  }
}

function GetReserveToSetFormDescription(){
  var description = [];
  
  description.push('注意:人数オーバーの場合は各自責任にて交通手段を確保下さい。\n');
  description.push('\n')
  
  //行き便
  description.push.apply(description,endFormCheck_Ontheway());
  //帰り便
  description.push.apply(description,endFormCheck_Onthewayback());
  
  //配列を合体
  var joinStr = description.join("");
  //フォームに値をセット
  var form = FormApp.getActiveForm();
  form.setDescription(joinStr);  
}

 

トリガーの設定

スクリプトを書いたら、保存アイコンと再生アイコンの間にある時計っぽいアイコンをクリックしてスクリプトをどのタイミングで動作させるかの設定をします。

f:id:rupic:20190304003338p:plain

 

新規スクリプトをクリックすると以下の画面が出てきますので設定していきます。

  1. 実行したい関数名を選択
  2. イベントソースを選択
  3. イベントの種類を選択
  4. 必要があればエラー通知を設定

f:id:rupic:20190304003628p:plain

ちなみにイベントソースは○時間毎や○月○日に実行など、バッチ的な動作も可能みたいですね。

こんな感じで作成したトリガーの一覧が表示されます。

f:id:rupic:20190304003626p:plain




結果はこんな感じ。

f:id:rupic:20190304002822p:plain

 

まとめ

 

次回はいつになるか分かりませんが、残りのタスクもメモしていきます。

年度末と言うこともあり最近は無駄に忙しいwwww

 

はじめてのGoogle Form ①

こんばんは。

毎年恒例の魔の3月を前にして既に瀕死状態の僕です。

 

google formで時間帯予約をするフォームを作成し、自身のIDで登録した結果を後日検索し内容を表示したいということを作成する機会があったので、いつかまたやる(?)時のメモとして残しておきます。

※時間の関係上、数回に分けて投稿します

 

実現したい事

  • Google Formで時間帯予約フォームを作成

  • 予約データをスプレッドシートと連携

  • 各時間帯には上限があり残席数を知らせたい(予約できなくする等の制限は不要)

  • 登録時にユーザーIDを入力してもらい予約のキャンセル/変更ができる

  • スプレッドシートのデータを検索し現在の登録状況を検索/表示する事ができる

  • ユーザーはスマホWebブラウザからのアクセスのみ(ガラケは無視でおk)

  • 尚、ユーザーはGoogleアカウントでログインしない事とする(震

 

Google Form

Googleドライブ上で動作するアンケートや小テスト等、アイデア次第で様々な用途に利用でき、しかも無料で利用する事ができる便利なサービスです。

f:id:rupic:20190225233327p:plain

Google Formで時間帯予約フォームを作成

まずはGoogle Formで予約フォームを作成してみましょう。

f:id:rupic:20190225234842p:plain

 作成の方法は非常に簡単です!

フォームの右側にある”+”ボタンをクリックすると様々な入力フォームを挿入する事が出来マウスでドラッグアンドドロップする事で配置の変更も可能となっています。

コントロール

  • 記述式:フリー入力欄を配置。バリデートの設定可
  • 段落:改行可能なフリー入力欄を配置。バリデートの設定可
  • ラジオボタン:複数選択肢の中より1つ選択する事の出来るコントロールを配置
  • チェックボックス:複数選択肢の中より複数選択する事の出来るコントロールを配置
  • プルダウン:予め用意された選択肢より一つ選択する事の出来るドロップダウン形式のコントロールを配置
  • ファイルのアップロード先:Googleドライブにアップロードする為のコントロールを配置。アップできるファイル形式、ファイル数、サイズ等指定可。Googleアカウントへのログイン必要
  • 均等目盛:1~10までの任意の幅での段階評価を配置
  • 選択式(グリッド):2次元のラジオボタンを配置。各行/各列での選択制限可
  • チェックボックス(グリッド):2次元のチェックボックスを配置。各行/各列での選択制限可
  • 日付:カレンダーより日付を選択可能なコントロールを配置
  • 時刻:時刻を入力可能なコントロールを配置

基本的にすべての要素に必須選択/入力の設定が可能

それぞれタイトルや説明を追加可能

用途に合ったものをポチポチ追加していけばOK

セクション

ラジオボタン等で選択した項目によって回答を分岐したい時にセクションを利用する事が出来ます。また、質問が多い時などセクションを分ける事でページングする事が可能となります。

f:id:rupic:20190226001259p:plain

写真・動画を追加可能

コントロールを追加する際に”写真を追加”または”動画を追加”ボタンをクリックする事で、フォームに写真や動画を追加することが可能となります。

間違い探しや、動画の感想的な何かを実装出来そうですね!

デザインを変更f:id:rupic:20190226001642p:plain

f:id:rupic:20190226001954p:plain

画面右上にあるパレットをクリックするとフォームのテーマカラーやフォント、ヘッダー部に表示する画像等の変更が可能となります。

見た目にこだわるあなたにピッタリな機能ですね(

予約データをスプレッドシートと連携

f:id:rupic:20190226002218p:plain

フォーム作成画面の回答タブをクリックすると、回答の一覧を見る事が出来ます。Google Formの回答はデフォルトではGoogleドライブ内に保存されるのですが、右上にあるスプレッドシートアイコンをクリックする事で、回答をGoogleスプレッドシートに転送する事が出来るようになります。

Googleスプレッドシートと連携しても回答は別々に保存されますのでGoogleスプレッドシートまたはGoogle Formの回答を個別に消してもお互いに影響を受けません。

f:id:rupic:20190226002652p:plain

スプレッドシートにデータ出力する事で、Excelライクにデータ分析したり、ごにょごにょする事が出来るので便利かもしれませんね。

まとめ

  •  Google Formはとにかく簡単にユーザー対話型のフォームを作成可能
  • 直観的に作成可能なのでTipsとか不要なくらい誰でもできる
  • 質問に応じて様々なコントロールが容易されている
  • デザインも変えれてシャレオツな感じにできる
  • Googleスプレッドシートとの連携でデータ分析も捗るかも?

 

こちらの記事が丁寧で分かりやすいです。

boxil.jp

IoT入門!Azure IoT Hub&sakura.io(さくらアイオー)体験ハンズオン@福岡に参加してきました

こんばんは。

飲みすぎて気がついたらウエストでうどん食べてましたw僕です。

 

本日はさくらインターネットさんで開催された”IoT入門!Azure IoT Hub&sakura.io(さくらアイオー)体験ハンズオン@福岡”に参加してきました!!

algyan.connpass.com

 

こちらはIoT ALGYAN(あるじゃん)さん主催のイベントで、セキュアで安価に使えるIoTプラットフォームである、Sakura.ioがAzure IoT HubとEvent Hubに正式対応したらしく、クラウドサービスも電子基板も両方使えるというなんとも面白そうな内容となっています。

*sakura.io(さくらアイオー)とは?

さくらインターネットが開発/提供している、モノゴトの情報をネットワークとやり取りする為に必要な全てを提供するIoTプラットフォームです。利用者のデバイスに組み込み、LTE閉域網経由で安全にやりとりするための「モジュール」、データの保存や外部のクラウドやアプリケーションサービスとの連携を提供する「プラットフォーム」を一体型で統合的に提供しています。

https://sakura.io/

 

今年から僕の職場での担当領域がIoT推進という謎の領域になった事もあり、気になって行ってきた次第です。

 

席には既に今回ハンズオンで使用する電子基板とハンズオンの内容が書かれた資料が置かれてました。

資料が親切!!!

f:id:rupic:20190217011905j:plain

 

オープニング

ゆるーく始まりました。 

f:id:rupic:20190217011912j:plain f:id:rupic:20190217011917j:plain

今回、何と言っても資料が丁寧で分かりやすい!!

参加者の内、僕を含めて8割くらいが初心者の中、そこまで詰まる事もなく順調でした。

 

Azure側の設定

Azure IoT HubでEdge側のデータを取得してStream AnalyticsでデータをBlobストレージに流し込むというハンズオンだったので、それぞれのリソースを作成し、必要な設定を実施。

この辺りは予習していた事もあり、難なく設定完了😄

 

speakerdeck.com

 

Edge側の設定

 

まずはArduino Unoに予め組み付けられたSakura.ioを取り出します。

ラズパイもそうでしたが、ずっしりとしていてなんか良い(

f:id:rupic:20190217011924j:plain f:id:rupic:20190217011927j:plain

Arduinoにセンサー類を簡単に取り付けする為にGroveベースシールドを合体!!

これをつける事で、LEDや温度センサーをワンタッチで取り付け可能になるそうです。

 

f:id:rupic:20190217011932j:plain f:id:rupic:20190217011936j:plain

指定されたコネクタにLED*3個と温度センサーを取り付け、ArduinoをUSBでPCと接続すると…LEDが光った!!!

デフォルトでそうなるプログラムが組まれているらしいですw

 

ここからは、ArduinoIDEから実際にプログラムをEdgeデバイスに書き込みます。

とは言っても予めコードはGitHubに準備されていたのでコピペでOKw

sakura.io用のFrameworkも準備されてて、本当に素人でも簡単に処理を実装する事ができるようになっているとの事。

 

ちなみに、プログラム言語で言うとこの”Hello World”をこちらの界隈では”エルチカ”と言うらしい。※LEDをチカチカさせてみる事

f:id:rupic:20190217014240p:plain

動作確認

ここは写真撮り忘れたんですww

まずは、ArduinoIDEからEdge側から送信されているデータを確認

f:id:rupic:20190217015318p:plain

こう言う機器の動作確認は目に見えて動いているのがわかるので、なんか嬉しくなりますね。

次にSakura.ioのポータル上で予め設定したWeb Soketにニアリアルタイムに表示されるう情報を確認。

ArduinoIDEの情報と並べて見ていても、ほぼリアルタイムでJSONデータが来ているのが分かります。

f:id:rupic:20190217015306p:plain

 

最後に、Stream AnalyticsのJobを再生してBlob内にデータが蓄積されている事を確認します。

データを良く見ると、Sakura.ioポータルに表示されている情報とAzureStrageの情報が違う事が分かります。

f:id:rupic:20190217015311p:plain

Sakura.ioで取得して送っている情報に追加情報を付け加えて保存しているからなのです。

f:id:rupic:20190217020119p:plain

 

まとめ

ここまでで今回のハンズオンは終わりだったのですが、データを確認するのに、Azure Data Exprolerを使用すると簡単に内容をチェックする事も可能ですね。あとPower BIを使ってグラフィカルにデータを表示してあげる事も良いですね!

正直、こう言う電子工作系は苦手意識が強すぎて、今まで触ってこなかったのだけど、こんなに簡単に設定〜センサー組み付け〜データのやりとりが実現出来るとは思いませんでした。

 

少しづつだけどこれから勉強していこう😊 

 

ラズパイ買ってみた😋

こんにちは。

月曜のお昼からこんなのんびり作業できるなんて良いですね😂

 

というのも、先週金曜からインフルにかかってしまって会社の規定で”インフルと診断された日から5日かつ解熱してから2日は出勤不可”という決まりがありまして、会社から治るまで来んなよwと言われてます。自身の年休使ってですけどねw

rupic.hatenablog.com

 

という訳で、せっかく年休溶かしてまで休めるならと何か有意義な事に時間を使いたいと思い、前々から気になっていた”Raspberry Pi model B+”をAmazonでポチりました。 

 まさかのタイムセールで昨日まで9,900円だったのに8,490円になってますね😿

 

到着〜開封の儀

さて、昨日注文したばかりなのに、流石Amazonさん。

もう届きましたよ。

f:id:rupic:20190204115142j:plain

早速開封していきましょう😆

 

f:id:rupic:20190204124554p:plain

キットの中身はこんな感じ!

  • Raspberry Pi3本体
  • 本体ケース
  • 日本語の取説
  • Micro SDHC(SanDisk32G)
  • SDアダプター(Type-C)
  • HDMIケーブル
  • 電源ケーブル(ON/OFFスイッチつき)

僕の様な初心者には優しい全部付きでの提供となっています。

f:id:rupic:20190204115217j:plain

ケースは3分割になるタイプ

f:id:rupic:20190204115213j:plain

ラズパイ本体はなんかずっしりとした重量があって思ってたよりもしっかりと出来てる気がします。

なんかそれっぽくなってきた気がしますね(開けただけだけどw

組み立て

では、組み立てていきましょう😎

PCを自作したりは良くやるのですが、どうしても電子工作的なやつはトラウマがありまして…

前に会社にあった誰が作ったかわからない自作基盤が故障した時に、良く分からないけどマイクロチップ?的なやつを抜き差しして爆発させた事があったり…ハンダ付けしてたらうっかり別の回路とくっ付けて煙が出てきたり…(

 

まぁ過去の話をしてても仕方ないので、とにかく慎重にくっ付けていきましょう!

f:id:rupic:20190204174457j:plain

基盤をケースの一番下の台座部に取り付けます。

この時、真上から押し込むと壊れますので、爪の下に基盤を潜り込ませる様にしましょう。(はじめ無理やりやって壊れそうになりました

f:id:rupic:20190204174504j:plain f:id:rupic:20190204174508j:plain

次にヒートシンクと何やらラズパイのマークの入ったエンブレムの様な物がありますね。ヒートシンクは裏が両面テープになっているのでCPUに貼り付けましょう。

f:id:rupic:20190204174512j:plain

まぁこんな感じですね。

ヒートシンクを取り付けたら後はケースを上から取り付けましょう。

f:id:rupic:20190204174516j:plain

取り付けが少し硬くて壊れないかとヒヤヒヤしながら慎重にはめていきます。

それぞれのコネクタにアクセスしやすい様にケースに各部位の名前が書いていてとても親切ですね😀

後は上蓋を付けて完成です!!

f:id:rupic:20190204174520j:plain

はい、余りましたよ。部品がw

っていうか何の部品なんだろうとggって見たらどうやらCPUの裏っ側に黒いチップ的なやつがあってそこに貼り付けるのが正解そう。(本当のところは分からないけど

f:id:rupic:20190204174529j:plain

こんな感じw

完成

まぁパーツも少ないし楽勝でしたね(震

 

f:id:rupic:20190204174541j:plain

MicroUSBは給電、画面出力用のHDMI、オーディオ用のピンジャック

f:id:rupic:20190204174536j:plain

有線LAN、USB*4ポート!!

f:id:rupic:20190204174545j:plain

MicroUSBスロット 

セットアップ

今回はスターターキットで購入の為、OSはすでにSDカードの中に入ってましたw

本来なら以下のサイトからOSを取得してSDに格納してあげないといけないですね。

www.raspberrypi.org

 

とりあえず電源をONにしてみるとOSを選択出来る画面に。

f:id:rupic:20190204194551j:plain

中にはWindows10 IoT Coreが入ってますね!!

UWP実行に特化した組み込みコンピューター向けのOSです。

docs.microsoft.com

 

今回は推奨表示のある”Raspbian”というOSをいれてみます。

f:id:rupic:20190204194547j:plain

インストールの時間が死ぬほど長いwwww

体調が本調子ではないのでうっかり昼寝しちゃいましたよw

f:id:rupic:20190204194555j:plain

起きてから画面を見てみるとWelcome状態でしたm(_ _)m

とりあえずWiFiロケールの設定をした後にリブートしてあげると普通のデスクトップPCの出来上がりです!!!

f:id:rupic:20190204194600j:plain

まとめ

 Raspberry Piを初めて触ってみましたが本当に簡単に組立→セットアップまでできるので、小学生くらいのお子さんとなら一緒に作ってみる事も可能だと思います。(今度、うちの息子にも買ってあげよう)

他にも色々な工作キットやセンサーキットも売ってるみたいなので気になりどころですね!!

 

明日は、ラズパイを使って出来る事を調べてエッジデバイスとしてラズパイを使ってみようかと思います。

 

インフルはじめました

昨日からめっちゃしんどいと思って熱計ったら39.9度。

時期も時期だしもしかしてと思い病院に行ったら、インフルエンザA型と診断されました(´•ω•̥`)

 

病院の先生にタミフルにするか、ゾフルーザにするか聞かれ、迷わずゾフルーザを選択!

1日でしっかり熱は下がったものの身体中が痛い😣

 

念の為、家族に伝染らないように別の部屋に隔離されてたのですが…

時すでに遅し。

嫁、長女、次女は既にインフルエンザにww

この時期は本当に気をつけないと自分だけでなく周りにも迷惑掛けてしまうので申し訳ない感じですね(><)

 

とりあえず会社は治るまで来るなって感じだしのんびり休養です。

皆様お気をつけて…

 

f:id:rupic:20190203004208j:image

 

 

今年はじめてのふくてん開催

こんばんは。

最近はバタバタしてて投稿ができてませんでしたw僕です。

 

本日は今年1回目のふくてん(Fukuoka.NET)をさくらインターネットさんに場所をお借りして開催いたしました!!

fukuten.connpass.com

 

自己紹介

ふくてん恒例ですね😊

月曜ということもあり参加人数は少なめでしたが、東京からのリモート参加+初めてふくてんに来て頂いた方もいらっしゃってなんだかほっこりしながら始まりました。

 

Cognitive Services使ってみませんか?

トップバッターは機材チェックの為にPCを繋いでたので、そのままやっちゃえという事で…僕でしたw

ä¸é伸ä¸ããã®åç

のんびり準備中の写真

 

今回は今年一回めという事もあり、Azureのサービスの中でも大好きな

Cognitive Services | Microsoft Azureについてお話させていただきましたm(_ _)m

www.slideshare.net

 

今までCognitive ServicesはComputer VisionFace APICustom Visionといった視覚カテゴリを使う事が多く他のサービスはあまり使った事がなかった為、今回すべてのサービスを使ってみようと思いこのセッションをやる事にしました。

 æ¾æ åªå¤§ããã®åç

しかし!!!

すべてのサービスを実際に使ってみる事って意外と大変w

公式のドキュメントやGit Hubのサンプルを見ながら資料をまとめつつ、Demoを作りつつ、なんとか間に合った感じでしたが、今回伝えたかった事はこれだけです!

 

まず使ってみませんか?

 

どんなものでもまず使ってみないと良いところ悪いところがわからないと思うんです。

使ってみてみると「こんな使い方ができるな」とか「このサービスと連携させると良いかも?」とか色々出てくると思うんです。

セッションはバタバタして伝わっていたかわからないですが、一人でも何か感じていただけたら嬉しいですね😄

 

P.S.ディスプレイが4Kの場合、めっちゃ表示がちっちゃくなって全く見えなくなるので事前に色々チェックしようww

 

アジャイルで日本一のカレーを作る方法

次は上野さんのセッションです!!

初めは今年5月のリニューアル後のさらなる発展をと開催された際に聴講した、Microsot澤円さんのプレゼンについて感じた事のお話。

www.facebook.com

 澤さんと写真めっちゃ羨ましいですww

 

中盤は現在のエンタープライズ企業におけるWFとアジャイル開発についての認識の違いや、どういった時にそれぞれのフレームワークが有効なのかを熱く語っていただきました。

確かに、うちの会社でも「アジャイルって言ってるけど、それどういう意味で使ってんの( 」って人めっちゃいるなーと思いながら聞いてましたw

 

後半は、これまた濃い話!!

システム開発現場における、「稼働率」と「作業効率」についてです。

例えばペアプログラミングをしたいと上司に申し出た場合、「同じ仕事を2人でするなんて作業効率が悪過ぎる」と言われてしまうが、実際にどうなんだろうという話でしたw

 

総括すると、日本一のカレーはこれだそうです!! 

 

.NET Docs & Tutorials Tour

 最後はMicrosoft MVPの松村さんのセッション!!

æ£®ç° é¦è£ããã®åç

 

内容は普段、松村さん自身も実践しているという、「.NETのドキュメントの歩き方と情報の集め方」についてのお話。

 

Microsoftの提供する、公式のドキュメント、Blog、Git Hubは必ずチェックするべき!!このクオリティで無料とかありえないレベルの充実感です!!!!

 

.NET系公式ドキュメント

docs.microsoft.com

docs.microsoft.com

www.microsoft.com

 

www.microsoft.com

 

Visual Studio系ドキュメント

docs.microsoft.com

 

Azure系ドキュメント

docs.microsoft.com

 

アナウンス Git Hub

github.com

 

飛び込みLT

松村さんのセッション開始直前にあの人が飛び込みで参加してくれました。ç³æ© è£å¤ªããã®åç

森田パイセンです。

しかも、WebだけでAzure APIの簡単なテスト方法やAzureのサービスのアーキテクチャに関するページの紹介など飛び込みとは思えない流石のLTでした!!

 

docs.microsoft.com

 

 

最後に、今回の参加者に現在G'zアカデミーに通われている方でLINE Botで動作している処理に遅延が発生しているとの事で、皆んなでモブモブしました。

gsacademy.tokyo

Azure Functionsについての内容だったので、松村さんが主体となって皆んなに教えてくれた感じになっちゃいましたが…

ç³æ© è£å¤ªããã®åç

 

こういう風に皆んなでわいわいしながら、今つまづいている事、困っている事を解決するなんてのも自身にとっての気づきになると思うので良いですね。

 

来月はもくもく会!!

またUPしますm(_ _)m

Magic Keyboard & Magic Tracpad2 買ってみた

こんばんは!

 

長女が生まれた時に我が家ではダイニングテーブルでご飯を食べるのが大変との事で、ダイニングテーブルを手放したのですが、長男、長女共に手がかからなくなって来たのもあり、そろそろダイニングテーブルを復活させようと前々から気になっていた、”COBA INDUSTRIAL WORKS”さんに伺いました。

 

www.cobaindustrialworks.com

 

道路を走っていると一際目を引く黒いコンテナで作られた店舗が特徴的で、店内に入ってみると八王子工務店のヒロミさんが出て来そうなくらい、The インダストリアルでした(

f:id:rupic:20190119232159p:plainf:id:rupic:20190119232325p:plain

 

主にアイアンを加工した製品と足場板を販売しているみたいで、価格も思ったよりリーズナブルな設定でびっくりでした。

店内の奥の方に、足早板を貼り合わせて作成したテーブルの天板を販売していたのですが、まさかのテーブルを配置する場所のサイズを測って来るのを忘れてしまい出直すことにwwww

まぁ急いで買う様なものでもないのでゆっくり考えるとします。

 

本題のMac用のMagic KeyboardとMagic Trackpad2ですが、PayPayの残額が残っていたので、ビックカメラで購入しました。

f:id:rupic:20190119233425p:plain

Magic Keyboard

こちらは以下の種類が販売されてました。

  • テンキーあり US
  • テンキーあり 日本語
  • テンキーなし US
  • テンキーなし 日本語

キーボード配列はUSの方が出来る感半端ないんですが、日本語一択です。

テンキーは、仕事上数値を入力する事が多いのでずっとテンキーありを使って来ましたが、自宅用なのもありスッキリした外観のテンキーなしを選択しました。

f:id:rupic:20190120002145p:plain

MacBookProのキーピッチと比べると少し広いけどほぼ同じくらい

Magic Trackpad2

Magic mouseがありがすが、マウスの使いづらさは嫁のiMacで体験済みなので

迷う事なくお買い上げです。

f:id:rupic:20190120002316p:plain

 

実際に使ってみて

f:id:rupic:20190119235456p:plain

少しでいいから充電しておいて欲しかったw

 

キーボードの打鍵感はすごくいいですね!!なんといってもFキーがある!!!!

 

MacBookProのキーボードは薄っぺらくてキーストロークが極端に浅い感じが苦手だったので(静かでいいですがw)、こちらはしっかりキーボード打ってる感じが好きです。

とはいっても、普段会社と自宅で使ってるのはFILCOの黒軸なので違和感はありますが…

 

track padに感しては、めちゃくちゃ作業性高いと思います。

そもそも持ち運び用に使っている、Surfaceのタイプカバーに比べてMacBookProのtrack padは”でかい!”、”使いやすい!”と思っていたのですが、さらに大きいのでWebページをスクロールする時にかなり便利。

 

二つとも Bluetooth接続なのでこたつに入ったままだらだらとPCしたい時にもってこいです😋

 

 

Mac track pad用保護フィルム貼り付け

こんばんは。

弊社は昨年より年度の期間が4月-3月から1月-12月に変更になり、現在は年初に当たるわけですががっつり年度末感がすごいですw

 

Macのキーボードカバーは取り付けしましたが使用しててやっぱり track padに傷が入るといやだなーと思い気になってこちらを購入。 

 

Surfaceはタイプカバーで取り外し可能なので汚れたり傷が入ったら、最悪取り替えればいいのですが、Macはそうはいきません。

色々レビューを見ながらそれっぽいもので安いものを探してこれに決めたんですが、中々いい買い物をしたみたいです!

 

商品は思ったより分厚くて大丈夫かなって感じはするんですが、貼ってみたら意外と滑りも良く違和感ない感じ!!

気泡も入ってない様だしお勧めします!!

Speech SDK を使用して音声認識してみる

こんばんは。

ふとTVをつけたら深キョンがドラマに出てて、可愛すぎてブログ書くのをやめようかと思いましたw僕です。

 

駆け出しMacユーザーの僕ですが、毎日少しずつでもMac触っていたら、思ったより使い勝手がいい事に最近気づき始めた次第です。

昨日の夜、久々にSurfaceで作業してたら、今まで普通に使ってたタイプカバーのタッチパッドは思ってたよりも小さくて驚きましたw

 

さて、今日はCognitive Servicesの一つである「Speech Service」を使ってみます。

前々から気にはなっていたのですが、日本語で音声認識なんて正直期待出来ないイメージが強いので手付かずのままだったのですが、触ってもないのに使えなさそーはないだろうと思い今回に至ります。

 

Pjtを作成します。

今回は.NET Coreを使ってコンソールアプリケーションを作成します。

f:id:rupic:20190115220632p:plain

先月GAされた.NET Core 2.2を選択

blogs.msdn.microsoft.com

f:id:rupic:20190115220637p:plain

適当に名前をつけてプロジェクトを作成しましょう

f:id:rupic:20190115220642p:plain

プロジェクトを追加したらNugetの追加から以下のパッケージをインストールします

 

 

f:id:rupic:20190115225831p:plain

Microsoft.CognitiveServices.Speech」

f:id:rupic:20190115230238p:plain

AzureポータルでCognitive Servicesを選択

f:id:rupic:20190115233608p:plain

 

f:id:rupic:20190115233828p:plain

CognitiveServicesの一覧を表示するためには右側の「さらに表示」をクリック

音声を選択します

f:id:rupic:20190115234341p:plain

作成をクリック

f:id:rupic:20190115234335p:plain

これもいつもな感じですねw

適当に名前をつけてリージョンやリソースグループを選択しデプロイします

f:id:rupic:20190115234322p:plain

数分後、デプロイが完了するのでサブスクリプションキーとリージョンをソースに貼り付けます。

f:id:rupic:20190115235354p:plain

こんな感じw

f:id:rupic:20190115235752p:plain

ここまできたらとりあえず、再生してみましょう!!!!

 

あら…。。。

"One or more errors occurred. (The type initializer for 'Microsoft.CognitiveServices.Speech.Internal.carbon_csharpPINVOKE' threw an exception.)"

とエラーが出てうまく動きません。。

f:id:rupic:20190116191808p:plain

マイクをPC内蔵のもので動作させたからかと思い色々調べてみたところ、

以下の記事を見つけましたw

github.com

 あーMacでSpeech SDK対応してないんですって(T ^ T)

今度時間がある時にWindowsで試してみるかなw

残念。。