精华内容
下载资源
问答
  • ”,vbYesNo)<>vbYes Then Exit Sub (4)使用常量的组合,赋值组Config变量,并设置第二个按钮为缺省按钮 Config=vbYesNo+vbQuestion+vbDefaultButton2 (5)若要在消息中强制换行,可在文本中使用vbCrLf(或vbNewLine)...

    92f4de845caa3548c642c9213bc4ac15.png

    1、作用

    在消息框中显示信息,并等待用户单击按钮,可返回单击的按钮值(比如“确定”或者“取消”)。通常用作显示变量值的一种方式。

    2、语法

    MsgBox(Prompt[,Buttons][,Title][,Helpfile,Context])

    参数说明:

    (1)Prompt,必需的参数,为字符串,作为显示在消息框中的消息文本。其最大长度约为1024个字符,由所用字符的宽度决定。如果prompt的内容超过一行,则可以在每一行之间用回车符(Chr(13))、换行符(Chr(10))或是回车与换行符的组合(Chr(13)&Chr(10))将各行分隔开来。

    (2)Buttons,可选的参数,为数值表达式的值之和,指定显示的按钮的数目及形式、使用的图标样式、缺省按钮及消息框的强制回应等,可以此定制消息框。若省略该参数,则其缺省值为0。设置值见下表。

    (3)Title,可选的参数,表示在消息框的标题栏中所显示的文本。若省略该参数,则将应用程序名放在标题栏中。

    (4)Helpfile,可选的参数,为字符串表达式,提供帮助文件。若有Helpfile,则必须有Context。

    (5)Context,可选的参数,为数值表达式,提供帮助主题。若有Context,则必须有Helpfile。

    3、Button参数

    用于MsgBox函数中Button参数的常量

    常量 值 说明

    vbOKOnly 0 只显示“确定”按钮

    VbOKCancel 1 显示“确定”和“取消”按钮

    VbAbortRetryIgnore 2 显示“终止”、“重试”和“忽略” 按钮

    VbYesNoCancel 3 显示“是”、“否”和“取消”按钮

    VbYesNo 4 显示“是”和“否”按钮

    VbRetryCancel 5 显示“重试”和“取消”按钮

    VbCritical 16 显示“关键信息”图标

    VbQuestion 32 显示“警告询问”图标

    VbExclamation 48 显示“警告消息”图标

    VbInformation 64 显示“通知消息”图标

    vbDefaultButton1 0 第一个按钮是缺省值(缺省设置)

    vbDefaultButton2 256第二个按钮是缺省值

    vbDefaultButton3 512第三个按钮是缺省值

    vbDefaultButton4 768第四个按钮是缺省值

    vbApplicationModal 0应用程序强制返回;应用程序一直被挂起,直到用户对消息框

    作出响应才继续工作

    vbSystemModal 4096系统强制返回;全部应用程序都被挂起,直到用户对消息框作

    出响应才继续工作

    vbMsgBoxHelpButton 16384将Help按钮添加到消息框

    VbMsgBoxSetForeground 65536指定消息框窗口作为前景窗口

    vbMsgBoxRight 524288文本为右对齐

    vbMsgBoxRtlReading 1048576指定文本应为在希伯来和阿拉伯语系统中的从右到左显示

    说明:

    (1)第一组值(0–5)描述了消息框中显示的按钮的类型与数目;第二组值(16,32,48,64)描述了图标的样式;第三组值(0,256,512,768)说明哪一个按钮是缺省值;而第四组值(0,4096)则决定消息框的强制返回性。将这些数字相加以生成Buttons参数值的时候,只能由每组值取用一个数字。

    (2)这些常数都是VBA指定的,可以在程序代码中使用这些常数名称代替实际数值。

    4、返回值

    用于MsgBox函数返回值的常量

    常数 值 说明

    vbOK 1 确定

    vbCancel 2 取消

    vbAbort 3 终止

    vbRetry 4 重试

    vbIgnore 5 忽略

    vbYes 6 是

    vbNo 7 否

    5、相关说明

    (1) 如果同时提供了Helpfile与Context参数,可以按F1键来查看与Context相应的帮助主题,Excel通常会在输入框中自动添加一个帮助(Help)按钮。

    (2)若在消息框中显示“取消”按钮,则按下ESC键与单击“取消”按钮效果相同。若消息框中有“帮助”按钮,则提供相关的帮助信息。

    (3)如果要输入多个参数并省略中间的某些参数,则必须在相应位置加入逗号分界符。

    6、示例

    (1)使用 MsgBox 函数,在具有“是”及“否”按钮的对话框中显示一条严重错误信息。示例中的缺省按钮为“否”,MsgBox函数的返回值视用户按哪一个钮而定。并假设DEMO.HLP为一帮助文件,其中有一个帮助主题代码为1000。

    Dim Msg,Style,Title,Help,Ctxt,Response,MyString

    Msg="Do you want to continue ?" ’定义消息文本

    Style = vbYesNo + vbCritical + vbDefaultButton2 ' 定义按钮

    Title = "MsgBox Demonstration" ' 定义标题文本

    Help = "DEMO.HLP" ' 定义帮助文件

    Ctxt = 1000 ' 定义帮助主题

    Response = MsgBox(Msg, Style, Title, Help, Ctxt)

    If Response = vbYes Then ' 用户按下“是”

    MyString = "Yes" ' 完成某操作

    Else ' 用户按下“否”

    MyString = "No" ' 完成某操作

    End If

    (2)只显示某消息

    MsgBox “Hello!”

    (3)将消息框返回的结果赋值给变量

    Ans=MsgBox(“Continue?”,vbYesNo)

    If MsgBox(“Continue?”,vbYesNo)<>vbYes Then Exit Sub

    (4)使用常量的组合,赋值组Config变量,并设置第二个按钮为缺省按钮

    Config=vbYesNo+vbQuestion+vbDefaultButton2

    (5)若要在消息中强制换行,可在文本中使用vbCrLf(或vbNewLine)常量,用&加空格与字符隔开。如

    MsgBox “This is the first line.” & vbNewLine & “Second line.”

    (6)可以在消息框中使用vbTab常量插入一个制表符。下面的过程使用一个消息框来显示5×5单元格区域中的所有值,用vbTab常量分隔列并使用vbCrLf常量插入一个新行。注意在MsgBox函数最多只显示1024个字符,因此限制了可显示的单元格数。

    Option Explicit

    Sub ShowRangeValue()

    Dim Msg As String

    Dim r As Integer, c As Integer

    Msg = ""

    For r = 1 To 5

    For c = 1 To 5

    Msg = Msg & Cells(r, c) & vbTab

    Next c

    Msg = Msg & vbCrLf

    Next r

    MsgBox Msg

    End Sub

    (7)在消息框语句中运用工作表函数以及设置显示的数置格式,如下面语句所示:

    MsgBox " selection has " & m & " cells ." & Chr(13) & " the sum is :" & Application.WorksheetFunction.Sum(Selection) & Chr(13) & "the average is :" & Format(Application.WorksheetFunction.Average(Selection), "#,##0.00"), vbInformation, "selection count & sum & average" & Chr(13)

    展开全文
  • 使用VBA来整理表格,甚至批量自动导出报表,其实就是模拟了人的行为。在整理表格的时候,我们常常需要选定某个区域,做复制、剪切或者粘贴的操作。选定某个区域因此,如何使用VBA来模拟这样的行为呢,这就涉及到...
    c1550db0814a836274604673cf0d18d1.png

    使用VBA来整理表格,甚至批量自动导出报表,其实就是模拟了人的行为。在整理表格的时候,我们常常需要选定某个区域,做复制、剪切或者粘贴的操作。

    111c22cdc6885175a24aacea5343524f.png

    选定某个区域

    因此,如何使用VBA来模拟这样的行为呢,这就涉及到range的用法了。另外为了更好的选择我们需要的单元格,本篇还会涉及到Cells、offset、resize、CurrentRegion、UsedRange等等的用法小记。这边我们将会根据一个个需求来学习VBA。

    需求1:选择B2单元格

    Sub main() Range("B2").SelectEnd Sub

    B2单元格是第2行,第2列,因此我们也可以使用Cells来改写

    Sub main() Cells(2, 2).SelectEnd Sub

    需求2:选择B2单元格,要求使用变量

    我们写VBA的时候,为了面对比较多变的情况,单元格的位置肯定有的时候是不固定的,需要使用到变量。因此这边我们可以这样改写。

    Sub main() Dim num As Integer Let num = 2 Range("B" & num).SelectEnd Sub

    range的接受的参数是一个字符串,因此只要用连接符 & 配置成正确的字符串格式,就不会报错了。

    如果使用Cells,Cells中含变量是更加方便的,一般我们循环的时候都是用Cells来循环的。

    Sub main() Dim num As Integer Let num = 2 Cells(num, num).SelectEnd Sub

    需求3:选择A1:B5单元格区域

    Sub main() Range("A1:B5").SelectEnd Sub

    这边也是这样,只要给range一个正确的字符串格式的参数就可以了。

    还可以使用Range和Cells搭配使用。

    Sub main() Range(Cells(1, 1), Cells(5, 2)).SelectEnd Sub

    注意Cells的参数是这样的:Cells(行的数字,列的数字)

    或者Range和Range之间也是可以混合使用的。

    Sub main() Range(Range("A1"), Range("B5")).SelectEnd Sub

    需求4:选择选择A1:B5单元格区域,要求使用变量

    Sub main() Dim n1 As Integer Dim n2 As Integer Let n1 = 1 Let n2 = 5 Range("A" & n1 & ":B" & n2).SelectEnd Sub

    需求5:选择第一列最后一个非空的单元格

    Sub main() Range("A65536").End(xlUp).SelectEnd Sub

    需求6:选择第二行最后一个非空的单元格

    这个必须得使用Cells定位。我们可以这么做

    Sub main() Cells(2, Columns.Count).End(xlToLeft).SelectEnd Sub

    Columns.Count代码最后一列,同理Rows.Count代表最后一行,因此需求5也可以用Cells改写,这里就不赘述了。

    需求7:选择A列最后一个空单元格

    Sub main() Range("A65536").End(xlUp).Offset(1,0).SelectEnd Sub

    这个比较有用,因为我们每次汇总的时候,都要复制粘贴,为了保持表格的连续性。都需要定位到最后一个空单元格。

    需求8:选择第1行最后一个空单元格

    Sub main() Cells(1, Columns.Count).End(xlToLeft).Offset(0, 1).SelectEnd Sub

    这边就涉及到offset的用法了,offset的用法如下例:

    offset(|A| , |B|) : 以选择单元格为起点,向下挪移A个单元格,向右挪移B个单元格。

    offset(-|A| , -|B|) : 以选择单元格为起点,向上挪移A个单元格,想左挪移B个单元格。

    需求:9:不使用CurrentRegion、UsedRange,选择整个区域

    这个需求我们以后常常会用,复制所有区域的数据到另一个sheet或者其他工作簿中。如果不使用CurrentRegion或UsedRange,我的思路是,先定位一个起始单元格比如A1,如果不需要表头可以定位A2,然后找到A2单元格所处的行的最后一个非空单元格,然后在顺势往下找到该列所处的最后一个非空单元格,选中。就是我们要的整个区域了。

    Sub main() Range(Range("A1"), Cells(1, Columns.Count). _ End(xlToLeft). _ End(xlDown)).SelectEnd Sub

    这边为了美观,进行了适当的折行,折行需要添加一个下划线_作为占位符,然后就可以换行了。切记下划线与前面的内容中间需要有空格。

    需求10:使用CurrentRegion、UsedRange

    Sub main() Range("A1").CurrentRegion.SelectEnd Sub

    使用CurrentRegion可以轻松选择所有区域。但是如果是不连续的区域,这边的选择会显得有些错误。如下图

    06ccf6ef0a036a97ff2fbd2dc6e97178.png

    因此我们可以使用UsedRange选择所有被使用的单元格

    Sub main() ActiveSheet.UsedRange.SelectEnd Sub
    2093d1b9dd91522bb507dcb9eb92f2a3.png

    UsedRange需要加上是在哪个Sheet中,无法默认是ActiveSheet。因此我们加上sheet名称。

    展开全文
  • 另外,如果 不加分隔符,则会自动换行。- (图3) 3,正确的排版输出,在同时打印输出多个变量时,有利于监视变量之间的关系。也起到美观作用(见文末装逼打印效果) 1 '此代码效果为图2 2 sub printTest() 3 For ...

    057f96db94c712ffa8611955fcd9ff91.png

    ​用户界面篇02

    “立即”窗口也能排版?

    关于Debug.Print语句在“立即”窗口中的排版
    1, 一个Debug.Print语句能同时打印多个变量或者常量(通常是String),各个单位之间分隔符有2种:半角逗号【,】,代表制表输出- (图1);半角分号【;】,代表连续输出- (图2)
    2, 如果多个Debug.Print语句打别打印变量或者常量,同样可以用半角逗号【,】,半角分号【;】连接,效果与上面语句一致 ;另外,如果不加分隔符,则会自动换行。-(图3)
    3,正确的排版输出,在同时打印输出多个变量时,有利于监视变量之间的关系。也起到美观作用(见文末装逼打印效果)

    46bc1ab05b7eec00c3286a81bc807437.png
     1  '此代码效果为图2
     2  sub printTest() 
     3    For Each cusLayout In cusLayouts
     4
     5    '一个Debug.Print打印多个变量
     6        Debug.Print cusLayout.Index & "-"; cusLayout.Name
     7
     8        '等价于下面2句
     9
    10    '多个Debug.Print打印多个变量    
    11        Debug.Print cusLayout.Index & "-";
    12        Debug.Print cusLayout.Name
    13    next
    14  end sub

    图1,使用逗号(制表)分隔

    f4382b005b91f771bd98ab162dac2c99.png

    图2,使用分号(直接)

    76145319b19f4b7260624ce297710246.png

    多行语句打印,末尾使用拼接符与图1,图2效果一致

    b99d6940001b0163db331848b70d046e.gif

    图3,常见的多行语句打印,正常换行

    b3afb01752dcceaf00e788fde3ad78e2.png

    提问:都是分隔符,有啥区别

    1,直接拼接与制表拼接在打印文本有对齐要求时候有不同效果。
    2,尤其是每条文本长短差异较大时候,制表文本对齐效果优势明显。留意GIF动图

    c20f6e11def221b3c1839f027dec4f33.gif

    关于拼接符 "&" 与 "+" 的知识延伸

    1,"&" 是强制拼接:无论前后的数据类型是什么,直接看作文本拼接在一起。
    2,"+" 仅能拼接相同类型的数据:String类型,效果与"&"一样;数值类型,就是普通的运算加法。

    32201a243c2b9edb34d7635cd08c5e84.gif

    个人经验Tips分享:实用意义?

    打印输出变量对每个写VBA的人作用不同
    1,对于需要大量遍历某些对象查看其参数的情况下,合理的打印输出调试结果有其应用场景。
    2,对于我,我经常需要更新PPT报告,稍有些VBA基础的同学应该知道,PPT里存在的对象几乎都是图形:文本框,图表,图片,自选形状 等等。
    3,因此,如果需要对图形进行改动,例如新增一个图形,那么参照图形的类型参数则需要经常去查。
    4,此时就需要把图形的类型常数通过“立即”窗口打印出来,当参数备用。需要填的时候,只需要瞄一眼“立即”窗口即可。
    5,而且,通过使用合适的分隔符,对于输出多个变量间的关系一一对应,有比较直观的展示帮助。
    6,当然,像下面那样钛合金装逼框的,平时玩玩就好 ^_^
    1    '此代码为打印某张PPT里的图形类型参数,同学们举一反三应用到自己需求中
    2    Debug.Print "============================================="
    3    Debug.Print "*", "图形名称", "图形类型", "  *"
    4    For Each shp In Slds(page).Shapes
    5        Debug.Print "*", shp.Name, shp.Type, "  *"
    6    Next
    7    Debug.Print "============================================="
    

    钛合金装逼专用输出框

    d6b8cc1b5c365c5424d4f620e54743dd.gif

    下一篇,到分析主题了,我会讲:

    传说中的“波士顿矩阵”的变体^_^

    《如何利用“四象限”分析商品等级》

    “会分析里的懂技术,懂技术里的会做分析”关注我,做个“文武双修”的数据分析师
    欢迎加入数据分析交流群,专业分析师亲自坐台
    个人微信:hi_ch1s,公众号:CaiCaiData
    展开全文
  • 利用VBA脚本,可以自动将考勤明细数据按月加工成月汇总统计报表,大大减少人力资源人员的工作量,且提高了数据准备性,快捷、省时、省力。一、前提1、考勤明细表必须包括4个字段:工号、姓名、部门、刷卡时间,样表...

    e461cce32dddb31247efb167564631e0.gif

    利用VBA脚本,可以自动将考勤明细数据按月加工成月汇总统计报表,大大减少人力资源人员的工作量,且提高了数据准备性,快捷、省时、省力。一、前提1、考勤明细表必须包括4个字段:工号、姓名、部门、刷卡时间,样表见下图;2、刷卡时间字段必须是“日期+时间”格式,例如:2020/03/01 08:16:24、2020/3/1 8:16:24、2020-03-01 08:16:24、2020-3-1 8:16:24

    fef530411c6f52ca9373d75db6661045.png

    二、代码

    1、两个辅助子过程

    1.1 建立考勤统计表

    Private Function 建立考勤统计表(sheetName As String) As Integer    If IsDate(Left(sheetName, 4) & "/" & Right(sheetName, 2) & "/01") = False Then        MsgBox "建立考勤统计表失败,表名就不是“年+月格式”。"        建立考勤统计表 = 0        Exit Function    End If    Dim secSheet As Worksheet    '建立第1考勤统计表    With Worksheets        Set secSheet = .Add(After:=Worksheets(.Count))    End With    secSheet.Name = sheetName    secSheet.Select    '定义各列名及宽度    secSheet.Cells(1, 1).Value = "工号"    secSheet.Columns(1).ColumnWidth = 6    secSheet.Columns(1).NumberFormatLocal = "@"    secSheet.Cells(1, 2).Value = "姓名"    secSheet.Columns(2).ColumnWidth = 6    secSheet.Cells(1, 3).Value = "部门"    secSheet.Columns(3).ColumnWidth = 13    secSheet.Range(Cells(1, 1), Cells(1, 3)).Interior.Color = RGB(0, 176, 240) '底色为亮蓝    '获取本月天数    Dim theDays%    theDays = Day(DateAdd("d", -1, DateAdd("m", 1, Format(Left(sheetName, 4) & "/" & Right(sheetName, 2) & "/01", "yyyy/m/d")))) '统计表年月的下月1日减1天即得到该月天数    For y = 1 To theDays        secSheet.Cells(1, 3 + y).Value = y & "日"        secSheet.Columns(3 + y).ColumnWidth = 3        '如果是周六周日        If Weekday(Format(Left(sheetName, 4) & "/" & Right(sheetName, 2) & "/" & y, "yyyy/m/d"), vbMonday) = 6 Or Weekday(Format(Left(sheetName, 4) & "/" & Right(sheetName, 2) & "/" & y, "yyyy/m/d"), vbMonday) = 7 Then            secSheet.Cells(1, 3 + y).Interior.Color = RGB(146, 208, 80) '底色为红色'            secSheet.Cells(1, 3 + y).Font.Color = RGB(255, 255, 255) '字体为白色        Else '如是周一至周五            secSheet.Cells(1, 3 + y).Interior.Color = RGB(0, 176, 240) '底色为亮蓝        End If    Next    secSheet.Cells(1, 3 + y).Value = "正常出勤天数" '此时y已经循环到 theDays +1    secSheet.Columns(3 + y).ColumnWidth = 5    secSheet.Columns(3 + y).HorizontalAlignment = xlCenter '列居中    secSheet.Cells(1, 3 + y + 1).Value = "不足8小时天数"    secSheet.Columns(3 + y + 1).ColumnWidth = 6    secSheet.Columns(3 + y + 1).HorizontalAlignment = xlCenter '列居中    secSheet.Cells(1, 3 + y + 2).Value = "打卡1次的天数"    secSheet.Columns(3 + y + 2).ColumnWidth = 9    secSheet.Columns(3 + y + 2).HorizontalAlignment = xlCenter '列居中    secSheet.Cells(1, 3 + y + 3).Value = "连续3天未打卡"    secSheet.Columns(3 + y + 3).ColumnWidth = 6    secSheet.Columns(3 + y + 3).HorizontalAlignment = xlCenter '列居中    secSheet.Cells(1, 3 + y + 4).Value = "打卡天数汇总" '此时y已经循环到32    secSheet.Columns(3 + y + 4).ColumnWidth = 5    secSheet.Columns(3 + y + 4).HorizontalAlignment = xlCenter '列居中    secSheet.Range(Cells(1, 3 + y), Cells(1, 3 + y + 4)).Interior.Color = RGB(0, 176, 240) '底色为亮蓝    '字号    secSheet.Cells.Select    With Selection.Font        .Name = "宋体"        .Size = 9    End With    '首行格式    secSheet.Rows(1).Select    With Selection        .AutoFilter '筛选        .HorizontalAlignment = xlCenter '水平居中        .VerticalAlignment = xlCenter '垂直居中        .WrapText = True '文本换行        .Orientation = 0        .AddIndent = False        .IndentLevel = 0        .ShrinkToFit = False        .ReadingOrder = xlContext        .MergeCells = False        .RowHeight = 25 '行高    End With    '冻结窗格    secSheet.Select    With ActiveWindow        .SplitColumn = 0        .SplitRow = 0    End With    ActiveWindow.FreezePanes = False    secSheet.Cells(2, 1).Select    ActiveWindow.FreezePanes = True    建立考勤统计表 = 1End Function

    1.2 统计表汇总加工

    Private Sub 统计表汇总加工(the0Time As String, the1Time As String, lessThanWorkHours As String, normalWork As String)    Dim aRow%, aCol%    aCol = ActiveSheet.UsedRange.Columns.Count '获取当前表的列数    aRow = ActiveSheet.UsedRange.Rows.Count '获取当前表有效行数    '----------数据整理及汇总列数据统计----------    Dim workDaysCUML%, normalWorkCUML%, lessThanWorkHoursCUML%, the1TimeCUML%, the0timeCNSC%    For i = 2 To aRow        workDaysCUML = 0 '出勤天数累计        normalWorkCUML = 0 '正常出勤的天数        lessThanWorkHoursCUML = 0 '打卡至少2次且不足6小时天数        the1TimeCUML = 0 '累计打卡次数为1次的天数        the0timeCNSC = 0 '连续未打卡的天数        '第1次循环,先遍历日期列进行统计        For ii = 1 To aCol            '定位日期列进行统计            If IsNumeric(Replace(Trim(Cells(1, ii).Value), "日", "")) Then                '正常出勤的天数                If Trim(Cells(i, ii).Value) = normalWork Then                    normalWorkCUML = normalWorkCUML + 1                    workDaysCUML = workDaysCUML + 1                 '累计打卡次数为1次的天数                ElseIf Trim(Cells(i, ii).Value) = the1Time Then                    the1TimeCUML = the1TimeCUML + 1                    Cells(i, ii).Interior.Color = RGB(255, 255, 0) '标记底色为黄色                    workDaysCUML = workDaysCUML + 1                '早退日期处理                ElseIf Trim(Cells(i, ii).Value) = lessThanWorkHours Then                    lessThanWorkHoursCUML = lessThanWorkHoursCUML + 1                    Cells(i, ii).Interior.Color = RGB(0, 255, 255) '标记底色为亮蓝色                    workDaysCUML = workDaysCUML + 1                '未打卡日期处理                ElseIf Trim(Cells(i, ii).Value) = "" Then                    Cells(i, ii).Value = the0Time '更改文字标记                    Cells(i, ii).Font.Color = RGB(166, 166, 166) '标记字体颜色为深灰色                    '连续3天未打卡处理                    If ii >= 3 Then                        If IsNumeric(Replace(Trim(Cells(1, ii - 2).Value), "日", "")) Then                            If Trim(Cells(i, ii - 2).Value) = the0Time And Trim(Cells(i, ii - 1).Value) = the0Time And Trim(Cells(i, ii).Value) = the0Time Then                                the0timeCNSC = 3                                Range(Cells(i, ii - 2), Cells(i, ii)).Interior.Color = RGB(255, 0, 0) '标记底色为红色                            End If                        End If                    End If                End If            End If        Next        '第2次循环,再遍历汇总列写入结果,以避免汇总列在日期之前当仅进行一次循环时写入不准确的结果        For ii = 1 To aCol            '定位“正常出勤天数”列写入结果            If normalWorkCUML > 0 And Trim(Cells(1, ii).Value) = "正常出勤天数" Then                Cells(i, ii).Value = normalWorkCUML            '定位“不足6小时天数”列写入结果            ElseIf lessThanWorkHoursCUML > 0 And Trim(Cells(1, ii).Value) = "不足8小时天数" Then                Cells(i, ii).Value = lessThanWorkHoursCUML            '定位“当日打卡次数为1次天数”列写入结果            ElseIf the1TimeCUML > 0 And Trim(Cells(1, ii).Value) = "打卡1次的天数" Then                Cells(i, ii).Value = the1TimeCUML            '定位“连续3天未打卡”列写入结果            ElseIf the0timeCNSC > 0 And Trim(Cells(1, ii).Value) = "连续3天未打卡" Then                Cells(i, ii).Value = "是"            '定位“汇总”列写入结果            ElseIf workDaysCUML > 0 And Trim(Cells(1, ii).Value) = "打卡天数汇总" Then                Cells(i, ii).Value = workDaysCUML            End If        Next    NextEnd Sub

    2、主过程

    Sub 考勤统计v1_2()    '定义考勤状态    Dim workHours%, the0Time$, the1Time$, lessThanWorkHours$, normalWork$    workHours = 28800 '工作时长 8小时,即8×3600 = 28800秒    the0Time = ""               '未打卡    the1Time = "忘考勤"         '打1次卡    lessThanWorkHours = "早退"  '打卡至少2次,不足正常工作时长    normalWork = "出勤"         '正常出勤    '----------设定当前sheet----------    Dim strThisName$, thisSheet, tCol%, tRow As Long    strThisName = ThisWorkbook.Name    ActiveSheet.Copy After:=Sheets(Sheets.Count)    Set thisSheet = Sheets(Sheets.Count)    tCol = thisSheet.UsedRange.Columns.Count '获取当前表的列数    tRow = thisSheet.UsedRange.Rows.Count '获取当前表有效行数    thisSheet.AutoFilterMode = False '关闭筛选    '定义列    Dim titleRow%, staffCode%, staffName%, deptName%, clockInTime%, clockInDevice%, recordSource%, clockInAddress%    titleRow = 0 '标题行    staffCode = 0 '工号    staffName = 0 '姓名    deptName = 0 '部门    clockInTime = 0 '刷卡时间    clockInDevice = 0 '设备名称    recordSource = 0 '记录来源    clockInAddress = 0 '移动考勤地址    '定位列    For i = 1 To 20 '标题行必须在20行之内        '取消隐藏行        thisSheet.Rows(i).Hidden = False        '循环定位列        For ii = 1 To tCol            '取消隐藏列            thisSheet.Columns(ii).Hidden = False            '删除空列            If Application.CountA(Columns(ii)) = 0 Then                thisSheet.Columns(ii).Delete                tCol = tCol - 1            End If            If Trim(thisSheet.Cells(i, ii).Value) = "工号" Then                titleRow = i                staffCode = ii            ElseIf Trim(thisSheet.Cells(i, ii).Value) = "姓名" Then                staffName = ii            ElseIf Trim(thisSheet.Cells(i, ii).Value) = "部门" Then                deptName = ii            ElseIf Trim(thisSheet.Cells(i, ii).Value) = "刷卡时间" Then                clockInTime = ii            ElseIf Trim(thisSheet.Cells(i, ii).Value) = "设备名称" Then                clockInDevice = ii            ElseIf Trim(thisSheet.Cells(i, ii).Value) = "记录来源" Then                recordSource = ii            ElseIf Trim(thisSheet.Cells(i, ii).Value) = "移动考勤地址" Then                clockInAddress = ii            End If        Next        If titleRow <> 0 Then            Exit For        End If    Next    If titleRow = 0 Then        MsgBox "20行之内没有定位到标题行,已退出脚本,请检查文件。"        GoTo exitSub    ElseIf staffCode = 0 Then        MsgBox "“工号”列未找到,已退出脚本,请检查文件。"        GoTo exitSub    ElseIf staffName = 0 Then        MsgBox "“姓名”列未找到,已退出脚本,请检查文件。"        GoTo exitSub    ElseIf deptName = 0 Then        MsgBox "“部门”列未找到,已退出脚本,请检查文件。"        GoTo exitSub    ElseIf clockInTime = 0 Then        MsgBox "“刷卡时间”列未找到,已退出脚本,请检查文件。"        GoTo exitSub    End If    If tRow <= titleRow Then        MsgBox "考勤明细表里没有有效的数据,已退出脚本。"        GoTo exitSub    End If    '关闭屏幕更新,提高运行速度    Application.ScreenUpdating = False    '删除空行    Dim n As Long    n = tRow    Do While n >= titleRow + 1        '取消隐藏行        thisSheet.Rows(n).Hidden = False        '工号为空或者刷时间为空的        If Trim(thisSheet.Cells(n, staffCode).Value) = "" Or Trim(thisSheet.Cells(n, clockInTime).Value = "") Then            thisSheet.Rows(n).Delete            tRow = tRow - 1        End If        n = n - 1    Loop    '按工号-刷卡时间排序    thisSheet.Range(Cells(titleRow + 1, 1), Cells(tRow, tCol)).Select    thisSheet.Sort.SortFields.Clear    thisSheet.Sort.SortFields.Add Key:=Range(Cells(titleRow + 1, staffCode), Cells(tRow, staffCode)), SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:=xlSortNormal    thisSheet.Sort.SortFields.Add Key:=Range(Cells(titleRow + 1, clockInTime), Cells(tRow, clockInTime)), SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:=xlSortNormal    With thisSheet.Sort        .SetRange Range(Cells(titleRow + 1, 1), Cells(tRow, tCol))        .Header = xlGuess        .MatchCase = False        .Orientation = xlTopToBottom        .SortMethod = xlPinYin        .Apply    End With    thisSheet.Cells(titleRow + 1, staffCode).Select    '----------循环写入考勤统计数据----------    Dim nn As Long, staffExists%, lastRecordStaffCode$    n = titleRow + 1    staffExists = 0 '统计表中员工是否存在,0不存在,1存在    lastRecordStaffCode = "" '上一个记录的工号    Dim clockInTimeEarliest As Date, clockInTimeLatest As Date    clockInTimeEarliest = Format("1900/1/1 0:0:0", "yyyy/m/d h:n:s") '最早打卡时间    clockInTimeLatest = Format("3000/12/31 23:59:59", "yyyy/m/d h:n:s") '最晚打卡时间    Dim secSheet As Worksheet, iCol%, iRow As Long, sheetCount%    iCol = 0    iRow = 0    sheetCount = 0 '记录第一个脚本建立的考勤统计表(sheet)位置    Do While n <= tRow        Set secSheet = Nothing '变量初始化        '当工号不为空,且刷卡时间数据为date格式        If Trim(thisSheet.Cells(n, staffCode).Value) <> "" And IsDate(Trim(thisSheet.Cells(n, clockInTime).Value)) Then            '循环判断是否有存在的表(sheet)            For i = 1 To ThisWorkbook.Sheets.Count                '如果有存在的表(sheet)                If ThisWorkbook.Sheets(i).Name = Format(Trim(thisSheet.Cells(n, clockInTime).Value), "yyyymm") Then                    Set secSheet = ThisWorkbook.Sheets(i)                    Exit For                End If            Next            If secSheet Is Nothing Then                '如果不存在则建立统计表(sheet)                If 建立考勤统计表(Format(Trim(thisSheet.Cells(n, clockInTime).Value), "yyyymm")) = 1 Then '成功                    Set secSheet = ActiveSheet                    '记录第一个脚本建立的考勤统计表(sheet)位置,后续循环表(sheet)统计加工时使用                    If sheetCount = 0 Then                        sheetCount = Sheets.Count                    End If                Else '不成功                    GoTo exitSub                End If            End If            iCol = secSheet.UsedRange.Columns.Count '获取当前表的列数            iRow = secSheet.UsedRange.Rows.Count '获取当前表有效行数            '当上一个记录的工号与本次记录工号相同(即统计表工号已经存在)            If lastRecordStaffCode = Format(Trim(thisSheet.Cells(n, clockInTime).Value), "yyyymm") & "-" & Trim(thisSheet.Cells(n, staffCode).Value) Then                staffExists = 1            Else                '否则是新增行(即统计表中不存在此员工)                staffExists = 0                iRow = iRow + 1 '行数+1                secSheet.Cells(iRow, 1).Value = Trim(thisSheet.Cells(n, staffCode).Value)  '工号                secSheet.Cells(iRow, 2).Value = Trim(thisSheet.Cells(n, staffName).Value) '姓名                secSheet.Cells(iRow, 3).Value = Trim(thisSheet.Cells(n, deptName).Value) '部门                lastRecordStaffCode = Format(Trim(thisSheet.Cells(n, clockInTime).Value), "yyyymm") & "-" & Trim(thisSheet.Cells(n, staffCode).Value)            End If            '定位刷卡日期所在列            For i = 1 To iCol                If Day(Trim(thisSheet.Cells(n, clockInTime).Value)) & "日" = Trim(secSheet.Cells(1, i).Value) Then                    '记录的最早时间 与 此条刷卡时间,进行日期对比                    '日期不同                    If Format(clockInTimeEarliest, "yyyy/m/d") <> Format(Trim(thisSheet.Cells(n, clockInTime).Value), "yyyy/m/d") Then                        clockInTimeEarliest = Format(Trim(thisSheet.Cells(n, clockInTime).Value), "yyyy/m/d h:n:s") '记录下最早时间                        secSheet.Cells(iRow, i) = the1Time '对应日期中记录[只打一次卡]的出勤状态                    '日期相同,但不足正常工作时长                    ElseIf Format(clockInTimeEarliest, "yyyy/m/d") = Format(Trim(thisSheet.Cells(n, clockInTime).Value), "yyyy/m/d") _                        And DateDiff("s", clockInTimeEarliest, Format(Trim(thisSheet.Cells(n, clockInTime).Value), "yyyy/m/d h:n:s")) < workHours _                        Then                        secSheet.Cells(iRow, i) = lessThanWorkHours '对应日期中记录[不足正常工作时长]的出勤状态                    '日期相同,且够正常工作时长                    ElseIf Format(clockInTimeEarliest, "yyyy/m/d") = Format(Trim(thisSheet.Cells(n, clockInTime).Value), "yyyy/m/d") _                        And DateDiff("s", clockInTimeEarliest, Format(Trim(thisSheet.Cells(n, clockInTime).Value), "yyyy/m/d h:n:s")) >= workHours _                        Then                        secSheet.Cells(iRow, i) = normalWork '对应日期中记录[正常]的出勤状态                    End If                End If            Next        End If        n = n + 1    Loop    '----------最终加工处理----------    If sheetCount > 0 Then        '循环遍历考勤表进行统计加工        For i = sheetCount To ThisWorkbook.Sheets.Count            '如果表(sheet)名为“年+月”            If IsDate(Left(ThisWorkbook.Sheets(i).Name, 4) & "/" & Right(ThisWorkbook.Sheets(i).Name, 2) & "/01") Then                Worksheets(i).Select                Call 统计表汇总加工(the0Time, the1Time, lessThanWorkHours, normalWork)            End If        Next    Else        MsgBox "无有效考勤数据,请检查考勤表!End"        GoTo exitSub    End If    Application.ScreenUpdating = TrueexitSub:    '最终展示第一个考勤统计表    thisSheet.Delete    Worksheets(sheetCount - 1).SelectEnd Sub

    三、运行结果

    执行脚本之后,会按不同的月份生成不同的sheet,每个sheet是一个月的考勤汇总统计数据,效果见下图。

    d2bcf39bcdb390325fdde2233913e9f2.png

    3a5ab42b13a6a852fee909ffad582991.png

    请点亮在看,可帮助到更多人603d5fcee7eaf37096c78f38474fc79b.gif
    展开全文
  • 3、Alt+Enter 单元格内强制换行 我们在实际录入数据的时候,常常需要对单元格内的文本或者数值进行换行操作,我见过有的同学在内容间一直按空格,直到触发了自动换行后进行换行。 其实,这时候我们就可以使用Alt+...
  • 3、Alt+Enter 单元格内强制换行 我们在实际录入数据的时候,常常需要对单元格内的文本或者数值进行换行操作,我见过有的同学在内容间一直按空格,直到触发了自动换行后进行换行。 其实,这时候我们就可以使用Alt+...
  • VBA中创建自动换行的XML文件

    千次阅读 2013-11-20 22:49:04
    以下是用来测试xml文件ForTest.xml及我自己生成xml文件outPut.xml,为来往方便测试,只留下一个节点,如果有乱码,请忽略。 ForTest.xml: Markieren Sie dieses Kontrollkästchen, um das ...
  • 德文就变成了乱码,故用MSXML2.DOMDocument对象来添加,但是最后由个问题就是,生成出来的xml文件时在一行的,用IE打开时换行的,但是用Nodepad++打开却是在一行,请问有什么方法能让它自动换行啊,非常感谢!...
  • 分享成果,随喜真能量。大家好,今日内容仍是和大家分享VBA编程中常用的简单“积木”... 192:在VBA中使用OpenTextFile方法打开文件,并将数据导入到工作表中VBA过程代码191:在VBA中使用Shell函数自动关闭电脑Sub...
  • Excel中单元格批量调整行间距,行高自动适应内容,且自动换行一、操作步骤1.打开EXCEL,选中要调整的单元列,点击开始菜单中的自动换行,换行成功后,点击格式中的自动调整行高2.按alt+F11 键(部分电脑是 Fn+alt+...
  • 熟悉VBA 但是不熟悉 xlwings 怎么办,可以调用 api 操作,如 xlwings 取消自动换行,xlwings选中某一列,xlwings获取最大行号,行标,最大列号,列标等等 个人常用代码如下,返回结果,截图如下 import xlwings ...
  • 但同样作为一个「懂点 Excel」的我,怎么可能这么傻傻地一个个点击单元格,然后一个个输入,哼,我是这么输入数据的,呐,你瞧~同事:哇,好厉害呀,这一定是需要 VBA 吧,太复杂了,我不会啊!我插着腰...
  • 很多人立马会想到用 VBA 编写。VBA 编写这样一个输入窗体确实不难,但是还有没有更简单的方法?其实 Excel 自身就带有这个功能,这就是我今天要介绍的“记录单”。示例:下图就是在“记录单”中录入表格数据的效果。...
  • EXCEL VBA 按关键字自动换行程序,这里是提取A列的部分关键字来确定分页符的插入
  • Gavin与狗(ID:callmeGavin8)01使用背景1、VBA简介VBA作为一种宏语言,在Excel、Word、PPT等软件中可Alt+F11一键开启编写。免去主流编程语言(如大热的Python)安装时的复杂与痛苦,像傻瓜一样复制代码进去即可立刻...
  • VBA_Excel自动

    2020-12-23 02:51:14
    没有语句结束符号,换行就是语句结束符号吧 1.定义变量 Dim a As Integer,b as Interger 变量不定义也可以直接赋值使用 2.逻辑等号 = 等号和赋值是同一个符号,根据所处语句系统自行判断 2.访问单元表 Worksheets...
  • VBA_单元格格式

    2020-02-11 21:08:12
    对齐方式选项卡 With Selection .HorizontalAlignment = xlRight 水平对齐方式 ....WrapText = False 自动换行 .Orientation = 0 文字方向 .AddIndent = False 缩进 .IndentLevel = 0 缩进量 .ShrinkToFit =...
  • 第55集 标签、按钮 259、 标签设置 1、自动适应字体大小 AutoSize的属性设置为true,可以自动调整大小以完全显示...WordWrap属性:如果为True则自动换行(默认)。 260、 按钮设置 一 按钮显示 1、鼠标放在按钮上时...
  • 用Excel中的宏获取VBA中的代码。

    千次阅读 2007-12-11 17:03:00
    >" src=...已单元格合并,自动换行,自动行高为例子:工具 -> 宏 - > 录制新宏操作Excel,设置表格属性,单元格合并,自动换行,最合适行高停止宏录制ALT + F11VBAProject(Book1) -> 模块
  • VBA-联通话费明细单-格式调整 Sub ChangeColumn() ... Rows(1).WrapText = True '设置第1行的属性为“自动换行” Rows(1).Font.Bold = False '设置第1行的字体为非粗体 Columns("A").ColumnWidt...
  • 方法一:在页眉处插入可以把印章图片放进页眉里,把图片的自动换行方式(文字环绕方式)设置为浮动式,如衬于文字上方、衬于文字下方等。然后把图片移动到适当的位置即可。如果文档不分节,只要把某一页的页眉设置好...
  • Excel 宏 VBA

    千次阅读 2012-05-03 13:51:36
    在公式中加&CHAR(10)&,同时要将单元格设置为自动换行。 同理:公式中加入冒号":"可用&CHAR(58)&利用+形进行序列填充时,若公式中含有多个单元格编号:T22&CHAR(58)&CHAR(10)U20,而我们只想要其中一个编号如U20发生...
  • 一、输出linux/dos格式文件 用print写内容到文件,一般会自动加回车和换行符号,即dos格式,用vi打开就是显示为^M。 open ThisWorkbook.Path ...号表示打印未结束,所以vba不会自动在后面加回车和换行符号 显示结果为:
  •  第一: 下面的 “ _" 也就是 空格下划线 在VBA中表示换行的意思;& 表示链接连个字符串的操作,注意 & 的前后是否需要空格 第二: 如果链接服务器,服务器名称,账号,密码,或者SQL语句有问题,都会报错说...
  • VBA常用技巧

    2014-12-21 16:39:28
    技巧60 使用VBA自动生成图表 12 技巧61 使用独立窗口显示图表 12 技巧62 导出工作表中的图表 12 技巧63 多图表制作 12 第5章 Application对象 12 技巧64 取得Excel版本信息 12 技巧65 取得当前用户名称 12 技巧66 ...
  • 如果设置WordWrap属性设置为True为自动换行 ScrollBars:是否显示滚动条 ListBox:列表框 Listbox.RowSource=”sheet1!D1:”D66”:列表框的条目,不可以与List属性同时使用 Initialize:窗体初始化时 AddItem:...
  • VBA编程技巧大全

    2013-08-05 09:03:19
    技巧60 使用VBA自动生成图表 145 技巧61 使用独立窗口显示图表 149 技巧62 导出工作表中的图表 150 技巧63 多图表制作 151 第5章 Application对象 155 技巧64 取得Excel版本信息 155 技巧65 取得当前用户名称 156 ...
  • 一、建表语句  不带分区版本:V1.0: ... '自动创建建表语句 '定义换行和TAB Ln = Chr(13) + Chr(10) TB = Chr(9) '定义脚本目录 Dim dir AS String dir = "C:\CREATE_TABLE_DDL" Set ...
  • 01040设置保存自动恢复文件的时间间隔和保存位置 01041停止屏幕刷新 01042使事件无效 01043使取消键无效 01044不显示警告信息对话框 01045设置使用的打印机 01046安装加载宏 01047利用GetOpenFilename方法获取文件名...
  • excel 工具箱

    2012-01-22 15:04:34
    【合并区域自动换行】:可以让具有合并单元格的区域在自动换行与不换行之间自由切换 【建立图片目录】:对指定文件夹下所有图片(GIF、PNG、JPG,JPEG)建立目录,并批量导入 【批量导入图片(精确匹配)】:瞬间导入...

空空如也

空空如也

1 2
收藏数 38
精华内容 15
关键字:

vba自动换行