FastReport 4程序员手册[全文5篇]

时间:2019-05-14 16:09:23下载本文作者:会员上传
简介:写写帮文库小编为你整理了多篇相关的《FastReport 4程序员手册》,但愿对你工作学习有帮助,当然你在写写帮文库还可以找到更多《FastReport 4程序员手册》。

第一篇:FastReport 4程序员手册

FastReport 程序员手册

一、使用TfrxReport 组件工作

1、加载并存储报表

默认情况下,报表窗体同项目窗体构存储在同一个DFM文件中。多数情况下,无须再操作,因而你就不必采用特殊方法加载报表。如果你决定在文件中存储报表窗体或者是数据库的Blob字段(他提供了非常大的弹性,你能够在非编译程序中修改),你必须使用“TfrxReport”提供的加载和存储方法。

function LoadFromFile(const FileName: String;ExceptionIfNotFound: Boolean = False): Boolean;从一个给定名字文件中加载报表。如果第二个参数等于“True”并且文件没找到,那么他会触发一个异常。如果文件加载成功,他返回“True”。

procedure LoadFromStream(Stream: TStream);从流中加载报表。

procedure SaveToFile(const FileName: String);用特殊名称文件存储报表。

procedure SaveToStream(Stream: TStream);把报表存在流中。

例如: Pascal: frxReport1.LoadFromFile('c:1.fr3');frxReport1.SaveToFile('c:2.fr3');C++: frxReport1->LoadFromFile(“c:1.fr3”);

frxReport1->SaveToFile(“c:2.fr3”);

2.设计报表

通过“TfrxReport.DesignReport”方法调用报表设计器。你必须在你的项目中包含报表设计器(必要条件是:要么使用“TfrxDesigner”组件,要么增加“frxDesgn”单元到uses列表)“DesigReport”方法接受两个默认参数:

procedure DesignReport(Modal: Boolean = True;MDIChild: Boolean = False);Modal参数决定设计器是否被模态,MDIChild参数允许把设计器窗体作为一个MDI子窗体。

例如:

frxReport1.DesignReport;

3.运行报表

应用下面两个“TfrxReport”方法中的一个启动报表: procedure ShowReport(ClearLastReport: Boolean = True);启动报表并在预览窗体中显示。如果“ClearLastReport”参数等于“False”,报表将会增加先前的一个报表结果,否则清除前一个报表结构。

function PrepareReport(ClearLastReport: Boolean = True): Boolean;启动报表,没有打开预览窗体,参数赋值与“ShowReport”方法同名。如果报表构造成功,他返回“True”。

多数情况下,使用第一种方法更为方便一些。在报表被构造的同时,他会立刻显示一个预览窗体。

当需要增加另一个报表到前一个报表中的时候,“ClearLastReport”参数显得方便些。(此类技术用于批量报表打印)。

例如:

frxReport1.ShowReport;

4.预览报表

使用两种途径显示一个报表是可能的:两者都是调用“TfrxReport.ShowReport”方法(先前描述过了),或者使用“TfrxReport.ShowPreparedReport”方法来帮助实现。在第二种情况下,报表构造没有被执行,但显示了一个完成的报表。也就是说,你要么在“PreparedReport”方法帮助下构造他,要么在构造前从文件中加载报表(查看“加载/存储完成的报表”)

例如:

Pascal: if frxReport1.PrepareReport then frxReport1.ShowPreparedReport;C++:

if(frxReport1->PrepareReport(true))frxReport1->ShowPreparedReport();

在这种情况下,报表构造器先被完成了,并显示在预览窗体中。构造一个庞大的报表可能要花费很多时间,那就是为什么使用“ShowReport”非等时同步方法会好于

“PrepareReport/ShowPreparedReport”方法。你可以通过“TfrxReport.PreviewOptions”属的缺省值设定预览参数值。(这句翻译的不够好,请参考原文)

原文参考:In this case, report construction is finished first, and after that it is displayed in the preview window.Construction of a large report can take

a lot of time, and that is why it is better to use the “ShowReport anisochronous” method, than the “PrepareReport/ShowPreparedReport” one.One can assign

preview settings by default via the “TfrxReport.PreviewOptions” property.[SPAN]

5、打印报表大多数情况下,你可以从预览窗体打印报表。要人工打印报表,你应该使用“TfrxReport.Print”方法,例如:

frxReport1.LoadFromFile(...);

frxReport1.PrepareReport;

frxReport1.Print;

同时,你可以在显示的打印对话框中设置打印参数,你也可以使用默认设定值。取消打印对话框,请参考“TfrxReport.PrintOptions”属性帮助

6.载入并存储报表

这个功能可以在预览窗口中执行。也可以使用手工方法执行,帮助参考“TfrxReport.PreviewPages”方法:

function LoadFromFile(const FileName: String;ExceptionIfNotFound: Boolean = False): Boolean;

procedure SaveToFile(const FileName: String);

procedure LoadFromStream(Stream: TStream);

procedure SaveToStream(Stream: TStream);赋值和参数化类似与TfrxReport相应的方法。文件包含了完成的报表,默认情况下以“FP3”为扩展名。

例如: Pascal: frxReport1.PreviewPages.LoadFromFile('c:1.fp3');frxReport1.ShowPreparedReport;

C++: frxReport1->PreviewPages->LoadFromFile(“c:1.fp3”);frxReport1->ShowPreparedReport();

注意,完成的报表加载完毕后,预览方法是通过“ShowPreparedReport” 方法执行的。

7.导出报表

他可以从预览窗口中执行。也可以手动操作,通过“FfrxReport.Export”方法,及这个方法中的参数,你可以导出你想要导出的文件类型:

frxReport1.Export(frxHTMLExport1);

导出过滤组件必须是有效的(你必须把他们放到你项目中的窗体上)并调整正确。

The export filter component must be available(you must put it on the form of your project)and be adjusted correctly.8.创建自定义预览窗体

FastReport在标准的预览窗口中显示报表。如果因为某些原因而不适合你,你可以创建一个自定义预览窗体。为了这个目的,需要设计FastReport组件面板中的“TfrxReport”组件。要显示报表,TfrxReport.Preview方法应该连接到这个组件。

在使用TfrxPreview组件的时候,有两个典型的问题。他不会处理按键(箭头,PgUp,PgDown等等)和鼠标滚轮(如果有的话)。要让TfrxPreview同按键工作,设置焦点给他(他是可以做到的,例如,在窗体的OnShow事件句柄中)

frxPreview.SetFocus;

要让TfrxPreview同鼠标滚轮工作,你必须创建OnMouseWheel事件句柄,并且调用TfrxPreview.MouseWheelScroll方法。

procedure TForm1.FormMouseWheel(Sender: TObject;Shift: TShiftState;WheelDelta: Integer;MousePos: TPoint;var Handled: Boolean);begin frxPreview1.MouseWheelScroll(WheelDelta);end;

9.建立复合报表(批量打印)

在某些情况下,需要立刻组织几个报表打印,或者在一个打印预览窗体中封装并呈现几个报表。要执行这些,在FastReport中有些工具能够允许建立一个新的报表附加在一个已经存在的报表上。“TfrxReport.PrepareReport”方法中有一个选项“ClearLasReport”布尔类型参数,默认情况下他等于True,这个参数定义了是否有必要在建立报表时清除前一个报表。下面的方法展示了如何从两个报表中建立一个批量报表: Pascal:

frxReport1.LoadFromFile('1.fr3');frxReport1.PrepareReport;frxReport1.LoadFromFile('2.fr3');frxReport1.PrepareReport(False);frxReport1.ShowPreparedReport;

C++:

frxReport1->LoadFromFile(“1.fr3”);frxReport1->PrepareReport(true);frxReport1->LoadFromFile(“2.fr3”);frxReport1->PrepareReport(false);frxReport1->ShowPreparedReport();我们加载并建立第一个报表,但并没有显示他。然后我们加载第二个报表到同一个TfrxReport对象,并使用“ClearLastReport”参数,让他等于False。这就允许第二个报表附加在先前建立的报表之后。接下来,我们在预览窗口中显示一个完成的报表。

9.1 复合报表中的页数

你可以使用“Page”,“Page#”,“TotalPages”和“TotalPages#”系统变量显示页数或总页数,在复合报表中,这些变量以下面的方式工作: Page批量报表页数

TotalPages批量报表总页数

9.2 合并符合报表页数

正如上面所说的,报表设计页中的“PrintOnPrevousPage”方法让你在打印报表的时候使用前一页的剩余空间接合报表。在复合报表中,允许你在前一个报表的最后一页的剩余空间创建一个新的报表。要执行这个,要使能每一个连续报表的第一个设计页“PrintOnPreviousePage”属性[SPAN]10.交互报表

在交互报表中,你可以在预览窗口定义任意报表对象的鼠标单击反应。例如,一个用户能够单击数据线,结果运行一个带有选择线的明细数据。

任何报表都能交互。要执行他,你仅仅需要创建TfrxReport.OnClickObject事件句柄。下面代码是这个事件句柄的示例:

Pascal:

