SAPジョブとバックグラウンド実行における基礎知識とTIPS [Fundamental knowledge and tips about SAP Job and program execution in background]

こんにちは。

今回は、SAPジョブ関連のTIPS集的なものをまとめてみました。開発者の方だけでなく、受け入れテストや結合テストを行う設計者・コンサルの方にも有用な情報になるかと思います。

## 内容

- SAPジョブとは

- プログラムのバックグラウンド実行とは

- TIPS

## SAPジョブとは

SAPジョブとは、指定した **実行条件** を満たした場合に、指定した **プログラム** を事前に指定した **設定内容（バリアント）** で実行し、結果を  **出力先** に出力する処理のことです。

SAPジョブを登録する際に必要な内容は以下のとおりです（✓：必須）

| 名称 | 必須 | 説明 |
|:-:|:-:|:-:|
|プログラムID|✓|実行するプログラムIDを設定|
|バリアント|   |プログラムの選択条件値を保存したもの|
|出力デバイスと出力設定|✓|処理結果の出力先と出力設定。ステップ単位で設定|
|実行条件|✓|処理を開始する条件。ジョブ単位で設定|

ジョブには、実行するプログラムとバリアント・出力デバイスを、 **ステップ（ステップ）** 単位で定義することができます。ジョブ単位で実行条件が設定でき、その条件を満たすとジョブが実行され、ステップの定義順に従って処理を実行していきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/326392/41ace712-3317-ff80-7dad-47a5049873c7.png)

**出力デバイス** はスプールデータを紙面などに出力する際に使用するデバイスのことで、主にプリンタなどを設定します。ジョブ実行は常に出力デバイスの設定が必須となるため、スプールへのデータ作成が不要な場合は、SAPシステム上にのみ設定する論理的な出力デバイス（「LP01」など）を設定することが多いです。

**スプール依頼** の設定のうち、ジョブに関連のあるところに絞ると以下のような設定が可能です。

| 項目 | 説明 |
|:-:|:-:|
|印刷時刻|出力内容を即時で出力デバイスに出力する or スプール依頼にのみ出力する or 両方|
|印刷後削除|出力デバイスへの出力後にスプール依頼データを自動で削除するか|
|スプール保存期間|スプール依頼データを何日間保持するか。最大8日までの1日刻み or 削除しない|
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/326392/c9dbbce9-a705-7d8f-ffb7-a5e2c29f4574.png)

ジョブは、処理結果（内容）を以下の2つの方法で出力できます。
プロジェクトにより多少傾向が異なることもありますが、私の経験上では下記のような違いがあると考えています。

* **ジョブログ：** 処理件数・成功件数・エラー件数・エラーメッセージといった、主に運用保守担当者がジョブのエラー内容などを確認するための内容
* **スプール依頼：** ジョブの出力内容を記録するSAPシステム上のデータ領域。 **出力デバイス** とその出力設定に従って出力される。帳票や結果一覧など、業務メンバーが業務遂行のために利用する内容が出力される

**実行条件** については下記のとおりです。バックグラウンドイベントについては過去アドオンでの利用事例を把握していません。「周期」は1日に1回、月に1回実行するなどの **周期ジョブ（サイクリックジョブ）** を設定する場合に使用します。

| 実行条件 | 起動するタイミング |
|:-:|:-:|
|即時|ジョブが登録された時点|
|時間|指定した実行日時が到達した時点|
|先行ジョブ|指定したジョブが終了した時点|
|イベント|指定したバックグラウンドイベントが呼び出された時点|
|周期|実行時間と日次・週次などの周期の組み合わせ|


登録されたジョブは以下のような **ステータス** を持ちます。

| ジョブステータス | 意味 |
|:-:|:-:|
|計画済(Scheduled)|ジョブが登録された|
|リリース済(Released)|登録されたジョブがリリースされ実行可能になった|
|実行中(Active)|処理実行中|
|中止(Canceled)|処理中のエラー発生、ユーザやシステムによる中止で処理が中断した|
|終了(Finished)|処理を終了（完了）|

