Excel“勇”助PB过难关

软件世界

  PowerBuilder(以下简称PB)是常用的面向对象的数据库开发工具之一,具有开发速度快、成本低、质量高、功能强等特点。作为企业的数据库管理人员,笔者在平时的工作中也经常使用PB。近日笔者在完成一个数据输出应用程序时,遇到了一个问题。下面把该问题及解决方法写出来,希望能给广大PB爱好者一些启发。

  目标功能

  笔者要实现的主要功能如下:录入油井原油化验过程中产生的原油粘度和对应的测量温度数据,打印输出“原油粘度—温度”化验报告和粘温曲线。

  问题突现

  笔者在实现数据录入、查询以及生成“原油粘度—温度”化验报告的程序编制上可谓轻车熟路,没有遇到任何障碍,但在粘温曲线的输出上却遇到了问题,根据有关资料,原油粘度和温度间是指数关系,也就是说,在输出曲线时应使用对数坐标。而使用PB数据窗口中的Graph构建数据图表,在设置好图表类型、标题、坐标轴属性并连接数据库预览输出后,却发现生成的对数图表(图1)存在如下问题:

  1.图表的输出线是连接各数据散点的折线,且无法通过设置图表属性来实现平滑输出。

  2.无法实现坐标轴刻度的设置,不能控制x轴温度值的0值原点,不能控制曲线的输出形态。

  3.不能提供对已知实验数据点的拟合方程曲线输出,也就无法实现数据图表在实验数据范围外的预测和推算功能。

  分析

  1.从PB本身下手

  为了验证此问题是否跟PB版本有关,笔者先后将程序的副本在PB6.5、PB7.0和PB8.0等版本中进行调试,虽然在不同版本中设置方法、操作步骤有所不同,但以上问题都存在且无法解决。

  2.跳出圈外,试用其他软件

  既然使用PB无法满足图表输出的需要,其他软件能否胜任呢?通过试验,笔者发现在Excel中就可以完美实现对数图表的输出。

  在Excel 2000/2002/2003中的操作方法基本相同,具体步骤如下:

  ①在Excel中建立粘度和温度数据对照表。

  ②单击工具栏的“图表向导”按钮,选择“自定义类型”选项卡中的“对数图”,单击“下一步”,在“系列”选项卡中添加“粘度”系列,并设置“名称”、“值”和“分类(x)轴标志”。

  ③单击“下一步”,设置“图表标题”、“分类(x)轴”和“数值(y)轴”的内容;在“网格线”选项卡中,选中“分类(x)轴”下的“主要网格线”及“数值(y)轴”下的“主要网格线”和“次要网格线”;在“图例”选项卡中取消“显示图例”项上的钩。单击“下一步”,选择“作为新工作表插入”并将新工作表命名为“曲线”,最后单击“完成”按钮。

  ④在“曲线”工作表中重新设置图表类型为“XY散点图”。然后对“图表标题”、“数值(y)轴标题”和“数值(x)轴标题”的字体、字号以及位置进行调整。

  ⑤选中数据系列后单击右键,选择“添加趋势线”,在“添加趋势线”窗口的“类型”选项卡中选择“乘幂”,在“选项”选项卡“趋势预测”栏中将“前推”设为20单位,“倒推”设为28单位。最后单击“确定”,设置完成后的对数图表如图2所示。

  这时只要改变粘度和温度数据对照表中的数据,曲线就会随着数据的改变自动变化。

  3.PB和Excel能否合作

  软件的大部分功能由PB实现,PB解决不了的问题由Excel解决,现在问题就转化为如何把PB中保存的数据写入Excel的指定位置。其实PB中已经提供了完成此功能的函数:

  OPENCHANNEL函数,可以在PB和Excel之间建立数据传输通道;

  SETREMOTE函数,可以通过通道把指定数据写入目标文件。

  代码实现

  利用PB中的OPENCHANNEL函数和SETREMOTE函数编写相应代码,实现由PB向Excel传送数据的功能,主要设计步骤如下(以下代码在PB6.5、7.0、8.0及Office 2000中调试通过):

  1.进入PB,在主窗口中创建两个按钮,将它们的Text属性分别设为“打开Excel文件”和“Excel输出”。

  2.分别在两个按钮的“Clicked”事件中输入代码。

  ① “打开Excel文件”按钮

  run("c:\program files\microsoft office\office\excel.exe d:\nwen\nwen.xls",maximized!)

  //运行Excel程序,打开一个Excel文件;这里使用的是Office 2000程序的默认安装路径,打开的是包含设计好的图表实例的文件。

  ②“Excel输出” 按钮

  long handle_1,i,j

  string jlh

  double nd1,cnwd1

  handle_1=openchannel("excel","nwen.xls")

  //建立与Excel之间的通道。

  j=dw_1.rowcount()//计算数据窗口中的记录数。

  if j > 1 then

  setremote("r1c1",trim(dw_1.getitemstring(1,"jh"))+"井粘温数据",handle_1)

  //将数据写入Excel文件的第一行第一列。

  for i=1 to j

  cnwd1=dw_1.getitemnumber(i,"cnwd")

  //获取数据窗口当前行的温度数据

  jlh="r"+trim(string(i+2))+"c1"

  //计算写入的行数并确定写入的位置

  setremote(jlh,string(cnwd1),handle_1)

  //将数据写入Excel文件的指定位置

  nd1=dw_1.getitemnumber(i,"nd")

  jlh="r"+trim(string(i+2))+"c2"

  setremote(jlh,string(nd1),handle_1)

  next

  end if

  closechannel(handle_1,handle(w_sjlr))//关闭通道

  相关函数的具体使用方法及参数说明可以参阅联机帮助或技术手册,这里不再详述。

  编后:在日常工作中,我们会遇到很多看似“简单”的应用问题,像上文提到的程序功能,我们也可以采用VB、VC、Delphi、C++ Builder等编程工具来实现,遇到的图表输出问题也可以通过程序模块来解决。但是,上文充分利用不同软件的优势,通过搭建软件间的数据传输通道,实现了软件间的优势互补,在不显著增加程序工作量的情况下,达到了很好的效果。希望读者朋友们能举一反三,更有创造性地解决问题。