【データ管理】Dレジスタは捨てろ。「配列」と「構造体」で変数を自動化する技術

  • URLをコピーしました!
\ 迷子にならないための地図 /

未経験から一人前への
「最短ルート」公開中

独学で「何から勉強すれば…?」と悩んでいませんか?
現場で戦える知識を、体系的にまとめました。

FA電気設計ロードマップを見る

「来週から、シリンダの数が10本から50本に増えます」

この仕様変更を聞いた瞬間、あなたは変数を50個コピペして作る「苦行」を想像して絶望していませんか?

Cyl1_StartCyl2_StartCyl3_Start……。

変数名の末尾に「_1」「_2」と手打ちして消耗するのは、今日で終わりにしましょう。 それはあなたの貴重な才能と時間を、単純作業のドブに捨てているのと同じです。

私は9年の設計経験の中で、この「数の暴力」に何度も直面してきました。 そのたびに私を救ってくれたのが、「配列」と「構造体」というデータ管理の技術です。

これを使えば、50本でも100本でも、変数の定義は「たった1行」で終わります。

今回は、変数プログラミングを劇的に楽にする「データのまとめ方」を解説します。
これをマスターすれば、理不尽な仕様変更で「台数を倍にして」と言われても、たった1秒・1行の修正で涼しい顔をして対応できるようになります。

ただし、この2つの概念を単なる「便利機能」として適当に使うと、今後のプログラム拡張で痛い目を見ます。本記事で「正しい型」を確実に身につけてください。


目次

変数定義地獄へようこそ

前回の記事(▶【命名規則】その変数、1年後に読めますか?プロが使う「プレフィックス」の魔法)で、変数には「わかりやすい名前(プレフィックス)」をつけるルールを学びました。

しかし、いざ実践しようとすると、一つのシリンダを動かすだけでも以下のように複数の変数が必要になります。

  • i_b_Cyl1_SensorFwd(前進端センサ)
  • i_b_Cyl1_SensorBwd(後退端センサ)
  • o_b_Cyl1_SolFwd(前進ソレノイド)
  • o_b_Cyl1_SolBwd(後退ソレノイド)

シリンダが1本ならこれでも構いません。 しかし、10本になったら40個、50本になったら200個の変数を、一つずつ手作業で定義しなければなりません。

これは苦行以外の何物でもありませんし、必ず入力ミス(バグ)が発生します。

この地獄から抜け出すための2つの武器が、「構造体」と「配列」です。


構造体(DUT)とは?=「お弁当箱」

PLCの構造体(DUT)を説明するための概念図。お弁当箱のように、ひとつの箱(Cyl_t)の中に、「SensorFwd」「SensorBwd」「SolFwd」「SolBwd」といった異なる役割のデータが仕切りで分けられて整理されている様子。

最初の武器は「構造体(DUT:Data Unit Type)」です。

これは、バラバラの変数を一つにまとめる「お弁当箱」だと考えてください。

なぜ構造体が必要なのか?

先ほどのシリンダの変数は、本来「1つのシリンダ」に関するデータなのに、リスト上ではバラバラに散らばってしまいます。

そこで、「シリンダ型(Cyl_t)」というオリジナルのお弁当箱を作ります。 箱の中には、あらかじめ以下の「仕切り(メンバ変数)」を作っておきます。

  • .SensorFwd (前進端)
  • .SensorBwd (後退端)
  • .SolFwd (前進出力)
  • .SolBwd (後退出力)
GX Works3における構造体(DUT)の設定画面。「i_b_SensorFwd(前進端センサ)」のように、個別のシリンダ番号を含まない汎用的なメンバ変数が定義されている。これが各シリンダ共通の「金型」となる。

定義が「1行」で終わる

このお弁当箱(構造体)を作ってしまえば、あとは変数を定義する時に「データ型」をこのお弁当箱にするだけです。

  • 変数名:Cyl_1
  • データ型:Cyl_t(シリンダ型)

これだけで、Cyl_1.SensorFwdCyl_1.SolFwd といった変数が自動的に全て生成されます。 関連するデータがひとまとめになるため、プログラムを書く時に「あの変数はどこだっけ?」と探す手間が完全に消滅します。

【結論】 関連する複数のデータは、構造体(お弁当箱)にまとめてパッケージ化せよ。


