公卫人

 找回密码
 立即注册

QQ登录

只需一步,快速开始

查看: 13515|回复: 39

[经验] 想成为魔法少女吗?来和VBA签订契约吧,浅谈公卫自动化报表。

  [复制链接]
baisenes 发表于 2023-1-26 13:28:45 | 显示全部楼层 |阅读模式

注册后推荐绑定QQ,之后方才可以使用下方的“用QQ帐号登录”。

您需要 登录 才可以下载或查看,没有账号?立即注册

x
本帖最后由 baisenes 于 2023-1-26 19:04 编辑
# w" |* f) p; w6 ]" G5 V- ~7 z& M
+ ~$ q: ?0 m( Y0 X0 ~" q前言
" X: k. M) K3 K8 a3 e很久以前就想写的经验分享,关于公卫专业必备的excel表格、access数据库使用技能,通过合理的数据表布局、配合vba实现数据采集、自动清洗、分析、自动生成报表。无论是在国二十出台以前,还是乙类乙管落实后的现在,这些技能都显著提高了本人及所在医院对疫情处理的速度和准确性(以至于我们医院恶名远扬,因为无论卫贱委要多急或者多不合理的报表,我们总能给出来,被兄弟单位骂卷王)。# d# c$ I- w- i. n( ?6 b
贴主营养食品专业,因此一些步骤可能流统的同学们有更好的办法,不足之处欢迎指出。本文主要做思路启发,目的在于让大家知道有这样一种方便的工具,可以提高我们的效率,并且无需过多的编程基础,学习曲线平缓。
( w2 u. Z. A7 b5 |5 B
6 z( {9 L" B$ F2 m5 U: O) H; I& O% Z
+ G# Y( b" j$ A1 l
                               
登录/注册后可看大图

1 I7 q1 u& _* ?4 T; ?' T1. 关于VBA?
8 s2 Q; Y5 j& F9 v' h. O( X* @  ]VBA是office套件中内置的脚本环境,也被称作宏,官方文档:
9 f9 S# ?  V" f6 `9 G! u2 Fhttps://learn.microsoft.com/zh-cn/office/vba/api/overview/excel1 I3 s" K3 g  M4 |" F* n9 C5 X$ ]
基础知识:
! g, c8 l9 |+ k5 o; ~( G8 y$ G; shttps://www.w3cschool.cn/excelvba/6 f7 d; |8 l2 o) a5 a' ]1 C
新手上路,以上两个链接直接看可能会头大,但是至少要先了解如何启用VBA功能:
1 H% a- T# z; b1 _https://www.w3cschool.cn/excelvba/excelvba-what.html& K- o" c8 a1 Z+ }- q
https://www.w3cschool.cn/excelvba/excelvba-macro.html
5 d$ R. _% R7 C  y- V; F$ N  G$ r; p9 b/ F  `
, G! z7 V6 [0 }! x4 S
2. VBA在EXCEL报表中能做什么?
, g; P) A- K* X. l! U& t9 E' U. s" e0 Y% I1 k" ?8 G; c, J
场景1:如,从其他单位接收电子表格,为疫情触网对象信息,接报单位需要核实接收的信息并落实管理,其中列内容基本固定但是某些列会出现一些经常性的错误(比如地址、身份证号、性别年龄)) ?& C' e! Q) u9 e2 n0 X( M8 `

: @! r7 E: m( b  Q) \通过简单的公式,我们可以根据身份证号快速计算当事人的性别和年龄,以下是不太准确但方便的算法(假设身份证号位于A1单元格):0 w( h' p$ S9 P5 S, E# e  y
  1. =IF(MOD(MID(A1,17,1),2)=1,"男","女")
    8 x2 R$ H9 m6 H3 r! i0 W
  2. =YEAR(TODAY())-MID(A1,7,4)
复制代码

1 c$ k. H$ \% I0 j: `- t年龄是粗暴地用当前年减去出生年,如果需要更准确的年龄,可以进一步修改公式
( s* K5 J! O1 Q& f: H+ ^# C  x9 p- Y$ O" w
对于地址,我们经常会遇到形如下的错误地址:
; I+ N- y6 ^8 q2 ?上海市上海市市辖区浦东新区上钢街道昌里路360号- V6 B' _+ \  {% S( y/ ^2 O
上海是市辖区浦东新区上钢新村街道昌里路360号# v/ O0 s3 J! b4 q
上海市上 钢街道昌里 路 360号
: E5 `; p& L# w& B" x8 ^上海市黄埔区南京东路街道成都北路290号(上海黄浦,广州黄埔)
  T( g6 ]. j/ C2 w上海市        荣乐西路1039弄1039号(上海的地址格式以弄、号、室为常见,部分地址没有弄只有号,流调人员可能不熟悉地址,因此一定要当事人报一个弄): g9 {1 J9 A' @0 i$ s5 J- E
2 R% I% a- I) F2 d
对于上述类型的部分错误,我们可以通过ctrl-h呼出替换窗口,把上海市、浦东新区、“ ”等常见的错误字符替换成"",替换后即可得到如下地址信息6 P2 ?& {: ]7 q: p% O+ q
昌里路360号6 b: N4 @/ I: |7 P; Q0 i0 u
昌里路360号. R  b7 x# A& @- e  W* B
昌里路360号2 H- x5 J' z. H8 k0 N0 v2 B
成都北路290号, I9 W0 ^% j6 e: O+ M
荣乐西路1039弄1039号
0 K) e9 I: v0 T但是如果每天接报10-20单,数百人,这样处理可能会非常辛苦,可以利用如下VBA代码将常见的错误字段自动移除:$ K) W1 f2 E7 P. {5 S& |/ z
  1. Sub 自动清理(); _- w' e5 W+ I, u) i
  2.     ' 地址清理 宏8 Q; {& \! ?. Z! a
  3.     ActiveWorkbook.Worksheets("纳管汇总表").Activate
    : q9 H, T/ v" N: D6 \6 q* t
  4.     '由于我们还有其他自动计算脚本引用了地址,所以需要在更新地址时关闭自动计算功能以提升性能
    % L" t! L1 j, O: Q5 C
  5.     Excel.Application.Calculation = xlCalculationManual0 M! t. ~# A* N$ z# C$ M
  6.     Sheets("纳管汇总表").Select
    ' {5 Y( G. L* ~/ h+ @3 c
  7.     '假设地址信息在H列8 O: }3 f3 f, e  G' b/ Z. ]' U2 c
  8.     With Sheets("纳管汇总表").Columns("H:H")
    9 c" z; S/ ~7 o- P* G- I6 U
  9.         .Replace What:="上海市", Replacement:="", LookAt:=xlPart, SearchOrder:=xlByRows, MatchCase:=False, SearchFormat:=False, ReplaceFormat:=False5 H8 \; \4 x7 O4 b6 m( k) E6 o
  10.         .Replace What:="上海是", Replacement:="", LookAt:=xlPart, SearchOrder:=xlByRows, MatchCase:=False, SearchFormat:=False, ReplaceFormat:=False6 {1 m3 M" C9 ]) @) e
  11.         .Replace What:="市辖区", Replacement:="", LookAt:=xlPart, SearchOrder:=xlByRows, MatchCase:=False, SearchFormat:=False, ReplaceFormat:=False; r4 a2 a4 D0 i9 x
  12.         .Replace What:="XX区", Replacement:="", LookAt:=xlPart, SearchOrder:=xlByRows, MatchCase:=False, SearchFormat:=False, ReplaceFormat:=False7 _* h) ?1 ?7 |" X7 U5 l' y
  13.         .Replace What:="XX街道", Replacement:="", LookAt:=xlPart, SearchOrder:=xlByRows, MatchCase:=False, SearchFormat:=False, ReplaceFormat:=False, L, `! Q2 e( X0 s: u# \
  14.         .Replace What:="XX居委", Replacement:="", LookAt:=xlPart, SearchOrder:=xlByRows, MatchCase:=False, SearchFormat:=False, ReplaceFormat:=False
    5 a& o- N' F- a. _9 ?2 A3 o
  15.         .Replace What:="XX居委", Replacement:="", LookAt:=xlPart, SearchOrder:=xlByRows, MatchCase:=False, SearchFormat:=False, ReplaceFormat:=False/ e8 y) A0 B2 z. M) r( A7 l% f
  16.         .Replace What:="XX居委", Replacement:="", LookAt:=xlPart, SearchOrder:=xlByRows, MatchCase:=False, SearchFormat:=False, ReplaceFormat:=False
    + B3 F0 t" {# b! B' U) }
  17.         .Replace What:="XX居委", Replacement:="", LookAt:=xlPart, SearchOrder:=xlByRows, MatchCase:=False, SearchFormat:=False, ReplaceFormat:=False: n, ?! S2 P$ B; {. B
  18.         .Replace What:="XX居委", Replacement:="", LookAt:=xlPart, SearchOrder:=xlByRows, MatchCase:=False, SearchFormat:=False, ReplaceFormat:=False
    - `) p' B1 D8 J8 k  j/ v
  19.         .Replace What:=" ", Replacement:="", LookAt:=xlPart, SearchOrder:=xlByRows, MatchCase:=False, SearchFormat:=False, ReplaceFormat:=False$ @1 v/ d' T3 d; m7 b, ^- s$ t: ^
  20.         .Replace What:="    ", Replacement:="", LookAt:=xlPart, SearchOrder:=xlByRows, MatchCase:=False, SearchFormat:=False, ReplaceFormat:=False
    . P4 v4 C3 B0 E/ ]( K
  21.     End With
    : U) j* \+ D0 {/ D6 m- v! g' ~& r
  22.     '重新打开自动计算
    " ?3 v4 ]4 v- k: U7 ~
  23.     Excel.Application.Calculation = xlCalculationAutomatic
    ! g( ]+ W1 l9 L  t6 Z/ x( B+ J, {
  24. End Sub
    ; F6 h3 G. k, O. l: G, X
复制代码
- e3 X6 U# c' X( Z1 z
2 t9 O* `3 ~% R1 {2 @
上述代码还可以实现批量的常见错误信息更正,或者字段替换,.Replace What:="A", Replacement:="B",可以把A换成B3 {- y* ?; l' U# a

8 y1 i, ?( K7 x  M# ]: Y& [& N
$ j  |7 o! }, y# Z2 v9 e5 u, P

评分

参与人数 3钢镚 +120 收起 理由
王Heart + 10 666!
sinonline + 10 积极发布原创帖子内容,再接再厉!
epiman + 100 积极发布原创帖子内容,再接再厉!

查看全部评分

本帖被以下淘专辑推荐:

  • · spss|主题: 19, 订阅: 0
 楼主| baisenes 发表于 2023-1-26 13:28:56 | 显示全部楼层
本帖最后由 baisenes 于 2023-1-26 13:31 编辑
% u; o+ t% M- G
/ P$ A2 e8 R  t场景2:已知管理汇总表A,要根据一定的规则(如密接1、2、4、7,次密接1、7,浦东判的次密1、5、7,徐汇判的次密2、6、7,黄浦判的次密1、2、3、4、5、6、7,松江判的密接7,不要问我为什么管理口径这么五花八门且SB),筛选出部分对象,输出采样单B0 v  Q' s' c: E* l

; m* Q0 B% O9 w7 z首先我们设置了一个形如此的工作台:
; W+ u8 @8 Q9 U- K. T0 l( K# z 微信截图_20230124191842.png
9 |* i, L; M, `! ^. w, x6 o! F从H4:P13范围分别设置目标管控类型,输出到哪张表,采样日期是管理开始的第几天
# [! s* |/ F4 u, C' b然后我们的汇总表是这样的(演示信息均非真实居民信息):% ]. L; K& z7 u
微信截图_20230124193216.png
# e5 I# G# R, h6 [7 S在工作簿中有一个隐藏的空采样单,调用生成采样单的脚本时会复制一份以便于粘贴信息,总的采样单生成脚本是这样的:
; ?; H7 U' I. @' n
  1. Sub CreateRnaTestForm(Optional ByVal filename As String = "")6 Q! |+ K$ n) g( q2 d% y' e
  2. '2 q! b2 P; u  g8 T: Y1 o0 ~" D
  3. '根据当前Selection创建采样单,如选区为空则使用全部筛选项目创建
    : w* @2 u' w2 G  Y
  4. '
    . u$ U* V& u! ]; A
  5.     Application.StatusBar = "正在根据当前选区创建采样单"
    1 @3 T0 U4 o; e- N  J- Q
  6.     Excel.Application.Calculation = xlCalculationManual# |2 D9 Y3 R( P. o) b
  7. 8 l! A/ X! ~$ W7 ~

  8. : Z) @. e& f; y
  9.     Sheets("纳管汇总表").Activate
    % \: y& {" `1 O# e0 |
  10.     SelectAll = False% f$ N+ b* F# a2 ]; U+ v
  11.     If Selection Is Nothing Then) n2 c' @0 f+ i& Z3 p
  12.         SelectAll = True( [7 z' z4 D0 r/ d3 A, _
  13.     Else9 `8 V) ]5 C" F! @2 o; s
  14.         Set CCloumn = Range("C:C")
    . Q# Z9 P4 l9 t$ ?4 w- P% j: J
  15.         Set Rng = Application.Intersect(CCloumn, Selection)7 B0 J7 K" P$ M, d. l2 J
  16.         If Rng Is Nothing Then4 h0 i$ _6 x9 t5 k: M
  17.             SelectAll = True
    8 B$ k+ _' s" J" M3 m
  18.         ElseIf Not Rng.address = Selection.address Then. O- ^4 C$ H- q
  19.             SelectAll = True1 k+ X9 |. V( |& L$ G( j
  20.         End If
    - \/ }/ d. ^# @0 y
  21.     End If% f- U6 B2 g" D  M, L
  22.     9 d! V2 F" @! n- ~" U: ]
  23.     If SelectAll Then" X! D9 u5 _4 ]1 G  ~
  24.         Range("C1").Select! C8 K& V( {! J9 L* v
  25.         Range(Selection, Selection.End(xlDown)).SpecialCells(xlCellTypeVisible).Select
    8 d8 A: P% [3 Y3 @! E. V  w- h; x5 O
  26.         If Selection.Count = 1 Then
    8 ~6 ~% `7 U/ q
  27.             Application.StatusBar = "选区为空创建失败"7 K$ m+ U3 |4 H6 L/ b( P: a6 h
  28.             Exit Sub: f) a$ V& h( Z. C
  29.         End If
    + ~' {; l4 D# p
  30.         Range("C1").Select
    8 i# i* P$ z4 I! `6 n
  31.         Selection.Offset(1, 0).Select3 {& c" |' ?' z  L6 G% `/ @
  32.         Range(Selection, Selection.End(xlDown)).SpecialCells(xlCellTypeVisible).Select
    * D" |: _. x: u4 X6 P
  33.     End If
    ' y" M) s1 w' C
  34. + w7 p2 ^6 c/ g7 e5 a) z
  35.     ' 将目标选区存入变量4 l' O) |: I0 p% {, V* [& s
  36.     Dim Collection  As Range '目标选区
    7 ^. f2 b1 L* ^$ i. p
  37.     Dim NewTestForm As Workbook '采样单区- `7 I7 p  ~- Q7 `6 d4 n
  38.     Set Collection = Selection7 F( G! A5 ]. ~) u) Q( B' d
  39.     Set TotalWB = ActiveWorkbook
    # @  R% e) a$ ^4 y0 A
  40.    
    ( G& k* {  V3 f9 [9 x9 Q$ h
  41.     If filename <> "" Then
    * _/ V4 P; n5 S, x) K6 |* L
  42.         For Each wb In Workbooks
    5 E# s' Y, U% k( Y" }" I( D0 B
  43.             For Each sh In wb.Sheets
    - p3 Q. _0 E- [6 B0 Y& O
  44.                 If sh.Name = filename Then0 T( ^  ?$ J6 H/ w" G0 |7 s9 y
  45.                     Set NewTestForm = wb
    ) a$ l! C9 J  p* @1 G3 E- n; @
  46.                     wb.Activate  S: G/ |1 e7 G* F% {; a
  47.                 End If* ]; G& z' \0 P4 O
  48.             Next
    + t$ q4 Q' w  B% W4 T5 Z3 a% D9 _
  49.         Next$ Z7 I6 C# H7 E- A% B+ x; ]
  50.     Else/ b, q6 D* a6 _4 G6 Q+ I$ B
  51.         filename = "采样单"8 i/ S& v& T; a% ~3 g/ x
  52.     End If5 H- A& ], b/ n
  53.    
    5 _1 O+ j8 T2 P0 A  F/ y" K
  54.     If NewTestForm Is Nothing Then$ h& J3 d# a: F7 L2 w5 h
  55.         '复制一份空白采样单
      z+ a, D( o1 Q, s
  56.         Sheets("采样单模板").Visible = True
    % X4 u' l2 i, ?8 A. u" V  k  T
  57.         Sheets("采样单模板").Select
    + ~, [0 K$ @" Y" {% Z
  58.         Sheets("采样单模板").Copy8 E8 K# \  z9 N  v1 b# @
  59.         Sheets("采样单模板").Select
    1 r- }& r2 y. \
  60.         Sheets("采样单模板").Name = filename3 A4 B2 U6 u4 }8 ~) j3 G
  61.         Set NewTestForm = ActiveWorkbook
    / a: B, y" k* r' S8 K9 f3 x
  62.     End If1 j# \- X0 X- b7 i+ C5 U; D
  63.     2 v/ O1 p  y7 W% v4 e& C# Y0 q
  64.     4 J* V8 Q" [* Z& C) t# A! \
  65.     Application.StatusBar = "复制姓名列": T3 F* m. A; ?1 C  N# t9 ^
  66.     Collection.Copy
    + f2 G# k$ z8 A" A
  67.     Dim startCell As Range
    5 ]5 ]; s6 }* r, Q
  68.     If Range("C1").End(xlDown).Row = 2 Then
    " A# ~. m' E+ B0 A. x
  69.         If IsEmpty(Range("C1").End(xlDown)) Then- @3 q$ O. J. z, O% u
  70.             Set startCell = Range("C1").End(xlDown)& ?5 U4 d( K) E
  71.         Else! @6 j6 S  E( T
  72.             Set startCell = Range("C1").End(xlDown).Offset(1, 0)
    / V$ g, H. q& K7 J0 B
  73.         End If2 @( R2 M: ^6 [& y+ t  W$ `$ [
  74.     Else# P, C6 t0 Q5 k, H7 I
  75.         Set startCell = Range("C1").End(xlDown).Offset(1, 0)" C3 Z) y! U& u
  76.     End If
    : [: t( n8 D" ~  |0 S( ?& W- Q
  77.     startCell.Select
    ( u  p3 s0 U6 S8 h3 W2 o
  78.     Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks:=False, Transpose:=False8 H9 |5 d& S2 R* A* T
  79.    
    & h- l3 k* y5 K+ |6 F( y
  80.     Application.StatusBar = "复制地址列"
    ( N! s- ^3 x/ `6 i) K0 G5 n3 n
  81.     Collection.Offset(0, 5).Copy
    ! s  i" Y( q( }4 L! u, j) L
  82.     Sheets(filename).Select
      o# f. k; `/ p% L% l) A3 |
  83.     startCell.Offset(0, 6).Select) t$ `& E: a. Z2 w
  84.     Selection.PasteSpecial Paste:=xlPasteValuesAndNumberFormats, Operation:=xlNone, SkipBlanks:=False, Transpose:=False
    ) ]/ \! v) @& A. f
  85.     0 s9 a: |3 n  t, h
  86.     Application.StatusBar = "复制联系方式列"
    4 B; P/ F' d: e
  87.     Collection.Offset(0, 6).Copy
    ) p2 {- Y6 \+ i
  88.     Sheets(filename).Select
    4 m/ z6 a; t# y
  89.     startCell.Offset(0, 7).Select' G0 e* T+ q, H9 z; |" Z
  90.     Selection.PasteSpecial Paste:=xlPasteValuesAndNumberFormats, Operation:=xlNone, SkipBlanks:=False, Transpose:=False
    / ~! h* F* j. K; E) ^" H8 _1 k
  91.     # ?' ?7 K$ \, e9 o  |
  92.     Application.StatusBar = "复制身份证号列"
    . u; \( b/ I6 k" n5 O
  93.     Collection.Offset(0, 3).Copy" M# y; B# y0 |* U
  94.     Sheets(filename).Select
    1 }7 ~$ v8 }& |# t7 Y/ r' U
  95.     startCell.Offset(0, 3).Select5 D0 J3 f& ^+ ~; z* t8 E
  96.     Selection.PasteSpecial Paste:=xlPasteValuesAndNumberFormats, Operation:=xlNone, SkipBlanks:=False, Transpose:=False& B" g, e6 F: b# b
  97.    
    0 B9 P& b. y" x: G
  98.     Application.StatusBar = "复制管控类型列"
    * W$ @  d1 a" i7 S
  99.     Collection.Offset(0, -1).Copy
    # v" {8 j8 P4 j
  100.     Sheets(filename).Select
      M. Y0 y, p1 W  w+ p2 }4 b
  101.     startCell.Offset(0, 4).Select7 J2 ]. Q' Z& U+ E
  102.     Selection.PasteSpecial Paste:=xlPasteValuesAndNumberFormats, Operation:=xlNone, SkipBlanks:=False, Transpose:=False
    6 b+ D2 `% M7 Q& N& a
  103.     1 T% C* i& m; U& ?, B$ i
  104.     Application.StatusBar = "复制隔离开始时间列"
    - C% r; g; x; r* j& o: ^  k$ q; ]
  105.     Collection.Offset(0, 8).Copy  @  `/ g; N( {
  106.     Sheets(filename).Select7 n% ?* Q$ q) T
  107.     startCell.Offset(0, 9).Select
    - T4 L# g8 C: ?3 {( G
  108.     Selection.PasteSpecial Paste:=xlPasteValuesAndNumberFormats, Operation:=xlNone, SkipBlanks:=False, Transpose:=False! z$ U8 I' q  ?1 m1 A$ h9 N
  109.     4 z8 `3 I# M9 M0 l  n
  110.     Application.StatusBar = "复制社区居委列"
    8 V" r3 Q, o0 q+ V  \9 B4 i( k1 s
  111.     Collection.Offset(0, 4).Copy) }5 o0 @, x! i; C2 u& f* i
  112.     Sheets(filename).Select+ }9 S( B! n* e6 }! T9 d
  113.     startCell.Offset(0, 8).Select
    / u# A% z, R) N2 @2 s
  114.     Selection.PasteSpecial Paste:=xlPasteValuesAndNumberFormats, Operation:=xlNone, SkipBlanks:=False, Transpose:=False( }% q/ @: v9 v# l1 N2 Z

  115. + w9 m# Z  U% ~% N6 b
  116.    
    6 e  ]! n; F+ A* q6 L$ ?( o( F
  117.     TotalWB.Sheets("采样单模板").Visible = False
    * d/ q) p9 g0 p* N- D
  118.     TotalWB.Sheets("纳管汇总表").Activate; @6 c# A+ j% _
  119.     NewTestForm.Sheets(filename).Activate& }! {' E5 l. _3 C2 Z4 c
  120. 5 f9 Z' t( b4 }) Y$ S
  121.     Excel.Application.Calculation = xlCalculationAutomatic9 o! U! l/ w+ k  a
  122.     Application.StatusBar = "创建采样单完毕"/ Z1 q# T9 R6 O/ P4 ~  F
  123. End Sub
    . V# I8 q" k/ r
  124. 6 n' w4 {$ s1 W  C( E/ A" G
  125. Private Sub CreateRnaTestPlanByManageType(calculatedDate)
    : c( p  @  e8 O; Y4 [4 y
  126.     Application.StatusBar = "根据管理类型生成采样单"
    3 w7 \6 s# X6 b7 a
  127.     Set plan = Range(Selection.Offset(0, 2), Selection.End(xlToRight))
    ) I9 ]$ Y3 F& w9 k0 s; Z+ A1 Y0 ]
  128.    
    2 l: [0 t0 ]5 H% ~; a/ m* k9 U
  129.     Dim filename As String( W% v$ h  w$ k( h! D2 \
  130.     Dim manageType As String6 q: d9 u0 ?; X0 g8 h6 r6 d
  131.     Dim arrayForDate() As Variant: T- Y) @- U% Z: ^$ s
  132.    
    3 g+ ?/ N" ^. x9 s0 k* K
  133.    
    ) e- w5 t: |+ L# J
  134.     filename = "【采样计划】" & (Selection.Offset(0, 1).Value) & Format(calculatedDate, "mmdd")
    1 g' O$ o" V( x% N! d
  135.     manageType = Selection.Value/ }. E$ K$ o0 f. L+ }/ k" T
  136.     '计算筛选器的纳管日期勾选+ h; h9 P+ S# H5 Z) {
  137.     Count = plan.Count * 2 - 11 s; {, z8 w( S0 h
  138.     ReDim arrayForDate(Count)$ H6 y, U& N+ x  E+ e; @3 a
  139.     For i = 0 To plan.Count - 1' f5 ?! I  j6 O* Z4 y
  140.         arrayForDate(i * 2) = 2
    " [+ L* c9 e% U( |" k8 b6 _
  141.         targetDate = calculatedDate + 1 - plan.Cells(i + 1).Value% ^. k( x5 I. Z
  142.         arrayForDate(i * 2 + 1) = targetDate
    ( }/ Q  u% Z6 a" i" V4 E
  143.     Next( p1 f8 U, C% s- P4 ]) c3 c8 C
  144.     $ G( F, d# {  g3 Y6 R$ Z
  145.     Application.StatusBar = "根据管理类型和日期创建筛选"' ?  P9 H! f) ~% Q" x+ R
  146.     Excel.Application.Calculation = xlCalculationManual4 g# b3 F0 A6 g8 t0 t
  147.     '重置筛选5 y1 ^: r/ q0 O) J" _0 w0 a$ o
  148.     Sheets("纳管汇总表").Activate' S1 c( d- y- S+ w
  149.     ActiveSheet.ListObjects("表2").Range.AutoFilter Field:=1  ^! x4 d8 \/ R3 p9 p
  150.     ActiveSheet.ListObjects("表2").Range.AutoFilter Field:=2, Criteria1:=manageType
    5 V+ t" w( q: Y) P, k6 d% V
  151.     ActiveSheet.ListObjects("表2").Range.AutoFilter Field:=3; O2 F: y" c: X, D, m
  152.     ActiveSheet.ListObjects("表2").Range.AutoFilter Field:=4& [1 o; C& ^$ @- ]( p8 A
  153.     ActiveSheet.ListObjects("表2").Range.AutoFilter Field:=5
    4 A8 s7 j8 z' E! V7 Y
  154.     ActiveSheet.ListObjects("表2").Range.AutoFilter Field:=6
    + m1 A% B% U: N: D& q
  155.     ActiveSheet.ListObjects("表2").Range.AutoFilter Field:=7; T. s" D4 c& ]) d. x
  156.     ActiveSheet.ListObjects("表2").Range.AutoFilter Field:=8
    * T# L* X0 w1 w) _% P
  157.     ActiveSheet.ListObjects("表2").Range.AutoFilter Field:=9' W& t) R  m. A  O* E& Z
  158.     ActiveSheet.ListObjects("表2").Range.AutoFilter Field:=10
    # b" F9 a) o. m
  159.     ActiveSheet.ListObjects("表2").Range.AutoFilter Field:=11, Operator:=xlFilterValues, Criteria2:=arrayForDate1 Y7 Y) q  I, B
  160.     ActiveSheet.ListObjects("表2").Range.AutoFilter Field:=12' \' b  I. G) U& N
  161.     ActiveSheet.ListObjects("表2").Range.AutoFilter Field:=13, Criteria1:="="- Z2 i6 J- k: \2 _4 l) Q
  162.     ActiveSheet.ListObjects("表2").Range.AutoFilter Field:=14* |! N6 n% d) |
  163.     ActiveSheet.ListObjects("表2").Range.AutoFilter Field:=154 D! y: P7 ?# b. i+ F7 @, q' @: S
  164.     Excel.Application.Calculation = xlCalculationAutomatic% R2 @* ], s3 [: Y6 H( i- q
  165.     $ t/ X' g1 a" `( U. q
  166.     Range("O1").Select
    0 V, _/ m* X; J* G/ H; |
  167.     Call CreateRnaTestForm(filename)$ s8 }4 u" H4 ~4 G' }& L
  168. End Sub
    4 c% b$ `; E! d3 O1 ?1 w
  169. 6 v0 q% B1 r$ @: {
  170. Sub CreateRnaTestPlanBySelectedManageType()
    6 d/ a  @" U# Z) ]
  171.     Dim calculatedDate
    , |6 n/ S, Z+ h/ w
  172.     Set magicSheet = ActiveSheet: \' h" `4 e% w8 B
  173.     If IsDate(Range("M14").Text) Then- M9 F4 o6 A% H
  174.         calculatedDate = CDate(Range("M14").Text)
    8 o6 t" }+ ?3 J9 S4 l
  175.         MsgBox "将要生成" & Range("M14").Text & "的采样计划"
    ; f) b3 z! I, r2 }
  176.     Else
    ! F) F+ C( H" l% A( a* G, U
  177.         MsgBox "M14单元格输入的内容无法转换为日期"0 C, q! D* _3 l9 {
  178.         Exit Sub
    7 J2 E( |! U1 T
  179.     End If) i' q1 y0 D9 s$ ?' Z
  180.    
    * ~  u2 X; n% G8 w6 l! k( D  X; l0 z
  181.     Call CreateRnaTestPlanByManageType(calculatedDate)) L" J5 W9 Q: U8 U5 ^
  182. End Sub( `2 E9 D0 U. m6 C& r/ e
  183. & P% G; T$ F3 b1 k7 t
  184. Sub CreateRnaTestPlayBySelectedDate()3 O: W  S* C3 A1 F' _
  185.     Dim calculatedDate$ C; h2 q2 T- t4 w- L$ B
  186.     Set magicSheet = ActiveSheet8 R* i7 n+ W& S7 K) b* M: w/ Z( f
  187.     If IsDate(Range("M14").Text) Then  r& A6 x* f5 \8 Q- S8 J" S
  188.         MsgBox "将要生成" & Range("M14").Text & "的采样计划"
    ' X! ~: L! t! |  T2 T7 }# F
  189.         calculatedDate = CDate(Range("M14").Text)6 R( r. L; [1 q0 H" o
  190.     Else
    & g% A" g9 {$ W# E5 C- N/ _
  191.         MsgBox "M14单元格输入的内容无法转换为日期"
    - b9 k$ {; U. u% X
  192.         Exit Sub# @' ]# N; j; t: G- b' y9 D
  193.     End If
    8 b5 X1 p- s- t  l7 l) M/ O4 q9 T
  194.    
    2 z7 D3 [) H. [3 k2 n7 h
  195.     Set target = Range("H4", Range("H4").End(xlDown)); p2 m0 ]( z6 F# |% U' o
  196.     For i = 1 To target.Count
    ) R6 j3 p9 Y6 F% y; W% y
  197.         magicSheet.Activate0 N( `( k7 z4 r: H- W
  198.         target.Cells(i).Select* `/ M1 O- q- ~# C9 _
  199.         CreateRnaTestPlanByManageType (calculatedDate)5 R& C6 Q5 s! l: y( H) `- ]/ A
  200.     Next6 _; i- F8 t+ J8 V3 a: |. ?) Y9 _) R
  201. End Sub
    ( I* Q, T! C2 k8 D! ^3 R4 ]1 y( B

  202. 7 z) G, u( a9 m+ ]
  203. Sub SetM14ToYesterday()
    " ^' ~% q9 H" n2 E6 N% L7 Z7 b
  204.     Range("M14").Value = Date - 1
    " N% z, n1 D: D3 s" i3 I& d2 S
  205. End Sub3 c1 H3 D9 a! }5 X+ [* V

  206. / r. w* y( P) b6 e2 p) {/ u
  207. Sub SetM14ToToday()- H4 m) i9 h2 r, P* Y. I+ Z
  208.     Range("M14").Value = Date
    8 M: v- d. v0 |' U1 ^+ |& Z: [9 Y
  209. End Sub7 O$ p9 ]: q! X: D3 ?

  210. ! p0 t6 @1 n6 q9 _: M, V) U! G
  211. Sub SetM14ToTomorrow()9 p  X# `( [  r) O. h( ]2 Y
  212.     Range("M14").Value = Date + 1  M: R6 l( g% _0 @. E
  213. End Sub
复制代码

2 D1 w5 g3 X% M% U* W根据上述代码,我们既可以先在M14单元格设置日期,然后点击生成特定的采样计划,又可以生成全部采样计划,也可以在纳管汇总表中选择特定的对象,生成特定人的采样单。6 J/ x3 a: n+ G7 Y5 H7 D

) x' n0 ~2 }1 N" s4 D尽管这些代码用于安排采样,但事实上转运、转单、派流调单,本质上都是大同小异的。' B9 {' }6 @0 c' m' {7 c
6 Q3 {% }3 t  O, G3 h- J' o
$ I/ T* c3 M$ P1 S5 \
3. 关于没有编程经验,VBA该如何上手?
, |) P6 I# ~8 y! M1 f/ _! S( _5 I* @! C) F6 X
首先,请克服远离舒适圈的恐惧感。不要将编写VBA联想为编程,想象它是SPSS或者SAS,把EXCEL工作簿和工作表想象成数据集,VBA是一种“特殊”的统计脚本,我们只是在做本专业的东西,并非编程。  C6 \4 }4 \6 p  h$ \- s0 s2 E, Z

