いったい一つのプログラムを組むのに何日かかって何度皆様にご迷惑をおかけしているのやら・・・。
内容は受注明細ファイルから1レコード読み、前のレコードと商品コードが一致しなかった場合、受注明細ファイルの商品コードをキーにし、商品マスタを検索。
該当レコードがあった場合商品マスタの商品名称(シフトコード含まないで)20桁を16桁に編集し、シフトコードの編集もしてから出力ファイルの商品名称にいれる。
もし商品マスタに該当レコードが無ければ、出力ファイルの商品名称に’未登録’を表示・・・
というものです。16桁編集はSUBプログラムとして補足資料に以下のものが書かれていました。

C P#010 PLIST
C PARM P#LEN 2 桁数
C PARM P#DATA 80 文字列
C PARM P#OPT 1 オプション
以上パラメーターの定義

C MOVEL'16' P#LEN
C MOVEL*BLANK P#DATA
C MOVEL****** P#DATA
C MOVEL*BLANK P#OPT
C CALL 'SUB0010R'
以上パラメーターにデータをセットして、サブプログラムの実行(CALL)
CALL終了後、P#DATAに16桁に編集された文字列が返ってくる。
*オプションは、サブプログラム側で何かしらのエラーが発生した場合、’1’を返してくる。

以上です。
この場合どのようなプログラムになるのでしょうか?
お助けください;;

このQ&Aに関連する最新のQ&A

A 回答 (3件)

こんにちわ。


お書きになられているコーディングそのままでだいたい、使えると思われます。
さきほどの御質問と組み合わせると思ってらっしゃるものが出来るかと思います。
但し、サブプロでエラーの時(オプションが1以外の時)どうするかは確認されたほうがいいかと思います。

コードはわざと書きませんので、がんばってやってみてください。
    • good
    • 0

お尋ねになりたいのは メインのコーディングですか それとも呼び出される「SUB0010R」のコーディングでしょうか? ご覧になっているのはどのような資料ですか。


社内の経験者や出入のSEさんは側にいらっしゃいませんか?
AS/400関連のメーカー情報誌には沢山サンプルがあるはずですので職場にあるものを見落としているのかもしれませんよ。

この回答への補足

メインです。
会社のサンプルですか・・・・
見れないんです;;
ユーザーがないのと、新しいマシーンへデータ移行中で使えないんです;;

補足日時:2001/11/29 15:42
    • good
    • 0

一つ疑問点があるのですが、商品マスタに登録されている品名は


IBMの漢字コードで登録されているのですよね。
それならサブプログラムまで使う必要が無いと思うのですが、
見た感じこのサブプログラムは通信などで他の漢字コードとして
入ってきた文字をIBM漢字コードに変換させる為の
プログラムの様に見えます。
IBMの漢字コードで入力している文字を20桁から16桁に
するのであれば、ただ単に適当な文字を1文字架空のフィールドに
入力してI仕様書でDSで区切って、1桁目と4桁目を取り出し
(シフトインとシフトアウト)20桁から16桁にしたときに
シフトインは入っているのでシフトアウトをいれてやるだけ
で大丈夫なはずです。

補足お願いします。

この回答への補足

仕様書にはその辺は全く記載されていません。
ファイルの設計書等もない状態です。
一応補足のプログラムを使えとだけは書いてありますが、
その他の注釈は全く皆無の状態です。
初心者にはお手上げです;;

補足日時:2001/11/29 15:33
    • good
    • 0

このQ&Aに関連する人気のQ&A

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aと関連する良く見られている質問

Q【C#】ifと#ifの違い、そして#endif

http://www.atmarkit.co.jp/fdotnet/csharp_abc/csharp_abc_019/csharp_abc03.html

このページを参考にしましたが普通のifと何が違うのかわからなかったです。
何のために必要なのかもう少しわかり易く教えて下さい。
また、#endifってなんでしょう?

Aベストアンサー

プリプロセッサというのは、コンパイル前にプログラムを書き換えてしまうような処理をします
そこにあるプログラムで言えば、次のものと同等になります