配列(Array)とは?=「ロッカー」

PLCの配列(Array)を説明するための概念図。同じ形をしたデータボックスが、番号(インデックス)が振られたロッカーのように一列に整然と並んでいる様子。「Cyl[1]」「Cyl[2]」と順番にアクセスでき、変数[i]で指定できることを示している。

2つ目の武器が「配列(Array)」です。

これは、同じ種類のデータを一列に並べた「ナンバリングされたロッカー」です。

「_1」と「[1]」の決定的な違い

変数の末尾に手打ちで「_1」「_2」と連番を振るのをやめてください。 代わりに、変数のデータ型を「配列([ ])」に設定します。

  • ❌ 悪い例:Cyl_1Cyl_2Cyl_3 (それぞれ独立した別の変数)
  • ⭕ 良い例:Cyl[1]Cyl[2]Cyl[3] (同じロッカーの1番、2番、3番)

配列最大のメリット:数字を「変数」にできる

「括弧の形が変わっただけじゃないか」と思いましたか? 全く違います。配列の最大の武器は、[ ] の中の数字(インデックス)を、別の変数で指定できることです。

つまり、Cyl[i] と書くことができるのです。

  • i が 1 の時は、1番のシリンダが動く。
  • i が 10 の時は、10番のシリンダが動く。

これこそが、Dレジスタ(D100など)の固定アドレスでは絶対に不可能な、変数プログラミングの到達点です。

【結論】 同じ種類のデータが複数あるなら、手打ちの連番を捨てて「配列」のロッカーに入れよ。


最強のコンボ:「構造体の配列」

ここまで来れば、プロがどうやって50本のシリンダを管理しているか、お分かりでしょう。

「お弁当箱(構造体)」を「ロッカー(配列)」に並べるのです。 つまり、「構造体の配列」を作ります。

変数定義で、こう宣言するだけです。

  • 変数名:Cyl
  • データ型:Cyl_t
  • 配列:[1..50]

たったこれだけの作業(1行)で、50本分・合計200個の変数が一瞬で完成します。 プログラム内で使う時は、Cyl[i].SolFwd(i番目のシリンダを前進させろ)と書くだけです。

もし「やっぱり100本に増やして」と言われたら? 配列のサイズを [1..50] から [1..100] に書き換えるだけ。作業時間は1秒です。

GX Works3におけるラベルの配列設定画面。データ型として作成した構造体「Cyl_t」を指定し、配列要素数にチェックを入れて「10」と入力している。「構造体の配列」をたった1行で一括定義している様子。
▲GXWorksの場合、データ型を「Cyl_t(構造体)」にし配列にチェックを入れて数を入力するだけ。これで一気に変数が作られます。

疑問:カッコの数字を変えるのも、結局手作業じゃないの?

ここで、鋭い人は一つの疑問にぶつかるはずです。

「ちょっと待って。1番シリンダの回路をコピペして、Cyl[1]Cyl[2] に書き換えるのって、結局 『文字を手作業で直してる』 ことには変わりなくない? デバイス番号を置換するのと何が違うの?」

その指摘は正しいです。ラダーで書く以上、数字の書き換え作業は発生します。

しかし、現場の最前線で設計しているプロから言わせると、「置換の安全性」と「仕様変更への耐性」が次元を超えて違います。

配列と構造体を愛用するのには、4つの明確な理由があります。

構造体の配列を利用したラダー回路図。1行目の「Cyl[1]」を使った起動回路をコピーし、2行目に貼り付けてカッコ内の数字を「2」に変更するだけで、2番シリンダの回路がノーミスで完成している様子。デバイス番号の計算や置換作業が不要であることを示している。

▲1行目をコピペして、数字を「1」から「2」に変えるだけ。デバイスのズレを気にする必要は一切ありません。

① オフセット(ズレ)の計算ミスがゼロになる

デバイス(X, Y, M)の場合、シリンダ1本あたり10個の信号があるとします。 「1番はM10〜M19だから、2番はM20〜M29にして…」と、頭の中で足し算をしながら置換しなければなりません。うっかり被るとダブルコイルで即バグです。

しかし構造体の配列なら、「1」という数字を「2」にするだけです。裏側で10個の信号がどう割り付けられるかは、PC(コンパイラ)が勝手にノーミスでやってくれます。連続した「空きデバイス」を探す手間もありません。

