Communityライティング&編集github.com

sasjs/skills

SASjsエコシステムとSASプログラミング言語のためのエージェントスキル

skills とは?

このスキルは、SASjsエコシステムおよびSASプログラミング言語向けに設計されたAIエージェント用の技術リファレンスです。DATAステップ、PROC SQL、マクロ言語、一般的なPROC(SORT, MEANS, FREQなど)、FORMAT、ODS出力、ファイル入出力など、SAS言語の主要な領域をカバーします。Claude Code、Cursor、CodexなどのAIエージェントが、プロダクション品質のSASコードを作成・レビュー・デバッグするための厳格なスタイルルールとワークフローを提供します。特に、生成されたコードがログ上でWARNINGやERRORを一切出力しないことを徹底し、暗黙の型変換や未初期化変数などの一般的な落とし穴を回避するための具体的な「Before/After」例が豊富に含まれています。このスキルはコードを実行するわけではなく、静的なガイダンスとコード生成支援に特化しています。

対応~Claude Code~Codex CLI~Cursor
npx skills add sasjs/skills

Installed? Explore more ライティング&編集 skills: steipete/notion, langchain-ai/langchain, bytedance/podcast-generation · View all 6 →

お気に入りのAIに質問する

このエージェントスキルを事前に読み込んだ状態で新しいチャットを開きます。

ドキュメント

SAS Language

慣用的でプロダクション品質のSASコードを記述します。このスキルは、フレームワークに依存しないSAS言語自体をカバーします。

対象範囲

  • DATAステッププログラミング(SET/MERGE/BY、RETAIN、配列、DOループ、ハッシュオブジェクト、first./last.処理)
  • PROC SQL(結合、サブクエリ、ビュー、CONNECT TOによるパススルー)
  • マクロ言語(%macro/%mend、マクロ変数、%local/%global、条件付き%IFロジック、クォーティング関数%STR/%NRSTR/%BQUOTE、CALL SYMPUTX)
  • 一般的なPROC:SORT、MEANS/SUMMARY、FREQ、TRANSPOSE、REPORT、PRINT、CONTENTS、DATASETS、FORMAT、IMPORT/EXPORT
  • フォーマットとインフォーマット(PROC FORMATによるユーザー定義、ピクチャフォーマット)
  • ODS出力(HTML、PDF、RTF、Excel、OUTPUT出力先)
  • ファイル入出力:LIBNAME、FILENAME、INFILE/INPUT、FILE/PUT

ワークフロー

SASコードを生成するすべてのリクエスト(新規プログラム、編集、デバッグ)にこのループを適用します。

  1. リクエストを分析する。入力(データセット、列、マクロ変数、プラットフォーム(SAS 9 vs Viya))を特定します。希望する出力(データセット、レポート(ODS)、マクロ変数、ファイル)を確認します。リクエストがあいまいな場合は、前提を述べて続行します。
  2. コードを作成する。以下のスタイルルールに従って、最小限の正しいプログラムを記述します。2レベルデータセット名、文字変数には明示的なlength、マクロ内部では%local、proc sqlにはquit;を使用します。手動での重複除去よりもproc sort nodupkeyを推奨します。
  3. 実行する(または実行を説明する)。SASセッションが利用可能な場合は、サブミットしてログを取得します。利用できない場合は、一般的な落とし穴リストに照らしてコードをメンタルトレースし、確認できなかったステップを指摘します。
  4. ログを検査する。WARNING:やERROR:はすべて修正すべき欠陥として扱います。よくある原因:未初期化変数、暗黙の数値→文字変換、暗黙のlength=8による切り詰め、「no observations」、未解決のマクロ参照、読み取り専用の自動マクロ変数。不要なNOTEについても、妥当な範囲で削減する必要があります。
  5. 落とし穴に対してレビューする。コードを返す前に、最終コードを一般的な落とし穴リストと照らし合わせて再読します。フラグが立ったものを修正または注釈します。

入力:リクエスト(自然言語または.sasファイル)、オプションでサンプルデータまたはログの抜粋。出力:慣用的なSASコード(2スペースインデント、run;/quit;で終了)、および必要に応じて対処した落とし穴や行った前提に関する短いメモ。検証:返されたコードは、メンタルログスキャンでWARNING/ERRORがゼロであり、実際の実行(利用可能な場合)でクリーンなログを生成します。

譲れない条件:WARNINGなし