// #define MY_SWITCH1→削除
// #undef MY_SWITCH2→削除
using System;

namespace ConsoleApplication1
{
class Class1
{
static void Main(string[] args)
{
// #if true→削除
Console.WriteLine("#if true"); // 条件が成立するのでそのまま
// #endif→削除
// #if false→削除
// 条件が不成立なので削除
// #endif→削除
// #if MY_SWITCH1 || MY_SWITCH2→削除
Console.WriteLine("MY_SWITCH1 or MY_SWITCH2 is ON");// 条件が成立するのでそのまま
// #else→削除
// 条件が成立しているので#elseは削除
// #endif→削除
//#if MY_SWITCH1 && MY_SWITCH2→削除
// 条件が不成立なので削除
// #else→削除
Console.WriteLine("MY_SWITCH1 and MY_SWITCH2 is OFF"); // 条件が不成立なので#elseはそのまま
// #endif→削除
}
}
}


使い道としては「実行中に変化しない条件分岐。使用しないコードは無効にして効率を上げたい」というときでしょう。

デバッグ時の表示に使う例はすでに出ています。

他に、同じソースコードを、GUIアプリケーションとコンソールアプリケーションとで共有する場合
GUI用には GUI_MODEを定義する/コンソール用には未定義にする としておけば

#if GUI_MODE
Messagebox("エラーです");
#else
Console.WriteLine("エラーです");
#endif

とすれば、GUI用にはメッセージボックスに、コンソール用にはコンソール画面にエラーメッセージが表示されるようになります。


C#だと、そんなに使う機会もないかもしれませんが、C/C++だと、CPU、OS等の環境に合せて適切な命令を選択する等に使用したりもします。

プリプロセッサというのは、コンパイル前にプログラムを書き換えてしまうような処理をします
そこにあるプログラムで言えば、次のものと同等になります

// #define MY_SWITCH1→削除
// #undef MY_SWITCH2→削除
using System;