0 x  z; Y& }  E$ y0 G" v其次,OFFICE套件内置宏录制功能,许多复杂的操作微软可以帮你自动生成VBA代码,我们只需要按照需求,对自动生成的代码进行Ctrl+CV,以及小修小补,绝大多数时候无需大动干戈。关于如何使用宏录制自动生成代码,可以参考如下教程:# h8 C) G: F  o' X$ `6 j2 {" {7 U
“录制简单的宏”章节
% K* w! j* {5 s4 d% H' f( o4 Lhttps://www.w3cschool.cn/excelvba/excelvba-what.html
1 R# @) R3 Q( N1 n# m$ {1 r. O+ t  q4 j2 L
4. 有哪些需要注意的?1 B# g' ]% I; ^# B( `" E( d
Excel的数据类型非常灵活,允许单元格中存储各式各样的内容并可能导致错误,例如最常见的身份证号变成科学计数法数字,还有固定电话带区号的丢失起始字段的0,因此将单元格数据类型明确设置是一个好习惯(无论你是否使用VBA自动处理),建议使用Excel的表格功能(Ctrl+T,也叫超级表),可以降低筛选、排序、以及数据复制粘贴时出错的可能。8 q/ I' v# D4 Q% t" h/ l
) j0 ?1 ^$ t- u0 `7 R9 f4 K/ u
最后,特别强调,程序绝对不是万能的。VBA可以将我们从繁琐机械的报表中解放出来,但是我们依然需要监督VBA正确工作,务必在自动生成报表后追加人工抽查、质控。
回复

使用道具 举报

 楼主| baisenes 发表于 2023-1-26 13:49:55 | 显示全部楼层
本帖最后由 baisenes 于 2023-3-5 16:56 编辑
9 k" i9 S$ K* T# k- K7 t/ ~+ o
" a- L! S: d6 ^7 l8 q/ P0 M===============23-3-5更新================
1 [# _( H& k5 W2 |- [9 J0 q进阶:使用ACCESS强化你的报表系统
+ v0 K9 N8 J; X* S% L3 k) ?# s: ]2 a$ c
当管理的个案数目逐渐增多,EXCEL表格的性能会出现显著下降。依照个人经验,能感受到明显的卡顿在2000条(个案中部分条目依赖公式计算)或者20000条(纯表格)时,此时对表格进行排序、筛选、或者是批量修改均能感受到界面卡顿。性能问题是EXCEL为我们提供强大的灵活性的代价,关于提高性能,我主要有以下办法:
) p  `% R8 m" L
, f$ t. u) p; _9 M! l! S; m0 E
  • 将公式的计算模式切换为手动,可以在个案行数在1000数量级且表格中多列依赖公式自动计算时明显改善性能,需要注意调整结束后重新计算数据,或者改回自动计算模式,否则会导致报表信息错误,或者坑害不知情的和你翻班的同事。
  • 分表,我们经常会遇到报表中绝大多数个案已经结案,仅近期个案为活跃条目。因此,我们可以创建一份复制Sheet,其表格结构与台账完全一致,结案条目剪切到这个Sheet中,通过减少台账长度的方式改善性能。
  • 等,事实上一些大企业处理excel报表时,每个动作计算10分钟都是经常发生的事,所以让工作的脚步放慢也没什么大不了的。
  • 迁移数据到access上面,excel作为前端展示数据和导出报表(终极解决办法)
    8 l0 s$ X' a6 V  K
