简介这是医院空气消毒记录本的电子文档面向医院感染管理、护理部及后勤保洁人员用于按科室、日期、消毒方式等维度记录每日空气消毒情况满足院感质控与上级检查的台账要求。资源仅包含1个doc文件包体约400KB内容为可直接修改的表格模板正文含作者、日期与医院名称占位信息适合基层医疗机构和社区卫生服务中心参照填写。目前已有55人学习下载说明该模板在同类场景中有一定需求。用户拿到后既可沿用其表格框架根据本院科室设置调整消毒区域、消毒剂种类与执行人栏目快速形成规范、可追溯的空气消毒登记台账也可将其作为院感培训时的示例文本或直接打印用于日常手写记录并归档备查。整个文档结构简明修改便捷。1. 医院空气消毒记录本把签字流程压缩成一次点击院感科每个季度都要翻一次消毒记录最常看到的不是“已消毒”而是“漏填日期”“开始时间晚于结束时间”“紫外线灯管累计时长明显超过寿命”。这份《医院空气消毒记录本.doc》在彰武县第四人民医院这类场景里本质上不是一张纸而是一张带签名权的数据采集表。把它拆开看至少包括三部分字段定义日期、区域、消毒方式、时间、操作人、校验规则时长不能为负、灯管有累计寿命、归档路径纸质或电子记录需要被复核。适合院感专员、信息科工程师和正在写护理质量管理系统的开发者参考。下面从字段模型开始逐步把它做成“点一下自动登记月底自动审计”的工具。2. 空气消毒记录本的数据字段与校验逻辑2.1 记录表为什么不能只写“空气已消毒”院感检查时记录本要被用来回答三个问题哪个区域在什么时间被消毒、用哪种方式消毒、谁负责执行的。如果一个单元格只写“√”等于没有数据。所以第一版表格至少要有“日期、消毒区域、消毒方式、开始时间、结束时间、消毒时长、操作人、复核人”这八个字段。每一条记录对应一次完整的消毒事件而不是一个班次。在我整理的表格结构里主键是“日期 消毒区域 开始时间”。医院里同一个区域一天可能消毒多次只按日期不唯一但同一区域在同一分钟开启两次消毒是异常数据。字段类型和校验规则如下字段类型校验规则说明记录日期日期 yyyy-mm-dd不能为空不得晚于今天夜班如果跨天结束日期要单独记录消毒区域下拉病区/治疗室/手术室等必填同一行不可复制粘贴跳空区域名称要与院感科备案一致消毒方式下拉紫外线灯管/空气消毒机/化学喷雾必填决定后续时长和累计指标开始时间时间 hh:mm不晚于结束时间由宏自动写入避免手写结束时间时间 hh:mm晚于开始时间也可以用开始时间时长计算消毒时长数值分钟紫外线 30–60空气消毒机按说明书化学喷雾需填浓度时长异常是最常见的检查点操作人下拉科室在编护士必填和排班表一致复核人下拉护士长/主班夜班记录复核人可以为空但次日上午必须补签这是很多系统容易忽略的“延迟校验”2.2 校验规则要区分“立即校验”和“事后校验”立即校验发生在录入那一刻比如开始时间晚于结束时间直接弹窗阻止。事后校验则用在月末复查比如紫外线灯管的累计使用时长如果某根灯管已经累计记录超过额定寿命需要提示更换。这类规则在 Word 表格里没法用公式直接做但可以完全由 VBA 在读表时计算。不同消毒方式的参数差异很大。紫外线灯管记录的是灯管编号和累计时长空气消毒机记录风速档位化学喷雾要记录药剂名称、浓度和配比。如果把这三类混在一列里写月底统计会非常痛苦。我的做法是保留一个“消毒方式”字段做总分类再把具体参数放进备注列日终由护士长复核。这样既不影响日常速记又能通过分类字段筛选统计。夜班跨天是另一个容易踩坑的地方。比如 23:30 启动紫外线次日 00:30 关闭如果只记一个日期结束时间减开始时间会得到负数。常见做法是把“日期”拆成“开始日期”和“结束日期”两列但这样会让日常填写多一步。折中方案是保留一个日期夜间记录开始时弹出选择是否跨天跨天则自动把结束日期显示为次日。这个判断同样放在宏里比让护士自己记两行要可靠得多。2.3 把字段落成 Word 表格时的版式细节医院环境里很多电脑还开着 Word 2007所以我不建议用新版内容控件而是用传统的 Word 表格加宏。表头一行数据区从第二行开始。每个单元格建议设置固定列宽日期列 22 mm时间列 18 mm区域列 40 mm。行高不小于 8 mm方便手指点选。为了避免操作人改错列录入区可以先用灰色底纹标记禁用主编辑区的直接输入。做法是先让表头和数据区都是可见状态然后进入“开发工具 - 限制编辑”勾选“仅允许在文档中进行此类型的编辑”再选择使用窗体域或保护段落。提示如果医院内网不允许安装第三方软件优先使用旧版窗体域FormFields。老版本 Word 对窗体域支持最稳不需要另存 .docx直接在当前 .doc 里就能保护。3. 用 Word VBA 让记录本自动写入时间和时长3.1 为什么选择 VBA 而不是 Excel这份记录本原始格式是 .doc意味着很多护士习惯双击 Word 直接填。Excel 虽然有更强的计算能力但院感科要的是“一张可以打印的签名页”不是电子台账。Word 中嵌入 VBA 后打开文档即可运行宏不需要单独安装程序打印格式也本来就排好了。相比改用数据库系统VBA 的改造周期最短且给后续 Python 复核留了同一个文件作为数据源。有个前提必须先解决Word 的宏默认是关闭的。第一次部署时我要到“Word 选项 - 信任中心 - 宏设置”里勾选“启用所有宏”再把文档所在目录加入受信任位置。如果护士连“启用内容”的红条都看不见脚本再好也没用。3.2 在表格末尾追加一条消毒记录先做最基础的动作在表格最后一行后面新增一行并把系统当前时间填入开始时间列。把以下代码放在 ThisDocument 模块里Sub AddDisinfectionRecord() Dim t As Word.Table Dim rNew As Word.Row Dim startTime As Date Dim durationMin As Integer 如果文档中没有主表则退出 If ActiveDocument.Tables.Count 0 Then MsgBox 当前文档中没有表格请先插入记录表。, vbExclamation Exit Sub End If Set t ActiveDocument.Tables(1) 复制表尾样式并追加一行 Set rNew t.Rows.Add(t.Rows.Last) 第1列写日期第4列写开始时间 rNew.Cells(1).Range.Text Format(Date, yyyy-mm-dd) startTime Time rNew.Cells(4).Range.Text Format(startTime, hh:nn) 弹出窗口让操作员填写时长默认60分钟 durationMin Val(InputBox(请输入本次消毒时长分钟, 消毒记录, 60)) If durationMin 0 Then rNew.Delete Exit Sub End If 用 DateAdd 计算结束时间n 表示分钟 rNew.Cells(5).Range.Text Format(DateAdd(n, durationMin, startTime), hh:nn) rNew.Cells(6).Range.Text CStr(durationMin) 光标跳转到消毒方式列等操作员选择 rNew.Cells(3).Range.Select End Sub这段代码关键在t.Rows.Add(t.Rows.Last)。t.Rows.Last指当前表格的最后一行Rows.Add会复制最后一行样式新行成为真正的末行。第 1、3、4、5、6 列分别对应记录日期、消毒方式、开始时间、结束时间、消毒时长。Format(startTime, hh:nn)输出 08:05 这种两位时间注意 Word VBA 中小时用 hh分钟用 nn如果写成mm会被当成月。DateAdd(n, durationMin, startTime)里的n是 VBA 的分钟间隔标识区别于m月份这个参数写错会得到完全错误的结束时间。3.3 防止重复登记和漏填消毒方式直接追加虽然方便但会在同一日期下生成两行月底对账时要人工分辨。所以在AddDisinfectionRecord开头需要加一个查重。先遍历表格第一列把每格文本中夹带的单元格结束符Chr(7)清掉再和今天的日期比较Dim i As Integer Dim cellText As String For i 2 To t.Rows.Count cellText Replace(t.Cell(i, 1).Range.Text, Chr(7), ) cellText Trim(cellText) If cellText Format(Date, yyyy-mm-dd) Then If MsgBox(今天已有记录是否仍要追加, vbYesNo vbQuestion) vbNo Then Exit Sub End If End If Next i把这段放在 3.2 代码的Set t之后即可。这里Replace(... Chr(7))是必须的因为 Word 表格单元格的Range.Text末尾会带一个\x07段落标记不清理会导致日期比较永远失败。MsgBox的第二个参数vbYesNo vbQuestion表示显示“是/否”按钮和问号图标返回值为vbYes或vbNo。查重只是提醒不是强制拦截因为某些科室确实需要在一天内对同一区域消毒两次。3.4 绑定到打开文档按钮在 Word 里按 AltF11 进入 VBA 编辑器插入模块并把上面代码粘贴进去然后关闭编辑器。接下来在“开发工具 - 宏”里运行一次AddDisinfectionRecord就能看到效果。如果觉得每次打开文档还要手动运行太麻烦可以在 ThisDocument 中挂一个事件Private Sub Document_New() AddDisinfectionRecord End SubDocument_New只在基于模板新建文档时触发。如果科室直接从旧记录本复制一份作为新记录本则不会触发。更稳的做法是在页脚放一个“新增记录”按钮需要先退出设计模式。这个按钮的动作就是执行AddDisinfectionRecord护士点击后光标自动跳到“消毒方式”下拉框不用去改单元格里的表头。按钮对应的代码库已经存在只是再套了一层Click事件不改变宏内部逻辑。4. 用 Python 对历史记录做漏登与时长异常复核4.1 为什么还要再做一层复核即使有宏操作人仍然可能绕过按钮直接改表格或者在下拉菜单中选择错误记录。Word 是文档不是数据库它不会自动保证所有记录都连续。月末交给院感科前我习惯用 Python 再扫一遍 .doc 原文件输出一张异常清单缺日期的、时段跨天的、时长不在合理范围内的。这一步也能把多科室多个记录本汇总成一张审计表。4.2 用 pywin32 读取 .doc 里的表格在 Windows 机器上最直接的方式是调用 Word 的 COM 接口。需要安装 pywin32pip install pywin32然后读取文档第一个表格import win32com.client word win32com.client.Dispatch(Word.Application) word.Visible False # 后台运行不弹出窗口 doc word.Documents.Open(rC:\disinfect\医院空气消毒记录本.doc) table doc.Tables(1) def clean(cell_text): # Word 单元格文本末尾有 \x07末尾还有一个 \r都要去掉 return cell_text.replace(\x07, ).replace(\r, ).strip() rows_data [] for row_idx in range(2, table.Rows.Count 1): # 从第2行开始跳过表头 row { date: clean(table.Cell(row_idx, 1).Range.Text), area: clean(table.Cell(row_idx, 2).Range.Text), method: clean(table.Cell(row_idx, 3).Range.Text), start: clean(table.Cell(row_idx, 4).Range.Text), end: clean(table.Cell(row_idx, 5).Range.Text), duration: clean(table.Cell(row_idx, 6).Range.Text), operator: clean(table.Cell(row_idx, 7).Range.Text), } if row[date]: rows_data.append(row) doc.Close(False) word.Quit() print(f共读入 {len(rows_data)} 条记录)参数说明table.Cell(row_idx, col_idx)的行列都从 1 开始与 Word 表格界面里的行列号一致。clean用来清掉 Word 写入单元格时的两个不可见字符\x07是单元格结束标记\r是段落回车。读取时word.Visible False能避免每次执行时闪出 Word 窗口但要注意如果文档被打开着COM 会复用已有进程建议脚本运行前先关闭 Word 进程。4.3 检查日期连续性与时长边界读出的记录是字符串。先转换成日期和时间对象再判断日期是否连续。如果某一天没有记录说明可能漏登记from datetime import datetime, timedelta cleaned [] for r in rows_data: try: d datetime.strptime(r[date], %Y-%m-%d).date() start datetime.strptime(f{r[date]} {r[start]}, %Y-%m-%d %H:%M) end datetime.strptime(f{r[date]} {r[end]}, %Y-%m-%d %H:%M) duration_min (end - start).total_seconds() / 60 except ValueError: cleaned.append({**r, error: 时间格式无法解析}) continue cleaned.append({ date: d, start: start.time(), end: end.time(), duration_min: duration_min, method: r[method], area: r[area], operator: r[operator], error: }) # 日期连续性把记录日期去重后排序检查每天间隔 all_dates sorted({c[date] for c in cleaned if c[date]}) missing_days [] for prev, curr in zip(all_dates, all_dates[1:]): if (curr - prev).days ! 1: missing_days.append((prev, curr)) # 时长异常紫外线按常规30-60分钟这里是经验值 abnormal [c for c in cleaned if c[duration_min] 20 or c[duration_min] 180]这段代码把“时间格式无法解析”的记录单独留在cleaned里error字段会被标注。zip(all_dates, all_dates[1:])成对比较相邻日期如果间隔不是 1 天就把起止日期记到missing_days。时长边界只是个示例真正应用时要按照每种设备的说明书配一套字典比如紫外线默认为 30 到 60 分钟空气消毒机是 60 到 120 分钟。如果需要更细可以再加一张配置表按method字段读取不同的上下限。4.4 输出可读的审计 CSV异常信息要交给护士长不能用控制台打印。我一般会生成audit_report.csv用utf-8-sig编码这样用 Excel 打开不会乱码with open(audit_report.csv, w, encodingutf-8-sig, newline) as fp: fp.write(日期,区域,消毒方式,开始,结束,时长,异常类型\n) for r in cleaned: problems [] if r[error]: problems.append(r[error]) if r in abnormal: problems.append(时长异常) if problems: fp.write(f{r[date]},{r.get(area,)},{r.get(method,)},{r.get(start,)},{r.get(end,)},{r[duration_min]:.0f},{/.join(problems)}\n) for prev, curr in missing_days: print(f缺失日期{prev timedelta(days1)} 到 {curr - timedelta(days1)})utf-8-sig会在文件开头写一个 BOM 头Excel 识别 UTF-8 的唯一可靠标志。newline是为了避免在 Windows 下出现空行。筛选条件里r in abnormal依赖列表对象比较只适用于当前进程里创建的 dict如果后续要扩展建议给每条记录加一个唯一 id或者直接用r[duration_min] 20 or r[duration_min] 180作为条件避免踩对象比较的坑。5. 进阶技巧锁定录入区域并一键导出 CSV5.1 用窗体域限制录入范围前面用宏自动写入时间但“消毒区域”“操作人”这两列还需要护士选择。直接把文档保护起来只允许填写窗体域可以避免“消毒区域”被改成随意文本。在 Word 2007 及以上版本中先插入下拉型窗体域光标定位到目标单元格开发工具 - 旧式工具 - 下拉型窗体域然后双击域设置下拉项。完成后在“限制编辑”里勾选“仅允许在文档中进行此类型的编辑”选择“填写窗体”再点“启动强制保护”。密码设成空会有风险我一般设置一个简单密码只发给护士长。强制保护后所有通过AddDisinfectionRecord写入日期的代码仍然可以运行因为宏不受窗体保护限制。但普通用户手动点击单元格时只能进入窗体域改不了其他单元格这让表结构不易被破坏。需要注意如果在一个已经保护的文档里调用Rows.Add追加新行新行中的窗体域不会自动携带所以AddDisinfectionRecord里最好在开头先执行ActiveDocument.Unprotect写入完成后再恢复保护否则会出现新行无法录入区域的假死状态。5.2 把当前记录本导出为 CSV 供审计配合第四章的 Python 脚本还可以在 VBA 里直接导出 CSV不用打开 Python 环境。以下宏把表格第二行到末行输出到共享目录Sub ExportToCsv() Dim fso As Object Dim ts As Object Dim t As Word.Table Dim i As Integer Dim line As String Set fso CreateObject(Scripting.FileSystemObject) Set ts fso.CreateTextFile(C:\tmp\disinfect_ Format(Date, yyyymmdd) .csv, True, False) Set t ActiveDocument.Tables(1) For i 2 To t.Rows.Count line cleanCell(t.Cell(i, 1)) , cleanCell(t.Cell(i, 3)) , _ cleanCell(t.Cell(i, 4)) , cleanCell(t.Cell(i, 5)) , _ cleanCell(t.Cell(i, 6)) ts.WriteLine line Next i ts.Close MsgBox 已导出 CSV End Sub Function cleanCell(c As Word.Cell) As String cleanCell Replace(c.Range.Text, Chr(7), ) cleanCell Replace(cleanCell, Chr(13), ) cleanCell Trim(cleanCell) End Function这里CreateTextFile(..., False)的最后参数表示非 Unicode也就是 ANSI。如果你希望 Excel 不出现中文乱码可以把False改成True生成 UTF-16也更容易被 Excel 识别。line拼的是“日期,消毒方式,开始,结束,时长”并没有处理单元格值本身包含逗号的情况。如果消毒区域名称里带逗号简单 CSV 会变成多列所以导出前最好先把表单域里可选的区域名称去掉逗号。运行 ExportToCsv 后检查生成文件名的日期前缀是否与系统时间一致如果共享目录写入失败先确认网络驱动器的写权限。本文还有配套的精品资源点击获取