namespace ConsoleApplication1
{
class Class1
{
static void Main(string[] args)
{
// #if true→削除
Console.WriteLine("#if true"); // 条件が成立するのでそのまま
// #endif→削除
// #if false→削除
// 条件が不成立なので削除
//...続きを読む

QC#でserialPort送信。RS232Cへ。

前回からの続きです。
http://oshiete1.goo.ne.jp/qa5537662.html

データ取得はうまくいきましたが、データを受け取ったというACK(0x06)を送信しようとしていますが、うまく受け取ってくれません。

http://www.robotsfx.com/robot/robohow/RoboHow60/RoboHow60.html
というサイトを参考にして、
// ACKを返す。
byte[] ack_data = new byte[1];
ack_data[0] = 06;
this.serialPort1.Write(ack_data, 0, 1);
というようにやっていますが、通信機器(アロハPC1)が受け取ってくれません。(最初のデータを送信後ACKを受け取らないと1秒後にデータを再送信される=同じデータが二回来る)

このような送信でよいのでしょうか?

Aベストアンサー

本当に送っていて相手が受け取れていないのか送れていないのかの確認とってますか?
↑RSケーブル作ればPC2台でハイパーターミナルでも確認できます
(ラインモニタつかってれば話が早いですがお持ちですか?)

C#知りませんがソフト以外のハード的な要因というのはありませんか?
(必要な信号入って無いとICが送信できません)

正常に送っていて相手が受け取っていないのであれば原因調べようがありません
相手側機器に問い合わせしてください

QC#にてCTI。RS232Cの受信と送信について。

C#でCTI機能の実現を目指しております。
プログラムは以下サイトからDLして改造しています。
http://tmp.junkbox.info/e14.html
しかし、エラーが頻発し原因不明です。

構成、仕様としては、
アロハPC1という機械から電話番号データを受信しPCに受け渡し。
・データを受け取る(ここは問題なし)
データ形式は
STX(02H)、着信日時(月日曜時分9桁)、電話番号(20桁)、ETX(03H)
として送られてきます。
例) 1214112050457771111
・正常データの場合はACK(06H)を返信(これをしない場合1秒後に同データが再送される)
・データ整形
・データ表示
というような形にしたいのです。

上記サイトのプログラムをアロハPC1に合わせて通信できるようにした状態ですと、例のような生データが問題なく表示されます。
これを以下のようにしてみましたが、エラーが出てしまいます。
private void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
{
// 受信文字列の取得
string receivedData = "";
string moji = "";
string moji2 = "";
try
{
receivedData = this.serialPort1.ReadExisting();
receivedData = receivedData.Replace(this.serialPort1.NewLine, "\r\n");

string[] week = { "(日)", "(月)", "(火)", "(水)", "(木)", "(金)", "(土)" };

string stx = receivedData.Substring(0, 1);
string etx = receivedData.Substring(30, 1);

// ACKを返す。
byte[] ack_data = new byte[1];
ack_data[0] = 06;
serialPort1.Write(ack_data,0,1);

string data_m = receivedData.Substring(1, 2);
string data_d = receivedData.Substring(3, 2);
string w = receivedData.Substring(5, 1);
int w2 = int.Parse(w);
string data_w = week[w2];
string data_h = receivedData.Substring(6, 2);
string data_i = receivedData.Substring(8, 2);

moji2 = receivedData.Substring(10, 20);
// スペースを痴漢
moji2 = moji2.Replace(" ", "");

moji = data_m + "月" + data_d + "日" + data_w + data_h + "時" + data_i + "分 ";
if (moji2 == "P")
{
moji = moji + "着信番号非通知\n";
}
else if (moji2 == "O")
{
moji = moji + "着信番号提供地域外\n";
}
else if (moji2 == "C")
{
moji = moji + "公衆電話\n";
}
else
{
moji = moji + moji2 + "\n";
}

}
catch (Exception ex)
{
moji = ex.Message;
}

// richTextBox側のスレッドに AddRecievedDataメソッドのポインタを渡して、
// 受信文字列を追加させる
AddRecievedDataDelegate add = new AddRecievedDataDelegate(AddRecievedData);
this.richTextBox1.Invoke(add, moji);
}
結果:
1221112260457771111
12月21日(月)12時26分 0457771111
1221112
startIndex に文字列の長さより大きい値を指定することはできません。
パラメータ名: startIndex260457771111
startIndex に文字列の長さより大きい値を指定することはできません。
パラメータ名: startIndex

Substringを削除すると「startIndex に文字列の長さより大きい値を指定することはできません。」というようなエラーは出てきません。
receivedData = this.serialPort1.ReadExisting();
を文字列を直接代入した場合はエラーは発生しません。

これをどのようにすれば正常に動くのでしょうか。

また、ACKが正常に送信できてないみたいなのも解れば助かります。
よろしくお願いします。

C#でCTI機能の実現を目指しております。
プログラムは以下サイトからDLして改造しています。
http://tmp.junkbox.info/e14.html
しかし、エラーが頻発し原因不明です。

構成、仕様としては、
アロハPC1という機械から電話番号データを受信しPCに受け渡し。
・データを受け取る(ここは問題なし)
データ形式は
STX(02H)、着信日時(月日曜時分9桁)、電話番号(20桁)、ETX(03H)
として送られてきます。
例) 1214112050457771111
・正常データの場合はACK(06H)を返信(これをしない場...続きを読む

Aベストアンサー

>・データを受け取る(ここは問題なし)
確認も無しに断言してはいけません。

このプログラムの問題点は、受信したデータ(receivedDat)が必ずしも31文字にならないことです。
SerialPortのDataReceived()イベントは、1文字受信するたびに発生します。
従って受信したデータには、ReadExisting()した時点でSerialPortに受信されている分しか入りません。
解決方法を2種類示しますが、動作確認はしていません。

◎解決方法1
ReadExisting()する前にBytesToReadをチェックして31文字未満ならReadしない。

◎解決方法2
一度に1文字ずつReadして文字をつないでいく。
このとき、
STXを受信する前は、Readしたデータは捨てる。(受信データは空にする)
STXを受信した後は、Readしたデータを受信データに継ぎ足していく。
ETXを受信したら(継ぎ足したデータがETXなら)、受信データ長を確認してACK送信にすすむ。

QRuby while line = DATA.gets と DATA.each do |line| の違い

DATA.each do |line|
if /code,(.+)/=~line
code=$1
elsif /name,(.+)/=~line
puts "code=#{code} name=#{$1}"
end
end
__END__
code,001
name,ipp
code,002
name,opp

上記実行結果は以下の様に変数codeの値が出力されません。
code= name=ipp
code= name=opp

ところがプログラムの一行目をwhile line = DATA.getsに変更すると、以下の様に値が出力されます。
code=001 name=ipp
code=002 name=opp

どういう理屈なんでしょうか? 教えていただけませんか?
また、DATA.each do |line|の書式で、変数code(DATAの一行前で代入した値)を有効にする方法はあるのでしょうか?

Aベストアンサー

eachはスコープを生成するので、
code=$1はeachブロック内のローカル変数と見なされます。
そのため、code=$1を通らないときはcodeに対する代入が行われていないと見なされ、
code==nilとなります。

Rubyリファレンスマニュアル - trap::スコープ、制御構造
http://www.ruby-lang.org/ja/man/?cmd=view;name=trap%3A%3A%A5%B9%A5%B3%A1%BC%A5%D7%A1%A2%C0%A9%B8%E6%B9%BD%C2%A4
より引用
| while や for がスコープを作らないのに対し、loop や each などのイテレータはスコープを作ります。


> DATA.each do |line|の書式で、変数code(DATAの一行前で代入した値)を有効にする方法はあるのでしょうか?
----
code=""
DATA.each do |line|
#後略
----
のように、あらかじめ変数codeを宣言(代入)しておけばよいです。


[参考]
http://blade.nagaokaut.ac.jp/cgi-bin/vframe.rb/ruby/ruby-list/8472?8393-8678

eachはスコープを生成するので、
code=$1はeachブロック内のローカル変数と見なされます。
そのため、code=$1を通らないときはcodeに対する代入が行われていないと見なされ、
code==nilとなります。

Rubyリファレンスマニュアル - trap::スコープ、制御構造
http://www.ruby-lang.org/ja/man/?cmd=view;name=trap%3A%3A%A5%B9%A5%B3%A1%BC%A5%D7%A1%A2%C0%A9%B8%E6%B9%BD%C2%A4
より引用
| while や for がスコープを作らないのに対し、loop や each などのイテレータはスコープを作ります。


> DATA...続きを読む

QAccessVBAで実行時エラー'429'が出ます

ACCESS2000,WindouwsME
ACCESSから既存のEXCELブックを呼び出そうとしていますが、
  
       略
EXCEL名 = S2 & "XXX.xls"
Set xls = GetObject(EXCEL名, "Excel.Sheet")
       略

の、2行目で以下のエラーが出てしまい困っています。

実行時エラー'429'
ActiveXコンポーネントはオブジェクトを作成できません。

動かすパソコンの環境で、出る時と出ない時があるようです。
VBEのツールメニューから参照設定を確認しているつもりですが、
ここの理解も含めて原因が良くつかめません。
解決策をコメントできる方がおられましたらお願いいたします。

Aベストアンサー

参考になるようなURLを見つけました。
http://moug.excite.co.jp/skillup/opm/opm05-05.htm
「すでにWordが起動しているときにはそのまま処理を続行しますが、未起動のときには番号429のエラーが発生します。」
ただし自作テストで
Sub test01()
Dim x As Object
Set x = GetObject("c:\My Documents\aa1.xls")
x.Activate
With activeworkbook
MsgBox x.worksheets("sheet1").range("a1").Value
End With
Set x = Nothing
End Subでテストすると、その時エクセルを起動していないがうまく行きました。
ただAccessのモジュールの画面でツール-参照設定-MicrosoftExcel9.0ObjectLibraryにチェックを入れて
いますが。


人気Q&Aランキング

おすすめ情報