APP下载

VBA 在医院统计领域的应用探讨

2021-10-13李昕昊周火明赖伏虎邓娟娟

中国医院统计 2021年4期
关键词:统计员专科架构

李昕昊 周火明 赖伏虎 徐 俊 邓娟娟 罗 燕

1 香港大学深圳医院,518000 广东 深圳; 2 深圳市宝安纯中医治疗医院,518101 广东 深圳

visual basic for applications(简称VBA)是新一代标准宏语言,是基于visual basic for Windows 发展而来的。它与传统的宏语言不同,传统的宏语言不具有高级语言的特征,没有面向对象的程序设计概念和方法;而VBA 提供了面向对象的程序设计方法,提供了相当完整的程序设计语言[1]。

VBA没有自己独立的工作环境,须依附于某一个主应用程序。VBA专门用于Office的各应用程序中,如Word、 Excel、 Access等。它的编写是以子过程和函数为单位,在 Access中以模块形式出现。随着微软办公软件的普遍化,灵活掌握VBA语言的使用,可以让复杂的工作简易化,减少不必要的重复性工作,提高工作效率[2-3]。

本文将从医院日报制作、每月医疗质量公示数据自动生成拆分、临床科室多维度多指标数据查询3个项目阐述VBA在医院统计中的应用。

1 医院日报制作项目

1.1 制作流程

1)首先把门诊报表、病房报表从BI决策支持系统导出。

2)点击汇总模板中运行按钮,程序自动把门诊报表、病房报表中对应病区和科室的入院、出院、转科等数据依次进行填充。

3)因存在患者出院召回、护士忘记预约登记出院等原因,造成BI决策支持系统中数据与HIS系统的数据不一致,所以需进行校核。先导出HIS系统中入院、出院、转科的数据,再点击核查模板中运行按钮 ,程序自动将汇总模板的数据与从HIS系统导出的数据进行核对。

4)校核无误后,点击日报模板中运行按钮,日报模板自动从汇总模板中读取相关数据进行填充,日报模板数据填充完成,程序结束。见图1。

图1 医院日报制作流程图

1.2 部分VBA代码

1.2.1 填充门诊工作量代码

Sub huizong_deal()

Application.ScreenUpdating = False ""关闭屏幕刷新

Application.Calculation = xlCalculationManual ""关闭自动计算,加快运行速度

On Error Resume Next

Dim FilesToOpen, FilesToOpen2, FilesToOpen3, arr1, brr1, arr2, brr2

Dim wb1_name As String, wb2_name As String, wb3_name As String, wb_name As String

Dim wb1 As Workbook, wb2 As Workbook, wb3 As Workbook

Dim i As Integer, j As Integer, i2 As Integer

Dim IRang As Range, IRang2 As Range, IRang3 As Range

ActiveSheet.Select

wb_name = ActiveWorkbook.Name

""填充门诊工作量数据

FilesToOpen2 = Application.GetOpenFilename("Excel,*.xls;*.xlsx;*.xlsm", , "选择【门诊工作量报表(专科)】", , False)

If FilesToOpen2 = False Then

Exit Sub

Else

Set wb2 = Workbooks.Open(FilesToOpen2, 0)

End If

Workbooks(wb_name).Activate

For Each IRang2 In Workbooks(wb_name).ActiveSheet.Range("Q2:Q32")

For Each IRang3 In wb2.Sheets(1).Range("A5:A35")

If IRang2.Value = IRang3.Value Then

Workbooks(wb_name).ActiveSheet.Range("C" & IRang2.Row & ":" & "P" & IRang2.Row).Value = _

wb2.Sheets(1).Range("B" & IRang3.Row & ":" & "O" & IRang3.Row).Value

End If

Next

Next

Workbooks(wb_name).ActiveSheet.Range("Q2:Q32").ClearContents

""关闭专科表,不保存

wb2_name = wb2.Name

Workbooks(wb2_name).Close False

1.2.2 填充住院工作量代码

""打开病房日记表,如果不选择表,则退出

