OmniAICreator/Qiita-1.07M huggingface dataset:
ROS2プログラミング演習_06: SLAM／Navigation [実機]

## はじめに

TurtleBot3をROS2（WSL2使用）で制御します．
本ページでは実機を使ってSLAM／Navigationをテストします．

#### 環境
・OS: Windows11 Pro (64bit)
・ROS: ROS2 humble (WSL2のUbuntu22.04に)

##### ロボット
・TurtleBot3 waffle pi (Raspberry Pi 3B+)
　または
・TurtleBot3 burger (Raspberry Pi 3B+)


##### ここまでの環境構築については下記参照
・WSL2にROS2を入れてgazeboでシミュレーションするまでの手順
https://qiita.com/pez/items/16011df0e663ceac694a

・TurtleBot3実機を動かすまでの手順
https://qiita.com/pez/items/bb18797ce516468c7875


## SLAMのテスト
TurtleBot3にSSH接続して立ち上げます
```ruby:
ssh ubuntu@[(例)172.28.**.** （turtlebotのIPアドレスを調べて接続）
※接続できたら
ros2 launch turtlebot3_bringup robot.launch.py
```
別のターミナルを立ち上げてロボットの操作を行えるようにします
teleop（キーボード操作）を使う場合は下記
※自分で作った my_teleop などを使ってもよい 
```ruby:リモートPCにて
ros2 run turtlebot3_teleop teleop_keyboard
```

動かせるようになったら下記で地図作成を開始します．「cartographer」と呼ばれるシステムを使用します．
```ruby:リモートPCにて（別のターミナルを立ち上げる）
ros2 launch turtlebot3_cartographer cartographer.launch.py
```
「rviz」が自動的に立ち上がりますのでその画面を見ながらロボットを動かし，周辺地図を作成していきます．ロボットの種類・その他環境によるかもしれませんが，かなりゆっくり動かさないとうまく作成できないかもしれません．


地図の保存
```ruby:リモートPCにて（別のターミナルを立ち上げる）
ros2 run nav2_map_server map_saver_cli -f ~/map
```
※mapの部分は任意の名前でOK，「~/」を入れるとホームディレクトリ直下に保存される


## ナビゲーションのテスト
※SLAMで地図が保存された後を想定しています

ナビゲーションノードを立ち上げる
```ruby:
$ ros2 launch turtlebot3_navigation2 navigation2.launch.py map:=$HOME/map.yaml
```
※map.yaml の部分はmapを保存した時の「自分でつけた名前」.yaml とｎ．

操作方法
1.「2D Pose Estimate」ボタンをクリック
2. 現在ロボットのいる位置をクリックして緑色の矢印をロボットが向いている方向に合わせる
3.「Navigation2 Goal」ボタンをクリック
4. ロボットを移動させたい位置をクリックして緑色の矢印を最終的にロボットに向かせたい方向に合わせる

ロボットが目的地に動いたら成功
誤植？(Windows Server DNS)

# 発覚した経緯
あれは、たしか新年度になったばかりのとある春の日だった…

そのとき俺は、ADサーバに標準搭載されているDNSサーバの設定変更を行っていた。
とある理由でDNSのログを取得しなければならなくなったので、ログの出力を有効にしようとしたときに、それは見つかった。

"ログを記録する"にチェックを入れて、ログの出力先のパスを指定して、ログファイルの最小サイズを指定して、…
![qiita_4_1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3773395/8ab2b30c-9bd8-414d-9a22-ac964f5d1cbf.jpeg)
![qiita_4_2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3773395/e4c7b328-dd0f-4090-b783-23cca24dd904.jpeg)

……最小サイズ？
なんやそれ。最大サイズならわかるけど、最小サイズ？？
普通、ログは取れば取るほどサイズは増える。例えば、0Bから数GBへと。
で、最小サイズを決めろ、って何や。まるでデータを取れば取るほどファイルサイズが減るかのように。
この世の質量って負の方向に増えてくんやったっけ…

そうして頭を悩ませ、訳の分からんまま設定を有効にするのはなんだかなあと思っている時、考えがよぎる。
# 翻訳ミスでは？
そこで、言語を英語にして再度確認してみると…
![qiita_4_3.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3773395/865f643e-f947-45d2-9a29-aa4510abbebd.jpeg)
![qiita_4_4.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3773395/695e9008-441a-48a4-aa60-4efadf94ce4f.jpeg)

ああスッキリ。そうそうコレコレ。最大サイズやよな普通。
ということで英語版の表記を信じて、最大サイズ(最小サイズ)を設定可能な上限値(下限値)に設定してログを有効化すると、無事ログが取得できましたとさ。めでたし * 2。

ちなみに、本表記を確認したのはWindows Server 2022。確認できる限り(2016まで)では、すべて"最小サイズ"という表記でした。きっと、実装されてからずっとそのままなんやろうな。

悩ませやがってMicros○ft。まあログ取れたからいいけど。
### おわりに
どうやら、目に見える物だけが真実とは限らないらしい。

よければ、今この記事を読んでいる皆さんも確認してほしい。
きっと、貴方のサーバも…

### ちなみに
これの日本語、英語以外の言語の表記もチェックしてやろうと思いましたが、
なんかこの後用事があったような気がするので私は諦めました。
語学に堪能な方、後はお任せします。

また、この「デバッグのログ」機能ですが、ログファイルのサイズが最小サイズ(最大サイズ)を超えると、別名で2つ目のファイルが生成されるかと思いきや、なんと1つ目のファイルを無に帰し同名のファイルを新たに作成しログを取り始めるというとてもスリリングな仕様となっています。
というわけで、私は999,999,999Byteを超える直前でリネームをして上書かれるのを回避していました。皆さんもご注意を。
【Next.js】JestのテストでReferenceError: Response is not definedのエラーの解決の仕方について

# はじめに
jestのテストでResponseを使おうとした際に下記のエラーが表示されました。

:::note warn
ReferenceError: Response is not defined
:::

調べるとNode.jsにはResponseクラスが存在しないと認識しているため、表示されるエラーのようでした。

```
global.Response = Response;
```

# 解決方法

node-fetchをインストールする

```
npm install node-fetch@2
```


```
const { Response } = require("node-fetch");

global.Response = Response;
```

# 参考
https://azukiazusa.dev/blog/node-js-fetch/




# おわりに
私の環境ではv3ではうまくいかなかったため、v2で対応しました。
既にNode.jsでもfetchをはじめ、Responseクラスも使えるようになっているようですが、Jestのテストではエラーが出ることがあるみたいです。


<br>


# JISOUのメンバー募集中！
プログラミングコーチングJISOUでは、新たなメンバーを募集しています。
日本一のアウトプットコミュニティでキャリアアップしませんか？
興味のある方は、ぜひホームページをのぞいてみてください！
▼▼▼

https://projisou.jp
C++でのビット演算の基本をマスターしよう

# ビット演算とは
ビット演算とは、その名の通りビット単位での演算を行うことです。
# 使い道
機械的に比較的軽量な演算を行うので、コードの軽量化に繋がります。
マスキング処理などにも使用することができます。
また、ビットを使用したフラグ管理(ビットフラグ)は軽いフラグの記述の実現が可能となります。
# 論理積(AND)演算
AND演算とは、二項の各桁の両方が1なら1、そうでないなら0に変換する演算です。
AND演算では``&`` 演算子を使用します。
```C++:And.cpp
#include <iostream>

int main() {
	int a = 12;
	int b = 10;
	int result = a & b;
	printf_s("result:%d\n", result);
	system("pause");
	return 0;
}
```

```:result
result:8
```
12と10を二進数にして考えてみます。
12...``1100``
10...``1010``
各桁にAND演算を行うと
``0100``となり10進数に直すと``8``となります。
# 論理和(OR)演算
OR演算とは、二項の各桁の片方が1なら1、両方が0なら0に変換する演算です。
OR演算では``|``演算子を使用します。
```C++:Or.cpp
#include <iostream>

int main() {
	int a = 12;
	int b = 10;
	int result = a | b;
	printf_s("result:%d\n", result);
	system("pause");
	return 0;
}
```

```:result
result:14
```
12と10を二進数にして考えてみます。
12...``1100``
10...``1010``
各桁にOR演算を行うと
``1110``となり10進数に直すと``14``となります。
# 排他的論理和(XOR)演算
XOR演算とは、片方が1で片方が0のものは1、両方が同じなら0となる演算です。
XOR演算では``^``演算子を使用します。
```C++:Xor.cpp
#include <iostream>

int main() {
	int a = 12;
	int b = 10;
	int result = a ^ b;
	printf_s("result:%d\n", result);
	system("pause");
	return 0;
}
```

```:result
result:6
```
12と10を二進数にして考えてみます。
12...``1100``
10...``1010``
各桁にXOR演算を行うと
``0110``となり10進数に直すと``6``となります。
# 論理否定(NOT)演算
論理否定は、すべてのビットを反転させる操作のことを指します。
論理否定では``~``演算子を使用します。
unsigned intでresultの値を考えると、大きすぎる値になるため、コードは割愛します。
# ビットシフト
ビットシフトとは、整数型のビットをずらす操作のことをいいます。
## 左にビットシフト
左ビットシフトでは``<<``演算子を使用し、右オペランドにずらす数を指定します。
```C++:LeftBitShift.cpp
#include <iostream>

int main() {
	int a = 3;
	int left = a << 2;

	printf_s("left %d\n", left);
    
	system("pause");
	return 0;
} 
```