②:連続した「空き地」を探す必要がない

デバイス(DやM)で50台分のデータを管理しようとすると、「M100からM599まで、連続して500個空いている場所」を探さなければなりません。そんな広大な空き地が見つからず、あちこちに飛び地で割り付けて、後で解読不能になるのがオチです。

配列なら、何百個のデータだろうと「コンパイラ(PC)」が勝手にメモリの空きを見つけてパズルのように配置してくれます。飛び地のリスクはゼロです。

③:パラメータ追加時の「地獄のズレ」が消滅する(★最大のメリット)

これが現場で最も威力を発揮します。 例えば、設計の終盤で「全シリンダに『異常アラーム』の信号を追加して!」と仕様変更が入ったとします。

  • デバイス管理の場合:
    すでに番号がギッチリ詰まっているので、アラーム用のデバイスをねじ込む隙間がありません。
    泣く泣く全てのデバイス番号を後ろにズラす大手術をするか、全く関係ない離れたデバイス(M1000〜など)にアラームだけをまとめて書き込む「スパゲッティ化」の二択を迫られます。
  • 構造体の場合:
    「お弁当箱(構造体)」の設計図に、「異常アラーム(b_Alarm)」という仕切りを1行追加するだけです。
    それだけで、Cyl[1].b_Alarm から Cyl[50].b_Alarm までの全シリンダに、自動的にアラーム変数が追加されます。既存のプログラムの並び順を気にする必要は一切ありません。

④ FB(ファンクションブロック)に「箱ごと」渡せる

以前の記事で学んだ「FB(たこ焼きの金型)」を作った時、普通の変数だと「前進端」「後退端」「前進指令」…と、端子(ピン)を何本も繋ぐ必要があります。

しかし構造体なら、「Cyl[1] というお弁当箱を丸ごと1個渡す」だけで、中のデータが全てFBに伝わります。ごちゃごちゃしていた配線が、たった1本で済むのです。


まとめ:変更に強い「数」の支配者になれ

  • 構造体(お弁当箱): 関連するデータを1つにまとめ、仕様変更(変数の追加)を一瞬で終わらせる。
  • 配列(ロッカー): 同じデータを一列に並べて、番号で安全に管理し、飛び地を防ぐ。

この2つを組み合わせることで、あなたは理不尽な仕様変更や「数の暴力」に一切動じない、最強のデータ管理能力を手に入れました。

「構造体」と「配列」という最強の箱を用意できたら、次はその箱の中身を自由自在に操るための「ST言語」を学びます。

「ST言語って難しそう…」と思うかもしれませんが、安心してください。パソコンのプログラミングのように、複雑なループ処理(FOR文など)を無理に使う必要はありません。むしろ、現場でラインを止める(WDTエラーの)リスクを冒してまで、初心者がFOR文を使うメリットはないのです。

覚えるべき文法は「IF(もし〜なら)」と「CASE(場合分け)」のたった2つだけ。これだけで、実務の9割は安全かつ確実に戦えます。

次回は、ラダーの限界を突破する「実践的ST言語の基礎」について解説します。

👇次の記事:覚えるのは2つだけ!絶対に事故らないST言語

あわせて読みたい
【ST言語】覚える文法は2つだけ!「IF」と「CASE」で書く実践ST言語入門 「ST言語は文法が多すぎて難しい…」と諦めていませんか? FAの現場で使うST文法は「IF」と「CASE」のたった2つで実務の9割がこなせます。無限ループで設備を止める危険な「FOR文」を回避し、安全にラダーを置き換えるプロの技術を解説。

💬 更新情報を X (Twitter) で発信中!

記事の更新通知や、現場で役立つ「電気制御の小ネタ」をツイートしています。 また、「記事のここが分からなかった」「現場でここが困っているけどどうしたらいい?」といった疑問があれば、DMで募集しています!個別のトラブル相談も、ブログのネタにさせていただけるなら大歓迎です!ぜひフォローして気軽に絡んでください!

バラバラのPLC変数が、構造体(お弁当箱)と配列(ロッカー)によって自動的に整理整頓され、スマートな工場の生産ラインへと流れていく様子を描いたアイキャッチ画像。

この記事が気に入ったら
フォローしてね!

よかったらシェアしてね!
  • URLをコピーしました!

この記事を書いた人

目次