FilesToOpen = Application.GetOpenFilename("Excel,*.xls;*.xlsx;*.xlsm", , "选择【病房日记表】", , False)

If FilesToOpen = False Then

Exit Sub

Else

Set wb1 = Workbooks.Open(FilesToOpen, 0)

End If

wb1_name = wb1.Name

j = ActiveSheet.Range("A6666").End(xlUp).Row

ActiveSheet.Columns("D:F").Hidden = True′隐藏D:F列

ReDim arr2(1 To j - 1, 1 To 1)

ReDim brr2(1 To j - 1, 1 To 1)

For i2 = 1 To j - 1

If Cells(i2 + 1, 1).Value <> "" Then

arr2(i2, 1) = Cells(i2 + 1, 1)

brr2(i2, 1) = arr2(i2, 1) & Cells(i2 + 1, 3)

Else

arr2(i2, 1) = arr2(i2 - 1, 1)

brr2(i2, 1) = arr2(i2 - 1, 1) & Cells(i2 + 1, 3)

End If

Next

Range("P2:P" & j) = brr2

For i = 1 To j - 1

Windows(wb1_name).Activate

If VBA.IsError(Application.VLookup(Range("P" & i + 1), IRang, 1, 0)) Then

If Range("C" & i + 1).Value <> "" Then

Range("G" & i + 1 & ":L" & i + 1).Interior.ColorIndex = 44

Range("N" & i + 1).Interior.ColorIndex = 44

Else

End If

Else

a = Application.Match(Range("P" & i + 1), IRang, 0)

Workbooks(wb_name).Activate

ActiveSheet.Range("F"&71+a-1&":K"&71+a-1).Value= Workbooks(wb1_name).Sheets(1).Range("G" & i + 1 & ":L" & i + 1).Value

ActiveSheet.Range("M"&71+a-1).Value= Workbooks(wb1_name).Sheets(1).Range("N" & i + 1).Value

End If

Next

Workbooks(wb_name).Activate

ActiveSheet.Range("P71:P888").ClearContents′清除辅助列的数据

Application.Calculation = xlCalculationAutomatic

Application.ScreenUpdating = True

End Sub

1.3 程序运行部分截图

程序运行部分截图见图2、图3。

图2 汇总模板填充门诊工作量数据

图3 数据自动导入日报模板

1.4 效果比较

某编制2 000张病床38个住院临床科室的三甲医院,在未使用此程序前,统计员每天需要花费4 h完成医疗运营日报数据的人工填充,校核以及生成,且时常出现复制粘贴错误、数据错行等问题。但自从使用VBA编码程序后,统计员只需要每天点击3个按钮,依次选择对应的Excel表格即可快速生成每天医疗运营日报。此过程花费不到10 min,不但提高了统计员的工作效率,而且数据质量也得到了很好的保障。

2 医疗质量公示数据项目

2.1 制作流程

1)首先收集12个职能部门关于临床科室共90个医疗质量指标和重点手术、重点病种数据;

2)对收集的Excel表格检查数据是否缺漏;

3)核查无误后,点击运行程序,输入即将生成医疗质量公示数据的年月份,点击确认,等待程序运行结束,共生成38个临床科室医疗质量公示数据表。

2.2 部分VBA程序代码

2.2.1 读取重点疾病和手术的路径、输入年月份的代码

Sub 医疗公示数据()

Application.ScreenUpdating = False′关闭屏幕更新

Application.DisplayAlerts = False′关闭警告开关

Dim FilesToOpen1, FilesToOpen2

Dim n As Byte, i As Byte, j As Byte, m As Byte, s As Byte

Dim wb1 As Workbook, wb2 As Workbook, wb1_again As Workbook

Dim ws1 As Worksheet, ws2 As Worksheet, ws3 As Worksheet

Dim wb1_name As String, wb2_name As String, New_wb1_name As String, FilesAllname As String, NameLineName As String

Dim x1 As Integer, y1 As Long

Dim New_name, New_Path′定义新名称,新路径

Dim wb3 As Workbook, k As Byte, w As Byte, g As Byte