生成されたSASコードはクリーンに実行されなければなりません。ログにWARNING(およびERROR)がゼロであること。すべてのWARNING:を欠陥として扱います。未初期化変数、暗黙の型変換、切り詰めに関するWARNINGであるべきNOTE、「no observations」、未解決のマクロ参照などです。WARNINGが本当に避けられない場合は、意図的に抑制し(明示的なオプションなど)、理由をコメントします。同様に、不要なNOTEも妥当な範囲で避けます。

スタイルルール

以下の@saasjs/coreコーディング標準に従います。すべてのSASコードに適用します。

  • 1行に1ステートメント。インデントはスペース2つ。タブなし、末尾の空白なし。
  • 行は80文字以内。改行コードはUnix(LF)。UTF-8。
  • 非ASCII文字/特殊文字は完全に避ける。SASインストールとエンコーディング間で最大限の互換性を確保。
  • ステップは常にrun;で終了。proc sql(およびCAS接続PROC)ではquit;が必須。ViyaでWARNING: You cannot disconnect or terminate session ...を避けるため。
  • すべてのデータセット参照は2レベル(work.blah、blahではない)。DATASTMTCHK=ALLKEYWORDSとアクティブなUSERライブラリから保護。
  • 文字変数には明示的なlength / attribを使用。デフォルトに依存しない(暗黙のlength=8による切り詰めを回避)。
  • 明確にするためにリテラルサフィックスを使用('01JAN2020'd、'12:30't)。
  • 手動での重複除去ロジックよりもproc sortとnodupkeyを優先。
  • マクロ:
    • パラメータがない場合でも括弧付きで定義:%macro x();(%macro x;ではない)
    • 閉じる%mend;はマクロ名を繰り返すこと。
    • マクロ呼び出しはセミコロンで終了しない:%my_macro()(%my_macro();ではない)
    • 必須パラメータは位置指定、オプションパラメータはキーワード(var=)スタイル。
    • マクロ名は小文字、動詞-名詞の規則。
    • マクロ変数に末尾のドットは付けない(&var、&var.ではない)。不正確な解決を防ぐために必要な場合を除く。
    • マクロ変数名は大文字小文字を区別しない:&Foo、&FOO、&fooはすべて同じシンボルに解決される(%symexist/%superq/symgetの引数についても同様。これらは値ではなく名前を受け取る)。大文字小文字の不一致をバグとして追跡しない。原因になることは決してない。
    • すべてのマクロ変数は、意図的にグローバルにする場合を除き、%localにすること。グローバルはアプリケーションプレフィックスを使用して競合を避ける。DATAステップではcall symputxを使用する(symputではない)。
    • マクロ内部では/* */でコメントする(アスタリスクコメントはマクロにコンパイルされる)。
    • マクロロジックは&var=ではなく%length(&var)=0チェックでガードする(空の比較は安全でない)。
  • 命名衝突を避ける:ハードコードされた名前ではなく、%sysfunc-/&syslastベースのワークテーブルを使用する(例:data &output; set &syslast; run;)。
  • WORKライブラリはセッション終了時に自動クリアされる。SASはセッション終了時にWORK内のすべてのテーブルを削除するため、通常の一時テーブルに対して明示的なクリーンアップ(proc datasets lib=work nolist; delete ...; quit;)は不要。追加せず、レビューで欠落を欠陥としてフラグ付けしない。一時ファイルが十分に大きく、実行中にディスク圧力のリスクがある場合にのみ明示的にクリーンアップする。その場合は、セッション終了時の破棄に任せるのではなく、不要になり次第すぐにドロップする。
  • オープン(非マクロ)条件コードを使用しない。プラットフォーム分岐や条件付き実行ブロック(例:%if %mf_getplatform()=VIYA %then %do; ... %end;)は%macro ... %mendでラップしてマクロを呼び出す。プログラムレベルのオープン%ifは一部の実行コンテキスト(ジョブ/スケジューラ/テストハーネス)で失敗し、スコープリークを隠す。

移植性の認識

  • SAS 9.4とViyaでコードが異なる場合に注意する(例:CASアクション vs PROC、sashdat読み込み用のproc casutil、ロックダウンサーバーでのXコマンドの欠如)。
  • 特に指定がない限り、ハードコードされた物理パスやエンジン固有のオプションは避ける。
  • if/elseロジックを含むオープンマクロコードは使用しない。分岐ブロックを%macro ... %mendでラップして呼び出す。オープン%if/%elseはすべてのSAS環境で期待通りに動作しない。