```:result
left:12
```
二進数にして考えてみます。
3...``0011``
これを2つ左にずらすため``1100``となり、10進数にすると``12``となります。
なお、ずらしたために右から出てくる値は0となります。
左にビットシフトを行う操作は``2^右オペランド``を左オペランドに乗算したものと同じ結果になります。
## 右にビットシフト
右ビットシフトでは``>>``演算子を使用し、右オペランドにずらす数を指定します。
```C++:RightBitShift.cpp
#include <iostream>

int main() {
	int a = 3;
	int right = a >> 1;

	printf_s("right %d\n", right);
    
	system("pause");
	return 0;
} 
```

```:result
right:1
```
二進数にして考えてみます。
3...``0011``
これを1つ右にずらすため``0001``となり、10進数にすると``1``となります。
右シフトの場合はコンパイラによっては左端が1で埋められる場合もあります。
右にビットシフトを行う操作は``2^右オペランド``を左オペランドに除算したものと同じ結果になります。
# 総括
ビットフラグを扱う際に必要となる考え方なので、まずは基本をマスターしてみましょう。
o3-pro の API を Node.js で軽く試す【OpenAI】

## はじめに

ChatGPT の Proプランへの提供と合わせて、API提供が開始された「o3-pro」の話です。


https://x.com/youtoy/status/1932596923506307196

●Model - OpenAI API 【o3-pro 】
https://platform.openai.com/docs/models/o3-pro

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/48133fea-4005-4a3e-bc42-2c4e20d92df6.png)


### 自分の環境での API利用可否の確認など

自分のアカウントで [OpenAI のプレイグラウンド](https://platform.openai.com/playground/)を見たところ、自分の環境では o3-pro の API で使えそうだったため、これを Node.js で試してみました。
※ プレイグラウンドで試す場合は API種別を「Responses API」にしておく必要があるようです

https://x.com/youtoy/status/1932636577127371167


#### 上記の補足： Responses API にのみ対応

o3-pro は Responses API にのみ対応している、という話が、プレイグラウンド上でも表示されていました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/caebd1a1-3e1f-47c0-b894-638d82996ac3.png)


## さっそく試す

過去にも、新しいAPI が出るたびにお試しをしているのですが、その時によく使っている以下のパッケージを使って試していきます。

●openai - npm
　https://www.npmjs.com/package/openai


### 下準備

#### パッケージのインストール

下準備を進めます。まずは以下でパッケージをインストールします。

```zsh
npm i openai
```

#### 環境変数の設定

また環境変数 OPENAI_API_KEY に、OpenAI の APIキーを設定します。


### コードと実行結果

#### 公式サンプルの確認

冒頭でも掲載していた[プライグラウンド上](https://platform.openai.com/playground/prompts?lang=node.js&models=o3-pro)で、o3-pro の JavaScript用のサンプルコードを確認してみます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/9a4bd574-e159-4fd9-b88c-ece692ab1186.png)


また、以下の API のドキュメントのサンプルコードも合わせて確認します。

●Reasoning models - OpenAI API
　https://platform.openai.com/docs/guides/reasoning?api-mode=responses&lang=javascript

上記の内容から、お試し用のコードを作ります（一部、使わなかった部分はコメントアウトした形にしてみています）。


#### 自分が用いたコードと実行結果


お試し用のコードは、以下のとおりです。

```javascript
import OpenAI from "openai";

const openai = new OpenAI({
  apiKey: process.env.OPENAI_API_KEY,
});

const prompt = `
あなたは誰？自己紹介を3つの文章で。
`;

const response = await openai.responses.create({
  model: "o3-pro",
  input: [
    {
      role: "user",
      content: prompt,
    },
  ],
  //   text: {
  //     format: {
  //       type: "text",
  //     },
  //   },
  reasoning: {
    effort: "medium",
    summary: "auto",
  },
  //   tools: [],
  //   store: true,
});

console.log(response.output_text);
console.log(response);
```


上記を実行した結果は、以下のとおりです。


![2025-06-11_12-26-04.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/dcdd1c98-6656-4ded-8551-d626ed39fa43.jpeg)

デバッグ出力した内容で `model: 'o3-pro-2025-06-10'` という出力も出ているので、無事 API経由で o3-pro を使えているようでした。


なお、トークン数などが出力されている末尾の部分も掲載してみます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/d4c6f7b8-a172-4e53-a03e-fdabac30ec71.png)

別途、性能の確認などもやっていければと思います。
brewの再インストール

自分用

```
echo "$(id -un) ALL=(ALL:ALL) NOPASSWD:ALL" | sudo tee -a /etc/sudoers
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/uninstall.sh)"
sudo rm -rf /opt/homebrew /usr/local/Homebrew /usr/local/Caskroom /usr/local/bin/brew
sudo rm -rf ~/Library/Caches/Homebrew ~/Library/Logs/Homebrew
```

```
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
echo "eval \"\$(/usr/local/bin/brew shellenv)\"" >> ~/.zprofile
```

Ctrl+C, Ctrl+D

```
brew install node
brew install watchman
brew install cocoapods
brew link --overwrite cocoapods
```
世界最大級のハッカソンに参加してみよう

# はじめに
現在、**Bolt.new**が主催する世界最大規模のハッカソン「**World’s Largest Hackathon presented by Bolt**」が開催されています。
総額100万ドルを超える賞金が贈られるそうで、世界最大の触れ込みは伊達じゃないようです。

# Bolt.newとは？
Bolt.newは**StackBlitz社**が開発した、プロンプトを入力するだけでAIがデザイン、フロントエンド、バックエンドを自動生成してくれるフルスタック開発プラットフォームです。
非エンジニアでも手軽にアプリケーション開発が可能です。

## 開催概要
**期間**：2025年5月30日（金）〜6月30日（月）午後2時（PDT）

**形式**：オンライン（世界中から参加可能）

**参加資格**：居住国の法定成年年齢以上の個人（特定の国・地域は除外）

**参加者数**：約81,600人が登録済み（2025年6月時点）

**主催**：Bolt.new

**結果発表**：審査を経て、2025年7月26日（土）にバーチャル授賞式にて優勝者を発表

## 審査基準
審査は以下の4つの観点で行われます。

**潜在的インパクト（Potential Impact）**
プロジェクトが解決しようとしている問題の重要性や、その解決策がもたらす価値の大きさ。

**アイデアの質（Quality of the Idea）**
プロジェクトの創造性や独自性。

**技術的実装（Technological Implementation）**
ソフトウェア開発の品質や、Bolt.newの機能を効果的に活用しているか。

**デザインとユーザー体験（Design & User Experience）**
ユーザーインターフェースの設計や、全体的なユーザー体験の質。

## 賞金や賞品
賞金総額 $1,012,500（約1.4億円）が用意されています。

**グローバル賞（上位10プロジェクト）**
| 順位 | 賞金(USD) | AWSクレジット | 賞品 |
|:-----------|------------:|:------------:|:------------:|
|1位|$100,000|$25,000|Espresso Monitor　1台|
|2位|$75,000|$25,000|Espresso Monitor　1台|
|3位|$50,000|$25,000|Espresso Monitor　1台|
|4位|$25,000|$25,000|Espresso Monitor　1台|
|5位|$22,500|$25,000|Espresso Monitor　1台|
|6位|$20,000|$25,000|Espresso Monitor　1台|
|7位|$17,500|$25,000|Espresso Monitor　1台|
|8位|$15,000|$25,000|Espresso Monitor　1台|
|9位|$12,500|$25,000|Espresso Monitor　1台|
|10位|$10,000|$25,000|Espresso Monitor　1台|

他にも地域別賞やチャレンジ賞、ボーナス賞などが設けられているようです。

感想
まるでお祭りの様なハッカソンですね。
これを機にBolt.newを使用してみるのも良いかもしれませんし、他の人のプロダクトを見て研究するという楽しみ方もあるかもしれません。
面白そうなので私も参加してみます。
Azure KinectをUbuntu 22.04 ROS2 Humbleで動かす手順

# Azure KinectをUbuntu 22.04 ROS2 Humbleで動かす手順

## 1. Azure Kinect SDKのインストール

### 1.1. .debファイルのダウンロード

以下のコマンドを実行して、Azure Kinect SDKの.debファイルをダウンロードします。

```bash
wget -P /tmp https://github.com/asukiaaa/Azure-Kinect-Sensor-SDK/releases/download/2923-08-26-ubuntu-22-04/libk4a1.4\_1.4.1\_amd64.deb
```

### 1.2. .debファイルのインストール

ダウンロードした.debファイルをインストールします。

```bash
sudo apt install /tmp/libk4a1.4\_1.4.1\_amd64.deb
```

### 1.3. USBの再接続

インストール後、Azure KinectのUSBケーブルを抜き差しして、デバイスを再認識させます。

## 2. ROS2 Humble用Azure Kinectドライバーの設定




### 2.1. `99-k4a.rules`ファイルのダウンロードと配置

Azure Kinectをroot権限なしで利用するために、`99-k4a.rules`ファイルをダウンロードし、`/etc/udev/rules.d/`に配置します。