ジョブは登録処理が始まると、登録が完了する前から **計画済** で登録されます。実行条件を設定された後でジョブが保存されると **リリース済** 、処理が実行されると **実行中** になります。処理が正常に終了した場合は **終了** 、処理が中断した場合は **中止** となります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/326392/8b7250a8-0d8b-b8da-3cd9-4580ee09e07f.png)

ジョブが登録されると、人間が設定したジョブを内部で識別するための番号をSAPが内部採番します。それが「ジョブID」です。登録するときに人間設定、もしくはプログラムIDが採用されるのが **ジョブ名** で、それに紐づけるため、SAPが内部で自動採番する番号が **ジョブNo.** です。ジョブNo.の確認方法は以下のとおりです。
**手順：** トランザクションSM37から対象ジョブのジョブ名をダブルクリック、またはカーソルを置いて、ジョブ詳細ボタンをクリック。ジョブの照会画面に遷移します。さらにジョブ詳細ボタンをクリックします。表示された画面で、 **「ID」** と表示されている項目の数字がジョブNo.となります（ここだけ「ID」なのはややこしいので、名称は統一してほしいですね）。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/326392/263e4d08-2863-e52e-de4d-cf6717b7122a.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/326392/2faaaa12-82a7-309d-5ac8-6bd39fe2b722.png)

なお、ジョブNo.はトランザクション：SM37のジョブ一覧にレイアウト変更を使って表示することが可能です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/326392/5942e0d4-8c4e-9a25-8690-6af971a6fac5.png)

## プログラムのバックグラウンド実行とは

ジョブとして、SAPプログラムをバックグラウンド実行する仕組みの説明をしましたが、ここでは、SAPプログラムを **バックグラウンド実行する** ことでジョブとして登録し実行する方法について説明します。「プログラムのバックグラウンド実行」はSE38第1画面・プログラムの選択画面からそれぞれ実行でき、機能が異なります。比較としてSM36のジョブ実行の場合についても記載します（✓：可能、✕：不可能）。

| 実行条件 | SE38第1画面から | プログラム選択画面から | SM36からのジョブ登録（参考） |
|:-:|:-:|:-:|:-:|
|ジョブ名指定|✓（後述）|実行プログラムID固定|✓|
|バリアント指定実行|✓|バリアント内容を選択画面に呼び出すことで可能|✓|
|ジョブステップの定義数|1のみ|1のみ|複数可能|
|ステップに使用バリアントを記録|✓|✕|✓|
|実行条件：即時実行|✓|✓|✓|
|実行条件：時間|✓|✓|✓|
|実行条件：先行ジョブ|✕|✓（後述）|✓|
|実行条件：イベント|✕|✓|✓|
|実行条件：実行周期|✓|✓|✓|

### SE38の第1画面からバックグラウンド実行

トランザクションSE38にて実行したいプログラムIDを指定の上、メニューバーの
**（追加）>プログラム>実行>バックグラウンド** を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/326392/082b9077-c118-22f4-4728-32b04a7a3c34.png)

以下の画面に到達しますので、レポート名（プログラム名）と、バリアント名を指定し、即時実行またはスケジュールをクリックします。即時実行の場合はそのとおりすぐにジョブが実行されます。スケジュールをクリックした場合は以降で実行日時や周期の設定を行います。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/326392/305dc353-cf78-29c7-75ee-1c64bd3d9746.png)

### プログラムの選択画面からバックグラウンド実行

プログラムを実行後の選択画面から、選択画面項目への入力またはバリアントを適用後、
**（追加）>プログラム>バックグラウンド実行**
と選択します。以降は、トランザクション：SM36でジョブステップを登録したのと同じ要領で、バックグラウンド実行を登録することが可能です。前述のとおり、１ジョブにつき１ステップ（１プログラム）のみの設定が可能となっています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/326392/d4f1bcc9-fb53-203d-0b7b-3c6eff82f681.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/326392/d250bd2c-3761-5c30-a670-086889088458.png)

## TIPS

