电子地图帮我忙──用Excel VBA制作油井动态GIS
软件世界
Excel除了可以实现日常统计报表的计算、汇总和打印等功能外,利用内嵌于Excel的VBA编程语言更能为统计业务应用“增光添彩“。本文以某油田50余口油井动态日报统计为例,尝试利用Excel VBA,结合油田地理图形开发出可视化的油井动态统计GIS(地理信息系统)。
一、问题的提出
油井动态统计作为油田开发统计工作中一项重要内容,是油田日常生产指挥决策的直接依据。每一口油井每一天的开井关井、产量等情况,是每一位油田生产管理者必须掌握的最基本的数据。传统的油井动态统计采用报表的方式来反映,缺乏直观性。因此,如果能够利用电子地图将每一口油井标注出来,并与油井动态统计数据链接在一起,通过浏览地图就能够一目了然地掌握油井的运转状况,那么不啻为油田统计工作的一种创新。
目前利用专业GIS应用软件可以方便地解决这个问题,但需要专业的软件开发队伍来完成,费用也较高。那么,是否可以利用我们经常使用的Excel来实现上述功能呢?笔者通过实践摸索,利用Excel在简单地理图形界面条件下也可以较好地做到这一点,且具备一般VBA编程水平的统计业务人员就可以实现。
二、问题的解决
(一)建立工作簿
打开Excel,新建工作簿,命名为“油井动态GIS”,建立工作表“数据采集”和“浏览地图”。
(二)绘制地理图形
选择“浏览地图”工作表,全选工作表,设置行高为10.5,列宽为1.5,使该工作表成为标准坐标的栅格模板。然后按照井位部署图,使用“绘图”工具中的线条功能绘制地图示意图(图1),并在相应位置的单元格中填上“●”,作为油井的标志,该单元格位置的行数和列数的信息需要输入保存到“数据采集”工作表中的“井位”指标栏中,如井号为“姚4”的油井,其行、列号分别为6和25,则应在“数据采集”工作表中对应井号的“井位”指标栏中填入6和25。
(三)油井数据录入
选择“数据采集”工作表,设置“井号”、“井位”、“产量”指标栏,“井号”中的数据是固定的,可根据实际情况一次录入;“井位”中的两项数据分别代表“浏览地图”工作表中标有“●”的单元格行、列的位置,只需要一次设置好,例如井号为“姚4”的油井(图2),它在“浏览地图”工作表中的单元格位置的行和列分别为6和25;“产量”中的数据根据油井实际生产情况的变化每日输入。如果某口油井当日停产,则产量为0。
(四)油井动态统计的可视化
1.要实现的功能
在“浏览地图”工作表添加一个命令按钮控件,该按钮与所编写的VBA程序链接(后文中详细介绍),如果要查询所有油井中产量在某个数值以上的油井,只要用鼠标点击按钮,就会弹出一个需要用户输入条件数值的文本框(图3)。在文本框中输入条件数值,则地图上所有大于这个数值的油井均显示为红色,否则显示为黑色(图4),并自动统计和显示符合条件数值的油井口数。当鼠标选中某一口油井时,自动显示该井产量(图5)。整体运行效果见图6。
2.程序实现
①使用For Next循环语句和AddComment插入批注的方法,从“数据采集”工作表的第一口油井“产量”开始循环到最后一口油井,将产量单元格中的数值赋值给“浏览地图”工作表中所对应的单元格批注,以便当鼠标选中某一口油井时,自动弹出批注框显示该井产量信息。
②每次循环中使用If判断分支语句,判断产量是否大于所设条件数值,如果大于所设条件数值,则根据该井在“数据采集”工作表“井位”中代表“浏览地图”工作表中标有“●”的单元格的行、列信息确定地图上的位置,并将该油井标志“●”属性设置为红色,否则设置为黑色。
③每次循环对符合查询条件的油井计数,循环结束后,使用MsgBox信息框功能,将油井计数显示在信息框中。
3.示例程序
Sub 查询条件()
Dim cx As String
'将cx声明为字符变量
Sheets("浏览地图").Select
'选择"浏览地图"工作表
cx=InputBox("请输入查询条件:即大于某产量的数值 ")
'弹出对话框,输入查询条件,并将查询的数值赋值给变量cx
Cells.Select '全选单元格
Selection.ClearComments
'清除插入的批注
js=0 '计数
For jw=2 To 54
'设定循环从第一口油井的第2行开始到最后一口油井的54行结束
cl=Sheets("数据采集").Cells(jw,4)
'将“数据采集”工作表中某口井的产量赋值给变量cl
h=Sheets("数据采集").Cells(jw,2)
'在“数据采集”工作表中找出代表
"浏览地图"工作表中某口油井单元格行号的数值,并赋值给变量h
l=Sheets("数据采集").Cells(jw,3)
'在“数据采集”工作表中找出代表
"浏览地图"工作表中某口油井单元格列号的数值,并赋值给变量l
Cells(Val(h),Val(l)).Select
'选定由行号h与列号l确定的单元格
Selection.AddComment
'给该单元格插入批注
Selection.Comment.Text Text:="产量:" & Chr(10) & cl & "吨"
'将产量数据cl显示在批注中
Selection.Comment.Visible=0
'将批注设置为隐藏,只有当鼠标选中后才显示内容
If Val(cl)>Val(cx) Then
Selection.Font.ColorIndex=3
'如果产量大于查询条件所规定的某个数值,则将油井标志"●"设置为红色
js=js+1
'记录符合查询条件的油井口数
Else
Selection.Font.ColorIndex=0
'如果产量不符合查询条件所规定的某个数值,则将油井标志"●"设置为黑色
End If
Next jw
msg=MsgBox(js &"口",0,"大于"& cx &"吨的油井共有")
'弹出信息框,显示符合查询条件cx的井数js
End Sub