```bash
wget https://raw.githubusercontent.com/microsoft/Azure-Kinect-Sensor-SDK/develop/scripts/99-k4a.rules
sudo cp 99-k4a.rules /etc/udev/rules.d/
```

### 2.2. Azure_Kinect_ROS_Driverのビルド

ROS2 Humble用のAzure Kinectドライバーをビルドします。まず、ROS2のワークスペースを作成し、ドライバーのリポジトリをクローンします。

```bash
mkdir -p ~/ros2_ws/src
cd ~/ros2_ws/src
git clone -b humble https://github.com/microsoft/Azure_Kinect_ROS_Driver.git
cd ~/ros2_ws
rosdep install --from-paths src --ignore-src -r -y
colcon build --symlink-install
```

### 2.3. ROS2ノードの起動確認

ビルドが完了したら、ROS2ノードを起動してAzure Kinectが認識されているか確認します。

```bash
source install/setup.bash
ros2 launch azure_kinect_ros_driver driver.launch.py
```




## 3. 動作確認 (Python Wrapper)

Azure Kinect SDKのインストールとROS2ドライバーの設定が完了したら、Pythonのwrapper (`pyk4a`) を利用して動作確認を行うことができます。

### 3.1. `pyk4a`のインストール

```bash
sudo apt install python3-pip
pip3 install pyk4a
```

### 3.2. 深度ビューアの実行

`pyk4a`のサンプルコードである深度ビューアをダウンロードして実行します。`helpers.py`も一緒にダウンロードしてください。

```bash
wget -P /tmp https://raw.githubusercontent.com/etiennedub/pyk4a/master/example/helpers.py https://raw.githubusercontent.com/etiennedub/pyk4a/master/example/viewer_depth.py
python3 /tmp/viewer_depth.py
```

これにより、Azure Kinectから取得した深度情報が表示され、SDKとドライバーが正しく動作していることを確認できます。

## 4. アンインストール

Azure Kinect SDKをアンインストールする場合は、以下のコマンドを実行します。

```bash
sudo apt autoremove libk4a1.4
```

## 5. 参考資料

