VBのフォームアプリケーションで以下のような図を描画したいです。
ある既存のソフトウェアが生成したコードの書かれたテキストファイルがあります。
そのファイル「CODE.txt」内には以下のようなコードが記述されています。
(ニーモニックコードと呼ばれています)
RD R1.0
OR R2.0
AND.NOT R3.0
WRT R4.0
ご覧の様にスペースと改行だけで区切られています。
知りたいのは、スペースと改行で区切られただけの文をVBで読んで描画する時、
どのように処理するのが理想的なのかという事です。
メソッドを自作するべきなのだろうと漠然と想像しているのですが、
開発の経験はゼロであり、ググり方すらよくわかりません。ご指南いただけると幸いです。
ひとまず以下のような変数と処理順序を考えてはみたのですが。
現在地X1 GX1 =0
現在地Y1 GY1 =0
現在地X2 GX2 =0
現在地Y2 GY2 =0
左壁 HK = 10
右壁 MK = 130
エレメント幅 EHABA = 30
エレメント高 ETAKA = 20
メソッドの説明
RDメソッド
GX1=HK GY1=ETAKA*1.5 に決定する。
a接点を書いて上にR1.0の文字を書く。
GX1=+ELEHABA 現在地1を更新。後で現在地2と合流予定。
ORメソッド
HK,GY1+ETAKAでa接点、文字R2.0を描画して右先端をGX2,GY2とし、
GX1,GY1まで線を延ばす
ANDメソッド
GX1,GY1でR3.0のb接点を描き、GX1=+EHABAにする
WRTメソッド
GX1,GY1からMK-EHABA,GY1まで線を引いてコイルを描く。
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
回答3件
0
ベストアンサー
実際の処理
読取ファイルの形式としては、スペースを区切り文字としたCSV形式のようです。
取得できる内容は、「処理の種類」と「エレメント名」ですね。
ファイル読み込みに関しては、普通に開いて1行ずつデータを取得し、Split関数で要素を分解すればいいと思います。
大まかな流れは、
①ファイルオープン
--(行取得ループ開始)--
②1行ずつデータを取得 ⇒EOFならループ終了
③取得したデータをスペースで分解(Split)
④分解した結果を配列(またはコレクション)に格納する。
--(ループ終了)--
--(配列のループ開始)--
⑤配列(コレクション)に格納された「処理の種類」によって、描画を行う
--(ループ終了)--
⑥ファイルを閉じる
という感じになりそうです。
※④の部分ですが、例題のように一つ前のエレメントを参照するくらいの処理ですむなら、ファイルを読みながら描画しても構わないかもしれません。
しかし前後関係の参照が複雑になることが想定されるようであれば、一度配列(またはコレクション)に要素を格納し、いつでも全てを参照できる状態にしてから描画を開始したほうが処理しやすいと思います。
エレメントの描画について
描画の部分については、ゴリ押しで行くとわかり難くなりそうですので、エレメントの要素を整理すると管理しやすくなるかもしれません。
それぞれのエレメントを配置するための情報として、
・どのエレメントから線を引くか(接続元)
・どのエレメントに線を繋げるか(接続先)
・エレメントを配置する座標(X、Y)
・エレメントの形状
・エレメントの名前
という要素がありそうです。
これらの情報をエレメントクラスとして管理すると、描画メソッドは渡されたエレメントクラスの情報を元に前後のエレメントと接続するような描画を行うだけの共通処理化にすることができると思います。
この観点で各メソッドを整理すると、以下のようになります。
(ラダー図というものには詳しくなく、今回少し調べた程度の知識ですので、不足や間違いがあったらすみません。。)
RD :左壁に接続する接点を配置する ・接続元:左壁 ・接続先:次のエレメント(ORを除く) ・X座標:1 ・Y座標:Y座標の最大+1 ・形状:接点
OR :直前のエレメントとのひとつ下・同じ横位置に並ぶ接点を配置する ・接続元:直前のエレメントの接続元と同じ ・接続先:次のエレメント(ORを除く) ・X座標:直前のエレメントと同じ ・Y座標:直前のエレメント+1 ・形状:接点
AND:RDと同じ高さ・ひとつ右に並ぶ接点を配置する ・接続元:直前のエレメント ・接続先:次のエレメント(ORを除く) ・X座標:直前のエレメント+1 ・Y座標:RDと同一 ・形状:接点
WRT:RDと同じ高さ・ひとつ右に並ぶコイルを配置し、右壁に接続する ・接続元:直前のエレメント ・接続先:右壁 ・X座標:直前のエレメント+1 ・Y座標:RDと同一 ・形状:コイル
ただし直前のエレメントもWRTだった場合、直前のWRTのひとつ下・同じ横位置に並ぶコイルを配置し、右壁に接続する
WRT:(直前のエレメントもWRTの場合) ・接続元:直前のエレメント(WRT)の接続元と同じ ・接続先:右壁 ・X座標:直前のエレメントと同じ ・Y座標:直前のエレメント+1 ・形状:コイル
最後に
開発経験ゼロからということでしたが、今回のアドバイスには少し難しい内容も含んでいます。
肝となりそうな部分は「VB スペース区切り」「VB コレクション」「VB クラスの作成 プロパティ」などのように検索すると、参考になるページが出てきそうですので頑張ってみてください。
まずはひとつの考え方として、参考になれば幸いです。
投稿2016/10/28 01:53
総合スコア3013
0
'これはVS2015 VisualBasicのフォームアプリケーションで作りました。
Public Class Form1
Dim HYOMUL As Integer = 1.4 '表示倍率(マルチプライ)
Dim EX As Integer = 49 * HYOMUL 'エレメントX座標大きさ
Dim HK As Integer = 10 * HYOMUL '左壁X座標
Dim MK As Integer = EX * 7 * HYOMUL '右壁X座標
Dim UK As Integer = 0 '上壁Y座標
Dim SK As Integer = 500 * HYOMUL '下壁Y座標
Dim GX1, GX2, GY2 As Integer '現在地X1,X2,Y2
Dim EY As Integer = 21 * HYOMUL 'エレメントY座標大きさ
Dim GY1 As Integer = EY '現在地Y1
Dim EXx1w7 As Integer = EX / 7 'EX1/7
Dim EXx3w7 As Integer = EX * 3 / 7 'EX3/7
Dim EYw3 As Integer = EY / 3 'EY/3
Dim AUE, ASITA, AHIDA, AMIGI, AOWA, BSITAX, BUEX, BSITAY,
BUEY, KOIHAJI, KOIHIDA, KOIMIGI, KOINAKA, KOIUE, KOIDEKA, ADOX, ADOY As Integer
'A接点の上Y、下Y、左X、右X,右の終わり、B接点の下X,Y,上X,Y,コイル始まりX、コイル左X,コイル上Y,コイルでかさ,
'アドレス表示座標X,Y
'文字を描画する為の宣言(?) Dim objFont = New Font("MS ゴシック", 8) Dim objGrp As Graphics = Me.CreateGraphics Public Sub Form1_Paint(sender As Object, e As PaintEventArgs) Handles PictureBox1.Paint Dim text1 As String = "Use StringFormat and Rectangle objects to" & " center text in a rectangle." Dim font1 As New Font("Arial", 12, FontStyle.Bold, GraphicsUnit.Point) Try Dim rect1 As New Rectangle(10, 10, 130, 140) ' Create a StringFormat object with the each line of text, and the block ' of text centered on the page. これ https://msdn.microsoft.com/ja-jp/library/332kzs7c(v=vs.110).aspx Dim stringFormat As New StringFormat() stringFormat.Alignment = StringAlignment.Center stringFormat.LineAlignment = StringAlignment.Center Finally font1.Dispose() End Try '壁を描く e.Graphics.DrawLine(Pens.Black, HK, UK, HK, SK) e.Graphics.DrawLine(Pens.Black, MK, UK, MK, SK) GY1 = EY * 2 'ここからニーモニックコードに対応する順番で記述。Call関数使用。引数にアドレス使用。 '変換後のオペランドである事を区別するため接頭語にNimoを付ける。 Call NimoRD("R1.0", e) Call NimoOR("R1.1", e) Call NimoAND("R1.A", e) Call NimoAND("R1.B", e) Call NimoAND("R1.C", e) Call NimoOR("R1.D", e) Call NimoWRT("R1.2", e) Call NimoRD("R2.0", e) Call NimoOR("R2.1", e) Call NimoWRT("R2.2", e) Call NimoRD("R3.0", e) Call NimoOR("R3.1", e) Call NimoWRT("R3.2", e) End Sub Public Sub NimoRD(ByVal ADORESU As String, e As PaintEventArgs) GX1 = HK AUE = GY1 - EYw3 ASITA = GY1 + EYw3 AHIDA = GX1 + EXx3w7 AMIGI = AHIDA + EXx1w7 AOWA = AMIGI + EXx3w7 ADOX = AHIDA - EXx1w7 * 2 ADOY = AUE - EYw3 * 2 e.Graphics.DrawLine(Pens.Black, GX1, GY1, AHIDA, GY1) e.Graphics.DrawLine(Pens.Black, AHIDA, AUE, AHIDA, ASITA) e.Graphics.DrawLine(Pens.Black, AMIGI, AUE, AMIGI, ASITA) e.Graphics.DrawLine(Pens.Black, AMIGI, GY1, AOWA, GY1) e.Graphics.DrawString(ADORESU, objFont, Brushes.Blue, ADOX, ADOY) GY2 = GY1 GX1 = AOWA End Sub Public Sub NimoOR(ByVal ADORESU As String, e As PaintEventArgs) GX2 = HK GY2 = GY2 + EY * 2 AUE = GY2 - EYw3 ASITA = GY2 + EYw3 AHIDA = GX2 + EXx3w7 AMIGI = AHIDA + EXx1w7 AOWA = AMIGI + EXx3w7 ADOX = AHIDA - EXx1w7 * 2 ADOY = AUE - EYw3 * 2 e.Graphics.DrawLine(Pens.Black, GX2, GY2, AHIDA, GY2) e.Graphics.DrawLine(Pens.Black, AHIDA, AUE, AHIDA, ASITA) e.Graphics.DrawLine(Pens.Black, AMIGI, AUE, AMIGI, ASITA) e.Graphics.DrawLine(Pens.Black, AMIGI, GY2, AOWA, GY2) e.Graphics.DrawLine(Pens.Black, AMIGI, GY2, GX1, GY2) e.Graphics.DrawString(ADORESU, objFont, Brushes.Blue, ADOX, ADOY) e.Graphics.DrawLine(Pens.Black, GX1, GY2, GX1, GY1) End Sub Public Sub NimoAND(ByVal ADORESU As String, e As PaintEventArgs) AUE = GY1 - EYw3 ASITA = GY1 + EYw3 AHIDA = GX1 + EXx3w7 AMIGI = AHIDA + EXx1w7 AOWA = AMIGI + EXx3w7 ADOX = AHIDA - EXx1w7 * 2 ADOY = AUE - EYw3 * 2 e.Graphics.DrawLine(Pens.Black, GX1, GY1, AHIDA, GY1) e.Graphics.DrawLine(Pens.Black, AHIDA, AUE, AHIDA, ASITA) e.Graphics.DrawLine(Pens.Black, AMIGI, AUE, AMIGI, ASITA) e.Graphics.DrawLine(Pens.Black, AMIGI, GY1, AOWA, GY1) e.Graphics.DrawString(ADORESU, objFont, Brushes.Blue, ADOX, ADOY) GX1 = AOWA End Sub Public Sub NimoWRT(ByVal ADORESU As String, e As PaintEventArgs) KOIDEKA = EYw3 * 2 KOIHIDA = MK - EX KOIUE = GY1 - EYw3 KOIMIGI = KOIHIDA + KOIDEKA ADOX = KOIHIDA - EXx1w7 ADOY = KOIUE - EYw3 * 2 e.Graphics.DrawLine(Pens.Black, GX1, GY1, KOIHIDA, GY1) e.Graphics.DrawLine(Pens.Black, KOIMIGI, GY1, MK, GY1) e.Graphics.DrawEllipse(Pens.Black, KOIHIDA, KOIUE, KOIDEKA, KOIDEKA) e.Graphics.DrawString(ADORESU, objFont, Brushes.Blue, ADOX, ADOY) GX1 = HK GY1 = GY2 + EY * 2 End Sub
End Class
投稿2016/10/29 08:50
総合スコア31
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
0
PLCのラダー図ですね。
VBでやるとしたら、PictureBoxにLineなどを使って(パターンとして)描画するのはどうでしょう。
またテキストファイルを文字列として条件により分岐しながら描画位置を算出しながら作製するのが良いかと。
文字もグラフィックとして取り扱います。
実現方法として無料で使えるVisual Studio 2015をインストールしてVBで作製。
投稿2016/10/27 11:13
総合スコア3747
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2016/10/29 08:27