常用資訊速查

取得pdf檔内文

基本上是利用模块CAM::PDF,以其提供的范例修改

#!/usr/bin/perl -w

package main;

use warnings;
use strict;
use CAM::PDF;
use Getopt::Long;
use Pod::Usage;

our $VERSION = '1.52';
my $lastx=0;
my $lasty=0;

my %opts = (
check => 0,
geom => 0,
verbose => 0,
help => 0,
version => 0,
);

Getopt::Long::Configure('bundling');
GetOptions('g|geometry' => \$opts{geom},
'c|check' => \$opts{check},
'v|verbose' => \$opts{verbose},
'h|help' => \$opts{help},
'V|version' => \$opts{version},
) or pod2usage(1);
if ($opts{help})
{
pod2usage(-exitstatus => 0, -verbose => 2);
}
if ($opts{version})
{
print "CAM::PDF v$CAM::PDF::VERSION\n";
exit 0;
}

if (@ARGV < 1)
{
pod2usage(1);
}

my $file = shift;
my $pagelist = shift;
my $outfile = shift;
my $doc = CAM::PDF->new($file) || die "$CAM::PDF::errstr\n";
open (FILE, ">$outfile");
open (FILE2, ">my$outfile");
foreach my $p ($doc->rangeToArray(1,$doc->numPages(),$pagelist))
{
if ($opts{check})
{
print "Checking page $p\n";
my $tree = $doc->getPageContentTree($p, $opts{verbose});
if (!$tree || !$tree->validate())
{
print " Failed\n";
}
else{
# print $tree;
$tree->render("CAM::PDF::Renderer::Dump");
# $tree->render("CAM::PDF::Renderer::Text");
}
if ($opts{geom})
{
$tree->computeGS();
}
}
else
{
my $str = $doc->getPageContent($p, $opts{verbose});
if (defined $str)
{
# CAM::PDF->asciify(\$str);
print FILE $str;
}
my $pagetree = $doc->getPageContentTree($p);
if (!$pagetree)
{
next;
}
$str=render($pagetree);
if (defined $str)
{
$str=~s/\. \./\.\./g;
$str=~s/^[ ]+$//mg;
$str=~s/\n+/\n/g;
$str=~s/\n.+\n//; #remove the first two lines
$str=~s/\n.\n//;
$str=~s/([a-zA-Z])\n/$1/mg;
$str=~s/\.+([0-9]+)/\($1\)/g;
$str=~s/^(I|II|III|IV|V|VI|VII|VIII|IX|x)([a-z]?)\./ $1$2\./mg;
$str=~s/^([A-Z])\./ $1\./mg;
$str=~s/^([0-9]+)\./ $1\./mg;
# $str=~s/\.+//g;
print FILE2 $str;
}
}
}

close FILE;
close FILE2;

sub _TJ
{
my $str = shift;
my $args_ref = shift;

if (@{$args_ref} != 1 || $args_ref->[0]->{type} ne 'array')
{
die 'Bad TJ';
}

$str =~ s/ (\S) \z /$1 /xms;
foreach my $node (@{$args_ref->[0]->{value}})
{
if ($node->{type} eq 'string' || $node->{type} eq 'hexstring')
{
$str .= $node->{value};
}
elsif ($node->{type} eq 'number')
{
# Heuristic:
# "offset of more than a quarter unit forward"
# means significant positive spacing
if ($node->{value} < -250)
{
$str =~ s/ (\S) \z /$1 /xms;
}
}
}
return $str;
}

sub _Tj
{
my $str = shift;
my $args_ref = shift;

if (@{$args_ref} < 1 ||
($args_ref->[-1]->{type} ne 'string' && $args_ref->[-1]->{type} ne 'hexstring'))
{
die 'Bad Tj';
}

$str =~ s/ (\S) \z /$1 /xms;

return $str . $args_ref->[-1]->{value};
}

sub _Tquote
{
my $str = shift;
my $args_ref = shift;

if (@{$args_ref} < 1 ||
($args_ref->[-1]->{type} ne 'string' && $args_ref->[-1]->{type} ne 'hexstring'))
{
die 'Bad Tquote';
}

$str =~ s/ [ ]* \z /\n/xms;

return $str . $args_ref->[-1]->{value};
}