0 @3 t( E3 k/ @1 Z4 M/ H; j. t$ @
" k7 j9 E, D: F
ACCESS是一种可靠的关系型数据库,如果你的大学计算机课程有讲过VisualFox(和英语政治体育一样是必修课,部分大学会讲VF,另一部分大学会讲VB),上手ACCESS是非常容易的事情。即使你的大学没有讲过这些,我们专业课的SPSS和SAS,对数据库数据表的操作也有简单的涉猎,其中SPSS的数据集,就是一个非常简单的数据表。事实上SPSS也支持链接关系型数据库,用SQL来管理你的统计数据。
2 ~$ b7 y) s: a! y1 h) t2 o( s- S3 J' q& b+ q0 V7 r' `
ACCESS的第一张表,和SPSS非常像,仅仅需要注意在数据库中表可以不止一张,每张表都有自己的主键,表之间可以通过主键-外键构建联系。
7 w8 j8 Z  |0 a. @! R例如,每个管理对象可能会有一堆随访记录(个案信息表-随访记录表,一对多关系)' ]$ ^6 B2 Y, B. V( N( Z
每个责任医生可能会有很多个管理对象,或者一个医生可能会临时管理其他医生的管理对象(多对多关系)
4 h+ F; \2 }2 W6 d与EXCEL的力大砖飞相比,ACCESS,或者说关系型数据库,可以更高效准确的处理这些复杂的信息。# t1 n% H: H7 u1 _
以下是ACCESS的概览信息3 j6 F( A4 s# X7 ?) }5 ~5 C9 m/ _& L
https://www.bootwiki.com/msaccess/msaccess-overview.html
* d# f7 h3 h) J9 s以及如何在ACCESS中使用VBA强化你的魔法' @: R$ t8 R& j; j) r
https://learn.microsoft.com/zh-cn/office/vba/api/overview/access
4 k3 ?% _( p7 v1 A  l# t/ O8 o除此之外,对于所有的关系型数据库,有一种通用的表达式,被称作SQL,非常强大,可以帮助你在几秒钟内完成传统上EXCEL可能你要处理几小时的工作
2 _' `" j5 R+ @# R/ o- \https://www.runoob.com/sql/sql-tutorial.html( A, t& \3 g/ S$ y8 p0 U, W7 f# `
在绝大多数关系型数据库中,SQL语法几乎都是通用的,仅部分细枝末节存在少量区别(就像是普通话和方言)
3 ?. t, d' ]& |# u4 Z: P5 dACCESS中你可以直接创建SQL语句(被称作查询),也可以在VBA中执行你的SQL语句。在ACCESS+VBA+SQL的辅助下,即使是百万行信息,非常复杂的处理,也只需要十几分钟。
4 m; f7 r& ]* q" o+ c) t: M- EACCESS中VBA操作数据表,可以通过直接执行SQL,也可以通过DAO接口:3 K- J4 H7 q; a1 F, H" h
https://learn.microsoft.com/zh-c ... ecordset-object-dao
回复

