OmniAICreator/Qiita-1.07M huggingface dataset:
【GAS】文法の基礎

### Logger.logとconsole.log
`Logger.log(変数)`などでログを出力する。
`console.log(変数)`も同様。

### 四則演算
```
function myFunction() {
  Logger.log(3+100);
}
```
`+` `-` `*` `/`で計算できる。
### 変数
```
function myFunction() {
  const a = 3;
  Logger.log(a)
}
```
`const`で定義した場合、変数の上書きはできない。
`let`で定義すると、変数の上書きが可能。
`const`で十分な場合は、通常`const`を利用する。

### データ型
```
function myFunction() {
  const data = [1.44, 77]
  Logger.log(typeof data)
}
```
`type of` で変数の型を返す。

### 配列
```
function myFunction() {
  const data  = [[1, 2, 3, 4],
                 [5, 6, 7, 8]];
  Logger.log(data[1][2]);
}
```

### オブジェクト
```
function myFunction() {
  const scores = {
    'japanese': 50,
    'english':60,
    'math':90,
    'science': 80
  };
  Logger.log(scores['english']);
  Logger.log(scores.english);
}
```
辞書型の変数について、`scores[’english’]`、`scores.english`などでヴァリューを指定することができる。

### 比較演算子
```
function myFunction() {
  Logger.log(1 > 3);
}
```
`=`は代入を意味するため、等しいことを条件としたい場合は`==`とする

### 制御構文~条件分岐
```
function myFunction() {
  const a = 10;
  if(a<3){
    Logger.log("aは3より小さいです");
  }
  else if(a >= 3 && a <= 5){
    Logger.log("aは3以上5以下です");
  }
  else{
    Logger.log("aは5以上です")
  }
}
```
### 制御構文~反復①
#### let in
```
function myFunction(){
  const nums = [1, 2, 3, 4, 5];
  for(let i=0; i<nums.length; i++){
    Logger.log(nums[i]);
  }
}
```
### 制御構文~反復②
#### for in
```
function myFunction(){
  const nums = [1, 2, 3, 4, 5];
  for(let i in nums){
    Logger.log(i);
  }
}
```

```
function myFunction(){
  const nums = [1, 2, 3, 4, 5];
  for(let num of nums){
    Logger.log(num);
  }
}
```
### 関数
```
// 台形の面積を返す関数
function clacTra1(up, down, height) {
  Logger.log((up+down)*height/2);
}

function clacTra2(up, down, height) {
  return((up+down)*height/2);
}

function mainFunc() {
  Logger.log(clacTra2(10, 5, 8));
}
```
returnの場合、値を返すだけであり、ログは出力されない。
出力するには、returnで返される関数をLoger.log()などに噛ませる必要がある。

### メソッド
オブジェクトがプロパティとして格納している関数。
#### 配列が持つメソッド: forEach()
```
// メソッド
function myMethod1() {
  const usernames = ['taka' ,'rei', 'saito', 'rucas'];
  usernames.forEach(function(username ,index){
    Logger.log(index+1+'番目の'+username+'さん');
  })
}

// アロー関数で記述する場合
function myMethod2() {
  const usernames = ['taka' ,'rei', 'saito', 'rucas'];
  usernames.forEach((username ,index) => {
    Logger.log(index+1+'番目の'+username+'さん');
  })
}

// 文字列ベースで変数を組み込む記述方法
function myMethod3() {
  const usernames = ['taka' ,'rei', 'saito', 'rucas'];
  usernames.forEach((username ,index) => {
    Logger.log(`${index}番目の${username}さん`);
  })
}

// 配列に新たな要素を追加
function myMethod4() {
  const usernames = ['taka' ,'rei', 'saito', 'rucas'];
  usernames.push('mao');
  usernames.forEach((username ,index) => {
    Logger.log(`${index}番目の${username}さん`);
  })
}
```
`for of` `for in` の両者を担う関数。
カスタムJavaScriptを書いて学んだこと

## 概要
はじめまして、今年６月からistyleの仲間入りをしました杉本です。
GoogleTagManagerやGoogleAnalytics4初心者、そして言語についても絶賛勉強中の超初心者目線でブログを書いていきたいと思います。
#### まずはじめに
GoogleTagManager（以降、GTM）のカスタムJavaScript（以降、カスタムJS）とは？

任意の設定で定義する変数というものがいくつか存在するうちのひとつで、JavaScript処理を行い、その結果を取得するものとなります。
#### 使い方
カスタムJSは値を返す匿名関数の形式をとる必要があるので、JavaScriptの記述は必ず「function () {」で始まり「}」で終わる形にして、「return 〇〇」という形で返す必要があります。

例）100という値を返したいとき
```javascript
function() {
 return 100;
 }
```
#### 活用例
例）あるページにてどのナビゲーションボタンをクリックしたのかを取得する変数
```javascript
function() {
 var gtmClickUrl = {{Click URL}};

 if (gtmClickUrl.includes('category_all.php')) { 
  return 'category';
 } else if (gtmClickUrl.includes('brand/list.php')) {
  return 'brand';
 } else {;} 
}
```
▲上記のコードは、
(‘ ’)で囲まれた文字列を含んだURLをクリックした場合、’ ’で囲まれた値を返すという内容になっています。

２行目の var gtmClickUrl = {{Click URL}}についてはクリックしたURLを指しているのですが、他にも閲覧したページを{{Page URL}}、クリックしたテキストを{{Click Text}}というように組み込み変数（あらかじめGTM上で登録してある変数）を利用して簡単に定義することができます。

上記のカスタムJSを書いた変数を下記のようにGTMでイベントパラメータの値として設定することで、returnで返ってきた値をイベントパラメータ値として取得することができます。

![blog.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3656660/d5ca670f-fc1a-1527-23eb-20a5a874e80d.png)

#### 気を付ける点
私がカスタムJSを書くうえで特にレビューで指摘をいただいた点をまとめました。

①変数名のつけ方
　・読み手が誤解しない名前を付けよう
　・変数名に情報を入れ込もう
　　例）
　　　限界値　→　max min
　　　範囲指定　→　first last / bigin end
　　　論理値　→　is has can shoud

②コードが冗長になってしまう
　・DRY原則（同じロジックを複数箇所に書かない）を意識しよう

 
どの言語でも言えることかもしれませんが、以上が初心者なりの気を付けるべきポイントでした。

これからもたくさんのコードを書き知識を増やしていって、ブログの内容も充実させていきたいと思います！
Githubコマンド一覧

<table>
  <caption>Github コマンド一覧</caption>
  <thead>
    <tr>
      <th>コマンド</th> <th>用途</th>
    </tr>
  </thead>
  <tr>
    <td>git init</td>
    <td>リポジトリの初期化
このディレクトリ以下を管理するリポジトリデータが格納される。</td>
  </tr>
  <tr>
    <td>git status</td>
    <td>現在のgitリポジトリーの状態を表示する。
ブランチの確認などを行う。
またファイルを新規作成など何らか変化を加えたあと
#Untracked files　以下に表示される</td>
  </tr>
  <tr>
  <td>
  git add</td>
  <td>変化を加えたファイルをgitリポジトリーの管理下に置くためにステージ領域と呼ばれる場所に登録する。コミットするの一時領域である。
-A:全てのファイルをステージ領域に置く</td>
  </tr>
  <tr>
  <td>git commit</td>
  <td>git commitのみだとテキストエディターを開き詳細なコメントを残す事ができる。
-m [message]:
--amend:直前のコミットメッセージを修正
-am"メッセージ”:git add とgit commitを同時に行える。</td>
  </tr>
  <tr>
  <td>git log</td>
  <td>リポジトリにコミットされたログを確認できる
--pretty=short:コミットメッセージを最初の一行のみ表示する
--graph:ブランチを視覚的に確認する。</td>
  </tr>
  <tr>
  <td>git diff</td>
  <td>変更差分を表示する
git diff HEAD:git add した後ワークツリーとステージ領域の差分がないため何も表示されない。最新コミットとの差分を確認する時に使う。</td>
  </tr>
  <tr>
  <td>git branch</td>
  <td>ブランチ一覧を表示
-a:ローカルとリモートの全て参照</td>
  </tr>
  <tr>
  <td>git checkout </td>
  <td>ブランチを切り替える。
-:一つ前のブランチに戻る
-b [new branch]:ブランチを新規作成し切り替える。
-b [new branch] origin/[remote branch]:リモート先のブランチをローカルブランチに反映させる時はnew branchとremote branchの名前は一緒にする</td>
  </tr>
  <tr>
  <td>git merge </td>
  <td>分岐したブランチをmasterに反映させる
--no-ff [branch]:マージしたことを記しコミットメッセージを立ち上げる。</td>
  </tr>
  <tr>
  <td>git reset --hard [戻りたいブランチのハッシュ]</td>
  <td>戻りたいブランチまで遡る</td>
  </tr>
  <tr>
  <td>git reflog</td>
  <td>現在のリポジトリーで行われた作業ログを確認する事ができる。</td>
  </tr>
  <tr>
  <td>git rebase -i HEAD[何個前まで遡るのか]</td>
  <td>ブランチで修正したものを反映させるために歴史を押しつぶす。
エディターが立ち上がりpickをfixupと書き換える。</td>
  </tr>
  <tr>
  <td>git remote add origin [git@github.com/~]</td>
  <td>github上で作成されたリポジトリをローカルリポジトリに登録する。他人のオリジナルのリポジトリforkしたものをclone後、最新の他人のリポジトリーをfetchするために