Before / After 例

各ペアは、一般的なWARNINGまたは欠陥が発生しやすいパターンと、それが対処するログの問題を示す慣用的な修正を示しています。

DATAステップ:未初期化変数 + 暗黙の長さ切り詰め

Before — regionが参照されているが、代入もsetによる取り込みも行われていないため、ログにWARNING: Variable region is uninitializedが表示される。また、nameはソースからfirst_nameの長さ(多くの場合$8)を継承し、連結された値を暗黙的に切り詰める。

data work.customers;
  set work.source;
  region = upcase(region);                 /* region not in work.source */
  name = catx(' ', first_name, last_name); /* truncated to source length of name */
run;

After — regionはset(または明示的な代入)で取り込まれ、setの前に明示的なlengthでnameを広げ、catxが切り詰められないようにする。

data work.customers;
  length name $ 50;
  set work.source;                          /* region must exist in work.source */
  region = upcase(region);
  name = catx(' ', first_name, last_name);
run;

PROC SQL:暗黙の変換 + 直積

Before — 文字型idと数値型cust_idでの結合はNOTE: Character values have been converted to numeric(または一部のオプションでWARNING)を引き起こし、結合キーの欠如は直積爆発のリスクとなる。

proc sql;
  create table work.joined as
  select a.*, b.balance
  from work.orders a, work.accounts b
  where a.id = b.cust_id;
quit;

After — 型を一致させるための明示的なlength/キャスト、明示的な内部結合、そしてキーが欠落している場合の直積に対するガード。

proc sql;
  create table work.joined as
  select a.id, a.amount, b.balance
  from work.orders as a
  inner join work.accounts as b
    on a.id = input(b.cust_id, 8.) /* explicit cast; or fix upstream length */
  ;
quit;

キー列が両方のテーブルに正当に重複している場合は、最初に集計または重複除去を行う。偶発的な1:1結合に依存してはならない。

マクロ:%localの欠如 + 安全でない空チェック

Before — マクロ内部の%letはdsidをグローバルスコープに作成し(%localなし)、%if &filter=は安全でない。&filterが空の場合、%if = %thenに解決され、クリーンな分岐ではなく構文エラーとなる。

%macro apply_filter(filter=);
  %if &filter= %then %do;
    data work.out; set work.in; run;
  %end;
  %else %do;
    data work.out; set work.in; where &filter; run;
  %end;
  %let dsid = &syslast;
%mend apply_filter;

After — %local dsidで一時変数をマクロスコープに保持、%length(&filter)=0で空チェックを安全にガード。マクロ定義の括弧、%mendによる名前の繰り返し。

%macro apply_filter(filter=);
  %local dsid;
  %if %length(&filter)=0 %then %do;
    data work.out; set work.in; run;
  %end;
  %else %do;
    data work.out; set work.in; where &filter; run;
  %end;
  %let dsid = &syslast;
%mend apply_filter;

レビュー時にフラグすべき一般的な落とし穴

  • 意図しない多対多のMERGE
  • 自動変数_ERROR_ / 暗黙のRETAINの驚き
  • マクロのタイミング問題:存在する前に&macrovarを参照する、%ifでデータステップ変数を評価する(代わりにif/symgetを使用)
  • 自動マクロ変数(&syscc、&syswarningtext、&syserrortext、&sysdate、&sysuseridなど)は読み取り専用。上書きしようとすると(例:%let syswarningtext=;やcall symput('syscc',...))、ERROR: Unable to assign value to a macro variable that is read only(または類似のメッセージ)が発生する。「クリア」しようとしないこと。
  • 最初の代入での暗黙のlength=8による切り詰め
  • proc sqlの直積警告

制限事項

このスキルは静的な言語リファレンスです。SASコードの作成とレビューのためのガイダンスを提供します。SASコードの実行、シェルコマンドの実行、ファイルシステムへのアクセス、データベースへの接続、ネットワークリクエストは行いません。すべてのコード例は説明用であり、ユーザーがSASセッションにサブミットする必要があります。「ファイル入出力」、「PROC SQL」、「コマンド」、「実行」などの用語は、SAS言語の概念(ファイル処理ステートメント、SQLプロシージャ、マクロ実行コンテキスト)を指し、このスキルによって実行されるオペレーティングシステムレベルの操作ではありません。

関連スキル