使用道具 举报

 楼主| baisenes 发表于 2023-1-26 13:50:57 | 显示全部楼层
===============占楼后续更新用2================
回复

使用道具 举报

没有好的ID 发表于 2023-1-26 15:54:56 | 显示全部楼层
感谢楼主的分享
回复

使用道具 举报

jingjing0916 发表于 2023-1-26 16:02:43 | 显示全部楼层
牛人,感谢分享
回复

使用道具 举报

contented-joy 发表于 2023-1-26 17:24:57 | 显示全部楼层
感谢分享,新年开好头
回复

使用道具 举报

YAR 发表于 2023-1-26 18:10:36 | 显示全部楼层
回复

使用道具 举报

 楼主| baisenes 发表于 2023-1-26 19:04:47 | 显示全部楼层
本帖最后由 baisenes 于 2023-1-26 21:39 编辑 2 M6 c- R8 o! o8 L
YAR 发表于 2023-1-26 18:10
; v; O& d& K' u0 T! RB站很多视频,可以学习哈

1 `% Q$ b! c9 |% y% w; ^, A5 V
/ @  \% w- ]" _* K. Z4 X/ |. I新年快乐
回复

使用道具 举报

tsinfneg 发表于 2023-1-27 09:41:07 | 显示全部楼层
用python不好吗,一是下一步办公软件都要国产化,python是开源的编程语言,国产操作系统完全支持;二是可以实现功能很多,统计和办公自动化只是其中很小一部分,pandas、numpy、sklearn三个工具库就能搞定数据统计、数据分析、机器学习了;三是针对大规模数据有着巨大的优势,运行速度非常快,excel光打开文件估计就得很长时间;四是对比楼主贴出的代码,同样的功能pythonr 代码更加简单,更好阅读和理解,从0起步几天就可以学会;五是对数据库特别是用与大数据的hbase+spark、clickhouse 的连接更加方便;六是可以编写更复杂的程序,实现精精美的分析图表(pyecharts),图文分析报告自动生成,让人可以从定期的重复工作中解放出来(如日报、月报、年报等);七是可以打包为程序,上传服务器,按需求定期自动执行。# h2 I- q3 w$ I! q
本地在三年的疫情防控中,数据清洗、数据比对、数据挖掘、大数据分析、监测预警、报告生成都是使用python完成的。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|会员|至尊|接种|公卫人 ( 沪ICP备06060850号-3 )

GMT+8, 2024-5-4 20:35 , Processed in 0.113209 second(s), 10 queries , Gzip On, MemCached On.

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表