- [1] asukiaaa. 試行錯誤な日々: azure kinectをubuntu22.04で動かすためのdebファイルを作った. (参照 2025-06-11). [https://asukiaaa.blogspot.com/2023/08/deb-file-of-azure-kinect-sdk-for-ubuntu-2204.html](https://asukiaaa.blogspot.com/2023/08/deb-file-of-azure-kinect-sdk-for-ubuntu-2204.html)
- [2] jlblancoc. Install Azure Kinect DK on Ubuntu 22.04 or newer · GitHub. (参照 2025-06-11). [https://gist.github.com/jlblancoc/ae2a082b0ed5af2e71645b04b7207210](https://gist.github.com/jlblancoc/ae2a082b0ed5af2e71645b04b7207210)
- [3] microsoft. Azure_Kinect_ROS_Driver. (参照 2025-06-11). [https://github.com/microsoft/Azure_Kinect_ROS_Driver/tree/humble](https://github.com/microsoft/Azure_Kinect_ROS_Driver/tree/humble)
絵文字1️⃣2️⃣3️⃣4️⃣ を含むドキュメントファイルを作成する場合の注意点

ドキュメント内に 1️⃣2️⃣3️⃣4️⃣ のような絵文字が含まれている場合、**メモ帳で開いた際に文字化けが発生しないか**確認する必要があります。

VSCode 等では問題なく表示されるため安心してしまいがちですが、**メモ帳では正常に表示されない可能性**があります。

この記事では、**この文字化け現象の回避方法についても紹介**します。

---

### ■ 回避方法

この問題は、文字コードを「UTF-8（BOM付き）」にしても**完全には解消できません**。

そのため、見た目や文章の自然さが多少損なわれたとしても、**1️⃣2️⃣3️⃣4️⃣ の直後に 📌 のような絵文字を追加する**ことを推奨します。

#### ▼ 具体例（変更前 → 変更後）

**変更前：**

```:変更前(実際にメモ帳に貼り付けてみて下さい！)
🔍 主な機能（全部で 4 つ！）
1️⃣ Unity エラー文を Ctrl + C するだけで、ChatGPT 用プロンプトに自動変換
2️⃣ 任意のシーンファイルに関連づいた .cs ファイルの名前と中身をクリップボードにコピー
3️⃣ 特定の .cs ファイルと関係ありそうな他ファイルもまとめてコピー
4️⃣ プロジェクト内の全 .cs ファイルを一括コピー
```

**変更後：**
```:変更後
🔍 主な機能（全部で 4 つ！）
1️⃣📌 Unity エラー文を Ctrl + C するだけで、ChatGPT 用プロンプトに自動変換
2️⃣📌 任意のシーンファイルに関連づいた .cs ファイルの名前と中身をクリップボードにコピー
3️⃣📌 特定の .cs ファイルと関係ありそうな他ファイルもまとめてコピー
4️⃣📌 プロジェクト内の全 .cs ファイルを一括コピー
```

このような対応以外に、**確実な回避策は存在しない**と考えています。  
メモ帳で開けるのに文字化けするドキュメントは致命的と考えているため、たとえ見た目に違和感があっても、**やむを得ず行うべき処置**です。

---

### まとめ

1️⃣2️⃣3️⃣4️⃣ を含む文章は、**メモ帳での表示に注意が必要**です。

そのため、**📌などの絵文字を併用する処置は、避けられない対応策**と考えるべきです。

この記事が少しでも参考になれば幸いです。  
ご覧いただき、ありがとうございました。

---

### 追記

この文章は ChatGPT で添削しています。
生成 AI による添削が嫌いな方は申し訳ありません。
マーケ施策の効果測定を『数式』で語る：Googleスプレッドシート活用術


はじめに
スタートアップでマーケティング支援をしていると、「この施策、本当に効果あるの？」という質問をよく受けます。
BIツールは高いし、GoogleAnalyticsだけでは物足りない。そんな時に重宝するのがGoogleスプレッドシートです。今回は実際に使っている効果測定の数式をシェアします。
基本的な効果測定指標の計算式
1. コンバージョン率（CVR）の計算
=B2/A2*100

A2: セッション数
B2: コンバージョン数
結果：CVR（%）

2. 獲得単価（CPA）の算出
=C2/B2

C2: 広告費
B2: コンバージョン数
結果：1件あたりの獲得コスト

3. ROASの自動計算
=D2/C2*100

D2: 売上
C2: 広告費
結果：広告費用対効果（%）

応用：時系列での成長率分析
前月比成長率
=(B3-B2)/B2*100

月次データで前月からの成長率を自動計算します。
移動平均での平滑化
=AVERAGE(B2:B8)

7日間の移動平均を出すことで、日々の変動に惑わされず、トレンドを把握できます。
実践：施策別効果測定ダッシュボード

実際のプロジェクトで使っているテンプレートの一部をご紹介します

A. 条件分岐での自動判定
=IF(E2>10,"Good",IF(E2>5,"Fair","Poor"))
CVRが10%以上なら"Good"、5-10%なら"Fair"、それ以下なら"Poor"と自動で評価。

B. 複数条件での施策評価
=IF(AND(F2>3,G2<5000),"推奨","要改善")
ROASが3以上かつCPAが5000円未満の場合のみ「推奨」と表示。

スタートアップならではの活用ポイント

1. リアルタイム共有
Googleスプレッドシートなら、チーム全員がリアルタイムで数値を確認できます。毎朝の数値チェックが習慣化されました。

2. 仮説検証の高速化
=IF(H2>I2,"施策A優位","施策B優位")
A/Bテストの結果を自動判定することで、意思決定のスピードが格段に上がります。

3. コスト効率の最適化
無料ツールでここまでできるのは、資金に限りがあるスタートアップには大きなメリットです。

まとめ
数式を使った効果測定は、感覚に頼らない意思決定を可能にします。特にスタートアップでは、限られたリソースを最大効率で活用する必要があるため、このような定量的アプローチが成長の鍵となります。
明日からでも使える数式を紹介しました。ぜひ皆さんのマーケティング活動に役立ててください。
【ロイター×python】lsegデータを取得

LSEGが提供しているLSEG Data library for pythonを使ってlsegデータを取得する方法。
LSEG Data library for pythonの詳細については、下記URL
https://developers.lseg.com/en/api-catalog/lseg-data-platform/lseg-data-library-for-python

### 事前準備と注意点

※EikonまたはWorkspaceのデスクトップをログイン状態で実行すること
※APPkEYの設定
① デスクトップの検索バーに"APP KEY"と入力して検索
② "App Display Name"を押す
③ "Eikon Data API'"にチェックをいれる
④ "Register New App"をクリック


### コードについて

lsegdatalibraryをインストール

```python
pip install lseg-data
```
参考：https://pypi.org/project/lseg-data/


#### 例：今回はLME Copper Cash Pit Commodity Futureの"OPEN","HIGH","LOW","CLOSE"のヒストリカルデータを取得
```python
import lseg.data as ld

ld.open_session()
st_date='2025/5/1'
end_date='2025/6/1'
#OPEN","HIGH","LOW","CLOSE, 
df=ld.get_history(universe= "MCU0", fields= ["OPEN_PRC","HIGH_1","LOW_1","TRDPRC_1","CASH_SETL"], start=st_date, end=end_date)

df
```

MCU0	OPEN_PRC	HIGH_1	LOW_1	TRDPRC_1	CASH_SETL
Date					
2025-05-02	***	***	***	***	***
2025-05-06	***	***	***	***	***
2025-05-07	***	***	***	***	***
（以下5/30までつづく）
（***には実際のデータが返ってきています。）

#### パラメータについて
・universe—基本的にRICコードと同じようです。
・fields—取得したい項目。デスクトップの検索バーでDIBと入力して検索すると、データ項目ブラウザを使用して、各データの項目を確認することができます。
・start—開始期間
・end—終了期間
※期間パラメータの指定した日付を含むかどうかは、テクニカルサポートに確認したところ、そのRICによるとのことでした。

このライブラリは、一度に大量のRICを検索したり、一定数以上プログラムでアクセスするとペナルティ？（制限？）があるようです。そして何よりこのライブラリは実行時間が長いです。
まだまだ不明な点は多く、使いこなせていないので今後も勉強しながら分かったことは発信していきます。
【インクリメントとデクリメント】

インクリメント一般的には「増加」や「増分」を意味する言葉ですが、コンピューターやプログラミングの分野では、変数の値を1増やす演算を指します。
反対に、値を1減らす演算はデクリメントと呼ばれます.
【SpringBootアノテーション一覧　バリデーション編】

バリデーションとはBean Validation を使って入力チェックをする方法。
電話番号は11桁で入力してください。みたいなやつ。ちゃんと入力しないと、送信できないで赤くなるやつ。

#### ＠NotNull
必須チェック（NULLの場合NG）

#### ＠NotEmpty
必須チェック（NULL、空文字の場合NG）

#### ＠Size
```
import javax.validation.constraints.Size;
@Size(min =2, max = 10, message = "パスワードは2文字以上10文字以下で登録してください")
```
桁数チェック

#### ＠Min
数値の最小値チェック数値の最小値チェック
```
@Min(value = 18, message = "年齢は18歳以上でなければなりません")
@Max(value = 100, message = "年齢は100歳以下でなければなりません")

メッセージなしの場合は数字だけでいい
@Min(18)
@Max(100)
```
#### ＠Max
数値の最大値チェック

#### ＠Pattern
正規表現チェック

#### ＠AssertTrue
相関チェック（returnがTrueの場合OK）

#### ＠AssertFalse
相関チェック（returnがFalseの場合OK）

#### ＠Valid
子クラスでもBean Validationを行いたい場合指定する


こちらを参考にしました！
[【Spring Boot】バリデーション](https://b1san-blog.com/post/spring/spring-validation/#%E3%83%90%E3%83%AA%E3%83%87%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3%E5%AE%9A%E7%BE%A9)
2026年に開催される全国のPHPカンファレンスのまとめ

# 2026年に開催される全国のPHPカンファレンスのまとめ

## PHPerKaigi 2026
- 開催日 : 2026年3月20日(金)〜3月22日(日)
- 開催場所 : 中野セントラルパークカンファレンス
- X : https://twitter.com/phperkaigi
- ハッシュタグ : [#phperkaigi](https://twitter.com/hashtag/phperkaigi?src=hashtag_click&f=live)
- fortee : https://fortee.jp/phperkaigi-2026

## PHPカンファレンス小田原 2026
- 開催日 : 2026年4月11日(土)
- 開催場所 : 未定
- X : https://twitter.com/phpcon_odawara
- ハッシュタグ : [#phpcon_odawara](https://twitter.com/hashtag/phpcon_odawara?src=hashtag_click&f=live)
OWASPを踏まえてAzure WAF ルールID 932100 と932105の違いを調査

MSの公開文章には、Azure WAF ルールID 932100 と932105の記載がありますが、同じ内容となっています。
では、両者の違いはどこでしょう。OWASPで調査してみました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/620054/c69d3302-878e-4002-b4d6-bdc9df3b751b.png)

まずはOWASPのgithub上で両者ルールIDの情報を取得します。Branchはv3.2/materにします。
https://github.com/SpiderLabs/owasp-modsecurity-crs/tree/v3.2/master

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/620054/5a03aaf5-340d-49ee-93d8-01ef9831d6ad.png)

次、ruleフォルダに行きます。932100と932105を検索して、932100.txtと932105.txtをクリックします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/620054/9a1fcfaf-1891-4eed-91e1-d33c1ebf29e6.png)

次、以下の内容が見れます。
932100.txt
https://github.com/SpiderLabs/owasp-modsecurity-crs/blob/v3.2/master/util/regexp-assemble/regexp-932100.txt

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/620054/0c04c985-ac97-4709-9520-d5053e7d5483.png)

https://github.com/SpiderLabs/owasp-modsecurity-crs/blob/v3.2/master/util/regexp-assemble/regexp-932105.txt
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/620054/a2a52101-a827-4345-a1d3-4b41132ada9b.png)

上記の詳細を確認するところ、両者はUnixコマンドインジェクションによるリモートコード実行（RCE）攻撃を検出するために設計されています。
主な違い点は
Rule 932100は、一般的なファイル操作や軽量なネットワーク/スクリプトコマンドを対象にしています。
Rule 932105は、システム管理、データベース、ネットワークスキャン、スクリプト言語など、より特化されたコマンドを対象としています。
🛴ループ処理まとめ🔁❻ ー .while / .unlessメソッド

## while文とは
- 条件式が`true`の間、ループ処理を実行する制御構文のこと
- 条件式が`false`の間、ループ処理を実行する制御構文はunless文


## 記法
```ruby
while 条件式 do
  処理内容
end
```
①条件式を評価→②`true`なら条件内容を実行→③処理終了後、条件式を再評価→④`false`の時点でループ終了

## 制御キーワード
- `break`：ループ即時終了
- `next`：現在のループをスキップ
- `redo`：同じループを再実行

## 基本的な例
```ruby
i = 1
while i <= 5 do
  puts i
  i += 1
end

# 実行結果 => 1 2 3 4 5
```
**`i += 1`の役割**
- `i += 1` ＝ `i = i + 1`
⚫️ `i = 1`の場合
- `i`は常に`1`のまま→ずっと`true`→無限ループ
⚫️ `i += 1`の場合
- `puts i`を実行後、次のループで`i + 1`がなされる
## `break`で即時終了
```ruby
i = 1
while i <= 5
  break if i == 3
  puts i
  i += 1
end

# 実行結果 => 1 2
```
## `next`で次の処理へスキップ
```ruby
i = 0
while i < 0
  i += 1
  next if i == 3
  puts i
end

# 実行結果 => 1 2 4 5
```

## まとめてみて
- `i += 1`がたまに頭から抜ける。
- `redo`の理解が乏しいから、学習して深めたい。
lockfileVersionを指定してインストールするには

npmのバージョンごとにpackage-lock.jsonのlockfileVersionはアップデートされていきます。

https://docs.npmjs.com/cli/v9/configuring-npm/package-lock-json/

最新版が望ましいですが
後方互換性の問題と、差分が多すぎると面倒なこともあるでしょう。

npmなら`NPM_CONFIG_LOCKFILE_VERSION`環境変数を指定するか、
`npm install --lockfile-version=3`といった形でオプションを設定すれば楽です

https://docs.npmjs.com/cli/v9/using-npm/config
laravel sail のコマンドを省略した

毎回長いコマンドを打つのが面倒になります。
そこでよく使うコマンドをalias化しました。


## よく使う Sail コマンドを alias 化！
以下の alias を .bashrc や .zshrc に追加することで、短いコマンドで Laravel Sail を操作できるようになります。

```bash
# Laravel Sail コマンド短縮
alias sail="./vendor/bin/sail"
alias sailup='./vendor/bin/sail up -d'

# Artisan コマンド短縮
alias sailclear='./vendor/bin/sail artisan config:clear && ./vendor/bin/sail artisan config:cache'
alias sailmigrate='./vendor/bin/sail artisan migrate'
alias sailmr='./vendor/bin/sail artisan migrate:fresh'
alias sailmrs='./vendor/bin/sail artisan migrate:fresh --seed'
alias sailmstatus='./vendor/bin/sail artisan migrate:status'
sailmakeseeder() {
  ./vendor/bin/sail artisan make:seeder "$1"
}
alias sailseed='./vendor/bin/sail artisan db:seed'
alias sailtinker='./vendor/bin/sail artisan tinker'
alias sailmysql='./vendor/bin/sail mysql'
alias sailvite='./vendor/bin/sail npm run dev'

sailmaketable() {
  echo "🚀 Artisan コマンドを実行します: $@ "
  ./vendor/bin/sail artisan "$@"
  echo "🛠️ マイグレーションを実行します..."
  ./vendor/bin/sail artisan migrate
}
```

## 反映方法
```bash
# bash の場合
source ~/.bashrc

# zsh の場合
source ~/.zshrc
```
## 使い方

sailup：Sail コンテナをバックグラウンドで起動

sailmigrate：マイグレーションを実行

sailmr：全テーブルを削除して再マイグレーション

sailmrs：マイグレーション後にシーディングまで実行

sailclear：設定キャッシュをリセット

sailmstatus：マイグレーションの状態を一覧表示（どのマイグレーションが実行済みか確認できます）

sailmakeseeder SeederName：Seederファイルを作成（例：sailmakeseeder UserSeeder）

sailseed：Seederを実行し、ダミーデータなどをデータベースに挿入

sailtinker：Laravelの対話型シェル（Tinker）を起動し、モデルの操作やDB操作をインタラクティブに行えます

sailmysql：MySQLクライアントを起動し、直接SQLを実行可能

sailvite：Laravel Sail コンテナ内で Vite の開発サーバーを起動します。

sailmaketable: 引数（例 table:sessions）を指定してテーブルの作成

※次はたぶんたくさんのテストデータの挿入？シーディングというのか？
pdftk の使い方

## Ubuntu 25.04 でのインストール

```bash
sudo apt install pdftk
```

## インストールの確認

```text
$ pdftk --version
pdftk port to java 3.3.3 a Handy Tool for Manipulating PDF Documents
Copyright (c) 2017-2018 Marc Vinyals - https://gitlab.com/pdftk-java/pdftk
Copyright (c) 2003-2013 Steward and Lee, LLC.
pdftk includes a modified version of the iText library.
Copyright (c) 1999-2009 Bruno Lowagie, Paulo Soares, et al.
This is free software; see the source code for copying conditions. There is
NO warranty, not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
```

## 最初の1ページを切り出す

```bash
pdftk input.pdf cat 1 output output.pdf
```
Djangoでmodels.CASCADEにしてもデータベースではCASCADEにならない


# 疑問　 : 「on_delete=models.CASCADE」を設定したのに「RESTRICT」になる
- 環境
    - Python : 3.12.11
    - Django : 4.2.11
    - MySQL : 8.0.32

Djangoで「on_delete=models.CASCADE」を設定した子レコードのある親レコードをデータベースで直接SQLを使って削除しようとしたらエラーになった。
「on_delete=models.CASCADE」を設定したらデータベースでも「CASCADE」になると思っていた。

```python
class AnimalArea(models.Model):
    animal_area_id = models.AutoField(primary_key=True)
    animal = models.ForeignKey(Animal, on_delete=models.CASCADE, verbose_name='CASCADEで親レコードが削除されると子レコードも削除されるようにする')
    area = models.ForeignKey(Area, on_delete=models.PROTECT, verbose_name='PROTECTで親レコードを削除しようとした際に、子レコードが存在すると拒否されるようにする')
```

しかし、実際は「on_delete=models.PROTECT」と同じ「RESTRICT」だった。
```sql
select TABLE_NAME,UPDATE_RULE,DELETE_RULE,REFERENCED_TABLE_NAME from information_schema.REFERENTIAL_CONSTRAINTS where table_name like 'animal_area';
```

|TABLE_NAME|UPDATE_RULE|DELETE_RULE|REFERENCED_TABLE_NAME|
|:--|:--|:--|:--|
|animal_area|RESTRICT|**RESTRICT**|area|
|animal_area|RESTRICT|RESTRICT|animal|


なぜだろう？

# 答え : Djangoはデフォルトで、「CASCADE」を削除しているため

> **CASCADE**
> カスケード削除。Django は SQL の制約 ON DELETE CASCADE の動作をエミュレートし、 ForeignKey を含むオブジェクトも削除します。
> 引用元 : [モデルフィールドリファレンス | Django documentation | Django](https://docs.djangoproject.com/ja/5.2/ref/models/fields/#django.db.models.CASCADE)

ん？親レコードを削除したら子レコードを削除できるのか？

> **RESTRICT**
> RestrictedError (django.db.IntegrityError のサブクラス) を発生させて、参照オブジェクトの削除を防ぎます。 PROTECT とは異なり、同じ操作で削除されるオブジェクトが CASCADE リレーションシップで参照されている場合、参照オブジェクトの削除は許可されます。
> 引用元 : [モデルフィールドリファレンス | Django documentation | Django](https://docs.djangoproject.com/ja/5.2/ref/models/fields/#django.db.models.RESTRICT)

「on_delete=models.CASCADE」の親レコードを削除する流れは、以下になるので「RESTRICT」で問題ないそうだ。

1. 親レコード(参照される側)の.delete()メソッドを実行
1. 親レコードを参照しているすべての子レコード(参照している側)を検索
1. 取得した子レコードを先に削除
1. 最後に親レコードを削除


## 「CASCADE」を削除してもpre_delete と post_deleteは使えるから安全
Djangoでは、モデルが削除される前後に特定の処理を挟むためのpre_deleteやpost_deleteといったシグナルがあります。

> **モデルのシグナル**
> django.db.models.signals モジュールは、モデルシステムによって送信される一連のシグナルを定義しています。
> (省略)
> **django.db.models.signals.pre_delete**
> モデルの delete() メソッドとクエリセットの delete() メソッドの開始時に送信されます。
> (省略)
> **django.db.models.signals.post_delete**
> pre_delete のようですが、モデルの delete() メソッドとクエリセットの delete() メソッドの終わりに送信されます。

データベースレベルで「CASCADE」で削除されると子レコードの削除がORマッパーを使わずに行われてしまうため、シグナルが子オブジェクトに対して発火しない。
なので「CASCADE」を削除することで、子レコードの削除がORマッパーを使って行うようにしてシグナルが発火するようにしている。

> **CASCADE**
> (省略)
> Model.delete() はリレーション先モデルでは呼び出されませんが、 pre_delete と post_delete シグナルは削除された全てのオブジェクトに対して送られます。
> 引用元 : [モデルフィールドリファレンス | Django documentation | Django](https://docs.djangoproject.com/ja/5.2/ref/models/fields/#django.db.models.CASCADE)

どうしてもデータベースで「CASCADE」にしたい場合は、マイグレーションファイルをいじったりして「CASCADE」を強制設定する必要があるよう。
ただ、直接データベースで操作を行う前提でなければ強制する必要はないように思う。
【TCP通信】アプリ間のソケット通信をデバッグするためのSocketDebuggerを使ってみた

# 1. はじめに
ソケット通信で「通信が来ない」「応答が返らない」...
そんなトラブル、経験ありませんか？

本記事では、TCP/UDPベースのアプリケーション開発中に発生しがちな通信トラブルを簡単に可視化・デバッグできる弊社の**SocketDebugger**をご紹介します。

# 2. 通信トラブルのよくあるシーン
開発現場でこんなことはありませんか？

- サーバー側は「受け取っていない」と言うが、クライアント側は送信したと言っている
- テスト中に意図しないデータが送信されている
- 複数のクライアントが同時に通信していてログがごちゃごちゃ

こういった「どこが悪いのかよくわからない」問題に**SocketDebugger**は役に立ちます。

# 3. SocketDebuggerの特徴とできること
- TCP通信（ソケット）
- UDP通信（ソケット）
- COM通信（シリアル）
- スクリプトによる通信制御
- パケットモニタ

# 4. 実際に使ってみる
ここでは、ローカルのTCPサーバーとクライアントの間の通信を**SocketDebugger**で実行してみます。

#### SocketDebuggerの起動
SocketDebuggerを2つ起動して、それぞれTCPサーバ、TCPクライアントとします。
（それぞれの設定は別記事でご説明します！）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4093303/606da773-abb1-44d8-9797-9048e628294b.png)

#### サーバ通信開始
TCPサーバの通信開始を行い、TCPクライアントからの接続状態待ちになります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4093303/37842f78-769e-4ea4-b49b-8b63b890d0bd.png)

#### クライアント通信開始
TCPクライアントの通信開始を行い、指定ポートでTCPサーバとの接続ができました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4093303/b4272e88-b13a-4af0-b905-baaa97baff20.png)

#### 送信データの作成
TCPクライアントで任意の送信データ「0123456789ABCDEF」を作成します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4093303/a007a0ef-c320-4c6e-b0c1-e48e4ed6bfae.png)

