質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
VB

VB(ビジュアルベーシック)はマイクロソフトによってつくられたオブジェクト指向プログラミング言語のひとつで、同社のQuickBASICが拡張されたものです。VB6の進化版といわれています。

Q&A

解決済

3回答

1667閲覧

VBでコードの書かれた既存テキストファイルを読ませ、描画したい

gamu

総合スコア31

VB

VB(ビジュアルベーシック)はマイクロソフトによってつくられたオブジェクト指向プログラミング言語のひとつで、同社のQuickBASICが拡張されたものです。VB6の進化版といわれています。

0グッド

0クリップ

投稿2016/10/27 09:35

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ページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答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

jawa

総合スコア3013

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

gamu

2016/10/29 08:27

細部まで考察していただいてありがとうございました。 検索方法まで示していただけて励みになります。 結果的には自己解決方法のように一応の描画は可能になりました。 実際の回路はより複雑な形になるのでまだまだ改良の余地はあります。 アドバイスを参考に頑張ります。
guest

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 'EX
3/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

gamu

総合スコア31

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

PLCのラダー図ですね。
VBでやるとしたら、PictureBoxにLineなどを使って(パターンとして)描画するのはどうでしょう。
またテキストファイルを文字列として条件により分岐しながら描画位置を算出しながら作製するのが良いかと。
文字もグラフィックとして取り扱います。
実現方法として無料で使えるVisual Studio 2015をインストールしてVBで作製。

投稿2016/10/27 11:13

MasahikoHirata

総合スコア3747

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

gamu

2016/10/29 08:21

ご回答ありがとうございました。 PictureBox1にはe.Graphics.DrawLineを使って描画きました。 文字はe.Graphics.DrawStringを使ってできました。 VisualStudio2015Communityを使っています。 無料は有難いです。解らないことが多いですが頑張ります。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問