以降、ジョブ関連の作業を行っていて判明した手法や、SNSで教えていただいた内容について記載していきます。

#### バックグラウンド実行でも、ジョブ名を設定できる
バックグラウンド実行時はプログラムIDがジョブ名に設定され変更できない、と長年思っていたのですが、以下の手順でバックグラウンド実行時にもジョブ名を設定できることを知りました。この内容をTwitterでツイートしたところ私と同様に「知らなかった」という方がいらっしゃいましたので記載しておきます。

**手順：** SE38の **第1画面からのバックグラウンド実行** を行い、 **スケジュール** を選択する。画面に「JobName」という項目がありジョブ名を設定することができる

プログラムのバックグラウンド実行を行う場合は即時実行で行うことが多く、この画面を見ることがなかったというのが見つけることが難しかった理由かと思いますが、SM36でなくてもジョブ名を設定できるのであれば、即時実行の場合にもジョブ名を設定できるようにしてほしいですよね。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/326392/4937af11-cb61-a339-9d31-b4eba7ea4fbc.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/326392/3a7f9170-8650-d97d-850e-d94723c59022.png)

#### バックグラウンド実行でも、処理の連続実行ができる
１つのジョブでプログラムを複数連続で実行したい場合は、ジョブのステップで設定すれば定義できることは上述したとおりですが、実はバックグラウンド実行でも同様の処理の連続実行が可能です。 **SM36を使えばジョブステップで定義できるんでしょ、なら意味なくね？** 、と思った方、 **もう本当そのとおりっす** :sweat:。顧客側の諸事情にて、SM36でのジョブ登録が使用できない中、大量のプログラムをジョブ実行する必要がある、というレアな条件の元で見つけた方法です。

**手順１：** 事前に先行ジョブを計画済またはリリースのステータスにしておく。 **選択画面からのバックグラウンド実行** を行い、実行条件で **「ジョブ後」** を選択する。ポップアップ画面からジョブ名を指定し、チェックまたは保存ボタンをクリックする。
※ **「ステータス依存開始」** にチェックを入れた場合、**先行ジョブが完了ステータスで終了した場合にのみ当ジョブが実行される** （先行ジョブが中止ステータスで終了した場合は当ジョブが実行されない）。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/326392/0c036dc6-57d0-233c-c7b0-7971395a35de.png)

**手順２：** 指定されたジョブ名と同じジョブ名であり、ステータスが **計画済** または **リリース** のジョブが複数ある場合は、さらにポップアップ画面が表示される。ジョブ名とジョブNo.から対象ジョブを確認し、行にカーソルを合わせ続行ボタンをクリックすることで先行ジョブを指定する。
※手順１にてチェックボタンをクリックしてこの画面に入った場合は、続行ボタンをクリック後、保存ボタンをクリックしてジョブを保存する必要がある。

**注意点：**
１．上記のスクリーンショットにて先行ジョブを2ジョブのうち1つから選択するように表示されていますが、先行ジョブと自身のジョブで同一プログラムが実行される場合、 **最上位行の内容は自身のジョブ** が表示されます（この時点で計画済ステータスでジョブが登録されていることが理由と思われます）。これを選択するとジョブを連続実行することができないので注意してください。
２．バックグラウンド連続実行の際は本来、自身のジョブNoが一番上に表示され、以降はジョブNo.が古い順から昇順に並びます。そのため表の最後部は自身の1つ前のジョブになるはずなのですが、この並び順が崩れる場合があります。再現方法や対応Noteがあるかは確認していませんが、必ず下記に記載しているテーブル：TBTCOにてジョブが想定どおりに連続実行する設定であるかを確認することをお勧めします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/326392/b8813b02-d2dd-9dda-6ac0-252bfe809d05.png)