Dim yuefen As String′定义月份的文字

""需要确认是否修改了读取重点疾病和手术的路径,避免读取其他月份的数据

TS = MsgBox("是否已经更新重点疾病和手术手术的当月路径?", vbYesNo)

If TS <> vbYes Then

Exit Sub

Else

End If

""主动输入月份,避免忘记修改月份

yuefen = InputBox("请输入年月份", "hello", , 2500, 3500)

""专科重点疾病数据处理部分

Set wb1 = ActiveWorkbook

wb1_name = ActiveWorkbook.Name

FilesAllname = ActiveWorkbook.Path & "”& wb1_name '获取路径和名称,方便最后重新打开

New_Path = wb1.Sheets("指标数据抽取").Range("B6").Value ′最终导出文件的路径

""New_name = wb1.Sheets("指标数据抽取").Range("B3").Value

FilesToOpen1 = wb1.Sheets("指标数据抽取").Range("B1").Value′读取重点疾病数据路径

FilesToOpen2 = wb1.Sheets("指标数据抽取").Range("B2").Value′读取重点手术数据路径

2.2.2 遍历文件夹读取即将生成的科室名称

""通过读取文件夹的方式复制每个工作簿的那一行科室名称

f_name = Dir(wb1.Path & "〔.xlsx") ′搜索当前文件夹

Do While f_name <> ""

wb1_name = ActiveWorkbook.Name

Set wb1 = ActiveWorkbook

If f_name <> wb1_name Then

Set wb3 = Workbooks.Open(wb1.Path & "、" & f_name)

For w = 1 To wb3.Sheets.Count

For g = 1 To wb1.Sheets.Count

If wb3.Sheets(w).Name = wb1.Sheets(g).Name Then

If wb3.Sheets(w).Name = "基本质控指标" Or wb3.Sheets(w).Name = "基本质控指标 --IMC" Then

k = wb3.Sheets(w).UsedRange.Columns.Count

wb3.Sheets(w).Activate

wb3.Sheets(w).Range(Cells(2, 5), Cells(2, k)).Copy

wb1.Sheets(g).Activate

wb1.Sheets(g).Cells(2, 5).PasteSpecial Paste:=xlPasteValues

wb1.Sheets(g).Range(Cells(1, 1), Cells(1, k)).Merge ""合并标题单元格

wb1.Sheets(g).Range(Cells(2, 5), Cells(2, k)).Columns.AutoFit ""自动调节列宽

wb1.Sheets(g).Columns(k + 1).Resize(, 20 - k).Delete

End If

End If

Next

Next

On Error Resume Next

Dim arr1, d As Object ""字典,删除多余的表

Set d = CreateObject("scripting.dictionary")

ReDim arr1(1, 1 To wb3.Sheets.Count)

For w = 1 To wb3.Sheets.Count

arr1(1, w) = wb3.Sheets(w).Name

d(arr1(1, w)) = ""

Next

For g = 1 To wb1.Sheets.Count

If d.exists(wb1.Sheets(g).Name) Then

Else

wb1.Sheets(g).Delete

g = g - 1

End If

Next

Set d = Nothing

Set arr1 = Nothing

End If

wb3.Close False

f_name = Dir′找寻下一个excel文件,否则无限循环

2.2.3 读取各科室重点疾病数据代码

""专科重点疾病数据处理部分

Sub Savetime(ws1 As Worksheet, ws2 As Worksheet)

On Error Resume Next "如果后面的程序出现"运行时错误"时,会继续运行,不中断

Application.ScreenUpdating = False′关闭屏幕更新

Application.DisplayAlerts = False′关闭警告开关

Dim IRange As Range

Set IRange = ws2.Range("F:F")

ws1.Activate

x1 = ws1.UsedRange.Columns.Count′读取第二行的列数,方便统计有几个科室

ws1.Rows(2).Insert

For n = 4 To x1

ActiveSheet.Cells(2, n) = Application.WorksheetFunction.CountIf(IRange, Cells(3, n))