#### データ送受信
TCPクライアントからデータ送信を実行すると、TCPサーバで「0123456789ABCDEF」を受信できました！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4093303/9c899f65-00a3-449b-a6d5-c23671b98c52.png)

# 5. まとめ
アプリケーション開発における通信確認の手間を大幅に削減できる**SocketDebugger**。  
まずは一度試してみてください！
今回は、**SocketDebugger**を使用したシンプルなTCP送受信の使い方を紹介しましたが、今後は様々な活用方法をチュートリアル形式で紹介していきたいと思います！

# 記事リンク
https://qiita.com/umezawa_udom/items/dba49ca754b5dcffb198

https://qiita.com/umezawa_udom/items/88afd06acb4cb4f1fb5a

# 株式会社ユードム
株式会社ユードムはITと人間力で社会に貢献します。

https://www.udom.co.jp/


SocketDebuggerのご購入はこちら（期間限定の試用版もあります）

https://www.udom.co.jp/sdg/index.html
ChatGPTのコード、動いたけど“わかってない”あなたへ贈る記事【JavaScript初〜中級者向け】

## はじめに

> ChatGPTでコードを出してもらって、コピペしたら動いた…けど、**仕組みはよくわからない**。

そんな経験、ありませんか？

この記事は、**ChatGPTから得たコードを「読める・直せる・応用できる」力を身につけたい人**のために書いています。

特にJavaScript初〜中級者の方向けに、よく出てくるコードを「仕組みから」解説していきます。

---

## 1. なぜChatGPTのコードは“わかりにくい”のか？

### ✅ ChatGPTは「最短で動く」コードを返してくれる

* エラーが出ない
* よくある構文で構成されている
* でも「なぜそう書くのか」が省略されがち