上記は、バックグラウンドジョブ実行の連続実行についてでした。SAP標準機能ではビジュアル的にジョブの前後関係を確認する方法がSM37の各ジョブ照会画面で先行ジョブ・後続ジョブのボタンをクリックして各ジョブ間を遷移することくらいしかできないため、大量ジョブの前後関係を管理・確認するのは大変難しいと思います。その代わりとして、テーブル：TBTCO（ジョブステータス概要テーブル）にて確認する方法を紹介します。下記のスクリーンショットの3行目の **バックグラウンドイベントパラメータ** (EVENTPARM)にジョブ名と先行ジョブのジョブNo.が記載されており前後関係を確認することができます。下記スクリーンショットでは、2行目（ジョブNo.19394300）のジョブが先行ジョブ、3行目（ジョブNo.19404800）がその後続ジョブとして設定されていることがわかります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/326392/4dd75c4e-bdf9-c756-ff27-d60c7e61809c.png)
また、右側の **後続ジョブ番号** （SUCCNUM）、 **先行ジョブ番号** （PREDNUM）でもこのテーブル独自の前後の紐づけが設定されています。こちらは、「ジョブNo.XXXXXXXXの後続ジョブのジョブNo.を取得」と言ったアドオンの仕様に対して、バックグラウンドイベントパラメータ項目を参照するより、より良いパフォーマンスで抽出を行いたい場合に利用できると思います。

#### 実行中ジョブの止め方
バリアントを間違えたジョブを動かしてしまった、処理がなかなか終わらないから抽出条件を見直して再度実行したい、など、実行中のジョブを止めたい場合があるかと思います。その場合、通常はSM37にてジョブを選択後、画面上にある、有効ジョブ停止ボタンをクリックします（下記スクショではジョブを選択していませんが、左端のチェックボックスにて指定が必要です）。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/326392/1b7e4bca-558c-8e12-cd2c-438c89a02323.png)

しかし、停止ボタンをクリックしてもすぐには終わず、数分経過して終わる、もしくはなかなか終わらないような場合もあります。この場合、プロセスIDを調べてトランザクション：SM51で停止する方法を以下に記載します。

**手順１：** ジョブNo.を確認するやり方と同様に、ジョブの照会画面からジョブ詳細画面を表示する。実行サーバ、WP（ワークプロセス）番号/PID（プロセスID）の内容を確認する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/326392/a5a20506-174d-e716-0e42-df0bfe6367de.png)

**手順２：** トランザクション：SM51を実行し、対象サーバの行をダブルクリックする（ECCかS/4HANAか、オンプレかクラウドかなどで表記等が異なる可能性あり）。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/326392/111f234f-baaf-dbf5-35b2-d0db8ba9b316.png)

**手順３：** WP番号とPIDから対象プログラムの行を確認してチェックをしたのち、メニューバーの、管理＞ワークプロセス＞中止＞「コアあり」にてプロセスを中止し、ジョブを中止ステータスで終了させることができる
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/326392/3502a01d-53f4-061e-1de1-8d769f2a4a15.png)
ジョブログには、下記のように表示されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/326392/e9a74e6e-1525-dcbe-9d62-1fb135de964c.png)

また、プロセスを中止する処理の最後に「コアあり」「コアなし」が選べますが、「コアなし」で試したところプロセスを中止できなかったため「コアあり」としました。「コアなし」でプロセスを停止できるケースをご存じの方がいらっしゃいましたらご教示をいただけましたら幸いです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/326392/67a6016e-4f6d-1116-6d2b-168e8528fbed.png)

## まとめ

以下のことを説明させていただきました。

・SAPジョブの基礎知識
・プログラムのバックグラウンド実行の方法が2種類あり、呼び出し箇所と機能がそれぞれ異なる
・時間指定実行をすることで、バックグラウンド実行時のジョブ名を設定できる
・ジョブステップのように、複数のバックグラウンド実行を連続で実行することができる
・実行中ジョブのプロセスを中止することでジョブを強制的に終了させることができる

ジョブ実行は、導入案件のアドオンのテストや運用保守案件でも使う機会が多くあり、機能についてはある程度は知っているように思っていましたが、まだ知らない機能があったのだなというのが実感です。皆さんの役に立つ機会がありましたら幸いです。今回は以上となります。ありがとうございました。