Next

y1 = Application.WorksheetFunction.Max(Range(Cells(2, 4), Cells(2, x1)))

Set ws1 = ActiveSheet

ActiveSheet.Range(Cells(4, 1), Cells(4 + (y1 - 1) * 9, 1)).Merge

For j = 4 To x1

m = 0

For i = 3 To ws2.Range("F6666").End(xlUp).Row

If ws1.Cells(3, j) = ws2.Cells(i, 6) Then

m = m + 1

If m = 1 Then

ws2.Activate

ws2.Range(Cells(i, 7), Cells(i, 15)).Copy

ws1.Activate

ws1.Cells(4, j).PasteSpecial Paste:=xlPasteValues, Transpose:=True

Else

ws2.Activate

ws2.Range(Cells(i, 7), Cells(i, 15)).Copy

ws1.Activate

ws1.Cells(4 + 9 * (m - 1), j).PasteSpecial Paste:=xlPasteValues, Transpose:=True

End If

End If

Next

Next

wb1.Activate

ws1.Rows(2).Delete′删除辅助行

ws1.Range("B3").Select′冻结窗体

ActiveWindow.FreezePanes = True

ws1.Rows("3:" & ws1.Range("B6666").End(xlUp).Row).AutoFit""自动调节行距

End Sub

2.3 程序运行部分截图

程序运行部分截图见图4。

图4 生成38个科室医疗质量公示数据Excel文件

2.4 效果比较

每月共38个临床科室,每个科室90个医疗质控指标和重点病种、重点手术明细数据,如果人工处理,统计员需要花费1 周的时间才能整理完成,并且数据经常出现错漏的情况,数据质量得不到保障。自从统计员使用此VBA程序后,效率快速提高,每月花费时

间不超过1 h就能完成,不再出现复制粘贴有误、错行等原因导致数据出错的现象。

3 Access多指标数据查询项目

3.1 项目背景

医院门诊、住院基本医疗数据查询需求量大,且时常要求统计员短时间内统计出结果,需求涉及三级公立医院绩效考核数据、住院医师培训基地督导、重点专科申报、科室诊疗质量基线调研、“3名工程”等。如果统计员使用广东省病案统计管理系统软件查询数据,不仅费时费力,而且存在软件运行效率低,操作不便等问题。所以运用VBA语言和数据库的原理研发Access多指标数据查询数据库,让数据查询速度更快,操作更加灵活便捷[4]。

3.2 部分VBA程序代码

3.2.1 更新基础数据中住院架构代码

Sub GX更新住院架构_Click()

DoCmd.Close acTable, "A新住院架构" '先关闭,否则会引起错误值

Call AddFile

If Len(AddFileName) = 0 Then

MsgBox "未选取工作簿,退出导入!", vbInformation + vbOKOnly, "信息提示"

Exit Sub

End If

ACName = CurrentProject.Name

' On Error GoTo End_Sub

Err.Clear′清除错误值

DoCmd.SetWarnings False′忽略警示

DoCmd.RunSQL "delete * From A新住院架构"

DoCmd.RunSQL "insert into A新住院架构(序号,大专科管理科室,专科管理科室,亚专科,绩效单元,直报分科单元,住院类型,科室名称,HIS科号,统一科号病案,维护科号病案)"&

_ "select 序号,大专科管理科室,专科管理科室,亚专科,绩效单元,直报分科单元,住院类型,科室名称,HIS科号,统一科号病案,维护科号病案"& _

DoCmd.SetWarnings True′恢复警示

MsgBox "住院架构更新导入成功!", vbInformation + vbOKOnly, "信息提示"

Exit Sub

End_Sub:

DoCmd.SetWarnings True′恢复警示

Msg = "错误编号 #"& Str(Err.Number) & "出错原因" _

& Err.Source & Chr(13) & Err.Description

MsgBox Msg, , "Error", Err.HelpFile, Err.HelpContext

End Sub

Function AddFile()

Dim FD As FileDialog

Set FD = Application.FileDialog(msoFileDialogOpen)