git remote [オリジナルのリポジトリを識別する識別子（origin以外なんでもいい）][他人のリポジトリー（git@github.com/~.git）]と書いて設定しておくこともできる。</td>
  </tr>
  <tr>
  <td>git push -u origin [local branch]</td>
  <td>リモートリポジトリーに送信する。</td>
  </tr>
  <tr>
  <td>git clone [git@github.com/~]</td>
  <td>リモートリポジトリーをローカルリポジトリーに反映させる。cloneした後は自動的にmasterブランチになる。</td>
  </tr>
  <tr>
  <td>git pull origin [remote branch]</td>
  <td>git push後のリモートリポジトリの状態をローカルリポジトリに反映させる。</td>
  </tr>
  <tr>
  <td>git fetch [git remoteでつけた名前(識別子)]</td>
  <td>git remote で設定した識別子で最新のオリジナルのリポジトリーを自分のリポジトリーに反映させてリポジトリーを最新の状態に保つ
git merge [識別子/master]でマージする</td>
  </tr>
</table>
文系大人初心者プログラミングするよ🔰【CSS】

そしてCSS
CSSは飾り付けみたいな感じだからすぐ反映されて体験が簡単だけど
デザイン力を磨いてきたことのない自分にとっては沼中の沼:frowning2:

ここも基礎の基礎で切り上げて、
あとの素敵なデザインは、世の中に溢れる天才センス先生方に任せます。



CSSはファイルを作成したらHTMLのhead要素から呼び込みます
```.css
<!DOCTYPE HTML>
<html>
  <head>
    <meta charset="UTF-8">
    <title>ページタイトル</title>
    <link rel="stylesheet" href="style3-3.css">　※ここに記述
  </head>
```

そして、HTMLファイルのbody要素の中の要素を指定して、cssファイルでその要素にどんな装飾を加えるか記述していきます。
以下はp要素の文字色を赤に指定しています
```.css
p {　　　　　　　
  color: red;  ※文字色を赤にする
}
```
cssでは、まず装飾したいhtmlのp要素を上記のように指定しますが、
上記の例では、このpのことを『セレクタ』、
何を装飾にするのかのcolorのことを『プロパティ』、
どう装飾するのかのredのことを『値』　　といいます。


また、上記だとファイル内のすべてのp要素の文字色が赤になってしまうので、変更する要素だけを指定する方法もあります

これにはclass属性とclassセレクタ、もしくはid属性とidセレクタを使用します。
【class属性とclassセレクタ】
まずhtmlファイルで変更したい一部のpをclass属性として指定
```.html
    <p>
      １つ目の段落
    </p>
    <p class="change">
      2つ目の段落
    </p>
```
上記のpが『属性』、changeが『属性値』


続いてcssファイルで指定したclass属性を青色に装飾
```css
.change {
  color: blue;
}
```
class属性をセレクタに指定する際は、セレクタ名の前に.が付きます


【id属性とidセレクタ】
id属性は1つのページ内で、同じid名を複数のHTML要素に付与しないという慣例が存在するため、ここだけ変更したい！というときに使う感じです。
```.html
<p id="change">
  テキスト
</p>
```
id属性名はchangeで指定

```.css
#change {
  color: blue;
}
```
idセレクタ名の前には#が付きます。


【部分装飾】
要素全体ではなく、テキスト等に部分的に装飾をすることもできます。
それが『span要素』。全然使いこなせてません:innocent:

```.html
 <p>
    テキスト<span class="bigfont">装飾</span>テキスト
 </p>
```


  ```.css
.blue {
  fontsize: 20px;
}
```

こんな感じでテキスト途中の装飾の文字だけ大きくしたりできます。

装飾にはテキストの色、サイズ、背景色、表示位置、のほか
画像だったりなんか色々できます:raising_hand:
この辺がこだわりだすと抜けられない沼。。
でもデザイナーさんもですがフロントサイドではめっちゃ大事なものなのはわかるし、日々便利なものが作られている感じするので、どこで切り上げていくのかが重要だと思いました:raised_hand:
rex0220 データ生成プラグイン 複数項目から複数レコードを生成