### ✅ よくある“わかりにくさ”の例

```js
const fetchData = async () => {
  const res = await fetch("https://api.example.com/data");
  const json = await res.json();
  console.log(json);
};
```

→ 動く。でも `async` と `await` の意味、説明された？

---

## 2. async / await の仕組みをちゃんと理解する

```js
async function getUser() {
  const response = await fetch("https://api.example.com/user");
  const data = await response.json();
  return data;
}
```

### ✅ これがやってること（ざっくり）

1. `fetch()`はPromise（非同期処理）を返す
2. `await`は「この処理が終わるまで止まる」指示
3. `async`が付いた関数は、自動的にPromiseを返す関数になる

### ✅ よくある間違い

```js
const user = getUser(); // → Promiseオブジェクトが返ってくるだけ
```

→ 正しくは：

```js
getUser().then(user => console.log(user));
// または
const user = await getUser(); // （async関数の中で）
```

---

## 3. なぜ“状態管理”が必要になるのか？

```js
let isLoading = false;

function fetchData() {
  isLoading = true;
  fetch("https://api.example.com")
    .then(res => res.json())
    .then(data => {
      console.log(data);
      isLoading = false;
    });
}
```

### ✅ ChatGPTがよく出す書き方だけど…

→ `isLoading` のような「状態変数」は、**UIや処理の進行制御**のためにある

### ✅ 状態の管理は今後のUI実装で避けて通れない

* ローディング中かどうか？
* エラーが起きたかどうか？
* データが取得済みかどうか？

→ この考えがわかると、Vue / React に進むときもスムーズ

---

## 4. map / filter / reduce の違い、わかってる？

```js
const list = [1, 2, 3];
const doubled = list.map(n => n * 2); // [2, 4, 6]
```

→ **map：変換用（個々の値を変える）**

```js
const filtered = list.filter(n => n > 1); // [2, 3]
```

→ **filter：条件で絞り込み**

```js
const sum = list.reduce((acc, n) => acc + n, 0); // 6
```

→ **reduce：累積処理（合計など）**

> ChatGPTが当たり前のように使うけど、「なんでこの関数なの？」と感じたら、こういう意図があるってこと。

---

## 5. じゃあどうやって“理解”していけばいいのか？

### ✅ 「動くコード」を「分解」してみる

```js
// ChatGPTが出した関数
const greet = name => alert(`Hello, ${name}`);

// 分解
function greet(name) {
  const message = `Hello, ${name}`;
  alert(message);
}
```

→ どこで処理されてるかが見えてくる

### ✅ ChatGPTに「このコードの意味を教えて」と聞く

→ 出てきたコードが意味不明なら、分解と併用で意味を知る

---

## 6. おわりに：ChatGPTは“先生”ではなく“相棒”

* ChatGPTは動くコードを出すけど、文脈や目的は説明してくれないことが多い
* だからこそ、「なぜそう書くのか？」を自分で理解していく力が大事
* この記事を読んだあなたは、「ChatGPTで出てきたコードを読める人」にもうなれてる

---

## まとめ：こんな風に成長していこう

| ステージ  | 課題           | 対策                       |
| ----- | ------------ | ------------------------ |
| 初心者   | 動いたけどよくわからん  | 分解＋ChatGPTに意味を聞く         |
| 中級者手前 | カスタマイズができない  | map/filter/reduceや非同期の理解 |
| 中級者   | 設計の理由まで考えられる | 状態管理や再利用性を意識             |

---

## フォローしてくれたあなたへ

Qiitaではこうした「ChatGPTを相棒にするための記事」をシリーズ化していきます。
JSの基礎力・読解力を一緒に伸ばしていきましょう！
プログラミング学習に集中できるBGMを完全主観で書いてみた🎵

## おれは集中力がない。だから声を聞くと頭に入らない。

ということで、プログラミング学習中にリピートで延々と聞き流している音楽をメモ的に以下に挙げます。気取っているように思うかもしれませんが、クラシック音楽は無限リピートすることで集中できる、本当に。はい、ベターです。ベルリンフィル教、カラヤン宗であり、ショルティ宗でもあります。ミーハーです。
吹奏楽でサックスを吹いていたこともあるので、クラシックへの憧れとコンプレックスが入り混じったレパートリーになりました。堅苦しくないので、ぜひ！

---
#### １. [交響曲第8番 第4楽章：Finale（A.ブルックナー）](https://youtu.be/dtRW5RbNmxk?si=4pyI41rwU282MP5-)
#### ２. [On The Shoulders of Giants（P.グレアム）](https://www.youtube.com/watch?v=zOlF8j0OOws)
#### ３. [交響曲第1番 第4楽章：Finale（J.ブラームス）](https://youtu.be/UiK69cGAwks?si=kHi9S2vpC4gxH_CJ)
#### ４.[無伴奏ヴァイオリン・パルティータ 第5楽章：シャコンヌ（J.S.バッハ） - L.ストコフスキー版](https://youtu.be/-MTErYL3tXQ?si=sfkYigga73iQWQQP)
#### ５.[夜のガスパール 第3曲：スカルボ（M.ラヴェル）- M.コンスタン版](https://youtu.be/bMnMFaLs74s?si=nMKWNR5qo4P-PRbc)
#### ６.[ヴァイオリン協奏曲 ニ短調（P.チャイコフスキー）](https://youtu.be/F9zHr5RJM2o?si=cvNAyyGoKQZY_7Z8&t=1280)
#### ７.[ピアノ協奏曲 ニ短調 BWV1052（J.S.バッハ）](https://youtu.be/osg_WmeLxQk?si=kR0f-6ZGVg58TME1)
#### ８.[交響詩「ドン・ファン」（R.シュトラウス）](https://youtu.be/53J_U5R9AXA?si=yOVqoZVfOChs0pGC)
#### ９.[交響曲第3番（A.ハチャトゥリアン）](https://youtu.be/--P9sTGqUHw?si=1maKobZh03OJInvf)
#### １０.[プラハ1968のための音楽（K.フサ）](https://youtu.be/Aw44PzSQAZg?si=oXIf6CmXhbHYV8HI)
#### １１.[バレエ音楽「春の祭典」（I.ストラヴィンスキー）](https://youtu.be/n8ECAIoG0jo?si=NDNf7g_2DOTrApvh&t=1724)
#### １２.[交響曲第2番 ニ長調（J.シベリウス）](https://youtu.be/asjKsoP4u6U?si=TJtv7MbzefSxOkIP&t=1782)
#### １３.[B-A-C-Hの名による幻想曲とフーガ S.529（F.リスト）](https://youtu.be/ovqDQLOHcX4?si=qlkvajKDxwyEu0sI)
#### １４.[ビゼーの「カルメン」の主題によるファンタジー（A.ローゼンブラッド）](https://youtu.be/8g-UPQUlz0E?si=8hXcJMFwsSCZjrKC)
#### １５.[弦楽四重奏曲 ヘ長調 （M.ラヴェル）](https://youtu.be/f7loz_Y5iOo?si=LxyAcaWtWE_ARpft)

---
最後に、
# クラシック音楽はフランクで取っ付きにくくない、かっこいい音楽だから、皆さんに聞いてほしい！！
聞いていただけた方、ぜひ感想いただけると嬉しいです。
おすすめのクラシックある方、教えてください。
誰でもどなたでもコメントウェルカムです。
以上
【チーム開発/Github】プルリクとレビューのやり方のメモ

## レビューのApprove方法について

下記のqitta記事にプルリクとレビューのやり方についてわかりやすくまとまっているので参考にできます。

https://qiita.com/obscure723/items/5265556d1b89e77c456b

下記の画面で、コメント例えば「LGTM」などを記載して「Approve」を押下するとレビュー依頼をしている人のコードのレビューが完了したことになる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/381629/5401e08e-3633-4586-a112-9a5e4144eb8d.png)

チーム開発をしないとGitを使用したプルリクやレビューのApproveなどはする機会が少ないので、覚えておきたいですね
Pointers and Arrays 2: Array of Pointer, The C Puzzle Book p.55

#include "defs.h"

int a[] = {0, 1, 2, 3, 4};
int *p[] = {a, a + 1, a + 2, a + 3, a + 4};
int **pp = p;

int main(void)
{
        // a はポインタ（配列の先頭アドレス）、*a は int
        PR(p, a); PRINT1(d, *a);

        // p はポインタ配列の先頭アドレス、*p は int*、**p は int
        PR(p, p); PR(p, *p); PRINT1(d, **p);

        // pp は int**、*pp は int*、**pp は int
        PR(p, pp); PR(p, *pp); PRINT1(d, **pp);

        NL;

        // それぞれインクリメント後の差分、値の表示
        pp++; PRINT3(d, pp - p, *pp - a, **pp);// W: format specifies type 'int' but the argument has type 'long' [-Wformat]
        pp++; PRINT3(d, pp - p, *pp - a, **pp);// W: format specifies type 'int' but the argument has type 'long' [-Wformat]
        ++pp; PRINT3(d, pp - p, *pp - a, **pp);// W: format specifies type 'int' but the argument has type 'long' [-Wformat]
        ++*pp; PRINT3(d, pp - p, *pp - a, **pp);//W: format specifies type 'int' but the argument has type 'long' [-Wformat]

        NL;

        // 再初期化
        pp = p;
        (void)**pp++; PRINT3(d, pp - p, *pp - a, **pp);// W: format specifies type 'int' but the argument has type 'long' [-Wformat]
        (void)*++*pp; PRINT3(d, pp - p, *pp - a, **pp);// W: format specifies type 'int' but the argument has type 'long' [-Wformat]
        ++**pp; PRINT3(d, pp - p, *pp - a, **pp);//       W: format specifies type 'int' but the argument has type 'long' [-Wformat]

        return 0;
}
Pointers and Arrays 1: simple pointer and array, The  C Puzzle Book, p.53 