With FD

.FilterIndex = 15

.InitialFileName = ""

If .Show = -1 Then

AddFileName = .SelectedItems(1)

Else

AddFileName = ""

Exit Function

End If

End With

End Function

3.2.2 住院工作量多指标数据查询代码

""住院工作量

strsql = "SELECT A新住院架构.序号, A新住院架构.大专科管理科室, A新住院架构.专科管理科室, A新住院架构.亚专科, A新住院架构.绩效单元, " _

& "A新住院架构.直报分科单元, A新住院架构.住院类型,A新住院架构.HIS科号, 多指标源数据表.年月, " _

& zyzblx2 _

& " FROM A新住院架构 INNER JOIN 多指标源数据表 ON A新住院架构.HIS科号 = 多指标源数据表.HIS科号"

Set zysql = CurrentDb.CreateQueryDef("过程表", strsql)

strsql2 = "PARAMETERS [Forms]![多指标数据查询]![dzb_start时间] Text ( 255 ), [Forms]![多指标数据查询]![dzb_finish时间] Text ( 255 ), " _

& "[Forms]![多指标数据查询]![dzb_架构类型] Short;" _

& " SELECT 过程表.大专科管理科室," & Forms!多指标数据查询!dzb_架构类型 & "," & zyzblx _

& " FROM 过程表 " _

& "WHERE 过程表.住院类型 In (" & qylx & ")" _

& "And (int(过程表.年月) " _

& "Between Forms!多指标数据查询!dzb_start时间 And Forms!多指标数据查询!dzb_finish时间)" _

& " GROUP BY 过程表.序号,过程表.大专科管理科室," & Forms!多指标数据查询!dzb_架构类型 & " ORDER BY 过程表.序号"

Set zysql2 = CurrentDb.CreateQueryDef("多指标数据查询住院-" & qylxmc, strsql2) ""

DoCmd.OpenQuery zysql2.Name

Application.Echo True ""启用刷写屏幕

3.3 程序运行部分截图

程序运行部分截图见图5、图6。

图5 Access多指标数据查询主界面

图6 Access多指标数据查询结果(模拟数据)

3.4 效果比较

通过Access数据库的研发,医院统计员每次只需要选择符合的统计范围和指标类型,选择展现的架构类型,单击查询按钮运行程序,数据便会快速呈现,而不再使用广东省病案统计管理系统或撰写SQL脚本在SQL server数据库客户端进行查询,效率得到很大的提升。前期通过对Access数据库研发,可以根据自己的需求进行灵活设计,统计员平时只需维护基础表即可。Access数据库的使用保障了数据的稳定性,不会随着业务数据的变动或人为误操作而造成不同时间查询的指标数据不一致的现象,并且使用界面简洁,非专业编程人员也能熟悉使用。

4 小结

本文通过3个项目实例,介绍了VBA在医院统计领域的应用。VBA不仅能帮助医院统计员从日常重复枯燥的工作中摆脱出来,提高工作效率,从而专注于更高质量的脑力劳动,而且能保证数据质量。在医院信息化建设程度不高且没有更好的BI决策系统或RPA机器人等辅助工具的情况下[5],采用VBA编程是一个不错的选择。VBA 易于学习掌握,医院统计员在日常工作中也可以使用宏记录器记录用户的各种操作并将其转换为VBA代码[6],快速将日常工作转换为VBA 程序代码,使工作自动化。如遇到更复杂的需求,则需要了解VBA编程的编写逻辑,或者RPA机器人平台的“录像(record)”/“编辑(edit)”功能。总之,VBA是适用于医院统计应用场景的一种较好的工具,医院统计人员可在实际工作中掌握使用。

猜你喜欢

统计员专科架构
基于FPGA的RNN硬件加速架构
功能架构在电子电气架构开发中的应用和实践
中外医学专业与专科设置对比分析及启示
小小统计员
小小统计员
LSN DCI EVPN VxLAN组网架构研究及实现
小小统计员
小小统计员
在联合中释放专科能量
论国内本科和专科的异同