sub _Td
{
my $str = shift;
my $args_ref = shift;

if (@{$args_ref} != 2 ||
$args_ref->[0]->{type} ne 'number' ||
$args_ref->[1]->{type} ne 'number')
{
die 'Bad Td/TD';
}

# Heuristic:
# "move down in Y, and Y motion a large fraction of the X motion"
# means new line
if ($args_ref->[1]->{value} < 0
# &&
# 2 * (abs $args_ref->[1]->{value}) > abs $args_ref->[0]->{value}
)
{
$str =~ s/ [ ]* \z /\n/xms;
}

return $str;
}

sub _Tm
{
my $str = shift;
my $args_ref = shift;

if (@{$args_ref} != 6 ||
$args_ref->[5]->{type} ne 'number' ||
$args_ref->[4]->{type} ne 'number')
{
die 'Bad Td/TD';
}
if ($lasty!=$args_ref->[5]->{value}){
$str=$str."\n";
}
$lastx=$args_ref->[4]->{value};
$lasty=$args_ref->[5]->{value};
# Heuristic:
# "move down in Y, and Y motion a large fraction of the X motion"
# means new line
# if ($args_ref->[1]->{value} < 0 &&
# 2 * (abs $args_ref->[1]->{value}) > abs $args_ref->[0]->{value})
# {
# $str =~ s/ [ ]* \z /\n/xms;
# }

# return $str."(".$args_ref->[4]->{value}."/".$args_ref->[5]->{value}.")";
return $str;
}