```c:pa1.c
#include "defs.h"

int a[]={0,1,2,3,4};

void main(){
	int i, *p;

	for( i=0; i<=4; i++ ) PR(d,a[i]);			//Pointers and Arrays 1.1
	NL;
	for( p= &a[0]; p<=&a[4]; p++ )
		PR(d,*p);								//Pointers and Arrays 1.2
	NL; NL;

	for( p= &a[0],i=1; i<=5; i++ )
		PR(d,p[i]);								//Pointers and Arrays 1.3
	NL;
	for( p=a,i=0; p+i<=a+4; p++,i++ )
		PR(d,*(p+i));							//Pointers and Arrays 1.4
	NL; NL;

	for( p=a+4; p>=a; p-- ) PR(d,*p);			//Pointers and Arrays 1.5
	NL;
	for( p=a+4,i=0; i<=4; i++ ) PR(d,p[-i]);	//Pointers and Arrays 1.6
	NL;
	for( p=a+4; p>=a; p-- ) PR(d,a[p-a]);		//Pointers and Arrays 1.7
	NL;
}
```

```shell-session:bash
$ gcc pa1.c
$ ./a.out
a[i] = 0        a[i] = 1        a[i] = 2        a[i] = 3        a[i] = 4
*p = 0  *p = 1  *p = 2  *p = 3  *p = 4

p[i] = 1        p[i] = 2        p[i] = 3        p[i] = 4        p[i] = 0
*(p+i) = 0      *(p+i) = 2      *(p+i) = 4

*p = 4  *p = 3  *p = 2  *p = 1  *p = 0
p[-i] = 4       p[-i] = 3       p[-i] = 2       p[-i] = 1       p[-i] = 0
a[p-a] = 4      a[p-a] = 3      a[p-a] = 2      a[p-a] = 1      a[p-a] = 0
```

本に結果が？になっているところがある。
黒字化2

Sub SafeDirectBlackenFontsOnlyNeeded()
    Dim folderPath As String
    Dim fileName As String
    Dim wb As Workbook
    Dim ws As Worksheet
    Dim cell As Range
    Dim rng As Range
    Dim fDialog As FileDialog

    ' フォルダ選択ダイアログ
    Set fDialog = Application.FileDialog(msoFileDialogFolderPicker)
    fDialog.Title = "処理するフォルダを選択してください"
    If fDialog.Show <> -1 Then
        MsgBox "キャンセルされました。", vbExclamation
        Exit Sub
    End If
    folderPath = fDialog.SelectedItems(1) & "\"

    fileName = Dir(folderPath & "*.xls*")

    Application.ScreenUpdating = False
    Application.DisplayAlerts = False

    Do While fileName <> ""
        On Error Resume Next
        Set wb = Workbooks.Open(folderPath & fileName, ReadOnly:=False)
        If wb Is Nothing Then
            MsgBox "開けないファイルがあります：" & fileName, vbExclamation
            fileName = Dir
            On Error GoTo 0
            Continue Do
        End If
        On Error GoTo 0

        For Each ws In wb.Sheets
            Set rng = Nothing
            On Error Resume Next
            Set rng = ws.UsedRange
            On Error GoTo 0

            If Not rng Is Nothing Then
                For Each cell In rng
                    If Not IsEmpty(cell) Then
                        If cell.Font.Color <> RGB(0, 0, 0) Then
                            cell.Font.Color = RGB(0, 0, 0)
                        End If
                    End If
                Next cell
            End If
        Next ws

        wb.Close SaveChanges:=True
        fileName = Dir
    Loop

    Application.ScreenUpdating = True
    Application.DisplayAlerts = True

    MsgBox "必要なセルのみ黒字化が完了しました。", vbInformation
End Sub
転職時の変更　リンク解除後のPlayGroundのアドレスについて



# 転職時の変更　リンク解除後のPlayGroundのアドレスについて