[データ生成プラグイン](https://qiita.com/rex0220/items/8e760adbfd69b9416b2d)で、複数項目から複数レコードを生成する例です。

# 概要

区分１、区分２、区分３の項目から、他アプリに区分ごとに３レコードを生成します。

- アプリ１からアプリ２への出力
    - 区分１ -> 区分
    - 区分２ -> 区分
    - 区分３ -> 区分

![2023-12-19_15h15_22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100572/93810869-5349-781b-5ba8-d10e43f3ca01.png)

# データ生成プラグイン設定
ループ配列で区分３つ分の処理を設定します。

![2023-12-19_15h21_01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100572/d3e13ad5-c973-7660-296a-0eec8dee4a95.png)

- 対象アプリ条件
会社名をキーとして生成します。

![2023-12-19_15h18_52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100572/5934ca70-97ac-750b-0e68-ed624c15d0ca.png)

- 設定項目
    - ループ配列: 3
        - 区分３つ分
    - 出力条件: CHOOSE($val,区分１,区分２,区分３)
        - 区分が入力されたもののみレコード生成します。
    - 区分: CHOOSE($val,区分１,区分２,区分３)
        - $VAL ループ変数(0,1,2)に対応する区分
    - 日付: CHOOSE($val,区分１日付,区分２日付,区分３日付)
        - $VAL ループ変数(0,1,2)に対応する日付

![2023-12-19_15h21_24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100572/95a02f14-07d5-b578-e5d2-fd65d2d26942.png)
イベント時系列解析入門　小山・島崎先生　近代科学者

```r
#p.123 pois regression

data("EuStockMarkets")
X=EuStockMarkets[,1:3]
Y=round(EuStockMarkets[,4])
X=as.matrix(cbind(1,X))

term=c()
for(i in 1:length(Y)){
term=c(term,sum(log(c(1:Y[i]))))  
}

beta=rep(0.01,4)
ite=1000

for(l in 1:ite){
lam=exp((X)%*%beta)
dL=t(X)%*%Y-t(X)%*%lam  
ddL=-t(X)%*%diag(c(lam))%*%X
beta=beta-solve(ddL)%*%dL
loglik=sum(Y*log(lam)-lam)-sum(term)
print(loglik)
}


```


```r
#p.123 pois regression

data("EuStockMarkets")
X=EuStockMarkets[,1:2]
YY=(EuStockMarkets[,3:4])
Y=YY[,1]
X=as.matrix(cbind(1,X))

term=c()
for(i in 1:length(Y)){
term=c(term,sum(log(c(1:Y[i]))))  
}

beta=rep(0.01,3)
ite=200

for(l in 1:ite){
lam=exp((X)%*%beta)
dL=t(X)%*%Y-t(X)%*%lam  
ddL=-t(X)%*%diag(c(lam))%*%X
beta=beta-solve(ddL)%*%dL
loglik=sum(Y*log(lam)-lam)-sum(term)
print(loglik)
}

beta1=beta


Y=YY[,2]
term=c()
for(i in 1:length(Y)){
term=c(term,sum(log(c(1:Y[i]))))  
}
beta=rep(0.01,3)
ite=200

for(l in 1:ite){
lam=exp((X)%*%beta)
dL=t(X)%*%Y-t(X)%*%lam  
ddL=-t(X)%*%diag(c(lam))%*%X
beta=beta-solve(ddL)%*%dL
loglik=sum(Y*log(lam)-lam)-sum(term)
print(loglik)
}

beta2=beta


#p.124 ガウス近似アルゴリズム(N=2)

sig=1
V=diag(1,3)
x=rep(10^(-6),3)

ite=nrow(X)
eta=10^(-2)

for(l in 1:ite){
lam1=exp(sum(x*beta1))
lam2=exp(sum(x*beta2))
term1=apply(t(t(cbind(beta1,beta2))*c(YY[l,]-cbind(lam1,lam2))),1,sum)
if(l!=1){term2=solve(V)%*%(x-x_pre)}else{term2=0}
dL=term1-term2
ddL=-as.numeric(lam1)*t(t(c(beta1)))%*%t(c(beta1))-as.numeric(lam2)*t(t(c(beta2)))%*%t(c(beta2))-solve(V)
x_pre=x
x=x-eta*solve(ddL)%*%dL
V=-solve(ddL)
V=V+diag(sig^2,3)
loglik=sum(YY[l,]*c(log(lam1),log(lam2)))-(lam1+lam2)-c(x-x_pre)%*%solve(V)%*%(x-x_pre)/2-sum(log(c(1:YY[l,1])))-sum(log(c(1:YY[l,2])))
#print(sum(abs(x-x_pre)))
print(c(loglik))

}


```
GoogleTagManagerイベントタグのトリガー設定_CSSとdata属性の違いについて

# ■概要
初めまして。2023年に入りGoogleTagManagerと出会い、計測周りを担当している池内です。
現在弊社ではGoogleTagManagerを使用し、計測イベントタグの管理、設置を行っております。

GoogleTagManagerと出会い、沢山学びを得たので今回はイベントタグ（クリックが発火条件）のトリガー設定にフォーカスしブログを書いていきたいと思います。

▼内容
* トリガーの基本的な設定方法
* トリガーを設定する上で使用する変数
* CSSセレクタとdata属性の違い

▼おまけ
* CSSセレクタでのトリガー設定方法
* data属性でのトリガー設定方法

※以下GoogleTagManagerをGTMと記述します


# ■トリガーの基本的な設定方法
GTMでイベントタグを設定するには必ずトリガーが必要になります。
トリガーは、どういうタイプでどのページでどういう挙動をしたらイベントタグを発火させるのか指定するものとなります

* どういうタイプで：
トリガータイプの選択。今回はクリックなのでクリック関連を選択

* どのページで：
Page HostnameとPage Pathを指定して発火させたいページを指定します

* どういう挙動で：
どこをクリックしたらタグを発火させるのか詳しく指定します。指定の方法は開発のいらないGTM内の機能（変数）で6つ。開発がいる変数が1つあります

この後各方法の違いについて説明します

# ■トリガーを設定する上で使用する変数
どこでクリックするのか詳しく指定するトリガー内で使う変数について解説します

開発なしver　よく使う変数は★を付けています
* ClickElement：クリックされた要素をまるごとCSSセレクタで指定　★
* ClickClasses：クリックされた要素のClass属性で指定
* ClickID：クリックされた要素のID属性で指定
* ClickTarget：クリックされた要素のTarget属性で指定
* ClickURL：クリックされた要素のURL情報で指定
※指定したページ内に同じURLが複数あればそれぞれ発火
* ClickText：クリックされた要素に記載されているテキストで指定
※テキストが変わったら発火しなくなります


開発ありver　よく使う変数は★を付けています
* data属性：data-●●という名前付けしたdata属性をページ内のクリックしたい部分に埋め込み、そのdata属性を目印としてトリガー設定　★

<br><font color="red">**弊社ではClickElementを選択しCSSセレクタで指定するかdata属性をページに埋め込み、指定するかの二択の手法を使っています**</font>

# ■CSSセレクタ（ClickElement）とdata属性の違い
|  |システム  |指定方法  |メリット  |デメリット  |
|---|---|---|---|---|
|CSSセレクタ  |なし  |ClickElementを選択しCSSセレクタを抜き出して指定  |開発不要のためすぐに設置可能  |他の改修でCSSセレクタが変更した際に計測不可   |
|data属性  |あり  |開発で入れたdata属性をGTMで登録し指定  |改修が入ったとしても計測が漏れる可能性が低い  |開発が必要なので設置に時間と工数が必要  |

弊社としては下記で使い分けています。

* 定常的に取りたいイベント：data属性
* 一時的に見たいイベント：CSSセレクタ

特に外部へ提供する予定のあるものはすべてdata属性で対応するようにしています

# おまけ
■CSSセレクタ（ClickElement）の指定方法
1.クリック箇所をページ内で表示
2.検証環境を開き、該当箇所にカーソルを当てる
3.青くなった箇所を右クリックしcopy→copy selectorでCSSセレクタをコピー
![スクリーンショット 2023-12-19 130552.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3631841/0a141b95-b6b5-fdbe-bb8b-101a6f4cc865.png)
4.トリガー設定にてClickElement・CSSセレクタに一致するを選択し、コピーしたCSSセレクタを貼り付け
![スクリーンショット 2023-12-19 130725.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3631841/d78c5869-50e2-4ee7-6e46-1c26548e066b.png)
<br>
■data属性の指定方法
1.クリック箇所に入れたいdata属性名を検討しこの時になんの値を送るかも同様に検討。値はパラメーターを取得したいときに活用できます
例：data-active = true or false
2.ページ内のどこに入れたいのか、data属性名と値を指定して開発依頼
3.開発された後にdata属性の変数を登録
 * 変数のタイプ：自動イベント変数
 * 変数タイプ：要素の属性
 * 属性名：開発で入れたdata属性名
![スクリーンショット 2023-12-19 131019.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3631841/7009de9a-5aad-9d14-b11e-324c63f5e316.png)

4.3で作成された変数を使って下記のようにトリガー設定
![スクリーンショット 2023-12-19 131209.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3631841/7874c628-596d-9776-3802-10d8b13b4758.png)
値で指定したくない場合は下記のように設定
true以外の値だったとしてもdata-activated-flagがある箇所で発火することが可能
![スクリーンショット 2023-12-19 131337.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3631841/9ef6969e-5b15-7f22-aae6-82c77660d17c.png)
使うことはあるのに忘れてしまう・これなんだっけ？な関数たち

この投稿はアイスタイル Advent Calendar 2023 の24日目の記事です。
# 始めに
初めまして、istyle で日々抽出業務をしている石崎です。
今回、ブログを書くにあたって
こういう関数を前に使用したけどどう書くんだっけ？どんな関数だっけ？
みたいなのが日付関連でちまちま出てきたのをまとめてみたいと思います。
他、使う頻度はそんなに多くないんだけど、頭の端にやりすぎてパッと出てこないテーブル関連や正規表現関連の関数などを数は少ないですが備忘録的な感じでまとめてみました。



# 日付関連
　型変換は毎回のように使用するので空で書けるけど、ちょっと思い出せないこの辺り。
　・CURRENT_DATE
　・DATE_DIFF
　・PARSE_DATE
　・PARSE_TIMESTAMP
　・GENERATE_DATE_ARRAY


　<strong>CURRENT_DATE</strong>
　今日の日付を出す関数。パッと出てこない。
　記法：current_date([time_zone])
　※基本は’Asia/Tokyo’

　<strong>DATA_DIFF (差分関数)</strong>
　日付間の日数を計算する時に使用。
　記法：DATA_DIFF(新しい日付, 古い日付, 比較期間)
　比較期間：DAY,WEEK,MONTH,YEAR
　注意点：日付を逆にしないようにする

　<strong>PARSE_DATE</strong>
　日付フォーマットを変換したいとき、しないといけない時に使用。
　記法：PARSE_DATE(変換したい日付フォーマット, 日付)
　※日付はカラム指定でも良い
　日付フォーマットでよく使用するのは下記
　YYYYMMDD ： '%Y%m%d'
　YYYY-MM-DD ： '%Y-%m-%d’
　
　<strong>PARSE_TIMESTAMP</strong>
　日時フォーマットを変換したいとき、しないといけない時に使用。
　記法：PARSE_TIMESTAMP(変換したい日時フォーマット, 日時)
　※日時はカラム指定でも良い
　日付フォーマットでよく使用するのは下記
　YYYY-MM-DD  H:M:S： '%Y-%m-%d %X'
　※%Xで%H:%M:%S を表現できる
　注意点：UTCと表示されていても実情はJSTの場合があるので定義書を要確認

　<strong>GENERATE_DATE_AGRRAY</strong>
　カレンダーを作成するときに使用。日次・月次対応できるが、パッとカレンダーを作成したいときに思い出せずいつもググってしまう関数。
　記法：GENERATE_DATE_ARRAY(開始日 ,  終了日)
　※終了日にCURRENT_DATE()を入れると今日までのカレンダーができる
　※月次の場合はGENERATE_DATE_ARRAY(開始日 ,終了日,INTERVAL 1 MONTH)
　　※開始日はDATE_TRUNC等で月変換が必要

# テーブル関連
　最近は日付別にシャーディングされたテーブルをあまり使用していなかったのでちょっと忘れ気味だったので忘れないように。
　・_TABLE_SUFFIX

　<strong>_TABLE_SUFFIX</strong>
　シャーディングされたテーブルなど xxxxx_20231130 と後ろに日付が入っているテーブルなどに使用
　記法：_TABLE_SUFFIX >= 日付 など
　日付指定にBETWEEN も使用できる。
　使用の際のテーブル側の表記は　xxxxx_*

# 正規表現関連
　中々覚えられない正規表現関連。そもそも^ とか [0-9] とか色々組み合わせあってお手上げ！といつも思ってしまう。けど、この辺りの関数は覚えておきたい。
　・REGEXP_CONTAINS
　・REGEXP_EXTRACT

　<strong>REGEXP_CONTAINS</strong>
　文字列が正規表現と一致するかを判定
　記法：REGEXP_CONTAINS(カラム , r 'URLやその一部')
　ex. REGEXP_CONTAINS(dim1, '.*test.*');
　
　<strong>REGEXP_EXTRACT</strong>
　指定した正規表現に続く文字等を抽出
　記法：REGEXP_EXTRACT(カラム , r 'URLやその一部')
　正規表現の記号を使用して制御できる（この辺りはまだ勉強中）
　ex. REGEXP_EXTRACT(email, r'^[a-zA-Z0-9_.+-]+')

  <table>
  <caption>よく見る正規表現</caption>
  <thead>
    <tr>
      <th>正規表現</th> <th>説明</th>
    </tr>
  </thead>
  <tr>
    <td> ^ </td> <td>直後の文字列が冒頭にある場合一致</td>
  </tr>
  <tr>
    <td> A|B </td> <td>ABどちらかに一致</td>
  </tr>
  <tr>
    <td> + </td> <td>直前の文字の1個以上の連続</td>
  </tr>
  <tr>
    <td> \w </td> <td>すべての半角英数字とアンダースコア</td>
  </tr>
  <tr>
    <td> [a-z],[0-9] </td> <td>[]内のいずれか１文字に一致</td>
  </tr>
</table>

つまり、[\w-]+ は英数字,アンダースコア( _ ),ハイフン( - ) のいずれかを少なくとも1文字以上繰り返すということ

# 終わりに
以上、SQLを書く上で使用する関数はたくさんあって覚えるのが大変ですが、使いこなせると効率的な分析やコーディングができるようになるので今後も活用の幅を広げつつ勉強していこうと思います。
TurboをJavaScriptから操作する実践例

# はじめに
本記事は錆びかけたRailsの知識を頑張ってアップデートするアドベントカレンダー17日目です。

Turboの公式ドキュメントには、TurboをJavaScriptから操作するための方法が載っています。

例えば、以下のような形です。

![fejiwaewua.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/65439/6d2b204f-c893-a198-d2b5-0b1e7389d32e.png)
(引用: https://turbo.hotwired.dev/reference/drive)

こちらの実践的な使い方がなかなか思いつかなかったのですが、Turboの参考となる情報ソースの1つ、[GO RAILS](https://gorails.com/)にわかりやすいかつ面白い例があったので紹介します。


# Turboで非同期による画面切り替えを行うセレクトボックスを作る

セレクトボックスの`onChange`オプションにJavaScriptを文字列で直接書き込むことにより、セレクトボックスで何らかの選択肢が選択されるたびに、そのJavaScriptが実行される、というものです。

```erb:_navigation.html.erb
<%= select_tag nil, options_for_select(items), class: "sm:hidden", onChange: "Turbo.visit(this.selectedOptions[0].value)" %>
```

このときselect_tagのオプションは選択肢(ページの名前)と実際のパスとのペアが入った二次元配列でした。

セレクトボックスが選択されると`Turbo.visit()`が実行され、選択したページのパスへ非同期でリクエストを送る、ということのようです。

### select_tagのonChangeオプションについて

あまり利用している例を見ないオプションですが、このオプション自体はかなり前から存在しているようです。

### options_for_select(items)のitemsについて

以下のような二次元配列になっています。

```erb:_navigation.html.erb
items = [
  ["Home", root_path],
  ["Calendar", calendar_path],
  ["Projects", projects_path],
  ["Tasks", tasks_path],
  ["Announcements", announcements_path]
]

```

`Turbo.visit`の引数が`hoge_path`となります。
製造メーカーからIT業界を歩いてみて

## イントロダクション
工作機械といった業界をご存知でしょうか？
工作機械とは金属や他の素材を加工して製品を作るための機械装置の総称です。
車のパーツや工具、電化製品などの一部を工作機械によって作られています。

私は前職で工作機械メーカーの電気設計に担当する仕事に携わっていました。
約３年前にITエンジニアとして仕事を変え、Webアプリケーション開発やスマホアプリ開発等の業務に携わっています。

この記事では主に前職の工作機械業界との違いや、生活の変化を私の経験を通して共有していきます。

## 働きやすさ
働きやすさで大きく変化がありました。

今の会社はフルリモートであり、基本的に出社は本人の任意によるところが多いです。
前職は製造メーカーであったので、現場での作業を強いられる為、リモート出社等は出来ませんでした。

リモートワークでは自分の時間をより自由に使えることが嬉しいです。出社時間がないことで、日常生活の様々なことが柔軟に行えるようになりました。また、電話対応や雑務が少ないため、仕事に集中しやすい環境です。

前職の場合、通常の設計作業以外に営業や製造管理、現場、品質保証部からの問い合わせが慌ただしく
常にマルチタスクの状態で仕事していた頃が懐かしいです。


## 業界間の文化の違い
文化の違いにも大きな差がある印象です。
大きな違いは新規制への関心度と受け入れです。

IT業界は技術の入れ替わりが激しく、新規の技術、コンテンツに常に関心があり、変化を快く受け入れる文化があります。
共通技術に対してオープンで透明性のあるコミュニティが数多くある印象です。

対して工作機械業界は技術の入れ替わり自体はIT業界に比べ穏やかであり、製品自体も２０から３０年前に納品した機械が未だに現役で稼働している工場が多い事や、ひとつの設計や組立のミスによって人身事故に繋がる等の背景から、非常に保守的で変化を嫌う文化なのかなといった印象です。


## コミュニティの違い
業界間の文化の違いでも触れましたが、コミュニティの違いも大きかったです。

共通技術に対しての個人のコミットの量は圧倒的にIT業界が優れています。
IT業界は技術カンファレンスや、研修の量が多く、市や県のサポートもありコミュニティや企業間の情報共有も盛んに行われいる印象です。

また技術コミニティで出会うエンジニアは、キャリアアップのためでけではなく、単純に技術自体への興味や、趣味の意味合いが強い方が多い印象があります。

仕事の道具といった位置付けではなく、ひとつの楽しみとしてコミュニティに参加する人が多い事は、私にとって衝撃でもあり嬉しい事でした。

## 総評
まとめると、ITエンジニアになって本当によかったと思います。
働きやすさや、仕事の奥深さ、コミュニティ、どれをとってもよい結果になりました。
この仕事に出会えてとても良かったと思っています。

このような仕事に出会えたキッカケとなったRubyコミュニティに対して何かしら恩返しが出来るようにと
地域のOSSイベントや、学生向けハッカソンに業務やボランティアで数多く参加しています。
そういった行動によってRubyコミュニティが盛り上がってくれるととっても嬉しいなと思っています。
GoogleAnalytics4移行で感じた管理の必要性について

# 概要
始めまして、istyleでGoogleAnalyticsなど計測周りの管理を担当している佐藤です。

現在弊社では、ユニバーサルアナリティクスを使ってユーザー行動の分析やサービス利用をしていますが、2024年7月1日に有料版のユニバーサルアナリティクスも計測停止になるということで、それまでにGoogleAnalytics4への移行をしなければならない状況です。

GoogleAnalytics4への移行作業の中でいくつか困った、大変だった場面はあったのですが、原因は全て一緒で管理ができていなかった事にありました。

困った場面は以下の移行です。
・イベント
・カスタムディメンション
・フィルタ

# ユニバーサルアナリティクスでの状況

### イベント
ここで言うイベントとは
クリックやインプレッションなどのユーザーアクションを指しています。

ユニバーサルアナリティクスではイベントの実装はHTMLにタグを直書きしており、どこにどのような計測タグが入っているのかは開発者に確認をしてもらう必要がありました。

また、イベントの管理もほぼ行えておらず、現在入っているイベントが利用されているものなのか利用されていないものなのかも不明な状態でした。

GoogleAnalytics4へ移行するイベントの洗い出しは「今計測しているものの中で必要なものを」
と言っても、どこに何が入っているのか分からない状態です。

### カスタムディメンション
カスタムディメンションとはGoogleが用意しているディメンションとは別に、ユーザーが自由に設定可能なディメンションです。

ユニバーサルアナリティクスのメインで使用しているプロパティにカスタムディメンションが10個程設定されているのですが、状態を把握できるものは3個くらいです。
移行の際、プラットフォームを横断した会議の場でどこで使っているものなのか記載頂くよう共有しましたが、それでも使用者や状況が不明なものは存在していました。

### フィルタ
こちらもユニバーサルアナリティクスでは誰が何の目的で設定したフィルタなのか証跡が残っておらず、1つずつフィルタの設定内容を見て移行するかどうかを改めて検討する必要がありました。

ちなみに、フィルタは計測したくないデータを除外する際にビュー単位で設定していくものです。

弊社ではメインで使っている１プロパティだけでも80以上のビューが存在しており、全てのフィルタ設定を確認するのは現実的ではないので、システムで参照していたりメインで使っているもののみを確認しました。

# GoogleAnalytics4では

### イベント
移行対象については既存のイベントベースではなく、一から必要なものをリストアップして頂きました。

また、GoogleAnalytics4移行のタイミングでGoogleTagManagerというタグ管理ツールも導入しており、どこにどのようなタグが入っているのかこちらで確認することが可能になります。

さらに、計測しているイベントについてはダッシュボード上でヒット数がモニタリングできる環境を整え、ヒット数の少ないものは削除を検討するという運用を行っていく予定です。

不要なものは残さず削除し、必要なものだけの状態を目指します。

### カスタムディメンション
利用者が不明なものについては移行しないという方針を取りました。
GoogleAnalytics4ではイベントというかたちで計測していくことになるので上記のイベントと同様、タグマネージャーとダッシュボードで管理をしていく予定です。

### フィルタ
判断が難しいものについては一旦移行せず、GoogleAnalytics4とユニバーサルアナリティクスを並行稼働させるタイミングでデータを見て、必要そうであれば移行する方針としました。

また、GoogleAnalytics4では最低限のフィルタとし、各サービス用のフィルタなどはBigQueryにエクスポートされたデータを加工したDWH側で吸収していく予定です。

# 最後に
ドキュメントとしてまとめて残すことや不要になったものを削除することは数値として影響がない場合
後回しになり、後回しになった結果忘れ去り...という負のスパイラルに陥りがちですが、今回の移行で改めて管理の大切さを身にしみて感じました。

設定状況だけでなく、設定した背景まで記録としてどこか一定の場所にまとまって残っていると今後また移行作業などが必要になった時などに、判断が容易になりそうです。

まだまだGoogleAnalytics4への移行途中なので、今後新たに得た教訓やナレッジなどあれば共有していきたいと思います。
機械学習で株価分析 08.経済指標データの取得

# はじめに
本記事では、**PythonでYahooFinanceのデータベースから経済指標情報を取得する方法**を紹介します。取得できるデータは、指定した経済指標の始値・高値・安値・終値・調整後終値・出来高です。

# 手順
### 1. yfinanceをインストール
以下のコードを実行してyfinanceをインストールします。実行環境はGoogle Colabを想定しています。
```python
!pip install yfinance
```

### 2. 必要なライブラリをインポート
以下のコードを実行して、必要なライブラリをインポートします。
```python
import yfinance as yf
yf.pdr_override()

import numpy  as np
import pandas as pd
from   pandas_datareader import data
import datetime
from   IPython.display   import display
```

### 3. データを取得する期間の指定
以下のコードを実行して、データを取得する期間を指定します。当日までのデータを取得するためには、終了日時に1日後を設定する必要があります。
```python
# データの取得開始日・取得終了日を設定
day_start = datetime.date(2021,1,1)
day_end   = datetime.date.today() + datetime.timedelta(days=1)
```


### 4. 経済指標データの取得と表示
以下のコードを実行して、経済指標データを取得し、コンソールに結果を表示します。指標名"^N225"は日経平均を表しています。その他の指標コードは検索すればかんたんにヒットします。なお、後段での株価データとの結合を見据え、ここで列名を編集しています。


```python
# 取得する指標を設定
fred_name = ["^N225"]

# 経済指標データ取得
df_fred = data.DataReader(fred_name, day_start, day_end, interval="1d")

# 列名を編集
for i in range(len(fred_name)):
  df_fred = df_fred.add_prefix(fred_name[i] + " ")

# 取得したデータを表示
display(df_fred)
```

# ソースコード全文
以下にソースコード全文を示します。

```python
!pip install yfinance

# 必要なライブラリをインポート
import yfinance as yf
yf.pdr_override()
import numpy  as np
import pandas as pd
from   pandas_datareader import data
import datetime
from   IPython.display   import display

# データの取得開始日・取得終了日を設定
day_start = datetime.date(2021,1,1)
day_end   = datetime.date.today() + datetime.timedelta(days=1)

# 取得する指標を設定
fred_name = ["^N225"]

# 経済指標データ取得
df_fred = data.DataReader(fred_name, day_start, day_end, interval="1d")

# 列名を編集
for i in range(len(fred_name)):
  df_fred = df_fred.add_prefix(fred_name[i] + " ")

# 取得したデータを表示
display(df_fred)
```

プログラムを実行し、コンソール上に指定した期間の経済指標情報が表示されれば成功です。

# 目次へのリンク

https://qiita.com/ryo2_9393/items/2b1ada62c2537c901b6b
SalesforceのApex classをダウンロードする【Tooling APIをPostmanから使う】


Postmanを使って確かめたいと思います。
PostmanからSalesforceにアクセスする方法は、以下を参考にして下さい。

+ [Postman : Salesforceで初めて使う時の処理手順](https://qiita.com/Keiji_otsubo/items/ac8571db2d836248e9f9)
+ [Postman : Salesforceで使う時の処理手順(既に一度接続した環境に対して)](https://qiita.com/Keiji_otsubo/items/6f493f98422551a946c3)
+ [Postman : Salesforceで使う時の処理手順(Salesforceの接続環境を切り替える)](https://qiita.com/Keiji_otsubo/items/ad4dc5062cdecf01b9a0)

# EntityDefinitionオブジェクトの検索

+ [Tooling API Objects/ApexClass](https://developer.salesforce.com/docs/atlas.en-us.api_tooling.meta/api_tooling/tooling_api_objects_apexclass.htm)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/3245c463-6d5b-c3ed-cfaa-b85a988effef.png)

qのパラメータに以下を設定します。SOQL文のスペースを+で置き換えた形です。

```
SELECT+Id,FullName+FROM+ApexClass
```

エラーになりますね。結果が１１返ってくるので１つでないとダメと言っている感じです。
このエラーはトレイルヘッドで良く見かけますね。

:::note alert
[
    {
        "message": "When retrieving results with Metadata or FullName fields, the query qualificatio​ns must specify no more than one row for retrieval. Result size: 11",
        "errorCode": "MALFORMED_QUERY"
    }
]
:::

確かに11個のApex Classがあります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/4c66a54c-6c6f-4605-68e2-df19448cf495.png)

適当にWHERE句を追加します。

```
SELECT+Id,FullName+FROM+ApexClass+WHERE+ApiVersion='58.0'
```

他の項目を使っても同じエラーになるんですよねぇ。何？

:::note alert
[
    {
        "message": "\nFullName FROM ApexClass WHERE ApiVersion='58.0'\n                              ^\nERROR at Row:1:Column:41\nvalue of filter criterion for field 'ApiVersion' must be of type double and should not be enclosed in quotes",
        "errorCode": "INVALID_FIELD"
    }
]
:::

あああ、数値だった

```
SELECT+Id,FullName+FROM+ApexClass+WHERE+ApiVersion=58.0
```

58.0も複数あるな。やっぱりName系を使う必要があるかも

:::note alert
[
    {
        "message": "When retrieving results with Metadata or FullName fields, the query qualificatio​ns must specify no more than one row for retrieval. Result size: 2",
        "errorCode": "MALFORMED_QUERY"
    }
]
:::

Nameが使えそう

```
SELECT+Id,FullName,body+FROM+ApexClass+WHERE+Name='Apex1'
```
取得できた

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/441dcb06-b672-ac23-5d1d-9e695da670bf.png)


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/f0b5cef8-29bc-36e8-8d73-179252637c95.png)


イベントログみたいにダウンロードできるか？

```
{{_endpoint}}/services/data/v{{version}}/tooling/sobjects/ApexClass/:ApexId
```

詳細情報が取得できただけですね。やはりコードはBodyみたい。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/03787962-dfb7-2a34-9df6-7612333baa58.png)
【Flutter】wrapの方向を縦で表示する


# はじめに

この記事は、株式会社スピードリンクジャパン Advent Calendar 2023 の19日目の記事です。

https://qiita.com/advent-calendar/2023/slj


こんにちは。
今回は、wrapの方向を縦で表示する方法を紹介します！:blush:

# 方法
![スクリーンショット 2023-08-13 20.18.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3524120/ce57fee2-1687-ea40-8538-b4c8b9db94e0.png)
Wrapの引数にdirectionを追加し、
`Axis.vertical`に設定します。



# 使用例
```dart
 @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text("wrapを縦にする"),
      ),
      body: Wrap(
        direction: Axis.vertical,
        children: <Widget>[
          Container(
            width: 100,
            height: 100,
            color: Colors.red,
          ),
          Container(
            width: 100,
            height: 100,
            color: Colors.blue,
          ),
          Container(
            width: 100,
            height: 100,
            color: Colors.yellow,
          )
        ],
      ),
    );
  }
}

```

# 実行例
![スクリーンショット 2023-12-18 19.22.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3524120/e95e7364-7f46-9c34-a037-330f229ac823.png)


# 最後に
ここまで見てくだり、ありがとうございます！！
寒い日が続きますので、体調にはお気をつけください:relaxed:
Rocky Linux 9でLinodeのLongviewを設定する備忘録

# 前提
LinodeのLongviewのyumレポジトリーは、CentOSやRocky Linux 9に対応していないため、インストールするには一工夫が必要となります。

# インストール方法

一部参照：[https://www.linode.com/docs/products/tools/longview/get-started/?tabs=centos](https://www.linode.com/docs/products/tools/longview/get-started/?tabs=centos)

## 依存パッケージの導入
`linode-longview` は `init.d` のスクリプトを使うので、initscriptsをインストールします

```sh
dnf install initscripts
```

## レポジトリー追加
CentOS 9のレポジトリーがないので、8を利用します。

``` /etc/yum.repos.d/longview.repo
[longview]
name=Longview Repo
baseurl=https://yum-longview.linode.com/centos/8/noarch/
enabled=1
gpgcheck=1
```

## 暗号化ポリシーを一時的に変更

```sh
update-crypto-policies --set DEFAULT:SHA1
```

## インストール

```sh
# APIキーを含むファイルの作成
mkdir /etc/linode/
echo 'ここにAPIキーを入れます' | sudo tee /etc/linode/longview.key

# GPGキーの登録
curl -O https://yum-longview.linode.com/linode.key
rpm --import linode.key

# 本体のインストール
dnf install linode-longview
```

最後のスクリプト実行時に失敗しますが、systemdのユニットファイルが自動的に展開されないためで、手動で設置します。

## ユニットファイルの設置と起動

```sh
# ユニットファイルの設置
curl -o /usr/lib/systemd/system/longview.service https://github.com/linode/longview/blob/master/Extras/init/longview.service

# init.dによって既に起動してしまっている場合は、該当プロセスをkillします。
# kill -9 [PID]

# 自動起動の有効化と起動
systemctl enable longview
systemctl start longview

# ステータス確認
systemctl status longview
```

## 最後に暗号化ポリシーを元に戻す

```sh
update-crypto-policies --set DEFAULT
```
Excelでマクロの実行が『セキュリティリスクこのファイルのソースが信頼できない…』でブロックされた時の対応

# 現象

xlsmファイルを開いた時に下記。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/7f1fbceb-4efc-478d-ec09-b72c0293a90f.png)

> セキュリティリスク
> このファイルのソースが信頼できないため、Microsoftによりマクロの実行がブロックされました。

xlsmファイルは作成元がはっきりしていて、マクロを実行しても問題が無いファイル。

# 対応

xlsmファイル上で右クリック → 『プロパティ』。
下記にチェック入れるとマクロを実行できました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/532577be-8479-1532-f9c0-dc99f93fd47b.png)

> このファイルは他のコンピューターから取得したものです。
> このコンピューターを保護するため、このファイルへのアクセスはブロックされる可能性があります。

# 蛇足

『許可する』にチェック入れるのはあくまで暫定対応だと思います。

『マクロが実行できなければ許可しておけばいい』という癖がつくと…

* ネットからダウンロードした怪しいマクロ入りエクセル
* メールに添付された怪しいマクロ入りエクセル

といったものまでホイホイ許可してしまう危険が高まります。

# バージョン

Microsoft Windows [Version 10.0.19045.3803]
Microsoft Excel for Microsoft 365 MSO (バージョン 2311 ビルド 16.0.17029.20108) 32 ビット
[Godot 4.2] LineEdit(とSpinBox)でEnterキーを押したら入力を終える

:::note info
`line_edit.release_focus()` を呼びましょう
:::

## Focus とは？
Focus とは、「アクティブなUI要素のうちどれが選択されているのか」を表す概念です。
「ゲームパッド操作でのメニュー操作中にカーソルが当たっているUI要素」をイメージすると分かりやすいかもしれません。
Focus を持つUI要素は必ず1つだけです。

## `LineEdit` と Focus
テキスト入力ができるUI要素である `LineEdit` 、およびそれを利用して数値のみの入力ができる `SpinBox`(下図参照) では、「自身がフォーカスを持っているか否か」で「入力中か否か」を判定しています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/699119/5121257e-b3e2-bb50-9050-ff7a4f03e970.png)

そして、デフォルトで Enter キーを押すと入力が確定される(かつ、対応したシグナルを発信する)ようになっているのですが……なんとフォーカスが外れません。
一応、「次の入力へ進む」だけならば Tab を押すと `focus_next` に設定されたノードへ進んでくれますが、「入力が終わったらとりあえずフォーカスを外したい」「Enter でも進んで欲しい」といった需要はあるかと思います。

## Focus を外す方法
[`Control.release_focus()`](https://docs.godotengine.org/ja/4.x/classes/class_control.html#class-control-method-release-focus) を呼ぶというわけです。
`LineEdit` は当然 `Control` を継承していますから、 `line_edit.release_focus()` のように書けば実装できます。

ただし、 `SpinBox` の場合は注意が必要です。
Focus を持っているのは `SpinBox` 本体ではなくて [`SpinBox.get_line_edit()`](https://docs.godotengine.org/ja/4.x/classes/class_spinbox.html#class-spinbox-method-get-line-edit) で取得できる、内部の `LineEdit` の方です。
そのため、 `spin_box.get_line_edit().release_focus()` としないと何も起きません。


## 参考文献
[Keyboard/Controller Navigation and Focus — Godot Engine (4.x)の日本語のドキュメント](https://docs.godotengine.org/ja/4.x/tutorials/ui/gui_navigation.html)
[Control — Godot Engine (4.x)の日本語のドキュメント](https://docs.godotengine.org/ja/4.x/classes/class_control.html#class-control-method-release-focus)
[LineEdit — Godot Engine (4.x)の日本語のドキュメント](https://docs.godotengine.org/ja/4.x/classes/class_lineedit.html)
[SpinBox — Godot Engine (4.x)の日本語のドキュメント](https://docs.godotengine.org/ja/4.x/classes/class_spinbox.html)
LINE WORKS の Contact API で連絡先データを取得する Python コード サンプル

LINE WORKS は一般の LINE ユーザーや LINE WORKS の他テナントのユーザーともやり取りできます。

それらの外部ユーザーの情報は連絡先データに格納されています。

ここでは LINE WORKS の Contact API で連絡先データを取得する Python コードのサンプルを紹介します。

以下の API を利用します。
TITLE: 連絡先リストの取得
URL: https://developers.worksmobile.com/jp/docs/contact-list?lang=ja

このスクリプトでは、各連絡先の「姓」、「名」、「外部ユーザーID」、「外部ユーザータイプ」を抽出し、カンマ区切りの形式で 1 行ずつ出力します。

用途に応じて、必要な情報を適宜に出力してください。

実際のアクセストークンをコードに設定し、ローカル環境やクラウドベースのPython環境でスクリプトを実行します。
```
import requests

# アクセストークンとその他の初期設定
access_token = 'YOUR_ACCESS_TOKEN'  # ここに実際のアクセストークンを設定
url = "https://www.worksapis.com/v1.0/contacts"
headers = {'Authorization': f'Bearer {access_token}'}

params = {
    'count': 100,  # 1回のリクエストで取得する連絡先の数
}

all_contacts = []  # すべての連絡先を格納するリスト

while True:
    response = requests.get(url, headers=headers, params=params)
    if response.status_code != 200:
        print("Error:", response.status_code, response.text)
        break

    data = response.json()
    all_contacts.extend(data.get('contacts', []))

    # nextCursorが存在しない場合はループを終了
    next_cursor = data.get('responseMetaData', {}).get('nextCursor')
    if not next_cursor:
        break

    # nextCursorをパラメータに設定して次のリクエストを準備
    params['cursor'] = next_cursor

# 各連絡先の特定フィールドをカンマ区切りで出力
for contact in all_contacts:
    last_name = contact.get('contactName', {}).get('lastName', '')
    first_name = contact.get('contactName', {}).get('firstName', '')

    linked_external_user = contact.get('linkedExternalUser')
    if linked_external_user is not None:
        external_user_id = linked_external_user.get('id', '')
        external_user_type = linked_external_user.get('type', '')
    else:
        external_user_id = ''
        external_user_type = ''

    print(f"{last_name}, {first_name}, {external_user_id}, {external_user_type}")

```
失敗談と改善策として取り組んだこと

## はじめに
担当した作業で与えられた作業期限を守れないケースを発生させてしまいました。
今回のことを忘れないよう、同じことを繰り返さないために失敗談と改善策を残します。

## 作業を担当するまでの経緯
3年前に先輩が開発したシステムの改修依頼があり、
システムが Nuxt2 を使用していたので改修と併せてバージョンアップも行うことに。

https://v2.nuxt.com/ja/


Nuxt2 → Nuxt3 へのバージョンアップは[以前対応した経験]があったので、
何となくやることや作業の手順が頭に入っていました。

ところが、今回はバージョンアップではなく Svelte へ書き換えることになりました。
(ちなみに Svelte は[先輩の記事]を読んでチュートリアルを1時間やった程度)

https://svelte.dev


## 失敗談

結果として作業期限の遅延が起きてしまいました。

最初に見積もられていた工数よりも多くの工数をかけてしまうことで、
作業期限に間に合わず、作業期限を遅延するという事態になってしまいました。

さらに体調が悪いにも関わらず、作業期限を気にして無理に出社し体調も崩してしまいました。

## 失敗した原因
作業期限の遅れについて自分が要因となった原因は3つ考えられました。

### 該当システムの機能理解不足
今回のシステムの機能の理解が不足していたため、
どの部分が何の処理を行なっているかという理解が一切できていないまま、
Svelte への書き換えを行ってしまいました。

実は Svelte への書き換えのサポートに別の先輩がついてくださったのですが、
システムの機能の理解が不足していたために、
結果としてサポートの先輩に機能の説明をしてもらうという無駄な作業を生んでしまいました。

### Svelte の知識不足
もちろんチュートリアルは一通り行いましたが全てが補えるわけではないので、
このシステムの改修作業に入る前に Svelte をもう少し触るべきだったと後悔しています。

### 進捗報告の不足
半日が終了した時点で進捗が遅れる可能性があった場合でも、
普段と変わらず定時の進捗報告しか行っていませんでした。
遅れる可能性が出た時点で進捗が遅れそうな事を報告すべきだったと反省しています。

## 改善策として取り組んだこと
上記の3つの原因に対して改善策を立てて実行することで、
これ以上作業に遅れが発生しないように改善しました。

### システムの機能を理解する
今回のシステムを以前開発した先輩にシステムの機能についての説明をしていただきました。
先輩から説明してもらった後に自分でも説明することでしっかり機能の理解をしました。

本来であればこの工程は Svelte への書き換えを始める前に行うのが適切だったので、
作業に入る前に先輩にシステムの機能について質問するべきだったと反省しています。


### 進捗報告を定時以外にも行う
今まで定時の進捗報告しか行っていませんでした。
ですが、作業が遅れる可能性が出た時点で進捗に影響が出るかもしれないことを伝え、
今後の作業の進め方を変えるなどの軌道修正を行えるようにしました。

## まとめ
進捗が遅れることによってミーティングを開いたり、
システムのことを知らない先輩に機能について質問したり、
結果的に作業以外にも無駄な時間を作ってしまいました。

今後様々なプロジェクトに参画することがあると思いますが、
今回のことを教訓にして同じことを繰り返さないように努めていきます。


[以前対応した経験]:https://qiita.com/oec-shimokawa/items/24263e6cf1ea762e567c
[先輩の記事]:https://qiita.com/kurata04/items/d39e004dc3c837bfc4a1
大学の課題を自動通知して欲しかった

# はじめに

これは、Lumos Advent CalendarのDay19の記事です。


# 内容

プログラミングを知ってから一年経っていない者が大学の課題通知BOTサービスを作ろうとして諦めるまでの流れをまとめました。

# 手法

方法としては、
- 大学のLMSという教材提供サイトにアクセスし、
- 課題とその期限が載っている文字列を取得し、
- discordで通知する
という方法を使いました。

プログラムはPythonで書き、SeleniumというWebスクレイピングのライブラリを使いました。

※Webスクレイピングとは、Webサイトのhtmlテキストから、指定した部分の文字列を取得したりする方法のこと。


# 改良

上記の手法は上手くいったので、サービス化に向けて以下の問題点を改良します。

- discordは普通の人にはハードルが高いので、LINEでの通知に変更する
- パスワードの扱いが`os.getenv`で環境変数から取得していたので、データベースを用いる
- パスワードのハッシュ化など安全に配慮する


# パスワードハッシュ化の問題点

最初作ったものは、ログインIDとパスワードを入力させて大学サイトにログインしていたのですが、ユーザーから預かったハッシュ値を用いても大学サイトにログインできません。                          
以下に該当のプログラムを載せておきます。

	username_input = driver.find_element(By.XPATH, '//	*[@id="loginForm"]/div[1]/div[1]/div[1]/div[2]/input')
	password_input = driver.find_element(By.XPATH, '//	*[@id="loginForm"]/div[1]/div[1]/div[2]/div[2]/input')
	username_input.send_keys(username) #username変数にgetenvで得たユーザーIDを格納していた
	password_input.send_keys(password) #password変数にgetenvで得たパスワードを格納していた
	next_btn = driver.find_element(By.XPATH, '//*[@id="loginForm"]/div[2]/button')
	next_btn.click()    

# 結論

パスワードの文字列そのものがないとログインできないので、ユーザーが大学サイトにそのパスワードでログインしたときにハッシュ値を得てトリガーにする、パスワードの保存の了承を得る、など別の方法を取るかリスクを取るかする必要がありそうです。

# 参考文献
[Pythonでハッシュ化を試してみる](https://qiita.com/Nats72/items/273a8cbba6a83c21542a)
[Markdown記法 サンプル集](989c6badefff69377da7)
Splunk Observability CloudとSplunk Enterpriseを使ってF1 2023ゲームデータを可視化してみた

Splunk Advent Calendar 2023 19日目です！
この記事では、Playstation4のゲームソフトF1 2023のプレイデータをSplunkで可視化します。 

※この記事はhttps://splunk.github.io/f1-simulator/ に記載されている手法を試しています。詳細はgithubの情報をご確認ください。

## Playstation側の設定
![Screenshot 2023-12-18 at 17.08.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3629253/ae9ccc94-cacb-b0c4-7aca-6d082560def5.png)
F1 2023の設定画面で、UDP telemetry dataをexportできます。
![Screenshot 2023-12-18 at 17.06.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3629253/34be1fe3-4c10-d31d-8aef-14158e795efe.png)


## データ転送用のサーバー構築
PS4からのtelemetryデータを受信するサーバーを立てます。
UDPのデータをこのサーバーで受けた後、splunk observability cloud、およびsplunk enterprise/cloudへ転送する仕組みです。
（このサーバーの仕組みは後日解説するかもしれません）

```mermaid
graph TD;
    PS4-->データ転送サーバー;
    データ転送サーバー-->Splunk_Enterprise/cloud;
    データ転送サーバー-->Splunk_Observability_cloud;
```

この記事ではEC2インスタンス上にubuntuを構築し、dockerをインストールしimageをpullします。
<br>

インスタンス情報
+ AWS/EC2 (Ubuntu 22.04 or above)
+ t2.large (2 vCPU, 8GB RAM)
+ External IP address
+ Inbound access ports 8501/tcp, 20777/udp

```
docker run --name f1_2023 -d -p 8501:8501/tcp -p 20777:20777/udp ghcr.io/splunk/f1_2023-amd64:latest
```

<br>

サーバーが起動できたら http://\<EC2 instance IP>:8501にアクセスします。
![Screenshot 2023-12-18 at 17.47.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3629253/fc394348-634c-06a7-d5c7-6c19745ca226.png)

Observability CloudとSplunk CloudのAccess Tokenを入力します。
（Access Tokenの入手方法は下記で説明します）






## Splunk Observability Cloudの設定
サイドバーにある Setting > Access Tokens > [New token]からtokenを作成します。
適当な名前をつけ、Ingest Tokenを作成します。
![Screenshot 2023-12-18 at 17.58.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3629253/c7b78cc5-d14d-aefc-e0dc-4f93ff913c06.png)

Access token一覧から該当のTokenを選択し、[show token]をクリックするとtokenが確認できます。

## Splunk Enterpriseの設定
設定 > データ入力 > HTTPイベントコレクター[新規追加] を選択し下記を入力します。
ソースタイプ：自動
インデックス：（任意）
![Screenshot 2023-12-18 at 17.16.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3629253/c6c42c8e-e720-cdba-3cf0-92087b5dbe19.png)

作成されたtokenをコピーします。
![Screenshot 2023-12-18 at 18.23.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3629253/c41663aa-1364-1d3c-eb57-e7ca28cb7edc.png)

## いざ可視化
まずは、Splunk Observability Cloudにてbrakeとspeedをグラフ化します
![Screenshot 2023-12-19 at 13.13.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3629253/fefc9637-47e6-b3b0-117d-d3fe93c73393.png)

dashboardのJSONファイルを[こちら](https://github.com/splunk/f1-simulator/blob/main/observability/dashboard_F1%202023%20-%20Current%20Player.json "dashboard")からダウンロードし、dashboardにimportして可視化します。real timeでデータが取り込まれることがわかりました。

![o11y (1).gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3629253/266a2871-303b-86fa-0054-86bf76cbadf9.gif)

<br>
Splunk Enterpriseでもこんな可視化ができます
（今回時間がなく以前作ったdashbordを表示しています）

![dashboard.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3629253/0eff9ea6-5a59-51dd-1f92-bf73d3c430af.jpeg)
Dashboardの作成、および取り込んだデータの形式説明は次の記事で説明しようと思います。

## 終わりに
今回はゲームのデータを可視化してみました。皆さんもぜひお試しください。
Happy Splunking!
機械学習で株価分析 07.個別の株式情報データの取得

# はじめに
本記事では、**PythonでYahooFinanceのデータベースから個別銘柄の財務情報を取得する方法**を紹介します。取得できるデータは多岐にわたるので、内容はデータのインデックスを自身でご確認ください。

# 手順
### 1. yfinanceをインストール
以下のコードを実行してyfinanceをインストールします。実行環境はGoogle Colabを想定しています。
```python
!pip install yfinance
```

### 2. 必要なライブラリをインポート
以下のコードを実行して、必要なライブラリをインポートします。
```python
import yfinance as yf
yf.pdr_override()

import numpy  as np
import pandas as pd
from   pandas_datareader import data
import datetime
from   IPython.display   import display
```

### 3. データを取得する期間の指定
以下のコードを実行して、データを取得する期間を指定します。当日までのデータを取得するためには、終了日時に1日後を設定する必要があります。

```python
# データの取得開始日・取得終了日を設定
day_start = datetime.date(2021,1,1)
day_end   = datetime.date.today() + datetime.timedelta(days=1)
```


### 4. 株価データの取得と表示
以下のコードを実行して、財務データを取得し、コンソールに結果を表示します。
以下では年単位・四半期単位の情報をそれぞれ表示しています。

```python
# 銘柄名を変数に格納
stocks      = ["4689.T"]
ticker_info = yf.Ticker("".join(stocks))

# 年単位の財務情報を表示
display(ticker_info.financials.T)

# 四半期単位の財務情報を表示
display(ticker_info.quarterly_financials.T)
```

### 5. 財務データの統合と整理
以下のコードを実行して、年単位・四半期単位の財務データを統合・整理し、コンソールに結果を表示します。

```python
# 年単位の財務情報と四半期単位の財務情報を統合
df_tickerinfo = pd.concat([ticker_info.financials.T, ticker_info.quarterly_financials.T[~ticker_info.quarterly_financials.T.index.isin(ticker_info.financials.T.index)]])

# データを時系列順に並び替え
df_tickerinfo = df_tickerinfo.sort_index()

# 統合したデータを表示
display(df_tickerinfo)

```

# ソースコード全文
以下にソースコード全文を示します。

```python
!pip install yfinance

# 必要なライブラリをインポート
import yfinance as yf
yf.pdr_override()
import numpy  as np
import pandas as pd
from   pandas_datareader import data
import datetime
from   IPython.display   import display

# データの取得開始日・取得終了日を設定
day_start = datetime.date(2021,1,1)
day_end   = datetime.date.today() + datetime.timedelta(days=1)

# 銘柄名を変数に格納
stocks      = ["4689.T"]
ticker_info = yf.Ticker("".join(stocks))

# 年単位の財務情報を表示
display(ticker_info.financials.T)

# 四半期単位の財務情報を表示
display(ticker_info.quarterly_financials.T)

# 年単位の財務情報と四半期単位の財務情報を統合
df_tickerinfo = pd.concat([ticker_info.financials.T, ticker_info.quarterly_financials.T[~ticker_info.quarterly_financials.T.index.isin(ticker_info.financials.T.index)]])

# データを時系列順に並び替え
df_tickerinfo = df_tickerinfo.sort_index()

# 統合したデータを表示
display(df_tickerinfo)
```

プログラムを実行し、コンソール上に指定した期間の財務情報が表示されれば成功です。

# 目次へのリンク

https://qiita.com/ryo2_9393/items/2b1ada62c2537c901b6b
Githubの有償版(Team)を申し込む手続き

Githubの有償版の申込みを経理担当者に説明するための資料

### Gitgub の費用
年間一人あたり$48


![Screenshot from 2023-12-19 13-55-37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/83761/b0906669-340f-49dd-889a-9a2790de1f99.png)
[引用元](https://github.co.jp/pricing.html)

### 組織名を登録する
![Screenshot from 2023-12-19 13-59-00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/83761/9eae5818-9e8a-53c5-c200-1500aef7b199.png)

[引用元](https://github.com/account/organizations/new?plan=business&pricing_exp=true&ref_cta=Continue%2520with%2520Team&ref_loc=cards&ref_page=%2Fpricing&plan_duration=month)　

### 支払い方法の詳細
![Screenshot from 2023-12-19 14-04-43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/83761/17fd1c4a-fa37-f76c-7972-cef5f8e3799d.png)
[引用元](https://github.com/organizations/signup_billing?ref_page=%2Fpricing&ref_cta=Continue+with+Team&ref_loc=cards&organization%5Bplan%5D=business&plan_duration=month&org_exists=false&organization%5Bprofile_name%5D=BorgRoid&organization%5Blogin%5D=BorgRoid&terms_of_service_type=corporate&organization%5Bcompany_name%5D=BorgRoid+Inc.&agreed_to_terms=yes&seats=1)

Billing email には、経理処理の担当者のメールアドレスを記入する。


### 続き
クレジットカードでの自動引き落としになる。
これらの作業は、エンジニアと経理の担当者で行う。
AccessからSQLServerにリンクしたテーブルで通貨型のカラムが空白になる

# 現象
元々、SQL Server 2014上で稼働していたDBを新サーバーのSQL Server 2022に移行して、Access2022よりリンクして環境を構築した際に発生。
SQL Server側はmoney型で、Accessのフォームより該当フィールドに入力して保存すると、money型のフィールドは全て消え競合エラーが発生、以後編集できなくなる。
SSMSから該当レコードを見てみると値は入っているが、Access側のフォームもテーブルもmoney型フィールドは空白。
# 全く原因不明
レコードロックされているのか、Access側から変更を試みると数十秒ストールして競合エラーが起こる。
SSMS側からの閲覧・変更は可能だったので、SSMS側からmoney型フィールドの値をとりあえず0変更すると、Access側からも正常に表示・変更出来るようになった。
しかし、新規レコード作成時にはまた同じ現象となる。
# 色々と調べた結果
money型は日本ではあまり一般的では無いらしい。
金額に小数点以下は使用しないのでint型で充分かと思い、int型に変更してみた。
すると何故か、問題が発生しなくなってしまった。
原因も何もさっぱり判らず仕舞いだが、正常に運用出来ているのでこれでよしとしました。
# 時間があったら・・・
int型をmoney型に戻してみたり（必要性ゼロですが）新規テーブルでmoney型を作った場合どうなるのか等を検証出来ればと思っています。
log 

``` java:demo.java

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;

import java.util.logging.Level;
import java.util.logging.Logger;

@Controller
public class UserController {

    private static final Logger logger = Logger.getLogger(UserController.class.getName());

    @GetMapping(value = "/user/add")
    public String displayAdd(Model model) {
        // 模拟登录完成时的操作
        // ...

        // 获取操作者ID和操作対象的管理者ユーザーID
        String operatorId = "操作者ID";
        String targetAdminUserId = "操作対象の管理者ユーザーID";

        // 输出日志
        logCompleteRegistration(operatorId, targetAdminUserId);

        // 将UserRequest对象添加到模型中
        model.addAttribute("userRequest", new UserRequest());

        // 返回视图名称
        return "user/add";
    }

    private void logCompleteRegistration(String operatorId, String targetAdminUserId) {
        // 输出日志信息
        logger.log(Level.INFO, "登録完了 - タイムタンブ・パス（機能を特定する情報として）: {0}, 操作者ID: {1}, 操作対象の管理者ユーザーID: {2}",
                new Object[]{"具体的なタイムタンブ・パス信息", operatorId, targetAdminUserId});
    }
}
```
[Blue Prism]ライセンス情報を保存したい #BluePrism

# ライセンス情報とは
これです。
![ライセンス画面.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/142092/2e78ab33-740b-e799-a839-1a2d537cbb31.png)

これをExcelに保存できないかなーというお話。
手でコピペ…… まあたくさんあるわけでもないし手作業でもいいっちゃいいけど、いちいち手でやるのはめんどくさいしダサいよね……。

# どこから取得できるの
BPALicenseテーブル、ライセンス情報があるのはlicensekey列です。
値はBase64エンコードされています。
これをデコードするとライセンス情報をXML形式で取得できます。

つまり
> BPALicenseテーブルから情報を取得
> 　↓
> デコード
> 　↓
> XMLをバラす

という手順。

# BPALicenceテーブルから情報を取得
BPのDBは普通のDBです。
つまりSSMSとかで普通に扱えるやつ。
ということは、OLEDB VBOでSQL文を投げてやればオッケーです。
OLEDB VBOは標準VBOです。

OLEDB自体の解説は、良いのがあちこちにあるので、それを読んでください。
- BP社公式note　[大容量データを扱う](https://note.com/blueprism/n/n0916a68ef006)
- UniversityのOLEDB講座 [Blue Prism® Further Developer Learning](https://blue-prism.docebosaas.com/learn/course/207/BluePrism%C2%AEFurtherDeveloperLearning)
- DXにユーザーガイドPDFが載ってます [Data - OLEDB - 10.1.0 ](https://digitalexchange.blueprism.com/dx/entry/3439/solution/data---oledb)

OLEDB VBOの「Get Collection」アクションで投げるSQL文は

```SQL
SELECT licensekey FROM [DB名].dbo.BPALicense
```

戻り値の型はCollectionです。

SELECT * でテーブルが全部まるっと取得できる……こともありますが、特殊なデータ型（System.Guid）になっている列がある場合は取得できず、エラーになってしまいます。
このBPALicenseテーブルもそのクチです。
なので、ほしい列名を明示して取得するほうが手堅いようです。

Guid型の列であっても取得したい（たとえばプロセスIDなどがそうです）場合は、ただ列名を書くのじゃなくて、こう書けば取得できます。
Guidは36文字なので、Charだと桁数が足りません、なので文字数を明記してあげます。

```SQL
cast(Processid as Char(36)) as Processid
```


# デコード

取得した値をデコードします。
デコードは、DXにVBOがあります。ユーザーガイドとサンプルプロセスもそこに置いてあります。
[Utility - Encode Decode](https://digitalexchange.blueprism.com/dx/entry/9648/solution/utility---encode-decode)
サンプルプロセスを参照して、「Base64 Decode」ステージをコピペして使用してください。

戻り値の型はText。XML形式で取得できます。

# XMLをバラす

XMLのままだと可読性もアレだし項目が分かれていないと使いづらいので、Collectionの形に整形します。
XMLをコレクションにするのはDXにあります。サンプルプロセスとユーザーガイドもこちらに。
[Utility - XML](https://digitalexchange.blueprism.com/dx/entry/3439/solution/utility---xml)

整形の手順はだいたいこんな感じ。
1. 「Get Child Elements」アクションで、まずXMLの行をバラします。
2. 値がカラでないかを検分します。カラだったら当該行は捨てます。
 ・バラした行に「Strip Tags」アクションを使って、タグを除いて本文だけにします。
 ・本文のLengthが0だったらその行はカラ。
3. バラした行に「Get Element」アクションを使って「Name」「Value」を取得。
4. 「Name」が見出し（タグ名）、「Value」が値です。出力用Collectionに追記します。
5. （オプション）出力用Colletionは「Name」「Value」の2列で作成してあるので、1行Collectionのほうが扱いやすいなら転置します。

※転置は、DXにある [日商エレクトロニクスのすごいやつ](https://digitalexchange.blueprism.com/dx/entry/83455/solution/bp) の「NEO - コレクション」VBOの中に、転置のアクションがあります。

![整形.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/142092/09902382-b33b-0e24-74c9-88f7c58efc17.png)

# 取得したCollectionをExcelに書き出す
あとはCollectionで有効なライセンスだけ選別するとか、必要な項目だけにするとかしてからExcelに書き出すと、だいたいこんなようなExcelが取得できます。
![Excel.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/142092/f5ba6edb-856a-0d92-a9de-75fd76b31e67.png)


# 終わりです

DXマジでたいていのものはあります。
なくても近いものを拾ってきて改造すれば、ゼロから作るより断然ラク。
こういう機能ないかなーと思ったらまずDXを捜索はマスト。検索機能クソだけど頑張れば見つかる。

それでもなかったらIdea Portalに投稿しておきましょう。BP社の中の人がどうにかしてくれるかも。
[Idea Portal](https://community.blueprism.com/t5/Product-Ideas/idb-p/ideas)
Salesforce認定アドミニストレーター試験レポート

# Salesforce認定アドミニストレーター試験レポート

この投稿は「Salesforce認定アドミニストレーター試験」に合格しましたので、そのレポートになります。

【目次】
 １．勉強法について
 ２．試験結果について
 ３．まとめ

### １．勉強法について
 ①Salesforceプロジェクトへの参画予定があったため、社内研修受講
　　・座学
　　・用意されたお題に対して、標準機能を使ってアプリケーション開発

 ②Trailhead(trailmix)＆社内勉強会

 ③Web問題集(非公式) 450問程度
　　[認定アドミニストレーター試験過去問演習](https://quizgenerator.net/quizhoster/files/d5dab2b6eced3650f02c367e06aca130/)
　　[Salesforce 認定 アドミニストレータ 模擬試験会場](https://quizgenerator.net/quizhoster/files/cead6a2d3860fd784670c26a8cbbf3e7/)
　　[SALES 4 BOX - 初心者のためのブログ](https://sales4box.com/)

 一番大きかったのは、Trailhead(trailmix)や社内研修でSalesforceを実際に操作した経験です。
 Salesforce開発経験がまったく無い状態だったため、座学だけでは理解が厳しかった印象です。
 実際に操作したり、開発（不明点を調べたり、試したり）することで、理解に繋がりました。
 Web問題集は閲覧したサイトの問題が古かったのか、そのものずばりという問題はほぼ出ませんでしたが、問題の出され方や用意される答えの傾向など参考になりました。
 問題も独特なので、問題に慣れるという意味ではやる意味はかなりあったと思います。また、Web問題集は、問題の解説がほぼなかったため、内容が不明な問題はネット検索したりして理解を深めました。


### ２．試験結果について
社内研修受講後、あまり勉強時間が取れなかったこともあり、現時点の理解度を試す意味でひとまず一回受けてみたところ、（かなりギリギリで）合格できました。
正答率67%（合格ライン65%）

| 単元 | 配点(%) | 問題数(想定) | 得点数(想定) |
| -------- | -------:| -------:| -------:|
| 設定とセットアップ | 20 | 12 | 7 |
| オブジェクトマネージャとLightning アプリケーションビルダー | 20 | 12 | 5 |
| セールス＆マーケティングアプリケーション | 12 | 7 | 5 |
| サービス＆サポートアプリケーション | 11 | 7 | 5 |
| 生産性向上とコラボレーション | 7 | 4 | 2 |
| データ管理＆分析 | 14 | 8 | 8 |
| ワークフロー/プロセスの自動化 | 16 | 10 | 8 |
| (合計) | 100 | 60 | 40 |


### ３．まとめ
無事合格できたものの、単元別に理解不足があるところが露呈してしまっているので、しっかり復習して、次のステップとして認定Platformアプリケーションビルダーへの挑戦もしてきます。