procedure TForm1.frxReport1ClickObject(Page: TfrxPage;View: TfrxView;Button: TMouseButton;Shift: TShiftState;var Modified: Boolean);begin if View.Name = 'Memo1' then ShowMessage('Memo1 contents:' + #13#10 + TfrxMemoView(View).Text);if View.Name = 'Memo2' then begin TfrxMemoView(View).Text := InputBox('Edit', 'Edit Memo2 text:', TfrxMemoView(View).Text);Modified := True;end;end;C++: void __fastcall TForm1::frxReport1ClickObject(TfrxView *Sender, TMouseButton Button, TShiftState Shift, bool &Modified){ TfrxMemoView * Memo;if(Memo = dynamic_cast (Sender)){ if(Memo->Name == “Memo1”)ShowMessage(“Memo1 contents:nr” + Memo->Text);if(Memo->Name == “Memo2”){ Memo->Text = InputBox(“Edit”, “Edit Memo2 text:”, Memo->Text);Modified = true;} } }

在对象的单击事件句柄上,你可以做如下事情:

-修改一个对象或页的内容,传递句柄(结果,被修改的将被特殊标记,因此修改的内容应该引起重视);

-由于使用重构或重新建立报表,调用TfrxReport.PrepareReport方法

在此例中,点击名字为memo1对象的结果显示这个对象内容的消息。当点击memo2是显示一个对话框,这个对象的内容可能被修改。设置Modified标志为True,允许保持和显示变更。

同样的方法,单击事件可以被定义成不同的响应。例如,运行一个新报表。如下注释是必要的。在FastReport3版本中,一个报表组件可以在一个预览窗口中显示唯一的报表(不像FastReport2.x版本)。那就是为什么一个报表预览窗也会在分开的对象中运行一个报表,或者是同一个对象,但当前报表必须被抹除。

关于给终端用户一个可单击对象提示定位,在预览窗口中,鼠标经过一个可单击对象的时候,我们可以修改鼠标的光标。要做到这些,在报表设计器上选择一个要设计的对象并设置他的cursor属性为不同于crDefault的某个值。

更多的细节涉及到定义的单击对象。在简单报表中,可以依照对象的名字或他的内容来定义。然而,这就不能更多的执行可修改的事例。例如,一个明细报表应当在一个数据选择行被创建。一个用户单击了内容为12的memo1对象。数据行让这个对象参考什么?那就是为什么你应当知道主键了,主键用于明确的标识这一行。FastReport能够赋值一个字串,包含任意数据(在我们的事例主键数据中),对于每个报表对象,这个字串存储在TagStr属性中。

让我们来通过一个报表的例子来举例说明,这个报表包含在FastReportDemo.exe-'Simple list'示例中。这是一个公司的客户列表,包含诸如客户名称,地址,联系人等数据。数据源是来自DBDEMOS演示数据库的Customer.db表。这个表有一个主键,CustNO字段,他没有出现在报表中。我们的任务是终止他通过参考单击完成报表上的任意对象记录他,这就意味着要获取主键的值,要执行此项操作,就要为所有对象的TagStr属性加入值,依赖于主数据栏: [Customers.“CustNo”]

在报表建立期间,使用相同的方法计算TagStr属性内容,同时计算文本对象的内容;这就意味着变量值会替代所有变量的位置。变量细节使用方括号括起来。那就是为什么行值是'1005', '2112'等类似值了。在报表建立后,包含TagStr属性对象的类型取决与主数据栏。一个简单的从字串到整形的转换就会提供给我们一个主键的值,这也是所需记录能够找到的主键。

如果主键是复合的(包含多个字段),TagStr属性的内容可能是如下值: [Table1.“Field1”];[Table1.“Field2”]

在构造一个报表完成后,TagStr属性包含“1000;1”类型值, 此值不同比相同要好。

11.从代码中存取报表对象 报表对象(例如:report page, band, memo-object)是不能在你的代码中直接存取的。这就意味着你不能通过名字寻址对象。例如,当你在你的窗体上寻址一个按钮。要寻址一个对象,在TfrxReport.FindObject方法中找到帮助:

Pascal: var Memo1: TfrxMemoView;Memo1 := frxReport1.FindObject('Memo1')as TfrxMemoView;C++: TfrxMemoView * Memo =

dynamic_cast (frxReport1->FindObject(“Memo1”));然后,你就能够寻址对象的属性和方法。你也使用“TfrxReport.Pages”属性寻址报表页。

Pascal: var Page1: TfrxReportPage;Page1 := frxReport1.Pages[1] as TfrxReportPage;C++: TfrxReportPage * Page1 = dynamic_cast (frxReport1->Pages[1]);

12.从代码中创建报表

作为一项规则,你将在设计器中创建多数报表。然而,在某些情况下(例如,当报表窗体未知的时候),使用代码手工创建一个报表是是十分必要的。想要手工创建一个报表,你需要执行下面的顺序步骤:添加数据源添加报表页-添加栏页

-设置栏属性,接着把他们同数据相连

-在每个栏上加入对象

-设置对象属性,接着把他们同数据相连

让我们来检查一下创建一个简单报表的类型列表。假设我们拥有如下组件:frxReport1: TfrxReport and frxDBDataSet1: TfrxDBDataSet(最后一个连接到DBDEMOS数据,Customer.db表)。我们的报表将包含一个带有报表标题和主数据栏的页。在报表标题栏上有一个带有“Hellow FastReport”文本的对象,主数据栏包含一个带有连接到“CustNo”字段的对象。

Pascal: var DataPage: TfrxDataPage;Page: TfrxReportPage;Band: TfrxBand;DataBand: TfrxMasterData;Memo: TfrxMemoView;

{ 清除报表 } frxReport1.Clear;{ 为报表添加数据集到可存取的列表中 } frxReport1.DataSets.Add(frxDBDataSet1);

{ 添加“Data”页 } DataPage := TfrxDataPage.Create(frxReport1);

{ 添加页 } Page := TfrxReportPage.Create(frxReport1);{ 创建唯一名称 } Page.CreateUniqueName;{ 设置默认字段大小, 纸张和打印方向 } Page.SetDefaults;{ 修改纸张方向 } Page.Orientation := poLandscape;

{ 添加一个报表标题栏 } Band := TfrxReportTitle.Create(Page);Band.CreateUniqueName;{ it is sufficient to set the ?Top? coordinate and height for a band } { both coordinates are in pixels } Band.Top := 0;Band.Height := 20;

{ 为标题栏添加一个对象 }

Memo := TfrxMemoView.Create(Band);Memo.CreateUniqueName;Memo.Text := 'Hello FastReport!';Memo.Height := 20;{ 这个对象将伸展坐标到栏的宽度 } Memo.Align := baWidth;

{ 添加主数据栏 } DataBand := TfrxMasterData.Create(Page);DataBand.CreateUniqueName;DataBand.DataSet := frxDBDataSet1;{ 顶端的调整应当比先前加入栏的顶部+高度大一些 } DataBand.Top := 100;DataBand.Height := 20;

{ 在主数据栏上添加一个对象 } Memo := TfrxMemoView.Create(DataBand);Memo.CreateUniqueName;{ 连接数据 } Memo.DataSet := frxDBDataSet1;Memo.DataField := 'CustNo';Memo.SetBounds(0, 0, 100, 20);{ 调整文本到右侧的对象边缘 } Memo.HAlign := haRight;

{ 显示报表 } frxReport1.ShowReport;

C++:

TfrxDataPage * DataPage;TfrxReportPage * Page;TfrxBand * Band;TfrxMasterData * DataBand;TfrxMemoView * Memo;

// 清除报表

frxReport1->Clear();

// 在报表上添加一个数据集到数据集存取列表 frxReport1->DataSets->Add(frxDBDataset1);

// 添加“数据”页

DataPage = new TfrxDataPage(frxReport1);// 添加一页

Page = new TfrxReportPage(frxReport1);

// 创建一个不重复的名称 Page->CreateUniqueName();

// 设置域大小, 纸张和默认的打印方向 Page->SetDefaults();

// 修改纸张的打印方向

Page->Orientation = poLandscape;

// 增加一个报表标题栏

Band = new TfrxReportTitle(Page);Band->CreateUniqueName();

// 为栏充分设置顶部坐标和高度 // 在像素上包含坐标 Band->Top = 0;Band->Height = 20;

// 在报表标题栏加入一个对象 Memo = new TfrxMemoView(Band);Memo->CreateUniqueName();Memo->Text = “Hello FastReport!”;Memo->Height = 20;

// 此对象将会被按照栏的宽度延展 Memo->Align = baWidth;

// 添加主数据栏

DataBand = new TfrxMasterData(Page);DataBand->CreateUniqueName();

DataBand->DataSet = frxDBDataset1;// 顶部坐标应该大于前边添加栏的顶部坐标+高度 DataBand->Top = 100;DataBand->Height = 20;

// 主数据上加入一个对象

Memo = new TfrxMemoView(DataBand);Memo->CreateUniqueName();// 连接到数据

Memo->DataSet = frxDBDataset1;Memo->DataField = “CustNo”;Memo->SetBounds(0, 0, 100, 20);

// 调整文本到右侧对象的空白 Memo->HAlign = haRight;// 显示报表

frxReport1->ShowReport(true);

让我们来解释一些细节:

所有在报表中使用的数据集都必须添加到数据源列表中,在我们示例中,是用frxReport1.DataSets.Add(frxDBDataSet1)这一行执行的。否则,报表就不会工作。

数据页对于插入内部数据集是必要的,例如TfrxADOTable。这些数据集只能放在数据页。

调用Page.SetDefaults不是必须的,因为在这个案例中页A4纸张设置和页边距都是0毫米。默认值设置10毫米页边距,并捕获打印机页大小和对齐方式。

在增加栏到页面的同时,你要确认他们没有互相重叠在一起。要执行他,顶部和高度的坐标是相似的。总是要在设计器中定位相同的位置的。

对象的坐标和大小是以像素为单位的,因为所有对象的left, Top, Width和Height属性都拥有扩展类型,你能够指出非整形值。下面常量用于转化像素到厘米和英寸:

fr01cm = 3.77953;fr1cm = 37.7953;fr01in = 9.6;fr1in = 96;

例如,一个栏的高度等于5毫米如下设定: Band.Height := fr01cm * 5;Band.Height := fr1cm * 0.5;

12.代码中创建对话框 我们知道,报表可以包含对话框窗体。下面的例子展示了如何创建一个带有OK按钮的对话框窗体:

Pascal:

{ for working with dialogue objects the following unit should be used }

uses frxDCtrl;var Page: TfrxDialogPage;Button: TfrxButtonControl;

{ 添加页 } Page := TfrxDialogPage.Create(frxReport1);{ 创建唯一名称 } Page.CreateUniqueName;{ 设置大小 } Page.Width := 200;Page.Height := 200;{ 设定位置 } Page.Position := poScreenCenter;

{ 添加一个按钮 } Button := TfrxButtonControl.Create(Page);Button.CreateUniqueName;Button.Caption := 'OK';Button.ModalResult := mrOk;Button.SetBounds(60, 140, 75, 25);

{ 显示报表 } frxReport1.ShowReport;C++:

//使用对话框对象工作,会用到下面的单元

#include “frxDCtrl.hpp”

TfrxDialogPage * Page;TfrxButtonControl * Button;

//添加一页

Page = new TfrxDialogPage(frxReport1);

//创建唯一名称

Page->CreateUniqueName();

//设置大小 Page->Width = 200;Page->Height = 200;

//设定位置

Page->Position = poScreenCenter;

// 添加一个按钮

Button = new TfrxButtonControl(Page);Button->CreateUniqueName();Button->Caption = “OK”;Button->ModalResult = mrOk;Button->SetBounds(60, 140, 75, 25);

//显示报表

frxReport1->ShowReport(true);

第二篇:程序员入门进阶手册

这篇文章,我主要是让你成为更为专业的入门程序员。请注意,此时,你可能需要读一些比较枯燥的书,但我想说,这些是非常非常重要的。你一定要坚持住。

编程技能

在系统地学习编程技能之前,我希望你能先看一下 “ The Key To Accelerating Your Coding Skills”,这篇文章会告诉你如何有效地快速提高自己的编程能力。然后接下来是下面几大块内容,但还只是入门级的。

编程技巧方面这个阶段,你可以开始了解一下 Java 语言了,我个人觉得 Java 是世界上目前为止综合排名最好的语言。你一定要学好这门语言。推荐《Java 核心技术(卷 1)》,除了让你了解 Java 的语法,它还会让你了解面向对象编程是个什么概念(如果你觉得这本书有点深,那么,你可以降低难度看更为基础的《Head First Java》)。然后,既然开始学习Java 了,那就一定要学 Spring,推荐看看《Spring in Action》或是直接从最新的 Spring Boot 开始,推荐看看《Spring Boot 实战》。关于 Spring 的这两本书,里面可能会有很多你从来没有听说过的东西,比如,IoC 和 AOP 之类的东西,能看懂多少就看懂多少,没事儿。

操作系统。这里你可以看看《鸟哥的 Linux 私房菜》,这本书会让你对计算机和操作系统,以及 Linux 有一个非常全面的了解,并能够管理或是操作好一个 Linux 系统。当然,这本书有很多比较专业的知识,你可能会看不懂,没关系,就暂时略过就好了。这本书的确并不适合初学者,你能看多少就看多少吧。

 网络协议你需要系统地了解一下数据库设计中的那些东西,这里推荐慕课网的一个在线课程--“数据库设计的那些事”。每个小课程不过 5-6 分钟,全部不到 2 个小时,我相信你一定能跟下来。你需要搞清楚数据的那几个范式,还有 SQL 语句的一些用法。当然,你还要学习和使用一下数据库,这里推荐学习开源的 MySQL。你可以看官方文档,也可以看一下这本书《MySQL 必知必会》。 前端方面在你处理中文时有时会发现有乱码出现,此时需要了解 ASCII 和 Unicode 这样的字符编码。这里推荐一篇文章Character encoding。还有 Github 上的这两个 Awesome 仓库:Awesome Unicode 和 Awesome Code Points。

为什么转成 Java 语言?

相信你可能会问,为什么之前学习的 Python 和 JavaScript 不接着学,而是直接切到 Java 语言上来,这样会不会切得太快了。这是一个好问题,这里需要说明一下,为什么我会切到 Java 这个语言上来,主要是有以下几方面考虑。1.Java 是所有语言里面综合实力最强的,这也是为什么几乎所有大型的互联网或是分布式架构基本上都是 Java 技术栈。所以,这是一个工业级的编程语言(Python 和 JavaScript 还达不到这样的水准)。

2.之所以,没有用 Java 来做入门语言而是用了 Python,这是因为编程是一件比较费脑子的事,一开始学习时,兴趣的培养很重要。Python 比较简单,容易上手,能够比较容易地提起兴趣,而用 Java 则可能比较难。3.在你有了一些编程语言的基础后,有了一些代码的逻辑后,切到工业级的编程语言上来,更为专业地学习编程,是非常有帮助的。像 Python 和 JavaScript 这样的动态语言用着是很爽,但是,只有像 C、C++ 和 Java 这样的静态语言才可以让你真正地进阶。

4.对于一个合格的程序员,掌握几门语言是非常正常的事情。一方面,这会让你对不同的语言进行比较,让你有更多的思考。另一方面,这也是一种学习能力的培养,会让你对于未来的新技术学习得更快。很多时候,一些程序员只在自己熟悉的技术而不是合适的技术上工作,这其实并不好,这会让你的视野受限,而视野会决定你的高度。综上所述,这就是在入门的时候我故意让你多学几门语言的原因。

编程工具

编程工具方面,你需要开始学习使用下面这些工具了。

 编程的 IDE。传统一点的,你可以使用 Eclipse。当然,我推荐你使用 Intellij IDEA。这两个工具都可以开发各种语言,但是主要用在 Java。如果你想玩得更时髦一些的话,使用 Visual Studio Code 也不错,这个工具潜力十足,用其开发 Python、JavaScript、Java、Go、C 和 C++ 都能得心应手(教程-本文发布时还基本没怎么翻译完)。

 版本管理工具。版本管理工具是非常重要的编程工具。传统的有 P4、SVN、CVS 等,但都会被 Git 取代,所以,你就只用学习Git 就好了。学习Git 的教程网上有很多,这里我推荐非常系统的 Pro Git 第二版(如 果你觉得 Pro Git 比较枯燥的话,备选猴子都能懂的 Git 入门),然后你要学会使用 GitHub。关于一些 Git 环境安装和准备以及 GitHub 使用,你可以自行 Google(比如:这篇Github and Git 图文教程 或是这篇Git 图文教程及详解)。

 调试前端程序。你需要学会使用 Chrome 调试前端程序,Google 一下会有很多文章,你可以看看 超完整的 Chrome 浏览器客户端调试大全。 数据库设计工具。你需要学会使用 MySQL WorkBench,这个工具很容易使用。相关的手册,你可以看一下官方文档。

实践项目

这回我们需要设计一个投票系统的项目。业务上的需求如下:

     用户只有在登录后,才可以生成投票表单。投票项可以单选,可以多选。

其它用户投票后显示当前投票结果(但是不能刷票)。投票有相应的时间,页面上需要出现倒计时。

投票结果需要用不同颜色不同长度的横条,并显示百分比和人数。

技术上的需求如下:

这回要用 Java Spring Boot 来实现了,然后,后端不返回任何的 HTML,只返回 JSon 数据给前端。

 由前端的 JQuery 来处理并操作相关的 HTML 动态生成在前端展示的页面。

 前端的页面还要是响应式的,也就是可以在手机端和电脑端有不同的呈现。这个可以用 Bootstrap 来完成。

如果你有兴趣,还可以挑战以下这些功能。

在微信中,通过微信授权后记录用户信息,以防止刷票。 可以不用刷页面,就可以动态地看到投票结果的变化。

 Google 一些画图表的 JavaScript 库,然后把图片表得风骚一些。

小结 上面那些书和知识你要看完,还要能理解并掌握,我估计你最少也要花 1-2 年左右的时间。如果你能够走到这里,把前面的那些知识都了解了,不用精通,能独立地做出上面的那些实践项目,那么,你就算是真正的入门了。

而且,你已经是一个 “ 全栈工程师 ” 的样子了,在这里我要给你一个大大的赞。如果这个时候,你对编程还有很大的热情,那么我要恭喜你了,你可能会是一个非常不错的程序员。加油啊!

上面的那些技术已经算是比较专业的了。如果你已经大致掌握了,我相信你可以找到至少年薪 20 万以上的工作了,而且你的知识面算是有不错的广度了。但是深度还不够,这个时候,是一个比较关键点了。

你可能已经沉醉在沾沾自喜的骄傲的情绪中,那么你也可以就此止步,加入一些公司,在那里按部就班地完成一些功能性的开发,成为一个搬砖的码农。你也可以开始选择一个方向开始深入。

我给你的建议是选择一个方向开始深入。因为你并不知道你未来会有多大的可能性,也不知道你会成为什么样的人,所以为什么不再更努力一把呢?

后面,我们就开始非常专业的程序员之路了。这也是一般程序员和高级程序员的分水岭了,能不能过去就看你的了。

第三篇:《程序员岗前培训手册》

程序员岗前培训手册

北京应用技术大学

目录(CONTENTS)

前言

面试是双向选择

软件公司研发技术岗位扫描与岗位职责

如何快速融入技术团队(程序员入岗的注意事项)优秀程序员应具有的品质与习惯 谈谈学习方法

外包软件、商品软件、项目软件简介

前言

同学们经过在北京应用技术大学两年的学习,都满怀憧憬地向往程序人生的开始,也对即将走上的工作岗位和环境充满了期待,期待通过程序来证明自我的价值。程序员,相信在很多同学眼中是一个有趣、特别、高薪、充满艰辛而又非常神秘的职业,因为手下那一行行跳动的代码不仅实现了生动的功能,同时也表达着程序员对人生的理解和追求。当程序员实现了一个独到的创意之后准备熄灯休息时,天已蒙蒙亮…..当程序员看着用户熟练地操作自己的软件解决一个个复杂事件时,脸上那写满成就的微笑…..的确在这个行业里出现了太多的英雄人物和企业,而每一个英雄的事迹和成就都足以让我们热血沸腾、摩拳擦掌……

在同学们即将步入程序员岗位之前,需要对软件研发相关职位的职责范围与工作特点有所了解,掌握一些入职的基本技巧和注意事项,检查自己的技能与行为习惯,有的放矢,提高面试和就业的成功率。入职后能尽快地融入到技术团队,近而快速成长,成为团队技术骨干和最优秀的职员。在工作中养成积极而良好的行为习惯和职业素养,为自己的职业发展创造一个良好的开端。

本手册从面试、技术岗位职责、如何快速融入技术团队、优秀程序员的品质与习惯、学习方法、外包软件/商业软件/项目软件简介等几个方面阐述了同学们在踏入工作岗位之前应该了解的知识和注意事项。

面试是双向选择

一般同学都会误认为面试时应聘者处于弱势,要接受招聘者的挑选,从而从心理上承受很大的压力,而影响自己正常的发挥和才能展示。其实大可不必,因为面试是双向的,选人和择业是平等的。况且现在市面上的用人单位或招聘岗位也是良莠不齐,甚至还有一些骗子公司,这就要求同学们在应聘时擦亮眼睛,注意分辨。当然大多数公司都是良性的,他们要么是已具规模,各部门及岗位功能分工很明确,他们会根据业务的发展或作为人才储备而有针对性的招聘相关技术人员,而有的公司可能是刚刚成立,业务与核心技术还未形成,他们需要招聘到能为他们提供解决方案或创意的技术人员,所以对于这些类型的公司,他们对人才的渴求也都不亚于同学们对工作岗位的渴求,若是聘到一个优秀的技术人员对业务或项目的推进将会使公司获得更大的利益,或者使公司的发展少走弯路甚至能改变一个公司的命运。相反,如果招不到合适的人才或者使用一个较差的技术人才,不但不能推进项目的进展,还要花费几个月的培养时间和费用,甚至阻碍业务开拓甚至项目搁浅。所以当同学们想得到一个工作岗位的同时,也要看到企业更需要一个优秀的员工,二者是平等的。在面试时,同学们在一种非常平和的心态下,充分发挥,尽可能地展示自己已经掌握的技能,展示学习能力和发展潜能;另一方面也要尽可能地提前了解公司的背景和业务以及应聘岗位的职能,从而加以辨别和选择。一旦本次面试不能成功,表明要么岗位不适合你,要么你不适合岗位,或者因为你本次的表现不佳,这都是很正常的,一定不要有挫败感,要及时总结面试时的表现方式以及沟通技巧,若感觉自己的确能够胜任该岗位,只是因为自己的临场发挥不佳而没有展示出自己的实际水平,也可及时和招聘公司联系,经询问确认对方没有找到合适人选的情况下,表明诚意,请求复试机会。总之,若本次失败,一定不要影响下一次的面试,要积极总结,为一下次面试作准备。

正常运营的公司因业务的不断发展,人才需要不断的更新、补充和储备,所以他们一直都需要人才,况且公司每次组织招聘都会花费一大笔费用,也希望能够找到合适的人才,所以公司面试时一般不会出太吊钻的问题来为难你,同学们也不要过分担心。

另一方面,同学们在坚信“天生我才必有用”的同时,也要正确看待现在的就业形势,对第一份工作也不要过于理想化,要摆正心态,坚持从基层做起,先就业再择业,职场上“骑驴找马”也未必不是一种现实的理性选择。

总之,面试是双向性的,是招聘单位与同学们相互展示、相互认识、互相挑选的一次沟通过程。同学们 在求职的过程中,要正确看待面试,放下思想包袱,充分重视,充分准备,从容应对。

软件公司研发技术岗位扫描与岗位职责

一般中小型软件公司设置的技术岗位有:研发总监、项目经理、需求分析人员、系统架构与分析人员、数据库设计人员、程序员、项目助理与文档专员、测试人员、技术支持(售前/售后)、美工或网站前台人员等,这些职位的工作联系非常密切,根据公司规模的大小,以上职位可由一人或多人兼任,比如一个小型的软件公司可能只有一个人完成软件的总体设计、架构、编码、测试、文档等工作。这些岗位的职责范围大致是:

研发总监:全面负责研发及技术部门的整体工作。

项目经理:在整个项目开发过程中组织项目所需的各项资源,对项目的范围、项目的质量、项目时间以及项目成本进行管理与控制。根据项目范围、质量、时间与成本的综合因素的考虑,进行项目的总体规划与阶段计划,保证项目组目标明确且理解一致;在项目生命周期的各个阶段,跟踪、检查项目组成员的工作质量;保证项目在预算成本范围内按规定的质量和进度达到项目目标。

需求分析人员:项目前期与客户方打交道最多的人,对于客户来说,他可以代表整个项目组,对于项目组成员来说他的意见可以代表客户方的意见,项目组内所有与客户需求相关的事情必需得到他的认可。他的工作主要是:

1、在项目前期根据《需求调研计划》对客户进行需求调研。

2、收集整理客户需求,负责编写《用户需求说明书》。

3、代表项目组与用户沟通与项目需求有关的所有事项。

4、代表客户与项目组成员沟通项目需求有关的所有事项。

5、负责《用户需求说明书》得到用户的认可与签字。

6、负责将完成的项目模块给客户做演示,并收集对完成模块的意见。

7、完成《需求变更说明书》,并得到用户的认可与签字。

8、协助项目组有关人员对需求进行理解。

系统架构与分析人员:是项目的总体设计师,组织构建新产品的开发与集成、新技术体系等,也可以理解为技术总监。是在技术上对所有重要事情做出决定的人。系统架构在整个软件开发过程中都起着非常重要的作用,并随着开发进程的推进而其职责或关注点不断地变化。

1、在需求阶段,负责理解和管理非功能性系统需求,比如软件的可维护性、性能、复用性、可靠性、有效性和可测试性等。审查客户和市场人员所提出的需求,确认开发团队所提出的设计;组织开发团队成员和开发过程的定义;协助需求分析师完成《用户需求说明书》、《需求变更说明书》等。

2、在设计阶段,负责对整个软件架构、关键模块、接口的设计。对系统进行分析与建模,完成《系统架构说明书》、《系统概要设计说明书》、《系统详细设计说明书》。

3、编码阶段,成为程序员的顾问,负责重点代码检查,并且经常性地要举行一些技术研讨会、技术培训班等;

4、测试及实施阶段,随着软件开始测试、集成和交付,集成和测试支持将成为工作重点;

数据库设计人员:根据《系统架构说明书》负责进行数据库选型与建模。由于数据库是整个系统运行的核心,数据库设计的好差直接影响着整个系统的开发效率和系统运行的优劣。他是项目组中唯一能对数据库进行直接操作的人,对数据库结构的每一次改动都要得到他的认可。主要职责:

1、根据数据库建模结果,绘制数据库关系图。进行数据库建库以及数据库进行初始化操作。

2、对数据库进行维护、备份、恢复、同步。

3、负责客户数据的导入导出。

4、根据《系统详细设计说明书》编写对应的视图、存储过程、函数、触发器等。

5、对项目组其它成员进行SQL方面的指导。

6、为测试建立相关测试数据。

程序员:负责系统的最终代码实现。主要职责:

1、参与需求调研、项目可行性分析、技术可行性分析和需求分析。

2、协助完成《系统详细设计说明书》,并根据《系统详细设计说明书》进行编码实现;

3、对自己代码进行复查,并进行简单的测试。

4、撰写相关技术实现或功能描述文档。

5、负责向项目经理及时反馈软件开发中的情况,并根据实际情况提出改进建议。

6、参与软件开发和维护过程中重大技术问题的解决。

项目助理或文档专员:协助项目经理在项目日常管理和数据分析方面的工作,进行与项目有关的协调工作,编写项目进度报表,参与组织项目协调会,组织项目非技术文档的编写、传递与归档,以及与市场人员或其他部门的日常沟通,协助项目资源协调工作。跟踪项目进展。项目或软件包的打包、发布以及授权锁的制作等工作。

测试员:负责实施软件测试。测试是整个项目系统中非常重要的一个环节,项目质量的保证,他的主要工作就是找到项目中存在的不合理、不合格的部份,并要求项目其它成员按其给定的项目质量完成项目。保证了系统功能实现是否与功能设计和需求定义一致。主要职责:

1、根据软件项目规范编写测试计划,设计测试数据和测试用例。

2、采用合适的测试方法实施软件测试,形成各阶段的测试报告,并对软件问题进行跟踪分析和反馈,推动测试中发现问题及时合理地解决。

3、完成对产品的集成测试与系统测试,对产品的功能、性能及其他方面的测试负责。

4、协助程序员进行软件代码检查,提出对软件的进一步改进的要求。

技术支持人员:主要负责软件产品或项目在技术层面上与客户的交流,根据工作重点分为售前支持和售后支持。

 售前支持:是销售人员和开发人员的桥梁,协调销售人员、用户、开发人员的关系,制作产品功能演示PPT文档或多媒体资料,将公司的技术实力向用户展示,技术标书的撰写,定期采集、分析和整理用户的需求,配合销售制订产品销售策略,从技术上支持市场销售业务等。

 售后支持:负责编写《用户手册》、《操作手册》,制作系统操作视频教程等多媒体培训教材;负责系统实施(包括系统安装、用户培训、系统试运行等),协助用户进行“用户确认测试”和编写《确认测试报告》;通过电话、网络、及时通讯等多种渠道解答用户在使用中的问题,提供售后服务。收集、整理用户的建议等。

美工或网站前台人员:负责完成软件设计师安排的功能界面设计和简单网站的设计。

1、负责对项目整体色彩的调配。

2、向系统分析师提出项目美化的建议。

3、为BS 项目提供一套或几套CSS样式表及HTML结构表

4、为CS项目提供符合项目内容的静态、动态图片。

5、并为程序员提供界面指导。

如何快速融入技术团队

——程序员入岗的注意事项

同学们刚刚结束学校的集体生活,面对新的工作环境、新领导、新同事、新任务、新的制度、新的生活节奏,很多的变化需要你尽快适应,很多的事情需要你独挡一面,而又有许多事情需要你与同事通力协作来完成…… 以下是新程序员入职后尽快融入技术团队应注意的事项:

1、认真学习公司的发展背景与历程、主营业务以及规章制度。

进入公司前可能对公司已经有了一些了解,入职后,相关人力资源管理部门会组织培训,解读公司文化,介绍公司发展背景、主要职能部门以及主要业务特点,学习公司考勤、人事、办公等管理规定和规章制度。有些新入职的程序员或技术人员,认为这些不含技术成分没有必要花精力去学习,其实这种认识是错误的,公司文化及各种制度是整个公司的灵魂,是公司正常经营活动保障和员工行为的一种约定,新职员只有对公司的发展背景和经营状态有充分的了解,接受公司文化,高度认同公司的核心价值观,严格遵守各种规章制度,才能自觉地规范自己的行为习惯,在工作学习中才有主动性,遇到工作压力时也能坦然地接受,不会有抵触心理,从而能更快地推动自己的工作。

2、积极学习业务知识、类库及现有程序资源,把握学习的技术方向。

程序员入职后,若有一个成熟的开发团队,一般都会有一个老职员来带领学习,这一阶段主要有三个方面的学习任务,第一是公司业务知识,因为程序员只有对业务知识熟悉了,才能更好的理解和把握功能需求,比如做通信方面的软件,你要学习一些通信行业知识;若做财务软件,你要了解一些财务知识。第二,现有的类库是公司开发部门积累的程序资源,学习和使用它可以规范统一程序的风格,提高开发的速度,掌握并能使用这些资源,可使你尽快与老职员有程序上的共同语言。第三,学习并加强在此领域的编程技能,因为在学校学习的是通用的知识,掌握的是一种知识导入与学习的方法,那么在公司应用方面也许要求你某一个方面很精通,比如网站的前台、数据库、图形处理、多媒体、网络编程等某些方面的技能需要强化。案例:

小张(男)和小胡(女)是同一个大学毕业的应届生,在2005年4月份同时进入公司做技术支持,当时两人的工资都是每月1500元,而两年后的今天小胡已是研发部的一个程序员,工资是每月4300元,而且是公司重点培养的对象之一。小张现在还是在做技术支持,工资是每月2600元,他们两人可以说是起点相同,但两年的发展却让他们有了明显的差距,小胡比较爱学习,工作非常踏实,对业务知识也掌握得非常精通,而且在做技术支持工作的时候,业余时间学习编程,由于做技术支持与程序员交流比较多,小胡抓住了这个学习编程的机会,但她从不在公司上班时间学习程序,在做技术支持工作时,她上班时间钻研业务知识、软件需求、学习程序实现的思想,业余时间练习代码。在做技术支持一年后,她通过了研发部的考核,进入研发部开始做编程。而小张与她对比就不同了,他只是做好本质工作,没有潜心学习,对业务知识、软件知识只是一般了解,工作上很业绩平平,总体上不出色也没出大的差错。工资涨得当然也慢,小张和小胡的起点相同,但小胡比较主动学习,很明显他们两个在职场上的差距就拉开了。

3、展示进步,创新思考,体现价值。

入职之初,通过积极的学习与适应,应该说进步是非常快的,要及时的总结,并把工作学习的总结和进步程度及时向主管汇报(口头、邮件、书面),阶段工作总结应包括以下几点:已经完成的工作、技术上的进步、业务上的进步、从学生到职员心态上的转变、八小时之外的学习状态等。这样一方面可以疏理一下知识结构,把握自己的学习阶段,一方面让主管根据你的知识结构和技能状态有针对性地给你分配合适的任务。

另外在工作当中也要注重思考,对工作进行适当的改进,并提出改进意见,这样能更快是体现出你的进步和工作价值。

4、积极参加团队活动,适应团队文化,创造与团队成员友好而积极的协作氛围。

能尽快适应团队文化,与同事友好沟通是任何岗位都需要的职业素质,只是在研发团队里要显得尤为重要,由于研发工作的重要与特殊性,若在软件商品化和产品化的开发阶段,不良的沟通协作可能导致项目的流产。另外,部分程序员写程序久了都会很注重与机器或代码交流,有的不容易与新职员交流,有的他们因有大量的工作任务而顾不上,有的是因为他们有太多的思想与创意,和一个新来的职员没有共同语言,有的是人为设置“技术壁垒”(因担心新职员威胁到自己的岗位,而不愿传授一些知识)。那么新职员一定不要因为他们没有主动与你交流而放弃交流,或者认为自己被冷落而与逐渐远离团队,而是要在适当的时间与他们主动交流,主动向他们请教,积极参加团队的集体活动,创造与同事交流合作的良好氛围。要尽可能地为团队多做贡献,不要因为多干一些工作或多加一点班,就有不良的情绪,从而影响正常的沟通与交流。另外,在研发团队里的沟通与协作,还体现在代码上,自己设计的功能模块是否能为别人提供良好的说明和程序接口。总之,与同事友好愉快的协作,尽快融入研发团队,是新入职的程序员技术快速进步和稳定职位的重要因素。

5、正确面对工作压力,学会释放“厌职”情绪。

许多同学进入一个新的工作环境,面对的是很多新事物,感觉工作节奏太快,工作压力太大。其实新职员有工作压力也是正常的,从职业生涯发展的角度来看,这种工作压力是非常必要的。同学们在进入公司后,要勇于接受工作压力,把这种压力作为进入初职锻炼的良好机会,树立良好的心态,不要逃避,更不要产生“厌职”情绪,公司还正在培养你,你却选择退缩而自炒“鱿鱼”。工作中要学会积极与同学沟通,注意工作方法,释放和减轻压力。其实我发现一些新职员说工作压力大,做事不顺心,仔细分析之后可以发现他们感觉的工作压力大与“不合群”有很大的关系。有些同学到公司后,一坐下就是八小时,语言和行为与同事格格不入导致他不敢言语不敢行动,下班时间到了,其实他不是工作学习本身的累,他们感到更累的是“心”。这些新职员在工作中总是希望别人主动接近自己,自己却不会主动与人交流,时间长了,同事觉得他“不爱说话”,也就逐渐放弃了与他的交往,这时他又会感到被排挤,感到孤独,心理压力就会增大。另外技术上单打独斗,不能利用别人的资源,因此完成相同的工作,付出的努力和压力就要比其他同事大得多。所以新职员在入职之初,一定要正确看待工作上正常的工作压力,学会与团队成员友好相处,创造一种“如鱼得水”的工作氛围,那么真正技术上的压力都不会成为问题的。

如果公司还没有成熟的开发团队,需要你一个人承担开发项目,着手组建开发团队,那么就要求你充分一切时间,利用网络资源,有技术难点及时到网络上寻求帮助,同时与相关部门人员密切合作,保持动态及时的沟通,及时报告工作进度,争取尽快拟出解决方案或产品。

优秀程序员应具有的品质与习惯

 善于理解与把握需求

程序员的劳动成果就是满足需求的程序,那么在动手写代码之前,只有完整地理解一个模块的需求才能做出好的程序,优秀的程序员在分析需求的基础上,应该能抓住问题的关键技术,从而能够建立合适的数据模型,尽量在代码中少走“弯路”。 善于学习与总结

当然善于学习,是对任何行业任何职业的最根本的要求,对于程序员,这种要求就更加高了。其实研发部门招聘程序员,其实并不一定注重你现在能做什么,而更注重的是你的学习能力、你的编程潜力,因为程序员是很容易被淘汰,很容易落伍的职业,一种技术可能仅仅在三两年内具有领先性,若你不能跟进新的技术,不学习新的技能,那么不断出现的新技术会使你显得非常笨拙。善于总结,也是学习能力的一种体现,每次完成一个研发任务,完成一段代码,都应当有目的的跟踪该程序的应用状况和用户反馈,随时总结,找到自己的不足,这样逐步提高,才能成长起来。

 规范化的编码习惯

养成良好的编码习惯,比如:变量命名清晰,语句嵌套明确,函数具有独立功能,适当注释等等,因为这些不但有助于代码的移植和纠错,也有助于不同人员之间的协作。 良好的文档习惯

良好的文档是正规研发流程中非常重要的环节,作为代码程序员,30%的工作时间写技术文档是很正常的,而作为高级程序员和系统分析员,这个比例还要高很多。缺乏文档,一个软件系统就缺乏生命力,在未来的查错,升级以及模块的复用时就都会遇到极大的麻烦。 代码复用性,模块化思维能力

复用性设计,模块化思维就是要程序员在完成任何一个功能模块或函数的时候,要多想一些,不要局限在完成当前任务的简单思路上,想想看该模块是否可以脱离这个系统存在,是否可以通过简单的修改参数的方式在其他系统和应用环境下直接引用,这样就能极大避免重复性的开发工作,如果一个软件研发单位和工作组能够在每一次研发过程中都考虑到这些问题,那么程序员就不会在重复性的工作中耽误太多时间,就会有更多时间和精力投入到创新的代码工作中去。 团队精神与沟通协作能力

这是程序员应该具备的最基本的,也是最重要的安身立命之本。软件或项目的各模块功能需求的理解准确,一个功能实现的修定,是否会影响其他模块等,没有充分及时的协作对一个项目来说几乎是不可想象的。我做了几年开发,感觉沟通真的太重要了,其实软件研发过程中最重要的不是技术问题,而是管理中的沟通问题,比如初级程序员或许是碍于面子或其他原因,不懂的问题也不想问,总是把问题掖着藏着,而高级程序员又不理解初级程序员的开发任务总是完不成,其实可能是高级程序员不了解初级程序员的真正困难,或者没有把要实现的逻辑和思路讲解清楚。合作起来总会有一些不透彻,要么一个问题讨论多次依然是问题没有结果,要么是有些问题根本不反映,大家都掖着藏着,报喜不报忧,待到问题暴露已无法挽回,严重的阻碍了项目的进度。所以我最好的建议就是,高级程序员应该把问题讲到明白为止,初级程序员应该把问题问到明白为止,并且不仅仅是口头上讲明白、听明白,还一定要形成文字,现在网络非常方便,公司都会有企业邮箱,把问题的讨论过程通过mail的形式记录保存,明确确认,这样障碍才能去除,项目才能得以顺利进展。

案例1:

陈某是北京某重点大学自动化专业的毕业生,编程基础知识非常扎实,在学校学习期间也有许多代码积累,从技术上说应该是很有潜力的,但他性格有点孤僻,不太容易与同事沟通,当时录用他时公司是看在他的编程基础很好,以为在研发部大家多带动他,应该会好些的。进公司有两个多月了,一次在做某油田项目中负责其中一个小模块的开发,在开发过程中我经常询问他有没什么问题,他每次都有些含糊地说没有。可当项目交付的时候,发现他做的某一功能与当初功能定义不符,客户就抓住这一点说与合同中需求描述不符,由此延期支付28万的余款,使该项目后期维护起来非常被动。而导致这一结果就是陈某在做程序时有问题自己绕过去了,没有及时与项目组成员交流,而独自采用了他熟悉的一种解决办法。项目汇报会刚结束,人事部门就通知陈某交接工作,到财务结算工资…..文摘:下面这故事《请按一下九层》我一直和我的同事们分享。是《读者》中的一篇文章: 这是全市最忙的一部电梯,上下班高峰时期,和公共汽车差不多,人挨着人。上电梯前和公司的人力资源总监相遇,说笑间,电梯来了,我们随人群一拥而进。每个人转转身子,做一小小的调整,找到了一种相对融洽的关系。这时,一只胳膊从人逢中穿过来,出现在我的鼻子前头。我扭头望去,一个小伙子隔着好几个人,伸手企图按电钮。他够得很辛苦,好几个人刚刚站踏实的身子不得不前挺后撅,发生了一阵小小的骚动。

那个人力资源总监问道:“你要去哪一层?”“九层。”有人抬起一个手指头立刻帮他按好了。没有谢谢。

下午在楼道里又碰到那个人力资源总监。“还记得早上电梯里那个要去九层的小伙子吗?”她问我。

“记得呀,是来应聘的吧?”九层,人力资源部所在地。“没错,挺好的小伙子,可我没要他。”“为什么?”

“缺少合作精神。”她露出一副专业HR的神情,“开口请求正当的帮助对他来说是件很困难的事情,得到帮助也不懂得感激。这种人很难让别人与他合作。”

我点头称是。如果那个小伙子坦然而自信地说一句“请按一下九层”,结果会怎样呢?大家不但不会反感他的打扰,而且帮助他的人还会心生助人的快乐,最后他也能得到想要的工作。

这个故事表明,良好沟通不仅仅体现在礼貌地说声“请”、“谢谢”,而是一个职员能够创造愉快、高效、和谐工作氛围的素质和习惯。

 时刻修定自己的认识和行为与公司的核心价值观(短期目标、长期目标)保持一致

公司或研发团队在什么时段做什么样的项目,或者根据项目进度的计划,在什么时间做什么功能模块,作为程序员要高度地与这些目标保持一致,不要在关键时刻“掉链子”,这是最重要的。

案例:

小张是公司里的转正不久的程序员,很聪明,对新技术接受很快,缺点就是非常的贪玩,对项目组的事缺乏主动性和责任心,平时的工作中主管已经提醒过他多次要注意工作的责任心,但他都不太放在心上,对事依然是敷衍。一次在做上海铁通的项目中,小张负责项目中的一个模块,当软件架构出来以后,需要出差上海为客户现场演示和进一步确认需求,由于合同还没有正式签下来,所以此行的技术交流对公司能不能签下这个项目至关重要,公司派由我和小张在内的项目组4人出差上海,临行前我们多次开会研究方案,确保拿下这个项目,下午到了上海之后约好第二天上午与客户见面,正当大家为第二天的交流捏一把汗,积极准备的时候,小张却说是第一次到上海,要求先去外滩看夜景,在得到项目组的否定之后,小张竟一个人偷偷到外滩看夜景至到深夜才回到宾馆。第二天的技术交流会上,小张负责的模块问题最多,虽然最后整个项目的交流还算成功,公司总算签下了这个项目,但小张也被辞退了。原因很简单,小张一直没有把公司的事放在心上,项目组出差第一目标是与客户交流好,拿下项目,而小张出差上海的第一目标是看一下外滩。所以象小张这样的技术上不管有多么出色,但总在公司的关键时刻“掉链子”,被公司辞退也是早晚的事。就在写此案例的前几天,在地铁上我偶遇小张,谈话中得知他被辞退后半年内又经历了一家公司。而此刻他又在匆匆地找工作。

谈谈学习方法

说起学习的方法,其实每个人都有自己的学习方法,也许这种方法对我来说有用,但不见得就对所有的人有用。所以,不要盲目的跟着别人的学习方法学习,要思考属于自己的学习方法。但以下几个原则是要遵守的:  坚持学习。首先要有毅力,对编程的狂热也可以在一定程度上起到帮助。学习编程应该说要经历好奇——困难——容易——郁闷——成就感——困惑——轻松的几个阶段的循回,不管哪个阶段都需要天天学习,坚持每天都要进步,不能半途而废,培养一种坚持克服困难的毅力。案例: 记得开发团队里有一个基础不是太好的程序员,刚入职两个多月,表现一般,有一天早上他眉飞色舞地在讲述昨天电视中的一个情节,我听到后就说了一句:“你还好意思说你看电视?”。他立刻明白了,就没说什么。从此他的进步是可以说是突飞猛进的,代码的质量和工作效率明显上了一个台阶,对项目的推动也是有目共睹的。几个月后的一次公司庆典上,他被评为“进步最快员工奖”,奖金3000元。奖后在他给我的Mail中发现了这句话:“你说我看电视的那句话改变了我的学习状态….我现在是马桶上、公交车上都在看书或笔记。”

 坚持实践。当你学到了一种新的技术或知识时,多实践是巩固学习的一种最好最有效的方法。这个实践不是照著书上的例子做一遍,而是根据自己的能力,给自己出题,然后去完成它。只有这样,你才能发现自己的不足,同时又增加了编程经验。要成为合格的程序员,光会写代码是远远不够的,更重要的是在实践中思考创新。实践的多少决定着“高手”和一般程序员界线,高手们并不是天才,他们是在无数个日日夜夜中磨炼出来的。成功能给我们带来无比的喜悦,但实践的过程却是无比的枯燥乏味。

 掌握编程思想。学一门语言,不能仅仅是语言,还要注重语言背后的思想方法,获得提出问题,分析问题,解决问题的能力,不是为编程而学习,因为编程语言和我们日常所说的语言一样,日常所说的语言是一种思想的表达,而编程语言是一种功能的实现。要学习它是如何来解决某一问题的,为什么要这样去做,他总是要符合客观事实的,存在某种逻辑,数据的组织,信息的传递,然后看该怎么样用编程语言来表达自己的想法。

 多问、多总结、多记笔记。“三人行必有我师”,也许在一次和别人不经意的谈话中,就可以迸出灵感的火花。著名的交换苹果理论说的是:“你有一个苹果,我有一个苹果,当我们互相交换苹果后,我们仍然互得一个苹果;你有一个想法,我有一个想法,当我们互相交换想法,我们则互得两个想法”。遇到问题,上网查看一些技术论坛,看看别人对同一问题的看法,会给你很大的启发。在这个网络时代,资料到处都有,无论什么先进的技术,你可以问身边的高手,问网上的同仁,只要查到资料,快的学上几天慢的一两个月也能学会,学会后总结出技术要点记下来,可写在本子上也可写在Blog上,编程技能的提高靠的是代码的积累,把所有自己的代码保存起来,并附有适当的笔记,这样,到用到时才能信手拈来,才能获得踏踏实实的进步。所以现在已没有写不出的程序了,写不出不是因为不够聪明,而是因为你没有耐心和找 BUG 的细心。

 不钻“牛角尖”,只抓主要问题,一些不影响工作的难点只要会用就行,这也体现了OOP的思想,你只要知道一个技术能完成什么功能就可以,至于它是如何实现的可暂时放一放,有时回过头来再看就不是什么难点了。当你遇到技术障碍的时候,不妨暂时远离电脑,看看窗外的风景,听听轻音乐,和朋友聊聊天。当重新开始工作的时候,我会发现那些难题现在竟然可以迎刃而解。

外包软件、商品软件、项目软件的操作模式简介

软件外包

就是一些发达国家的软件公司将他们的一些非核心的软件项目通过外包的形式交给人力资源成本相对较低的国家的公司开发,以达到降低软件开发成本的目的。因为软件开发的成本中70%是人力资源成本,所以,降低人力资源成本将有效地降低软件开发的成本。软件外包已经成为发达国家的软件公司降低成本的一种重要的手段。软件外包的大幅度增长为人力资源成本相对较低的印度和中国带来了新的发展机会。企业与企业之间的外包就是:企业(A)为了专注核心竞争力业务和降低软件项目成本,将软件项目中的全部或部分工作发包给提供企业(B)完成; 商业软件 商业软件(又叫“商品软件”)就是由商业公司在调研大多数行业用户的需求上开发的软件,该软件基本上能满足这些用户的需求,而且它的功能不会因个别或少数用户的要求而改动。随着互联网的兴起和软件授权销售方式的普及,商品软件的销售可软件公司直销、代理销售、专业下载网站销售等多种渠道,软件授权许可的销售模式往往是根据使用商品软件的用户数和安装该软件的计算机数来收取许可费用。项目软件 就是软件公司专门为某个客户开发的软件系统,该系统由委托开发的客户配合调研需求,“量体裁衣”,在关键阶段双方可派技术人员互相“渗透”,密切合作,共同完成系统的开发和实施以及运行。项目软件与外包软件的操作模式有相同性也有不同性。产品经理与项目经理

简单地说,产品经理是做正确的事,其所领导的产品是否符合市场的需求,是否能给公司带来利润的。而项目经理是把事情做正确,把事情作得完美,在时间,成本和资源约束的条件下完成目标。项目经理要对某个产品进行开发的管理,负责开发的进度,开发过程中的协调等有关开发方面的问题,他最大的目标是时间第一、立项目标达成第一。并不会很尊重产品本身的市场需求以及业务逻辑的问题。

而产品经理是横向管理的,也就是说他将负责某个产品或者某个产品线从商业计划市场竞争开发需求推广方案渠道策略等各个方面。产品经理一个产品线从头到尾的重要参与人。

第四篇:RPG AS400程序员培训手册6

CL、CMD

其实有关这一章,以及屏幕文件的,在网上已经有很多人写过了,想了想,还是说一下吧。

5.1 CL 程序

5.1.1 基本认识

简单的理解,CL 程序就是和RPG 相对应的,是控制语言(Control Language)。类型为

CLP、CLLE 的源代码编译出来的程序,都属于CL 程序。

可能还是不够直观,这么说吧,我们在交互式命令行上输入的命令,用程序的方式来执

行,这个执行的程序,就是CL 程序。

学过UNIX 的会比较好懂,CL 程序有点类似于SHELL,不过SHELL 是可以直接执行的,而且不用编译;CL 程序需要编译,而且要用CALL 的方式来执行。不过原理是接近的,都是在程序中直接调用命令行的语句。

所以说,CL 程序其实很好写,只要会输入命令,就可以写CL 程序了。在编辑CL 程

序时,也可以用“命令 + F4”的方式来写,不需要老老实实的整行输入。

CL 程序不像RPGLE 程序,在编写时,可以使用自由格式书写;一行的内容如果太长

要,在最末尾处用“+”表示换行

举个最简单的例子,比如说新建个名为FHS01CL 的CLP 源程序,代码如下:

PGM

WRKACTJOB

ENDPGM

编译此程序,然后CALL 之,系统就会执行命令WRKACTJOB,查看当前的活动作业,效果与在交互式命令行下输入WRKACTJOB 是一样的。

当我们输入F12,退出WRKACTJOB 时,系统就会继续向下执行,发现是ENDPGM,表示程序结束了,于是判定执行完毕,退出至交互式画面。

5.1.2 CL 程序的常用语法及命令:

一、程序的开始与结束:

PGM PARM(&A &B)/* 开始CL 程序 */

ENDPGM /* 结束CL 程序 */

CL 程序,和RPGLE 程序一样,也可以有程序的入口参数,而且程序的入口参数

都是可传递的(也就是输入的参数如果在程序中被修改过,那么原调用的程序中的相应

参数也会进行变化。不过CL 的入口参数只能为字符型,或数字型的单个字段,不能象

RPGLE 程序中那么多样化(字段、结构、数组、指针)。

如果CL 程序没有入口参数时,那么就可以不需要后面的PARM 语句,直接写成PGM

即可。

写CL 程序时,不妨多使用F4,看看系统的帮助,这样就不用记那么多命令的参

数名。

二、变量及其定义

CL程序中的所有变量,都使用&做为前缀,这一点与RPGLE 程序不同。比如说

PGM PARM(&A &B)

就表示入口参数为A、B 这两个变量

在CL 程序中使用到的变量,都必须使用DCL 语句来定义:

DCL VAR(&FLD01)TYPE(*CHAR)LEN(10)

DCL VAR(&FLD02)TYPE(*DEC)LEN(10 2)

上述语句表示:

定义变量FLD01,10 位长的字符型变量

定义变量FLD02,10 长,其中2 位小数的数字型变量

除了字符、数字之外,CL 程序还可以定义逻辑变量(*LGL),逻辑变量允许的值只

能为’1’或’0’。不过通常有字符与数字也就够了。CL 程序的主要功能在于进行命令处理,而不是处理字符串以及数据库

三、CL 常用命令:

CHGVAR--变量赋值

CHGVAR VAR(&FLD01)VALUE(‘ABCD’)

即是将变量FLD01 赋值成为’ABCD’(左对齐),同理,VALUE 的括号中也可

以填写一个变量,即表示将此变量的值赋值到变量FLD01 中。

数字型变量的赋值同样也是使用CHGVAR 语句。

当变量中只包含数字时(0—9),数字型变量与字符型变量可以使用CHGVAR

语句进行转换,这一点与RPGLE 中的MOVE 语句比较类似。

IF--条件判断语句

IF COND(&FLD01 *EQ '1')THEN(CHGVAR VAR(&FLD02)+

VALUE('0'))

当变量FLD01 等于’1’时,将变量FLD02 中的值更改为’0’

THEN 后面,即是当符合条件时,要执行的命令。写起来其实没有看上去那么

复杂,多用F4 就会发现CL 程序写简单。

就比如上例,先写IF,然后按F4,在Condition 处填写条件语句,然后在

Command 处填上CHGVAR,再按F4,再去填相应的处理语句,这样写,就比直

接把整句抄下来就简单多了。

上面这种写法,只能在符合条件时,执行一条CL 语句;如果要执行多条,就

必须写做:

IF COND(&FLD01 *EQ '1')THEN(DO)

CHGVAR VAR(&FLD02)VALUE(‘0’)

其它执行语句

ENDDO 也就是THEN 后面,用DO,表示接下来的语句都是在这个IF 条件成立时才

执行(DO)的。

然后结束处用ENDDO,必须要有。ENDDO 在这里和循环没有任何关系,表

示的是ENDIF 的意思,但是CL 语句里没有ENDIF,只有ENDDO。

IF 语句中,表示判断的关键字与RPGLE 中的Ifxx 操作码类似,有

*EQ *GT *LT *GE *LE *NE

用来表示逻辑关系的关键字有

*AND, *OR, *NOT

GOTO--跳转语句

GOTO 语句与RPGLE 中的GOTO 是一样的,都是跳转的意思。

FHSTAG:

GOTO CMDLBL(FHSTAG)

注意,这里定义标签是用“:” 冒号

MONMSG--监控错误信息

我们使用CL 语句时,执行的命令可能会报出一些异常错误,从而导致整个程

序中断,需要手工干预。MONMSG 命令可以监控我们预定的错误信息,使CL 程

序正常的向下运行。举例而言,如果CL 程序中有如下语句:

CALL PGM(FHS01R)

MONMSG MSGID(CPF4131)

则表示当系统调用程序FHS01R 时,如果发现有CPF4131(声明的文件重新编

译过,但程序未重新编译)的错,那么CL 程序将不会异常中断,仅仅只是不运行

程序FHS01R,然后继续向下执行CL 程序

MONMSG 还可以用于在监控到错误信息之后,进行处理,如下:

CALL PGM(FHS01R)MONMSG MSGID(CPF4131)EXEC(CHGVAR VAR(&FLD01)+

VALUE('0'))

这句话就表示当发现有CPF4131 的错误之时,将变量FLD01 赋值成为’0’

如果要执行多句的话,和IF 语句的方法类似,也是使用DO 与ENDDO

MONMSG MSGID(CPF4131)EXEC(DO)

CHGVAR VAR(&FLD01)VALUE(‘0’)

其它处理语句

ENDDO

5.1.3 不常用的语法

%SST--取字符串

CHGVAR VAR(&FLD01)VALUE(%SST(&FLD02 3 1))

表示将字符变量FLD02,从第3 位开始,取1 位,左对齐赋值到变量FLD01 中。

%SST 的括号的参数中,第一个参数必须为字符型变量,第二个参数表示起始位,第三个参数表示要截取的长度。

*CAT--拼字符串

DCL VAR(&FLD01)TYPE(*CHAR)LEN(10)

CHGVAR VAR(&FLD01)VALUE('A' *CAT 'B')

即表示将10 位长的字符型变量赋值成为’AB ‘

‘A’,‘B’,也可以使用变量,如

CHGVAR VAR(&FLD01)VALUE(&FLD02 *CAT &FLD03)

要注意,*CAT 不能去掉字符串末尾的空,从效果上来看,有点类似于RPGLE 中的EVAL 操作码,而不是CAT 操作码

+、-、*、/--数学运算

数字型变量,可以进行数学运算 CHGVAR VAR(&FLD01)VALUE(&FLD01 + &FLD02)

即等同于RPGLE 程序中的 EVAL FLD01 = FLD01 + FLD0

2同理,-、*、/ 分别对应减、乘、除

不过数学运行常用于RPGLE 程序中,较少用在CL 控制里面,这里只是介绍一下。

读取文件:(From Cuer:P1421)

DCL VAR(&FLD01)TYPE(*CHAR)LEN(2)

DCLF FILE(FHSLIB/PFFHS)

RCVF

CHGVAR VAR(&FLD01)VALUE(&FHS01)

以上这段CL 的意思,就是在CL 程序中读取PFFHS 文件,然后将读到的第一条记

录赋值到CL 的临时变量FLD01 中。

如果要将一个文件从头读到尾,则可以用如下语句来实现:

DCLF FILE(FHSLIB/PFFHS)

LOOP:

RCVF

MONMSG MSGID(CPF0864)EXEC(GOTO CMDLBL(EXIT))

读取到每条记录后的处理语句

GOTO CMDLBL(LOOP)

EXIT:

也就是说,信息CPF0864,即表示未读取到记录。

在CL 程序中声明文件使用DCLF 语句,一个CL 文件中只能声明一个文件,声明

语句必须在CL 控制语句之前。

使用声明的文件中的字段,同样需要在字段名前加上“&” ;

CL 程序中,无法控制游标,无法对记录进行定位操作。所以CL 程序对文件的操 作是比较弱的,通常我最多只用来读取某些只含少量记录的参数文件。

5.2 CMD

CMD 是用来生成命令的,执行后可以像其它系统命令一样,直接输入命令,或是F4,不需要像CLP 一样,要CALL 一下。

其实CMD 本质上也是执行CLP 或RPGLE(在编译时指定),用起来,无非就是好看点,直接一些,除此之外的意义,似乎也就没什么了。

举个例子,比如我们查看一个文件中的内容时,可以使用SQL 来查看,也可以使用命

令RUNQRY 命令来实现(RUNQRY QRYFILE(文件名))。但在我们要频繁查看文件

时,这两种方式似乎都不是很爽,也就是说要输入的内容都不是最少的,那我们可以设计一

个CMD,譬如说叫SEE,希望实现的最终效果,是在命令行输入“SEE 文件名”,就

可以查看PF 文件中的记录。那么,我们按如下步骤来实现:

1.建立一个CLP 程序,比如叫SEECLP,代码如下

PGM PARM(&FILENAME)

RUNQRY QRYFILE(&FILENAME)

ENDPGM

2.编译此程序

3.建立一个CMD 程序(即源代码的属性为CMD),代码如下:

CMD PROMPT(' 显示文件记录 ')

PARM KWD(NAME)TYPE(*CHAR)LEN(10)MIN(1)+

CHOICE(' 显示文件记录内容 ')+

PROMPT('Display file record')

4.编译此CMD,用F4,可见如下画面:

Create Command(CRTCMD)

Type choices, press Enter.Command............> SEE Name

Library...........> FHSLIB Name, *CURLIB

Program to process command...> SEE Name, *REXX

Library...........> *LIBL Name, *LIBL, *CURLIB

Source file..........> FHSFILE Name

Library...........> FHSLIB Name, *LIBL, *CURLIB

Source member.........> SEE Name, *CMD

Threadsafe...........*NO *YES, *NO, *COND

其中,蓝色字体显示的,就是我们需要输入这个CMD 要调用的程序名(默认值与

CMD同名),这里我们将此项内容填为SEECLP,表示SEE 这个CMD,调用的是SEECLP

这个程序

5.编译成功之后,我们在命令行执行“SEE 文件名”,就可以看到指定文件的记录。也可以用SEE + F4 的方式来使用

6.要注意,CMD 中,PARM 表示的就是CMD 命令的参数,参数的个数、类型、长

度都必须与其调用的程序相匹配,但名称可以与其调用的程序中的参数名称不一

样,而且名称前面不能有“&”字符。

7.在PARM 参数中,MIN(1),表示该项参数必须有值(即最小的有效长度为1),当

参数无值时,将会自动出现SEE + F4 的效果,同时该项参数高亮显示。试一试

就知道了

第五篇:RPG AS400程序员培训手册

2.8.4.4 O--R

ON-ERROR(On-Error)

没用过

OPEN {(E)}(Open File for Processing)打开文件

Factory 1 Operation Factory 2 Result HI LO EQ

OPEN 文件名

OPEN 后面的目标,必须是在当前程序中已声明的文件名(不是文件的记录格式名),而且在OPEN 操作之后,在程序结束之前之前,必须有对应的CLOSE 操作。

使用OPEN 操作,文件在声明时,必须使用USROPN 关键字(详见D 行说明)。

ORxx(Or)逻辑判断—或

Factory 1 Operation Factory 2 Result HI LO EQ

FLD01 IFGT FLD0

3FLD01 OREQ FLD0

2等价于

IF FLD01>FLD03 OR FLD01=FLD02

与IF、IFxx,AND、ANDxx 类似,RPGLE 的写法OR,比RPG 的写法ORxx 要灵活,而且可以用来表达一些复杂的逻辑关系。有鉴于此,所以通常IF 语句中,我会以OR 为主,基本不用ORxx。如果在编程序方面,公司/项目组无硬性要求,那我觉得还是少用ORxx 吧,总觉得这种写法的逻辑关系看起来不直接,尤其是有很复杂的AND,OR 时。

OTHER(Otherwise Select)分支语句的判断

与分支语句SELECT 一起使用,表示不符合上述所有条件时的操作,如下:

Factory 1 Operation Factory 2 Result HI LO EQ

SELECT

WHEN 条件判断1 处理语句1

WHEN 条件判断

2处理语句2

OTHER

处理语句

3ENDSL

在这个例子中,当满足条件判断1 时,运行处理语句1,运行结束后跳至ENDSL 处;

如果不满足条件判断1,则程序继续向下执行,判断是否满足条件判断2。当满足条件判断2 时,运行处理语句2,跳至ENDSL;当不满足

当不满足条件判断2 时,程序继续向下执下,当读到OTHER 操作码时,无条件运

行处理语句3(即当程序当前不满足以上所以条件判断时,则执行OTHER 之后的语句。

处理语句允许有很多句;

条件判断可以写得很复杂,也允许对不同的字段进行判断;比如说C 语言也有分支语

句switch,但是这个语句只能对一个字段进行分支判断,ILE 语言与它不同,允许对不同的字段进行判断

就我目前掌握的测试情况,上述的SELECT—WHEN--OTHER—ENDSL,其实也可以

写做:

IF 条件判断

1处理语句1

ELSEIF 条件判断2

处理语句2

ELSE

处理语句3

ENDIF 即WHEN 与ELSEIF 是类似的,这样说,应该可以明白了吧。

总之,SELECT—ENDSL 是一个很好用的语法,尤其是在表示很多不同的分支处理时。

OUT {(E)}(Write a Data Area)

没用过,讲数据域的。

PARM(Identify Parameters)定义入口参数

Factory 1 Operation Factory 2 Result HI LO EQR

*ENTRY PLIST

PARM FLD01

关于具体内容讲解,详见前面所说“入口参数”一章。

允许做为入口参数的有:普通变量、结构变量、数组变量

关于PARM、PLIST,还有一种在Factory 1,Factory 2 也填写变量或指示器的用

法,不过我不知道它具体表示什么意思,也不知道该怎么用。请用过的来补充。PLIST(Identify a Parameter List)同上

POST {(E)}(Post)

没用过

READ {(N | E)}(Read a Record)读取记录

1.基本语法:

Factory 1 Operation Factory 2 Result HI LO EQ

READ 文件记录格式名 45 46

READ后面跟的,必须是声明的文件记录格式名;

LO 指示器表示锁表指示器,当在指定的时间(CHGPF,WAITRCD 项可看到),需要读取的记录仍被锁,将会打开LO 指示器,即*IN45=’1’;

EQ指示器为是否读到指示器。当未读到仸何记录时,打开EQ 指示器,即*IN46=’1’

2.当文件在程序中,是用只读的方式声明时,READ 操作并不会造成锁表; 如果文件在程序中是用修改的方式声明,READ 操作成功后,该记录被锁;直到执

行解锁操作(UNLOCK,或UPDATE),或READ 该文件的其它记录,才会解锁

如果文件是用修改的方式声明,但希望READ 操作不锁表时,那么就用READ(N),即

Factory 1 Operation Factory 2 Result HI LO EQ

READ(N)文件记录格式名 45 46

这样读文件,就不会锁记录,但是同时也不能修改记录。如果需要修改记录,那么 在修改之前(包括对文件字段赋值之前),还必须再对该记录进行一次定位操作(比如

CHAIN、READ 语句均可)。也就是说,如果要修改记录,必须先锁住当前记录(很合理吧)

3.当执行READ 操作时,程序是根据游标当前在文件中所指向的位置,顺序读取下

一条记录。关于游标是如何指向,还不是一个很简单的问题,所以将会在下一章“数

据库相关知识”中具体讲解。

4.执行READ 操作时,允许声明的文件没有键值。(即PF 文件)

READC {(E)}(Read Next Changed Record)

没用过,读下一次修改过的记录?

READE {(N | E)}(Read Equal Key)读取键值相等的记录

语法与READ 操作码大致一样,这里不再重复,只说不同的:

假设程序中已声明逻辑文件PFFHSL3(键值为FHS01+FHS02)

Factory 1 Operation Factory 2 Result HI LO EQ

FHSKEY KLIST

KFLD FLD0

1KFLD FLD02

FHSKEY SETLL FMTFHS DOW 1=1

FHSKEY READE FMTFHS 1

5IF *IN15=’1’

LEAVE

ENDIF

ENDDO

这段话的意思,就是定义组合键值FHSKEY,然后根据这个FHSKEY 在逻辑文件

PFFHSL3 中去定位,循环读取PFFHSL3 中,FHS01、FHS03 与FLD01、FLD02 相等的记

录。当读取记录结束,或键值不等时,退出循环(*IN15 是EQ 指示器)。如果将READE 操

作码换成READ 操作码的话(当然,Factory 1 处也就不能有值),就没有“键值不等时退出

循环”这一层意思,只是读不到记录时就退出循环,但有时我们使用逻辑文件,仅仅是需要

它的排序,而不需要读不到键值相等的记录就退出循环。所以说,使用READ 操作码,还

是READE 操作码,需要根据实际的要求来决定。

以上的Factory 1 处填写值的系统处理,当READE 操作码在Factory 1 处未填写值时,系统实际上是将当前的值与读到的上一条记录的关键字进行比较,而不是与SETLL 时的键

值做比较(读第一条记录不做比较!),如果键值不等时,置EQ 指示器为1。也就是说,如果没有与FHSKEY 键值相同的录,那么系统并不是直接找开EQ 指示器,而是会一直保

持正常地往下读,直到找到与读到的第一条记录关键字不同的记录,才会打开EQ 指示器,所以要注意。

READP {(N | E)}(Read Prior Record)读取记录—游标上移

简单来说,READ、READE 操作时,游标在数据文件中,是下移的;即读完第一条记

录,游标指向第二条记录;读完第二条记录,游标指向第三条记录,依此类推,直至最后一 条记录。但READP 则正好相反,游标是上移的,即读完第三条记录后,游标指向第二条记

录;读完第二条记录后,游标指向第一条记录,直至读完第一条记录。一般来说,用READ、READE 的概率会比READP、READPE 的概率高得多,不过在某些情况下,使用READP 操作,又的确会很省事,这个一时间想不起例子来,大家可在编

程序时多实践。

READPE {(N | E)}(Read Prior Equal)

虽然我没用过,但猜想它应该就是指游标上移,按键值去读取文件。与READP 的关系,就类似于READE 与READ 的关系。

REALLOC {(E)}(Re-allocate Storage)

没用过

REL {(E)}(Release)

没用过

RESET {(E)}(Reset)

将数据结构赋值成为初始值。

注意是初始值,不是清空。如定义结构:

D FHSDS DS

D FHS01 10 INZ(’ABCD’)

D FHS02 5 INZ(’EFGH’)

那么,不管对该结构如何赋值,当执行语句: C RESET FHSDS

之后,FHS01 将会变成’ABCD,FHS02 将会变成’EFGH’,即恢复成为初始值。

RETURN {(H | M | R)}(Return to Caller)

RETURN 是程序结束。

在前面,“简单的程序流程”中,我们讲过,“SETON LR” 与RETURN 这两句话一

起,做为程序的结束。这里,再详细解释一下两者之间的区别,以及关系: 如果不写RETURN,只写“SETON LR”,程序执行完最后一句之后,将会再从第一

句开始执行,造成死循环。在简单的程序流程这个例子中,程序原来只想修改读到的第一条 记录,而如果没有RETURN 的话,将会把所有的记录都修改掉,直到最后找不到可修改的记录,然后系统报错,异常中断。(这种离奇的现象现在又测试不到了,可能是当时写错程 序了?把F 写成了P?不管它,当是我写错了,总之RETURN 是表示程序结束,没有

RETURN,主程序无可执行的语句时,它也会结束;如果RETURN 出现在主程序的中间,那么RETURN 后面的语句将不会执行)

如果只写RETURN,不打开指示器*INLR,根据blogliou 所说 “程序不会强制将内存

中的数据写到磁盘中。400 缺省的是BLOCK 输出,即数据记录满一个BLOCK 块时才会将

这一组记录写到磁盘上。那么如果这时BLOCK 没满,数据信息不会立刻写到磁盘上。之后 有其它作业用到该文件,读取的数据就不完整。”

但如果文件有唯一键字,或记录日志,必须同步写时,其实BLOCK 实际被忽略,也就 是此时不会有错。目前我们用的是MIMIX 备份,客户实际上将所有的文件都列入日志,这

时不写也不会出现上述错误。但为避免一些潜在的问题,养成良好的编程风格,建议将 SETON LR 与RETURN 一同,做为程序结束的标志。当然,如果某个程序频繁被调用,且 不涉及文 操作时,可考虑不打开指示器*INLR,仅用RETURN 作为结束,这样程序不

会被PURGE 出内存,可提高调用效率。

如果没写RETURN,也没有打开指示器*INLR,在编译时,系统将会报40 级错,说找

不到程序结束的语句,所以大可放心。ROLBK {(E)}(Roll Back)

1.基本语法

Factory 1 Operation Factory 2 Result

ROLBK

2.该操作码无其它参数,就是指对事务处理进行回滚操作。3.ILE 程序中,ROLBK 操作可随时进行,也允许在没有声明COMMIT 类型的文件的情况下,仍进行ROLBK 操作(对该进程这前的事务进行确认处理)f

4.关于日志的确认回滚操作,在后面会另设专门章节讲述。

2.8.4.5 S--Z SCAN {(E)}(Scan Character String)扫描字符串

扫描字符或字符串Factory 1 在目标字符串Factory 2 中是否存在Factory 1 Operation Factory 2 Result HI LO EQ

FLD01 SCAN FLD02 N 26

FLD01 可以是字符,也可以是字符变量;可以是一位长,也可以是多位长。

当FLD01 在FLD02 中存在时,EQ 指示器打开,即*IN26=’1’,同时将FLD02 中的起始

位置,赋值给N;

当FLD01 在FLD02 中不存在时,EQ 指示器保持关闭状态,即*IN26=’0’,同时N=0

允许从FLD02 中的指定位置开始检查:

FLD01 SCAN FLD02:2 N 26

如上句,即表示从FLD02 的第2 位,开始扫描。

在实际使用中,比如说我们判断某个字符是否为数字,就可以先定义一个0—9 的常量,然后将要判断的字符去SCAN 一下这个常量

SELECT(Begin a Select Group)分支语句

在操作码“OTHER”中讲过,为方便读者,列出简单语法如下:

Factory 1 Operation Factory 2 Result HI LO EQ

SELECT

WHEN 条件判断

1处理语句1

WHEN 条件判断2 处理语句

2OTHER

处理语句

3ENDSL

要注意,SELECT 操作码,必须有对应的ENDSL 操作码,否则编译无法通过。

SETGT {(E)}(Set Greater Than)定位操作—大于

举个例子吧,假设文件中有一个字段,是标识顺序号的,1、2、3、4。即该字段为1,表示第一条记录,该字段为2,表示第2 条记录。那么: Factory 1 Operation Factory 2 Result HI LO EQSETGT 文件记录格式名

READ 文件记录格式名

这个READ 操作,READ 到的,是第3 条记录。也就是说,SETGT 操作码,会将游标

定位到大于键值的第一条记录前。

在实际使用中,如果我们是按逻辑文件读取,而且读了一条记录之后,对其键值相同的 记录都不需要再读取时,就可以用SETGT,不过需要注意,Factory 1 项,需要是与键值相

同的变量,即如果文件是使用多个字段做为键值,那么我们也需要先定义一个组合键值的变

量,然后Factory 1 处填写这个组合键值的变量名。

当声明文件的键值有多项时,Factory 1 项的键值,允许小于文件的键值,但顺序必须

一致。即声明的文件如果键值为:FHS01、FHS02、FHS03,那么我们在程序中定义三个类

型与之相同的变量FLD01、FLD02、FLD03,以下写法都是有效的FLDKEY KLIST

KFLD FLD0

1KFLD FLD0

2KFLD FLD03 FLDKEY SETGT 文件记录格式名

FLDKEY KLIST

KFLD FLD01

KFLD FLD02

FLDKEY SETGT 文件记录格式名

FLD01 SETLL 文件记录格式名

SETLL {(E)}(Set Lower Limit)定位操作—小于

语法与SETGT 相同,含义与SETGT 不同。SETLL 操作码,会将游标定位到与键值相

等的第一条记录之前,仍是上例,如果是 2 SETLL 文件记录格式名

READ 文件记录格式名

那么READ 操作码读到的记录,就是第2 条记录,看到了吧,和SETGT 不同。

SETLL 操作码还可以用来简单判断当前键值是否存在有记录,以PFFHSL3 为例(键值

为FHS01、FHS02)

Factory 1 Operation Factory 2 Result HI LO EQ

FHSKEY KLIST

KFLD FLD0

1KFLD FLD0

2EVAL FLD01=’01’

EVAL FLD02=’02’

FHSKEY SETLL 文件记录格式名 44

当文件中有相应记录时,EQ 指示器打开,即*IN44=’1’

当文件中无相应记录时,EQ 指示器关闭,即*IN44=’0’(与CHAIN 正好相反,要注意)

而在这种用法中,SETLL 与CHAIN 的区别在于,CHAIN 是定位读取了记录,而SETLL 仅仅只是判断该记录是否存在。所以用SETLL 操作,不能修改记录,也无法取出记录的值。

只能判断记录是否存在。如果要修改记录,或取出记录的值,还需要有一个读取定位的操作,如READ,或READE、READP 等(最常用的,应该就是READ 操作)

SETOFF(Set Indicator Off)关闭指示器

Factory 1 Operation Factory 2 Result HI LO EQ

SETOFF 10 11 1

2等价于

EVAL *IN10=’0’

EVAL *IN11=’0’

EVAL *IN12=’0’

在SETOFF 这个操作码中,指示器填在HI、LO、EQ 哪里都没关系,都是表示要被关

闭的指示器

SETON(Set Indicator On)打开指示器

Factory 1 Operation Factory 2 Result HI LO EQ

SETOFF 10 11 1

2等价于

EVAL *IN10=’1’

EVAL *IN11=’1’

EVAL *IN12=’1’

在SETON 这个操作码中,指示器填在HI、LO、EQ 哪里都没关系,都是表示要被关闭的指示器

SHTDN(Shut Down)

没用过

SORTA(Sort an Array)没用过

SQRT {(H)}(Square Root)开方

Factory 1 Operation Factory 2 Result HI LO EQSQRT 3 N

这时,N=3(因为3 的平方为9)9、3 都可以是数字型变量,或者直接是数字 SUB {(H)}(Subtract)减法操作

Factory 1 Operation Factory 2 Result HI LO EQ

FLD01 SUB FLD02 FLD0

3SUB FLD02 FLD03

看过前面的ADD、MULT 操作码,这里不用解释也应该明白是什么意思了吧。那就不

多说了。

SUBDUR {(E)}(Subtract Duration)日期相减

1.减日期

Factory 1 Operation Factory 2 Result HI LO EQ

FLD01 SUBDUR N:*Y FLD02

表示将日期型变量FLD01 减去N 年,赋值到日期型变量FLD02 中;

N 可以是一个数字型变量,也可以就是一个数字,N 允许为负数 *Y,*M,*D(还有其它的参数值,可见ADDDUR,其中有详细解释)

2.判断两个日期型变量之间的天/月/年数

Factory 1 Operation Factory 2 Result HI LO EQ

FLD01 SUBDUR FLD02 N:*D

这时,N 做为一结果变量,表示日期型变量FLD01 与FLD02 之间的天数

SUBST {(P | E)}(Substring)取字符/字符串 Factory 1 Operation Factory 2 Result HI LO EQSUBST FLD01:3 FLD02

表示从字段FLD01 的第3 位开始,取2 位,左对齐赋值到字段FLD02 中。

要求字段FLD01 的长度必须大于或等于3+2 位,否则程序会报错。

可以尝试用%SUBST 语句,也是等价的,如下

EVAL FLD02=%SUBST(FLD01:3:2)

表示的是同样的意思。

起始位数3,取的长度2,在两种写法之下,都可以使用数字型变量来表达。

相比较之下,%SUBST 还有一种用法,就是对字符的指定位置赋值,这个就厉害了:

EVAL %SUBST(FLD02:3:2)=’01’

看到了吧,这句话就是说,使字段FLD02 的第3、4 位(即从第三位开始,两位长)等

于“01”

TAG(Tag)定义标签,与GOTO 同用

Factory 1 Operation Factory 2 Result HI LO EQ

FHSTAG TAG

TEST {(D | T | Z | E)}(Test Date/Time/Timestamp)

没用过

TESTB(Test Bit)

没用过

TESTN(Test Numeric)

没用过

TESTZ(Test Zone)

没用过

TIME(Time of Day)--取当前系统时间 Factory 1 Operation Factory 2 Result HI LO EQ

TIME FLD01

FLD01 可以是时间型或数字型变量

UNLOCK {(E)}(Unlock a Data Area or Release a Record)解锁

Factory 1 Operation Factory 2 Result HI LO EQ

UNLOCK 文件记录格式名

UNLOCK 是解锁操作,在某种程度上,可以将UNLOCK 视为ROLBK,将UPDATE

视为COMMIT。即如果锁定某条记录,并对其字段进行赋值之后,使用UPDATE 语句,将

会把修改后的结果保存下来,即修改文件,而UNLOCK 语句则不会修改文件,即否认了之 前对文件字段做的赋值修改。

从程序的执行效率上来讲,UNLOCK 的执行效率是高于UPDATE 的,因为UPDATE

操作时,系统需要对文件的每一个字段进行确认处理(DEBUG 时可以看到),而UNLOCK 就

是简单的解锁而已。

UPDATE(Modify Existing Record)修改记录

语法与UNLOCK 一样。

这里需要说明一下,在执行UPDATE 的时候,必须先使用READ、CHAIN 等操作码锁

定一条记录。如果未锁住记录,UPDATE 操作码将会报错。当执行了UNLOCK、UPDATE、以及ROLBK 语句时,等于是解锁,此时再执行UPDATE 操作码之前,必须再次锁住记录

操作;

WHEN {(M | R)}(When)分支判断语句中的条件判断

在操作码“OTHER”,“SELECT”中都讲过,仍列出简单语法如下:

Factory 1 Operation Factory 2 Result HI LO EQ

SELECT

WHEN 条件判断1 处理语句1

WHEN 条件判断

2处理语句2

OTHER

处理语句

3ENDSL

WHENxx(When True Then Select)

上面的语法,是RPGLE 的语法,WHENxx 是RPG 的语法,也就是

SELECT

FLD01 WHENEQ FLD02

处理语句

1……..这样的语法,在表达复杂的逻辑关系时,必须与ANDxx,ORxx 一起使用,所以我不

使用WHENxx 这个操作码。

WRITE(Create New Records)写记录

常用的方式:

Factory 1 Operation Factory 2 Result HI LO EQ

CLEAR 文件记录格式名

EVAL 文件字段1=xxxx

EVAL 文件字段2=xxxx

WRITE 文件记录格式名

表示在文件中写入一条新记录。文件需要声明为可写的。

通常会在给文件字段赋值之前,作一次CLEAR 操作来进行初始化,以避免不必要的麻烦。XFOOT {(H)}(Sum the Elements of an Array)

没用过,看帮助,是表示对数组字段的累加统计。

假设DIMDATA 定义为一个数字型的数组变量,FHS01 为一个足够大的数字型变量

Factory 1 Operation Factory 2 Result HI LO EQ

XFOOT DIMDATA FHS01

就表示将数组DIMDATA 中的所有记录的值都取出来,汇总相加,赋值到数字变量

FHS01 中

XLATE {(P | E)}(Translate)

将一个字符串中指定的字符,更换成另外的字符。

举例:如MYCHAR1,MYCHAR2 都是两个20 位长的字符型变量

C MOVEL 'ABCAAAC123' MYCHAR1

C 'A':'9' XLATE MYCHAR1 MYCHAR2

执行过这个语句之后,MYCHAR2 就等于”9BC999C123’,即将字符串MYCHAR1 中所

有的“A”都变成了“9”;

XLATE 也可能指定起始位置。如上句更改为:

C 'A':'9' XLATE MYCHAR1:4 MYCHAR2

则MYCHAR2 等于“ABC999C123”,指从第4 位开始(含第4 位),将“A”变成“9”

赋值。

Z-ADD {(H)}(Zero and Add)向数字型变量赋值

Factory 1 Operation Factory 2 Result HI LO EQ

Z-ADD FLD01 FLD02

将数字型变量FLD01,赋值到数字型变量FLD02 中。

Z-ADD、MOVE 虽然同是赋值操作码,但Z-ADD 的用法就远没有MOVE 那么变化多

端,只能在数字型变量之间赋值。所以也没有什么可说的了。zero 如果要对数字型变量赋初值,使用*ZERO

Z-ADD *ZERO FLD02

Z-SUB {(H)}(Zero and Subtract)用0 减

Factory 1 Operation Factory 2 Result HI LO EQ

Z-SUB FLD01 FLD02

等价于

0 SUB FLD01 FLD02

等价于

EVAL FLD02=FLD01*(-1)

*ALL

*ALL 是个很有意义的变量,举例:

EVAL FLD01=*ALL’0’

表示将字符型变量FLD01 赋值为全’0’

CLOSE *ALL

就表示关闭所有文件,意义与上面是不同的%LEN

取字符串的长度,举例:

(MYLEN 为数字型变量,FLD01 为字符型变量)

EVAL MYLEN = %LEN(FLD01)

这句话的意思,是指取字符串FLD01 的长度,不过通常这样用是没意义的,因为直接

用%LEN 操作码,取到的是字符串的总长度,不是有效字符的长度,也就是说FLD01 长度

为2,那么MYLEN 就恒等于2,不会变。就算变量FLD01 中没有值,取出的MYLEN 也等

于2.。所以,%LEN 通常会与%TRIM 或是%TRIMR 一起使用,语法在下面介绍。

%TRIM,%TRIMR

都是去字符串变量中的空字符意思,%TRIM 是去字符串左边的空字符;%TRIMR 是去

字符串右边的空格。

通常我们在写程序中,都是默认字符串变量左对齐,所以我们使用%TRIMR 操作码的概率应该高一点。举例:

EVAL MYLEN = %LEN(%TRIMR(FLD01))

这时的MYLEN,就是指变量FLD01 中的有效长度(前提条件是FLD01 中如果有值,是左对齐)。如果FLD01 为空,那么MYFLEN 为0;如果FLD01 首位有值,第二位为空,那么MYLEN 为1;如果FLD01 两位都不为空,那么MYLEN 就等于2。

如果字符串左对齐,那么就使用%TRIMR

还有一种用法,假设字符串FLD04 为4 位长的字符,FLD01,FLD02 都是2 位长的字

符,且FLD01 等于“A ”,FLD02 等于“BC”,那我们执行:

EVAL FLD04 = FLD01 + FLD01 + FLD02

FLD04 就等于“A A ”,也就是第二位与第四位都是空的,最后加的FLD02 其实无

效。

而如果执行

EVAL FLD04 = %TRIMR(FLD01)+ %TRIMR(FLD01)+ FLD02

则FLD04 就等于“AABC”,也就是说,在这里,%TRIMR(FLD01),是等价于单字符

“A”的MONITOR

监控程序信息。据说是可以屏蔽掉出错信息,避免程序异常中断,未经测试。

下载FastReport 4程序员手册[全文5篇]word格式文档
下载FastReport 4程序员手册[全文5篇].doc
将本文档下载到自己电脑,方便修改和收藏,请勿使用迅雷等下载。
点此处下载文档

文档为doc格式


声明:本文内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:645879355@qq.com 进行举报,并提供相关证据,工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。

相关范文推荐

    RPG AS400程序员培训手册9(优秀范文五篇)

    8 其它8.1 报表打印 在这里,简单说一下报表。其实据说RPG 设计之初,主要就是为了解决报表问题。不过发展到现在,在我接触过的系统中,觉得报表在RPG 编程之中反而退居其次,大部分......

    C语言常见错误集合大全-完整版-程序员必备手册

    C语言常见错误集合大全-完整版-程序员必备手册.txt43风帆,不挂在桅杆上,是一块无用的布;桅杆,不挂上风帆,是一根平常的柱;理想,不付诸行动是虚无缥缈的雾;行动,而没有理想,是徒走没有......

    程序员(范文模版)

    作业:研究一个新或自己感兴趣的职业 v介绍:名称定义 v典型生涯路径:从新手到最高职位的生涯路径 v趋势:技术、组织结构、培训、经济趋势对职业的影响v薪酬:差别、地域差别v所......

    程序员

    7.5.3系统测试和调试 1.系统测试的意义及目的 系统测试是为了发现错误而执行程序的过程,成功的测试是发现了至今尚未发现的错误的测试。 测试的目的就是希望能以最少的人力和时......

    程序员

    程序员之死 程序员:举世至主,万元之源,众物所幕,神祗皆掌,岁能长立,箜有己出。弈中悲苦,是自了得!幸事祸事飘忽于其思想,晓如今,心思想,新纪元,心结缘,把话晾。 世间万物,出于思想,毁亦思想......

    C语言常见错误集合大全-完整版-程序员必备手册5篇

    C语言的最大特点是:功能强、使用方便灵活。C编译的程序对语法检查并不象其它高级语言那么严格,这就给编程人员留下“灵活的余地”,但还是由于这个灵活给程序的调试带来了许多不......

    程序员年终工作总结

    程序员年终工作总结 程序员年终工作总结1 来公司担负法度模范员一职已一年多光阴,在这20xx年的光阴里,我学到了许多器械。每个人都是在总结中发展,在审视中完善本身。在这半年......

    程序员小品

    当 蛤 蟆 爱 上 天 鹅 天源迪科电信事业部华中区2014届实习生敬上 演员表: 男主角 小哈:胡传文 女主角 小鹅:李慧梅 女主角妈妈:尚广安 王小丽: 李银银 小帅:张贺东 旁白( ):王娜娜......