+ [リンク解除後のPlayGroundのアドレスについて](https://trailhead.salesforce.com/ja/trailblazer-community/feed/0D54S00000NPuwc)

サポートへ問い合わせを行ったところ、本件はグローバルでの対応となるとのことでした。
英語で問い合わせを行ったところ、下記のような回答がありましたので共有させていただきます。

▼ステップ1：Eメール " 個人のGmail "でTrailheadにログインする。
設定ページを開き、「メールアカウント」で新しいメールアドレス（私はYahooアドレスを使いました。）を入力し、ログアウトします。

▼ステップ2：ステップ1で接続/追加した新しいメールアドレスでTrailheadにログイン > 設定ページに移動 > 「メール」、「Google」、「gmail.com」の接続を解除し、ログアウトします。

▼ステップ3："PlayGroundで表記されないアドレス"で新しいトレイルヘッドアカウントを作成します。
設定ページに移動し、メールアカウントの下にステップ1の新しい電子メールを接続します。
アカウントをマージした後、新しい電子メールアドレスを削除、" 個人のGmail "のみにします。

本操作後にPlayGroundにログインしたところ、無事解決いたしました。

 

★考慮すべき点として、
1.参加していたコミュニティはすべて消えてしまいました。
2.プロフィール画像が消えてしまいました。
操作前にコミュニティは控えておくべきかと思います。


# 質問

+ [I switched companies and my playground email defaults to my prior company email](https://trailhead.salesforce.com/trailblazer-community/feed/0D5KX00000SXT0D0AX)


:::note
Please check this article. 
https://trailhead.salesforce.com/trailblazer-community/feed/0D54S00000BqLZ8SAN

https://trailhead.salesforce.com/trailblazer-community/feed/0D54S00000A8qLzSAJ
:::
【データ分析基盤】SnowflakeのCoreProを受けての後学のための振り返り〜

## SnowflakeCoreProを受験
snowflakeの認定試験の登竜門である`SnowPro Core`を受けてきた際の後学の為の備忘メモを残しておきます。

## 振り返りが必要な項目について
### フェデレーション認証とは？
定義：
SAML/OAuth 経由で Okta, Azure AD など IdP と Snowflake を連携する方式
特徴：
ユーザー認証は Snowflake ではなく IdP が行う
ログイン時は IdP の認証画面に遷移する（SSO、外部ブラウザ認証など）
SnowSQL では --authenticator externalbrowser を指定して起動

### セキュアビューとは？
意図：
データのロジックやメタデータを秘匿化
ビューの中身を他ユーザーが確認できない（EXPLAIN でも不可）

違い：
通常ビューは内部構造や参照テーブルが見える
セキュアビューはセキュリティ上安全なマスキングの一種

### PUT / COPY INTO / GET の違い

| コマンド      | 用途                         |
| --------- | -------------------------- |
| PUT       | ローカル → ステージ（アップロード）        |
| COPY INTO | ステージ → テーブル or テーブル → ステージ |
| GET       | ステージ → ローカル（ダウンロード）        |


Snowflakeからのアンロード／エクスポート
COPY INTO @stage FROM table_name を使用

例：
```sql.sql
COPY INTO @my_stage/data_ 
FROM my_table 
FILE_FORMAT = (TYPE = 'CSV');
GET でローカルにダウンロード可能
```

### OPERATE と USAGE の違い
| 権限      | 内容                                                 |
| ------- | -------------------------------------------------- |
| USAGE   | オブジェクトの「存在確認・参照」が可能。操作はできない                        |
| OPERATE | Warehouse や Task などの実行操作（Resume/Suspend や開始/停止）が可能 |


### FLATTEN と LATERAL の使い方
FLATTEN：ARRAY や VARIANT のネストデータを行単位に展開

LATERAL：FLATTEN した行を他の列と一緒に結合するために使う

SELECT id, f.value
FROM json_table,
LATERAL FLATTEN(input => json_table.data) f;

### 浮動小数が扱えるフォーマット
Parquet, Avro, ORC
Snowflake が扱うデータ形式のうち、浮動小数点数に適した形式
アンロード時の FILE_FORMAT に指定可能



### クエリプロファイルの見方（重要）
https://blog.truestar.co.jp/snowflake/20221130/52144/

| 項目                 | 内容                            |
| ------------------ | ----------------------------- |
| Time (ms)          | ステップごとの処理時間（遅延特定に重要）          |
| Rows               | 処理された行数（大量に処理される箇所を特定）        |
| Bytes scanned      | スキャンされたデータ量（マイクロパーティションの無駄確認） |
| Partitions scanned | クラスタリングとフィルタの効き具合の指標          |

### VARIANT の最大値
1セルあたり最大 16MB（非圧縮）
深いネストは最大 100 階層まで

### ドライバーのバージョン確認方法
snowflakeのバージョンを格にする方法もあるので、下記に整理しておく。
| ツール     | 方法                                                  |
| ------- | --------------------------------------------------- |
| SnowSQL | `snowsql -v`                                        |
| JDBC    | `SnowflakeDriver.class.getVersion()` など Java コードで確認 |
| Web UI  | Snowsight > Help > About（バージョン確認）                   |


### 仮想ウェアハウスが詰まる原因と対処法
症状：
複数プロセスが同時に実行 → キューが溜まり遅くなる
時間が経てば自然回復することもあるが、それは一時的な対応に過ぎない

正しい対応方法：

| 対処方法                | 推奨度 |
| ------------------- | --- |
| JOINの見直し・クエリ最適化     | ◎   |
| ウェアハウスのサイズを上げる      | ◎   |
| マルチクラスターを設定しクラスター追加 | ◎   |
| SELECT句の最適化（不要列削除）  | ◯   |
| 放置して時間解決を待つだけ       | ✕   |

### 非相関・相関のサブクエリ
Snowflakeにおいてもサブクエリ発行時に非相関・相関のサブクエリの考え方がもちろんあるのでサブクエリの考え方は押さえておきたい。
簡単にイメージで説明すると
非相関サブクエリは、呼び出し元とサブクエリ内で参照しあっていない(=`相関がない`)、一方で相関サブクエリは、サブクエリ内で呼び出し元のテーブルなどが参照されている(=`相関しあっている`)と言うイメージになるかと思う。

下記がわかりやすくまとめられている。

https://note.com/rimi_ai/n/nbe68bac1826f

### タグについて
snowflakeには、スキーマレベルのオブジェクトとしてタグをつけることができるとのことで、概念については覚えておきたい。
https://docs.snowflake.com/ja/user-guide/object-tagging
Salesforceでシステム管理者でカスタムメタデータ型を削除しようとするとアクセス権がありませんエラー

同じチームの他の方が消してくれたのでその方からの情報を和訳してここに記しておく

#### Troubleshooting Steps（トラブルシューティング手順）

##### Translation Workbench（翻訳ワークベンチ）を有効化：

1. 設定に移動します。
1. 「翻訳言語設定（Translation Language Settings）」を検索します。
1. 翻訳ワークベンチ（Translation Workbench）で「有効化」をクリックします。
1. いずれかの言語をアクティブにして、自分自身に割り当てます。
1. 保存します。
1. カスタムメタデータの削除をもう一度試みます。
1. 削除に成功したら、翻訳ワークベンチを無効化しても問題ありません。

#### Common Causes（よくある原因）

##### Translation Workbench（翻訳ワークベンチ）：

これはよくある原因です。翻訳ワークベンチがカスタムメタデータの削除を妨げることがあり、管理者でも影響を受ける場合があります。
取り消し線調査

Sub FindStrikethroughCellsInFolder()
    Dim folderPath As String
    Dim fileName As String
    Dim wb As Workbook
    Dim ws As Worksheet
    Dim cell As Range
    Dim rng As Range
    Dim fDialog As FileDialog
    Dim resultRow As Long
    Dim resultWb As Workbook
    Dim resultWs As Worksheet

    ' 結果記録用ブックを作成
    Set resultWb = Workbooks.Add
    Set resultWs = resultWb.Sheets(1)
    resultWs.Range("A1:D1").Value = Array("ファイル名", "シート名", "セル", "値")
    resultRow = 2

    ' フォルダ選択ダイアログ
    Set fDialog = Application.FileDialog(msoFileDialogFolderPicker)
    fDialog.Title = "処理するフォルダを選択してください"

    If fDialog.Show <> -1 Then
        MsgBox "キャンセルされました。", vbExclamation
        Exit Sub
    End If

    folderPath = fDialog.SelectedItems(1) & "\"
    fileName = Dir(folderPath & "*.xls*")

    Application.ScreenUpdating = False
    Application.DisplayAlerts = False

    Do While fileName <> ""
        Set wb = Workbooks.Open(folderPath & fileName, ReadOnly:=True)

        For Each ws In wb.Sheets
            On Error Resume Next
            Set rng = ws.UsedRange.SpecialCells(xlCellTypeConstants)
            On Error GoTo 0
            
            If Not rng Is Nothing Then
                For Each cell In rng
                    If cell.Font.Strikethrough = True Then
                        resultWs.Cells(resultRow, 1).Value = wb.Name
                        resultWs.Cells(resultRow, 2).Value = ws.Name
                        resultWs.Cells(resultRow, 3).Value = cell.Address
                        resultWs.Cells(resultRow, 4).Value = cell.Value
                        resultRow = resultRow + 1
                    End If
                Next cell
            End If
        Next ws

        wb.Close SaveChanges:=False
        fileName = Dir
    Loop

    Application.ScreenUpdating = True
    Application.DisplayAlerts = True

    MsgBox "取り消し線セルの検索が完了しました。", vbInformation
End Sub
Pointers and Arrays 3, Multidimension, p.57 




```c:pa3.c
// Pointers and Arrays 3, Multidimension, p.57 
// https://qiita.com/kaizen_nagoya/items/cbb0ab7b914b513d62e8
#include "defs.h"

int a[3][3] = {
        { 1, 2, 3 },
        { 4, 5, 6 },
        { 7, 8, 9 }
};
int *pa[3] = {
        a[0], a[1], a[2]
};
int *p = a[0];

void main(void)
{
        int i;

        for( i=0; i<3; i++ )
                PRINT3(d, a[i][2-i], *a[i], *(*(a+i)+i) );
        NL;

        for( i=0; i<3; i++ )
                PRINT2(d, *pa[i], p[i] );
}

```
```shell-session:bash
inst19@teachB:~$ gcc pa3.c
inst19@teachB:~$ ./a.out
a[i][2-i] = 3   *a[i] = 1       *(*(a+i)+i) = 1
a[i][2-i] = 5   *a[i] = 4       *(*(a+i)+i) = 5
a[i][2-i] = 7   *a[i] = 7       *(*(a+i)+i) = 9

*pa[i] = 1      p[i] = 1
*pa[i] = 4      p[i] = 2
*pa[i] = 7      p[i] = 3
```
タブ・スペース診断ツール indent-doctor

ちょっとコード変更してフォーマッターかけたら差分が全行になって困ったことありますか？私はよくあります...。

タブ・スペースにこだわりもなく、統一規約のある開発体制にいないので、ついついコードエディタのデフォルトで書き始めてしまったり、他に人から引き継いだコードをフォーマッターONでセーブすると大変なことになります。

ということで、タブスペースを判定する`indent-doctor`というパッケージを作ってみました。

判定するだけでなく、biomeとvscode形式で設定を出力することができます。これで、チェックして保存しておくと、以降はフォーマットを統一することができます。

## 特徴

- タブ、スペース、混在インデントを検出
- スペースインデントのサイズを自動判定
- Biome、VSCode形式での設定出力に対応
- 標準入力からの読み込みにも対応

## 使用方法

### npx

`npx indent-doctor [file_name]`

### bun

`bunx indent-doctor [file_name]`


### 出力結果（標準）

```
=== Indent Analysis Results ===

Indent Type: Spaces
Indent Size: 2 spaces

--- Statistics ---
Total Lines: 10
Indented Lines: 8
  - Spaces: 8 lines
  - Tabs: 0 lines
  - Mixed: 0 lines

--- Recommendations ---
✅ Indentation is consistent using Spaces.
```

### オプション

以下の出力フォーマットに対応しています。

- `-f biome` Biome Config形式
```
{
  "$schema": "https://biomejs.dev/schemas/1.8.3/schema.json",
  "formatter": {
    "enabled": true,
    "formatWithErrors": false,
    "indentStyle": "space",
    "indentWidth": 2,
    "lineEnding": "lf",
    "lineWidth": 80,
    "attributePosition": "auto"
  }
}
```

- `-f vscode` VSCode setting形式

```
{
  "editor.insertSpaces": true,
  "editor.tabSize": 2,
  "editor.detectIndentation": false
}
```

## URL

https://www.npmjs.com/package/indent-doctor

## メモ

- 自分用ツールですが類似のツールが見当たらないのと、パッケージとして公開をしてみたかったので勉強がてら作ってみました
- テストが完全とは言い難いですが、何かダメパターンがあれば教えてください
黒字化

Sub MakeAllSheetsFontBlackInSelectedFolder()
    Dim folderPath As String
    Dim fileName As String
    Dim wb As Workbook
    Dim ws As Worksheet
    Dim fDialog As FileDialog

    ' フォルダー選択ダイアログを表示
    Set fDialog = Application.FileDialog(msoFileDialogFolderPicker)
    fDialog.Title = "処理するフォルダを選択してください"
    
    If fDialog.Show <> -1 Then
        MsgBox "キャンセルされました。", vbExclamation
        Exit Sub
    End If
    
    folderPath = fDialog.SelectedItems(1) & "\"

    ' ファイル取得と処理
    fileName = Dir(folderPath & "*.xls*")
    
    Application.ScreenUpdating = False
    Application.DisplayAlerts = False
    
    Do While fileName <> ""
        Set wb = Workbooks.Open(folderPath & fileName)
        
        For Each ws In wb.Sheets
            ws.Cells.Font.ColorIndex = 1 ' 黒字
        Next ws
        
        wb.Close SaveChanges:=True
        fileName = Dir
    Loop
    
    Application.ScreenUpdating = True
    Application.DisplayAlerts = True
    
    MsgBox "すべてのファイルの全シートを黒字化しました。", vbInformation
End Sub