sub _Tstar
{
my $str = shift;

$str =~ s/ [ ]* \z /\n/xms;

return $str;
}
sub render
{
# my $pkg = shift;
my $pagetree = shift;
my $verbose = shift;

my $str = q{};
my @stack = ([@{$pagetree->{blocks}}]);
my $in_textblock = 0;

## The stack is a list of blocks. We do depth-first on blocks, but
## we must be sure to traverse the children of the blocks in their
## original order.

while (@stack > 0)
{
# keep grabbing the same node until it's empty
my $node = $stack[-1];
if (ref $node)
{
if (@{$node} > 0) # Still has children?
{
my $block = shift @{$node}; # grab the next child
if ($block->{type} eq 'block')
{
if ($block->{name} eq 'BT')
{
# Insert a flag on the stack to say when we leave the BT block
push @stack, 'BT';
$in_textblock = 1;
}
push @stack, [@{$block->{value}}]; # descend
}
elsif ($in_textblock)
{
if ($block->{type} ne 'op')
{
die 'misconception';
}
my @args = @{$block->{args}};

$str = $block->{name} eq 'TJ' ? _TJ( $str, \@args )
: $block->{name} eq 'Tj' ? _Tj( $str, \@args )
: $block->{name} eq q{\'} ? _Tquote( $str, \@args )
: $block->{name} eq q{\"} ? _Tquote( $str, \@args )
: $block->{name} eq 'Td' ? _Td( $str, \@args )
: $block->{name} eq 'TD' ? _Td( $str, \@args )
: $block->{name} eq 'Tm' ? _Tm( $str, \@args )
: $block->{name} eq 'T*' ? _Tstar( $str )
: $str;
}
}
else
{
# Node is now empty, clear it from the stack
pop @stack;
}
}
else
{
# This is the 'BT' flag we pushed on the stack above
pop @stack;
$in_textblock = 0;

# Add a line break to divide the text
$str =~ s/ [ ]* \z /\n/xms;
}
}
return $str;
}

2009年6月25日 星期四

Can a regular expression span over multiple lines?

http://www.delphifaq.com/faq/perl/f770.shtml

Answer:
No. You have to do tricks like replacing all \n with a certain string (e.g. __NEWLINE__), then use this certain string in your regex and finally replace all __NEWLINE__ with \n again.

世界知名概率学家钟开莱逝世享年92岁

机率与统计书单(二) 我提到过的机率学家钟开莱,在月初刚过世。以下摘录两篇相关的文章以资纪念,也让人更了解这位大师不媚俗哗众的风骨。他的确是个不讨当权者喜爱的人物,无怪乎在华人世界知名度相对来说并不高。

http://www.sciencenet.cn/htmlnews/2009/6/220403.shtm

据斯坦福大学官方网站消息,世界知名概率学家、华裔数学家、斯坦福大学数学系前系主任钟开莱先生,于6月2日在菲律宾辞世,享年92岁。

钟开莱(Kai Lai Chung)1917年生于上海,浙江杭州人。1936年入清华大学物理系,1940年毕业于西南联合大学数学系,之后留校任数学系助教。钟开莱师从华罗庚,也是中国概率论与数理统计研究的开拓者之一的许宝騄的学生。1944年考取第六届庚子赔款公费留美奖学金。1945年底赴美国留学,1947年获普林斯顿大学博士学位。上世纪五十年代任教于美国纽约州塞纳克斯大学(Syracuse),六十年代以后任斯坦福大学数学系教授、系主任、荣休教授。钟开莱先生著有十余部专著,为世界公认的二十世纪后半叶“概率学界学术教父”。

WanZheng: 钟开莱教授逸传(zz)

发信人: th2168 (th2168), 信区: DMS.THU
标 题: 钟开莱教授逸传(zz)
发信站: 水木社区 (Wed Jun 17 12:20:00 2009), 站内

这个暑假在普林斯顿为Erhan Cinlar教授做研究。他是世界一流的概率学家,尤其在马尔可夫链和泊松过程这两个专题上建树颇多。他在普林斯顿联合创建了世界上唯一的运筹和金融工程系,得以使普林斯顿大学在这一领域的教育和研究走在世界前列。他曾是我概率课的教授,因为这个关系得以央求他收我做暑假研究。当初面试我时,他在最后问了一句,“对了,你有没有听说过Kai Lai Chung?”他就在一张白纸上写下这几个英语字母。我说,没听说过。他愣了一愣,“奇怪了,他告诉我他在中国还是挺有名的啊。”

到了6月2日我们正式开始做课题,第一天见面,Cinlar教授问我的第一句话,“你真没听说过Kai Lai Chung?”我又摇了摇头。他说,“唉,Chung昨天过世了。我和他认识四十多年了。”Cinlar教授并没有显得特别悲伤,只是沉默了几秒,就开始布置课题的相关任务。

接连两次提到这个人名,我对这个Kai Lai Chung产生了好奇,去google搜索了一下。只怪两个拼音系统产生的混淆,这Kai Lai Chung就是国际著名的概率学家钟开莱先生。今天又见Cinlar教授的时候,我便说,的确知道钟开莱这个人,我和他都是上海人嘛。他一下子来了兴趣,指了指桌上的两大格文件夹,“喏,这都是我四十几年和钟开莱的通信。” 他随便翻阅了几封,都是手写的白纸黑字,有的是聊家常,有的是讨论共同的朋友,有的是研究学术问题。早年的信件,钟开莱教授的英文手写潦草而优美,用细密的圆珠笔和钢笔书写。后来的信件上的字体,渐渐地粗了,大了,用记号笔书写,一笔一画像小孩子在练字,甚至有两行写到后面交叉在一起,模糊不可认。Cinlar说,那是因为钟开莱晚年受眼疾困扰,最后两年几近失明。 他指了指一封信,他说,“你看这里,开莱不写of me,一定要写of moi,还有,还有这里,不写my,一定要写mon。他平时说话的时候也是这样,一副法国人派头。”他顿了顿,说,“真是个人物啊!”就从这说开去,Cinlar教授讲了许多关于钟开莱的逸闻。

关于钟开莱的生平、学生时代和华罗庚、吴有训等学术巨擎抬杠,这些在百度百科里都有记载。我这里就记录一下Cinlar教授亲身经历的或者听钟开莱亲口所说的一些往事。

1945年,钟开莱获得庚子赔款公费留美奖学金到普林斯顿大学攻读博士学位。到普林斯顿第一天,他就说,“今天是我到美利坚的第一天,我一定要到镇上最好的餐馆大吃一顿!”就这样,他从火车站拖着行李一路走到普林斯顿最好的法式餐馆Lahiere’s. 他那么多大包小包,风尘仆仆蓬头垢面,好说歹说才被男侍放进餐馆。到了餐馆,也是天有神助,在那个没有网络没有电视信息闭塞的年代,他竟然一眼就认出了其中一个食客就是Harald Cramér。Harald Cramér当时是概率和统计学界的世界第一人,是斯德哥尔摩大学派到普林斯顿的访问学者,也才来普林斯顿没几天。钟开莱就跑到Cramér面前,一本正经地介绍自己,共同吃了一顿饭,饭毕之后Cramér就成了钟开莱的博士生导师。Cramér只在普林斯顿呆了两年,两年之后,钟开莱拿到了博士学位,而Cramér则回到斯德哥尔摩大学当了校长。

钟开莱成名之后和Cinlar参加了许多国际学术会议。有一次在德国柏林的会议,中间休息一次,学者们喝咖啡联络感情。会议的主席是一个新近崭露头角的年轻人,走到钟开莱面前想和他套近乎。那年轻人还没开头,钟开莱就劈头盖脸的骂开了,“主席啊,刚才发言的那个俄罗斯人,讲两句话就要表扬自己,一表扬自己就要大家祝酒,发言一小时祝了十一次酒。我们不能说他,你就不能提醒提醒他吗,真是不开窍。”年轻人彻底懵了。钟开莱不再说话,低头吃蛋糕喝咖啡。过了一会,看到年轻人还没走,突然说,“算了算了,姑且念在蛋糕的份上。啧啧,这德国人真是会做蛋糕啊。”

钟开莱和Cinlar共同创办了一系列讨论概率论难题的讲习班,定期在不同的大学举行讲习班,还编辑了许多学术刊物。有一期讲习班在钟开莱任教的斯坦福大学,时间定在一个周二的下午。Cinlar就和钟开莱说,“周二下午斯坦福还有一个统计学大会,很多统计学家肯定两个会议都想来。你不如换个时间吧。”钟开莱击掌笑着说,“我就是特意安排在这个时间的!这样所有的统计学家就来不了我的讲习班啦。我最讨厌统计学家了。”

刚入清华大学时,钟开莱是物理系学生。因为吊儿郎当逃课得罪了吴有训教授,只能转到数学系。到数学系又觉得华罗庚太罗嗦,到普林斯顿之后专攻数学中研究最少的概率论。概率和统计不分家,要做概率上的学问一定要有扎实的统计功底,而钟开莱偏偏又公然宣布自己“最讨厌统计学家。”他把自己能生展拳脚的范围缩得很小,就是在这样一个鲜有人探索的领域,他打出了一片天地,成了美国概率论界第一人。近年来,概率论因为在金融经济领域的应用,迅速成为学术热门。而今在美国研究概率的教授和学子,要么是钟开莱的学生,要么是学生的学生。他的概率论著作被专业学术论文引用次数最多,据美国数学学会评价,“Chung's writing is literate, elegant, wise, humane. He takes the reader into his confidence, explaining ideas, motivation, and circumstances.”如果钟开莱一生研究物理,研究基础数学,也许也要成为美国物理和基础数学的第一人,而他只是因为“讨厌那些人”而轻易放弃了。

在Cinlar回忆的往事中,不时蹦出一些我从来没听说过的人名。每每我现出疑惑的神情,教授就解释说,“喏,这是当时最聪明的拓扑学家。”“喏,这是当时普林斯顿高等研究院的院长。”这样的次数多了,他突然笑嘻嘻地说,“诞琦,你一定奇怪我怎么认识那么多名人?实话告诉你,我的朋友全是学术名人。至于开莱啊,他结交的名人就更多了,不但有学术上的,还有政治上和商业上的。他的妻子是菲律宾一个很显赫家族的千金小姐,他的儿子现在在华尔街的一家公司做CEO。至于公司的名字嘛,嘿嘿,我以后再告诉你吧。”

然后,Cinlar教授望着书架上的几册书,我知道了,在他的视线中,已经不再有我,也不再有那些书,满满地全是属于老人的回忆。Cinlar说,“我第一次遇到开莱,我就知道我们要成为终身的好朋友。真是个人物啊!你知道什么叫人物吗?就是,我有许多话要说,又不敢说,他全部替我说出来了。”

Cinlar教授的概率论课是我在普林斯顿上过的最难、最幽默,也是收获最大的课程。他总是穿着一身黑色小礼服,白色衬衫黑色领结,在黑板上用优美的花体字写板书。一开始,习惯了Powerpoint板书的同学都怨声载道,抱怨看不懂花体字。不久,大家就被这矮小的土耳其老人的幽默所打动了,他的演讲与教科书无关,听了演讲再去看书,多花心思想想,常有豁然开朗之感。

暑假课题开始后,每两天就去见Cinlar一次,每次,不但是布置新任务,还会告诉我好多有关的趣事。他说,“有一个很傻的广告里,一个女人担心地说,她今天抽了五枝烟,这样下去要得癌了。诞琦,一天抽五支香烟要抽80年才刚刚有风险可能得癌啊!我年轻时,那才叫抽烟,一天抽三包,现在不也是好好的?”还有一次,他告诉我为什么蘑菇收藏家是世界上最危险的爱好。他说,收藏蘑菇到一定境界 ,必定要自己到森林里采集中意的蘑菇,这世界上菌菇品种那么多,长得差不多,弄得不好就要出人命了。他又说,有一次,他看一本叫作《菌菇收藏》的书,书里面写到一种蘑菇,有剧毒,书的作者偏要以身试法,去尝了尝,尝完之后写道“大家都说这种蘑菇有剧毒。我发现我吃了这种蘑菇之后的反应和吃了其他蘑菇的反应别无二致,我只是全身发了两天红疹。”Cinlar教授说到这里,兴高采烈地拍着桌子,“诞琦啊,就是这么一个对所有菌菇都过敏的人,竟然写了一本《菌菇收藏》!这样的人竟然也有!”

Cinlar教授说,钟开莱也是这样一个对什么都过分好奇的人,也是一个常常摆出法国绅士风度西装笔挺的学者。前些日子,我听了陶哲轩的演讲,觉得陶哲轩是个不折不扣的天才。今天我听了Cinlar讲关于钟开莱的逸闻,觉得像钟开莱那样对什么都过分好奇的人是另一种类型的天才。他永远不会厌倦自己的学识,厌倦这个世界,听到见到什么,都啧啧地说,“ 啊,啊,太有趣了!”他又是一个颇有些唐吉珂德式的骑士幻想的绅士。然而,绅士的时代已经过去了。互相交换手写书信四十余年的时代已经过去了。许多普林斯顿的教授不再穿正装去演讲堂,我所知道天天穿西装上班的教授只有三个,概率学家Cinlar,数学家Robert Gunning,和前外交部官员Thomas Christenson教授。万物都会死,不但生物会死,礼仪和习俗也会死。那么,那个彬彬有礼的时代已经死了。对此,Cinlar教授说,“大家都会死的嘛。死不就是一个随机分布吗?”

2009年5月31日,在钟开莱教授的妻子在菲律宾的故乡罗哈斯市(Roxas)的别墅里,钟开莱进入了梦乡。2009年6月1日,钟开莱教授没有醒来。他死在一片芳香的椰子树与海风的梦境里,终年92岁。对此,Cinlar教授评论道,“你知道世界上最幸运的事是什么吗?就是在睡梦里死去。我这个老朋友,真是世界上最幸运的人。”这或许真的是世界上最幸运的一生,出生在战火纷乱的年代,死于一片良辰美景,在中国历史上学术最自由的清华大学和西南联大受教育,一辈子无论学什么都是师从这个领域的巨人。在自己研究的领域,他是美国第一人,桃李天下,被称为“概率学界教父”。他家庭幸福富有,子孙事业有为。

然而,倘若钟开莱当真无愧于是“概率学界教父”,是现今所有概率学家的恩师,那么,钟教授在中国的名声,应该和陈省身齐名。事实上,在中国,钟开莱的名声远不如陈。究其原因,他常年在海外定居、与菲律宾豪门联姻,固然影响了他在中国的知名度。然而,如陶哲轩之类在澳大利亚出生的华裔,成名后都能在中国妇孺皆知,可见钟开莱的不知名,有更深层的原因。这原因,借用Cinlar教授的话,“你知道什么叫人物吗?就是,我有许多话要说,又不敢说,他全部替我说出来了。 ”陈省身和钟开莱的区别,就是敢不敢把话全部说出来的区别,或者,更浅显一点,就是郭靖和黄老邪的区别。一个是中规中矩面面俱到的,一个是“我黄药师是何等样人。”钟开莱那一句“我最讨厌统计学家了”,就不知得罪了多少人,少了多少人在他的故乡为他说话。

不过,钟开莱,这个有着晋人傲骨的、愤世嫉俗的绅士,是不会对此介意的,他连华罗庚都敢得罪,怎么还会在乎死后的名声呢?而我在这里所做的,只是怕那似水流年的时光会把所有的人所有的事都绿坝成一个中规中矩的面面俱到的影子。让我在这里,为一个离经叛道者,立一块丰碑。
--
YOU'LL NEVER WALK ALONE


※ 来源:・水木社区 http://newsmth.net・[FROM: 59.66.185.*]






偶感

--------------------------------------------------------------------------------

作者:钟开莱

  救国自是大好事,然而我听见人说到这两个字的时候,十次里倒有九次不免“毛指”。
  有爱国牌毛巾,有九一八真藕粉,有新生活化学洗染店,尤有新生活运动之必需纯粹国货黑呢帽大批已到之广告。记得还有人曾论证“永安虎标万金油”与救国之关系,使人看了真要替《论语》欣幸得了这许多资料。
  前胡蝶女士等来杭表演话剧《笑与泪》及《还我河山》,有人问我看了作何感想,我说:“胡蝶是好的,别的也不错,只是他们后来似乎不必皆救国。”原来这两个剧本的partand parcel都是三角恋爱,到后来却不知怎的一来,你也救国他也救国了。于是此剧本乃一变而为“民族主义的”的了。
  别人余不知,我之去看胡蝶,目的却是看胡蝶,而谁都知道胡蝶之值得看并非因她救国。
  上文说了“别人余不知”,恐怕有点不老实,实说呢,我就不相信世上真有人买呢帽为行新生活,吃藕粉为纪念九一 八!虽然买呢帽的学生很可以在交到训导处去的生活日记上记上一条“今日购国货呢帽一顶,为实行新生活之表示”,或在写给他父亲要钱的信上说“男因实行新生活,已购新生活国货呢帽一顶,价洋三元二角……”云云,之类。
  尝论中国人最为虚伪,试一读所谓笔记小说之类,淫词艳句,摭拾皆是。篇中每每记载一男女淫奔或人鬼阴合之事,其中描写尽可极尽诲淫之能事,而最后则必加上一段天道昭彰,果报不爽,于是男女皆不得善果而终。这样一来,观者即以作者在“戒淫”,而作者亦自己说服了自己在“戒淫”了,于是明明一部大淫书,遂一变而为劝善文!近日所谓救国,亦复类是,谈恋爱恐为人骂,则假救国之名而行,一本书三百页中二百九十页尽可卿卿我我我我卿卿,只要最后十页中来一下什么东北义勇军或西北垦殖队,就算爱国小说了。作者明知自己在写恋爱,读者亦明知自己在看恋爱,而彼此心照不宣,大家救国,呜呼,此国之所以不得不救乎?

  原载《人间世》1934年6月第5期

2009年6月15日 星期一

如何转PDF文件为text文件?

http://www.9php.com/FAQ/cxsjl/perl/2008/08/2560469127856.html

其实CAM::PDF已经相当不错用了,对比其它ruby/python写的模组,结果已经很不错

http://search.cpan.org/~cdolan/CAM-PDF/bin/getpdftext.pl

getpdftext.pl 就是利用CAM::PDF对pdf文件进行处理

对比getPageContentTree的内容,可以用常规表示法得到相当正确的结果

AS400下编程的文件

http://it.sinru.com/bbs/read.php?tid=1608
1、文件类型
这里所说的文件主要是指物理文件、逻辑文件、显示文件和打印文件。物理文件和逻辑文件主要是存储数据的文件;显示文件主要是用于画面显示格式和属性的;打印文件主要是控制打印文件的布局和显示格式的。这些文件都是在RPG程序中的 F表中进行声明的,供程序中数据处理和存储使用。利用通过RPG程序从多个物理文件中取得相应的数据项显示到画面上,也可以通过RPG程序将用户在画面上输入的数据存储到物理文件中。物理文件中的数据是实际客观存在的,而显示文件和打印文件中的数据只是在程序运行时才有存在,程序退出后其中的数据也相应的消失。
2、文件使用
RPG程序中对所用的文件进行声明以后,这些文件中的字段名称都可以作为已知变量使用。比如当对一个文件进行读操作后,该字段名称中的值即为文件当前读到记录的相应的字段的值,在RPG程序中就可以通过引用该字段名称来获得当前记录的相应字段的值。如果要想文件中写入数据,只需要在RPG程序中,将想要写入的数值传送到相应的字段名称中,然后执行文件的写操作,就可以生成一条新的纪录。更新文件也是一样,不同的就是执行文件的更新操作。显示文件和打印文件的使用也类似,都是将想要的数值传入相应文件的相应字段中,然后执行相应的操作即可。

主要的几种说明表(H, F, I, E, C)

RPG语言中对作用不同的部分分别用开头一列字母来划分,也可以称为XX表或XX部。
RPG语言中包括H表、 F表、 E表、 I表、 C表、 L表、 O表。
但是现在经常用到的主要是H表、 F表、 E表、 I表、 C表。
H表(控制说明标):提供你的程序和系统的信息,其中可说明程序的名字、程序所用日期的格式和是否应用交替核对排序和文件翻译。(可选)
F表(文件说明表):描述程序应用的所有文件信息,包括文件名、如何应用文件、文件记录的大小、文件应用的输入输出设备、文件是否被外部指示器控制等。
E表(扩展说明表):描述所有在程序中应用的记录地址文件、表文件和矩阵文件的信息;包括记录地文件、矩阵或表的名字,表或矩阵数据记录的入口数目,表或矩阵的入口数目及长度。
I表(输入说明表):可以定义数据结构,说明输入文件的记录和字段的一些信息。
C表(计算说明表): 描述在数据上作的计算和计算次序,也可以用于控制某些输入输出操作;其信息包括对操作说明控制级和条件指示器,程序中应用的字段和常数,被处理的操作以及处理之后是否设置结果指示器等,这也是我们编码主要处理的部分,这里实现了程序的处理功能。

写给刚接触RPG的朋友 --- 如何编写RPG程序(1)

http://it.sinru.com/bbs/read.php?tid=573

先说说RPG一般用来做什么吧,举例说:
1. 整个RPG程序不包含任何外部程序,只是做些简单的数学运算,或者对数据区、DATAQ等非文件目标进行操作,这属于相对最简单的情况;
2. RPG程序对物理文件或者逻辑文件进行读、写、更新、删除操作;
3. RPG程序结合物理文件或逻辑文件、以及显示文件进行操作,这属于比较复杂的情况;
4. RPG程序结合物理文件或逻辑文件、显示文件、以及ICF文件(即通讯文件)进行操作,这种情况也比较复杂。
当然,以上的情况只是平时使用的归纳,你也可以根据自己的实际需要结合各种情况,此处不再深入探讨。

以下结合例子简单说说各种情况,假设以下源码文件存放的路径是 库MYLIB、源物理文件MYSRCPF
1. (1)代码如下:

.....CL0N01N02N03Factor1+++OpcdeFactor2+++ResultLenDHHiLoEqComments++++
*************** Beginning of data *************************************
C 'HELLO, W'DSPLY
.....CL0N01N02N03Factor1+++OpcdeFactor2+++ResultLenDHHiLoEqComments++++
C SETON LR
****************** End of data ****************************************


【注】
DSPLY表示显示变量值;
SETON表示给指示器置为*ON的状态,即'1',“SETON LR”表示把LR指示器置为*ON,该句的意思表示最后一条记录,即程序结束。
在按F6创建成员时,source type一栏我们写RPG
然后按回车,进入编辑界面
按5下空格,输入C、然后按F4,在屏幕下方出现一个输入界面。
在这里边我们就很容易找到每个代码所对应的位置。
其中factory1和2里边是我们所操作的变量,他俩中间是用来操作变量的命令。
在往后的result里边是操作后的结果,然后的len是长度,然后的d是小数位数。
需要注意的是,一般来收,数字在输入的时候是要求右对齐的,字符左对齐。
输入完按回车,把光标移到0001.00处输入I按回车即可进入下一行。
还有一点,最后那一行的LR是对应EQ的,编辑完后按F3,在出现的界面中输入Y保存。

按F3保存,假设该文件名是MYRPG,所在的库是MYLIB,源物理文件是MYSRCPF。

编译调用前,要编辑库列表
输入EDTLIBL,按回车,在LIBRARY对应的位置上输入你的库名
在使用某个对象的时候要保证其存在,同时其所在的库也要在系统的库列表上能够找到。系统搜索所要用的对象时是按照系统的库列表的顺序从上向下进行查找的,例如:库列表为下所示
10 QLIB1
20 QLIB2
30 QLIB3
……
如果在QLIB1和QLIB2两个库中都有叫做OBJECT1的对象,那么当程序用到OBJECT1的时候,实际使用的将是位于列表前面的QLIB1中的 OBJECT1,而不是QLIB2中的,因此我们在编译和运行程序的时候一定要注意库列表的值,免得使用不合适的对象而造成程序运行不正确。

程序写好之后,应该进行编译了。用WRKMBRPDM FILE(MYLIB/MYSRCPF),找到刚才的文件MYRPG,输入14,按F4,进入“Create RPG/400 Program (CRTRPGPGM)” 画面,参数:
(i) Program: 生成的目标名(假如为MYOBJ);
(ii) Library: 生成的目标存放的库(假如为MYLIB)。
参数填好之后,按确认键即进行编译,如果程序没错,则生成目标文件,假设为MYOBJ。
在命令行输入CALL MYLIB/MYOBJ,这时命令上应该显示'HELLO, W'。
(【注】目标即可执行文件)

写给刚接触as400的朋友的补充

http://it.sinru.com/bbs/read.php?tid=1607

关于as400的一些讲解:

As400的库类似于windows上的文件夹,但他与windows有些区别。
主要的层次关系是:库-〉对象-〉成员
其最上一层是一个叫做QSYS的库,这也是唯一一个特殊的库,因为它的下面仍然可以包含其他的库,而除此之外的库下都不能再有库。也就是说,库只有一个层次,不象windows下面的文件夹是可以多层存在的。

紧跟着库下来的一层是对象。一般来说,对象是一个可以实际应用和运行的。例如:编译后的数据文件,打印文件和程序。当然,对象也不仅仅包括这些,还有其他属性的对象,最常见的就是QPRGSRC\QDDSSRC\QDSPSRC,这些名字都是预定俗成的名字,当然也可以改成其他的名字。
这几个对象是作为物理源文件属性的。

对象的下面一层叫做成员。最常见的成员类型包括 PF LF DSPF RPG PRTF。这些类型的成员是我们在实际编程中经常打交道的,因为我们所作的编码工作就是针对这几个类型的成员进行的。成员编译后形成相应的对象。如 PF\LF --->可以存储数据的物理文件和相应的逻辑文件;RPG --->可执行的程序,等等。编译系统根据文件不同的类型编译后会形成不同的对象类型。

AS400下RPG编程的常用命令

EDTLIBL 编辑系统的库列表
STRPDM 启动管理工具(对库,对象,成员进行管理操作的工作)
STRSDA 启动SDA(画面和菜单的可视化操作工具)
WRKLIBPDM (LIBNAME) 直接对库操作
WRKMBRPDM (LIB/OBJ MBR) 直接队成员进行操作
STRISDB 单步调试命令
STRDBG DEBUG命令
ENDDBG ENDDBG 命令
RUNQRY FILENAME数据文件查询命令,查看里面的数据
UPDDTA FILENAME 数据库文件更新命令,可以对数据文件中的数据进行更新操作
CLRPFM FILENAME 删除数据文件中的全部数据
CALL PGMNAME (‘’PARM1 ‘PARM2’ ……..) 调用程序的命令

tn5250 is a telnet client for the IBM iSeries and AS/400


http://tn5250.sourceforge.net/

tn5250 is a telnet client for the IBM iSeries and AS/400 that emulates 5250 terminals and printers.

其实以我先学过C/C++/DELPHI/ASSEMBLY再来学RPG的感觉,我觉得RPG真的就是个TELNET到主机上写组语的一个系统。在1988年这可能已经很先进了,相对于UNIX还在发展中,程式的开发可能还是必需用C。不过现在AS/400若论其存在价值,可能只有业主不想花钱重新开发这样的利基而已了…

1. 写给刚接触AS/400的朋友 --- 如何建立库、文件和成员

http://it.sinru.com/bbs/read.php?tid=572

鉴于很多朋友都还是刚接触AS/400,我就从系统登陆开始简单说说吧!
打开AS/400仿真终端(可以是PCOM、CA等软件,如何配置就不说了),输入用户名和密码,进入系统。

如果你的权限足够的话,可以使用CRTLIB命令给自己建个库,如:
CRTLIB LIB(MYLIB) TYPE(*TEST) TEXT('for test')
库建好之后,你可以使用STRPDM->2,在Library处输入库名MYLIB,按确认键就进入该库。

这时库下面没任何文件,你可以使用CRTSRCPF命令建立一个源物理文件,用来放置源码,如:
CRTSRCPF FILE(MYLIB/MYSRCPF) IGCDTA(*YES) TEXT('源物理文件')
【注:】参数IGCDTA(*YES)表示该源物理文件里头的源码文件都可以使用中文

到此为止,自己存放源码的地方已经生成,你可以直接使用以下命令直接进入该源物理文件:
WRKMBRPDM FILE(MYLIB/MYSRCPF)

进入该文件之后,就可以建立任何源码文件了,按F6,显示“Start Source Entry Utility (STRSEU)”画面,参数说明如下:
1. Source member:表示建立的成员名,我们把它理解成存放源码的文件就可以,类似WINDOW平台的TXT文件;
2. Source type:表示建立的成员名的类型,如果不确定,可按 F4 查看,常用类型有
(1)PF: 物理文件;
(2)LF: 逻辑文件;
(3)RPG: RPG程序源码文件;
(4)RPGLE: RPGLE程序源码文件;
(5)DSPF: 显示文件;
(6)CLP: CLP程序源码文件;
(7)CMD: 命令文件
……
3. Text 'description':表示对该文件的描述,可填可不填。
上面的参数填好之后,即进入源码编辑环境,可以写代码了。

代码写完之后:
1. 如果要保存并且退出编辑器,按F3,出现“Exit”画面,参数Change/create member置为Y即可。
2. 如果只想保存而不想退出的话,在编辑器的顶端的命令行输入SAVE,按确认键即可。
3. 如果要放弃更改,那么在编辑器的顶端的命令行输入CAN,按确认键即可。