码迷,mamicode.com
首页 > 编程语言 > 详细

[VBA源码] 2018模拟_普通类平行计划1_普通类平行录取_物理化学技术.xlsm

时间:2018-05-04 21:23:28      阅读:630      评论:0      收藏:0      [点我收藏+]

标签:测试   单元格   col   单元   select   special   mode   count   func   

测试了下浙江省教育考试院给的2018年模拟演练(志愿填报)文件,发现bug颇多,想自行修改下VBA代码,却发现VBA有项目密码,不想就此停手,故参考网上的相关资料将VBA源码提取出来,附于此处,方便有需要者自行改进代码逻辑,仅供学习研究使用,请勿用于商业用途,如有违反后果自负,版权及解释权归浙江省教育考试院所有

为了避免不必要的麻烦,文件下载和密码问题请自行解决,本处仅提供源码。

文件来自:浙江省高校招生志愿填报系统(模拟)


VBAProject

Microsoft Excel 对象

Sheet1

‘工作表单元格的值发生改变,触发Worksheet_Change事件
‘     target为发生变化的单元格或区域
‘     Application.EnableEvents = False表示再此后发生单元格变化等事件时不会触发事件过程,避免“死循环”
‘     Application.EnableEvents = True 恢复正常事件过程
‘     只有第1列中单元格发生变化时,才处理,其他情况Undo,即值不允许改变
‘     第1列的值发生变化分两种情况:(只有值大于等于1才认为是合理的,超过目前已选数默认为等于已选序号最大值+1)
‘          1、原来已选,值发生变化,选择序号进行调整,重新排序
‘          2、原来“待选”,值发生变化,重新排序
‘     处理排序问题由ReSort完成后
‘
Private Sub Worksheet_Change(ByVal target As Range)
    Dim R As Long, C As Long, Key As Long
    Application.EnableEvents = False
    On Error Resume Next
    If target.Column = 1 And target.Count = 1 Then        ‘检测到第1列一个元素有操作
        R = target.Row
        C = target.Column
        Key = Val(target.Value)
        If R > 2 And R <= NumSelected + 2 Then
            If Key >= 1 Then
                ReSort R, C, Key
            Else
                Application.Undo
                Cells(R, 1).Select
                MsgBox "请输入一个不小于1的整数!", vbCritical, "序号错误提示信息"
            End If
        ElseIf R > NumSelected + 2 And R <= NumUnselected + NumSelected + 2 Then
            If Key >= 1 Then
                ReSort R, C, Key
            Else
                Application.Undo
                Cells(R, 1).Select
                MsgBox "请输入一个不小于1的整数!", vbCritical, "序号错误提示信息"
                ‘target.Value = "待选"
            End If
        Else
            Application.Undo
        End If
    Else
        Application.Undo
    End If
    Application.EnableEvents = True
End Sub

‘单元格焦点发生改变,一般是选择单元格操作
‘原来在这个单元格,再单击鼠标选择这个单元格,这种情况不触发事件
Private Sub Worksheet_SelectionChange(ByVal target As Range)
    Application.EnableEvents = False
    On Error Resume Next
    S = target.Address
    If target.Address = target.EntireRow.Address And target.Rows.Count = 1 Then   ‘判断选择一行的条件
        R = target.Row
        If R > 2 And R <= NumUnselected + NumSelected + 2 Then                    ‘判断是否在项目行范围内
            If Cells(R, 1).Value = "待选" Then                                    ‘只有第1列为“待选”或值>=1
                Selectitem R
            ElseIf Val(Cells(R, 1).Value) >= 1 Then
                CancelLine R
            End If
        End If
    ElseIf target.Address = target.EntireRow.Address And target.Rows.Count > 1 Then   ‘判断选择多行的条件
        ‘连续多行处理target.Address
        If InStr(1, S, ",") = 0 Then
            n = InStr(1, S, ":")
            R1 = Mid(S, 2, n - 2)
            R2 = Right(S, Len(S) - n - 1)
            If R1 > NumSelected + 2 And R2 <= NumUnselected + NumSelected + 2 Then
                SelectMultiTtems R1, R2
            ElseIf R1 > 2 And R2 <= NumSelected + 2 Then
                CancelMultiLines R1, R2
            End If
        End If
    ElseIf target.Address = "$L$1:$M$1" Then                                ‘自动保存导入文档处理
        If NumSelected = 0 Then
            MsgBox "    目前已选志愿项=0,不生成志愿文档!" + vbCrLf + vbCrLf, vbCritical, "自动生成志愿文档提示"
        Else
            Yes = MsgBox("系统将选中志愿项(前80项)保存到‘志愿导入表.xls’文档中" + vbCrLf + vbCrLf + vbTab + vbTab + "确定要继续吗?", vbQuestion + vbYesNo, "自动生成志愿文档提示")
            If Yes = vbYes Then
                SaveAsExcel
                MsgBox "  志愿文档“志愿导入表.xls”已经成功生成!" + vbCrLf + vbCrLf + "  志愿文档保存在本工作簿文档所在文件夹中", vbInformation, "自动生成志愿文档提示"
            End If
        End If
        Worksheets("Sheet1").Range("A2").Select
    End If
    Application.EnableEvents = True
End Sub

ThisWorkBook

Private Sub Workbook_Open()
    Dim Welcome As String
    Range("A1").Select    ‘打开窗体停留在A1单元格
    Welcome = "欢迎进入志愿预选Excel操作文档!" + vbCrLf + vbCrLf
    Welcome = Welcome + "1、请按照操作说明进行选择操作。" + vbCrLf
    Welcome = Welcome + "2、单击【自动生成志愿文档】单元格,生成文档“志愿导入表.xls”。" + vbCrLf
    Welcome = Welcome + "3、文档“志愿导入表.xls”保存在与当前操作文档相同的文件夹中。" + vbCrLf
    Welcome = Welcome + "4、通过志愿填报系统将“志愿导入表.xls”导入到志愿填报系统网页。" + vbCrLf
    MsgBox Welcome, vbInformation, "志愿预选文档欢迎信息"
    VBAInitlize             ‘初始化
End Sub

模块

模块1

Public NumUnselected As Long, NumSelected As Long
Public NumColumn As Long
Public MaxItem As Integer

Sub VBAInitlize()
    ‘前两行冻结
    MaxItem = 80                        ‘普通批次最多填报80个志愿
    ActiveWindow.SplitColumn = 0
    ActiveWindow.SplitRow = 2
    ActiveWindow.FreezePanes = True
    Application.EnableEvents = False    ‘事件失效:ReCount事件过程中有改变单元格值的语句,会引发Change事件。该语句用于屏蔽事件的发生
    ReCount
    Application.EnableEvents = True     ‘事件可用
    Range("A1").Select                  ‘打开窗体后焦点在A1单元格
End Sub

‘   计算几个重要数据:已选数量、未选数量、有效列数
‘       统计已选志愿个数NumSelected:3-30000行统计第1列大于等于1的个数
‘       统计未选志愿个数NumUnselected:3-30000行统计第1列“待选”的个数
‘       统计有效列数NumColumn:第2列中非空项
‘       第1行第3列显示已选项数
‘       第1行第6列显示总项数
Sub ReCount()
    NumSelected = Application.WorksheetFunction.CountIf(Range("A3:A30000"), ">=1")      ‘已选项数
    NumUnselected = Application.WorksheetFunction.CountIf(Range("A3:A30000"), "待选")   ‘未选项数
    NumColumn = Application.WorksheetFunction.CountIf(Cells(3, 1).EntireRow, "<>")      ‘有效列数
    Cells(1, 3).Value = NumSelected                                                     ‘已选项数
    Cells(1, 6).Value = NumUnselected + NumSelected                                     ‘总项数
End Sub


‘重新排序的设计思想:
‘   1、为新序号留出空间,即从新序号后的全部序号都加1,这样新序号就唯一了
‘   2、按照序号重新排序,这是调用Excel内部过程完成后的
‘   3、排序结束后,重新编号
‘   重新排序分2种情况
‘       1、在已选区域中输入有效序号(大于等于1)
‘       2、在待选区域中输入有效序号(大于等于1)
‘       Key为输入的序号,R为行号,C为列号
Sub ReSort(ByVal R As Long, ByVal C As Long, Key As Long)
    Dim S1 As String, S2 As String
    S1 = Cells(R, 3).Value      ‘待改变序号项目的院校名,用于弹出框信息提示
    S2 = Cells(R, 5).Value      ‘待改变序号项目的专业名,用于弹出框信息提示
    For I = Key To NumSelected              ‘改变序号:从Key开始到先前已选数,序号+1;如果Key大于已选数,该循环跳过,不执行
        Cells(I + 2, 1).Value = I + 1       ‘这样就为新序号留出空间了
    Next I
    Cells(R, C).Value = Key                 ‘在上述改变序号过程中有可能被一起“改变”了
    RA = "A" & R & ":" & Chr(NumColumn + 64) & R                    ‘准备改变格式
    Range(RA).Font.Color = vbBlue
    Range(RA).Interior.ThemeColor = xlThemeColorAccent4
    Range(RA).Interior.TintAndShade = 0.599963377788629
    AllRange = "A3:" & Chr(NumColumn + 64) & (NumSelected + NumUnselected + 102)
    Range(AllRange).Sort key1:=Range("A3"), order1:=xlAscending     ‘重新排序
    If R > NumSelected + 2 Then             ‘判断是否新选择的:如果是新选择的,选中数+1,未选数-1
        NumSelected = NumSelected + 1
        NumUnselected = NumUnselected - 1
    End If
    Cells(1, 3).Value = NumSelected
    For I = 1 To NumSelected
        Cells(I + 2, 1).Value = I           ‘各序号刷新一遍
    Next I
    If Key > NumSelected Then Key = NumSelected
    Cells(Key + 2, 1).EntireRow.Select      ‘焦点保持在刚改变序号的行
    MsgBox "你选择的志愿项排在预选志愿的第(" & Key & ")号:" + vbCrLf + vbCrLf + "      “" & S1 + " - " + S2 & "”", vbOKOnly, "志愿选择提示信息"
End Sub

‘选中一行的处理:
‘     1、原来是待选行,将“待选”改为最后一项预选值(NumSelected = NumSelected + 1),同时改变“目前已选志愿数”所在单元的值
‘     2、将选中行数据区域的底纹与字体颜色作相应修改
‘     3、按照预选志愿序号进行排序
‘     4、最后焦点落在本行,只是位置、格式发生了改变
Sub Selectitem(ByVal R As Integer)
    S1 = Cells(R, 3).Value
    S2 = Cells(R, 5).Value
    Yes = MsgBox("你确定要选择下列项目作为预选志愿项吗?" + vbCrLf + vbCrLf + "      “" & S1 + " - " + S2 & "”", vbYesNo, "志愿选择提示信息")
    If Yes = vbYes Then
        NumSelected = NumSelected + 1           ‘已选值+1
        NumUnselected = NumUnselected - 1       ‘未选值-1
        Cells(1, 3).Value = NumSelected         ‘“目前已选志愿数”单元格赋值
        Cells(R, 1) = NumSelected               ‘所选行赋最新序号
        RA = "A" & R & ":" & Chr(NumColumn + 64) & R    ‘以下改变格式
        Range(RA).Font.Color = vbBlue
        Range(RA).Interior.ThemeColor = xlThemeColorAccent4
        Range(RA).Interior.TintAndShade = 0.599963377788629
        AllRange = "A3:" & Chr(NumColumn + 64) & (NumSelected + NumUnselected + 102)
        Range(AllRange).Sort key1:=Range("A3"), order1:=xlAscending     ‘重新排序
        Cells(NumSelected + 2, 1).EntireRow.Select
        MsgBox "你选择的志愿项排在预选志愿的第(" & NumSelected & ")号:" + vbCrLf + vbCrLf + "      “" & S1 + " - " + S2 & "”", vbOKOnly, "志愿选择提示信息"
    End If
End Sub

‘选中多行的处理:
‘     1、原来是待选区域,将“待选”改为最后一项预选值(NumSelected = NumSelected + 1),同时改变已选值所在单元的值
‘     2、将选中行数据区域的底纹与字体颜色作相应修改
‘     3、按照预选志愿序号进行排序
‘     4、最后焦点落在已选区域,只是位置、格式发生了改变
‘     5、多行选择可以是在“筛选”状态下进行的
Sub SelectMultiTtems(ByVal R1 As Integer, ByVal R2 As Integer)
    Dim n As Long  ‘选中志愿项目数
    Dim m As Long, R As Long
    Dim AllRange As String, Range1 As String, S As String
    
    m = NumSelected + 1              ‘选中项起始序号
    Range1 = "A" & R1 & ":A" & R2    ‘选中区域
    n = Range(Range1).SpecialCells(xlCellTypeVisible).Count    ‘计算行数n。没有用n=abs(R2-R1)+1计算是考虑了筛选情况下的选择问题
    If n > 2 Then     ‘行数不同,提示方式略有不同
        ‘超过2行
        S = "      " + Cells(R1, 3).Value + " - " + Cells(R1, 5).Value + vbCrLf
        S = S + "      ..............." + vbCrLf
        S = S + "      " + Cells(R2, 3).Value + " - " + Cells(R2, 5).Value
    Else
        ‘2行
        S = "      " + Cells(R1, 3).Value + " - " + Cells(R1, 5).Value + vbCrLf
        S = S + "      " + Cells(R2, 3).Value + " - " + Cells(R2, 5).Value
    End If
    S1 = "你确定要选择下列" & n & "个(第" & R1 & " ... " & R2 & "行)项目作为预选志愿吗?"
    Yes = MsgBox(S1 + vbCrLf + vbCrLf + S, vbYesNo, "志愿选择提示信息")
    If Yes = vbYes Then
        For R = R1 To R2
            If Range("A" & R).EntireRow.Hidden = False Then                 ‘对筛选情况下的隐藏行不处理,下面是一行一行的处理过程
                NumSelected = NumSelected + 1                               ‘已选数+1
                NumUnselected = NumUnselected - 1                           ‘未选数-1
                Cells(1, 3).Value = NumSelected                             ‘“目前已选志愿数”单元格赋值
                Cells(R, 1) = NumSelected                                   ‘所选行赋最新序号
                RA = "A" & R & ":" & Chr(NumColumn + 64) & R                ‘以下修改格式
                Range(RA).Font.Color = vbBlue
                Range(RA).Interior.ThemeColor = xlThemeColorAccent4
                Range(RA).Interior.TintAndShade = 0.599963377788629
            End If
        Next R
        AllRange = "A3:" & Chr(NumColumn + 64) & (NumSelected + NumUnselected + 102)
        ActiveSheet.AutoFilterMode = False                              ‘取消筛选状态
        Range(AllRange).Sort key1:=Range("A3"), order1:=xlAscending     ‘依据序号关键字重新排序
        Range("$" & m + 2 & ":$" & m + n + 1).Select                    ‘选择后还是这个区域选中,只是格式、位置都已经变化了
        MsgBox "你选择的志愿项排在预选志愿的第(" & m & "-" & m + n - 1 & ")号:" + vbCrLf + vbCrLf + S, vbOKOnly, "志愿选择提示信息"
    End If
End Sub

‘撤销一行的处理:
‘     1、将所选行后的序号依次减一,并将该行序号改为“待选”
‘     2、已选值减一(NumSelected = NumSelected - 1),同时改变“目前已选志愿数”所在单元的值,未选值加一
‘     3、将选中行数据区域的底纹与字体颜色作相应修改
‘     3、按照预选志愿序号进行排序
‘     4、最后焦点绝对位置不变
Sub CancelLine(ByVal R As Integer)
    Dim KR As Integer, S1 As String, S2 As String, RA As String
    Dim AllRange As String, Range1 As String
    
    S1 = Cells(R, 3).Value
    S2 = Cells(R, 5).Value
    KR = R
    Yes = MsgBox("你确定要撤销该预选志愿项吗?" + vbCrLf + vbCrLf + "      “" & S1 + " - " + S2 & "”", vbYesNo, "志愿撤销提示信息")
    If Yes = vbYes Then
        For I = R + 1 To NumSelected + 2
            Cells(I, 1).Value = Cells(I, 1).Value - 1       ‘将所选行后的序号依次减一
        Next I
        Cells(R, 1).Value = "待选"                          ‘将该行序号改为“待选”
        NumSelected = NumSelected - 1                       ‘已选数-1
        NumUnselected = NumUnselected + 1                   ‘未选数+1
        Cells(1, 3).Value = NumSelected                     ‘“目前已选志愿数”单元格赋值
        RA = "A" & R & ":" & Chr(NumColumn + 64) & R        ‘以下修改格式
        Range(RA).Interior.Pattern = xlNone
        Range(RA).Font.ColorIndex = xlAutomatic
        AllRange = "A3:" & Chr(NumColumn + 64) & (NumSelected + NumUnselected + 102)
        Range(AllRange).Sort key1:=Range("A3"), order1:=xlAscending, key2:=Range("B3"), order2:=xlAscending, key3:=Range("D3"), order3:=xlAscending     ‘重新排序
        For R = 1 To NumSelected
            Cells(R + 2, 1).Value = R           ‘各序号刷新一遍
        Next R
        Cells(KR, 1).Select                     ‘焦点位置设置
    End If
End Sub

‘撤销多行的处理:
‘     1、将所选区域按照行序依次处理:已选值减一,未选值加一,序号改为“待选”,同时改变“目前已选志愿数”所在单元的值,将选中行数据区域的底纹与字体颜色作相应修改
‘     2、按照预选志愿序号进行排序
‘     3、从原来选择的撤销区域起始行开始到最后,重新刷新序号
‘     4、最后焦点定位与原来选择区域的起始行
Sub CancelMultiLines(ByVal R1 As Integer, ByVal R2 As Integer)
    Dim n As Integer    ‘选中预选志愿项目数
    
    Range1 = "A" & R1 & ":A" & R2
    n = Range(Range1).SpecialCells(xlCellTypeVisible).Count
    If n > 2 Then
        ‘超过2项
        S = "      " + Cells(R1, 3).Value + " - " + Cells(R1, 5).Value + vbCrLf
        S = S + "      ..............." + vbCrLf
        S = S + "      " + Cells(R2, 3).Value + " - " + Cells(R2, 5).Value
    Else
        ‘2项
        S = "      " + Cells(R1, 3).Value + " - " + Cells(R1, 5).Value + vbCrLf
        S = S + "      " + Cells(R2, 3).Value + " - " + Cells(R2, 5).Value
    End If
    S1 = "你确定要撤销下列" & n & "个(第" & R1 & "-" & R2 & "行)预选志愿项吗?"
    Yes = MsgBox(S1 + vbCrLf + vbCrLf + S, vbYesNo, "志愿撤销提示信息")
    If Yes = vbYes Then
        For R = R1 To R2                            ‘所选区域按行从小到大分别处理
            If Range("A" & R).EntireRow.Hidden = False Then
                NumSelected = NumSelected - 1       ‘已选数-1
                NumUnselected = NumUnselected + 1   ‘未选数+1
                Cells(1, 3).Value = NumSelected     ‘“目前已选志愿数”单元格赋值
                Cells(R, 1) = "待选"                ‘将该行序号改为“待选”
                RA = "A" & R & ":" & Chr(NumColumn + 64) & R    ‘以下修改格式
                Range(RA).Interior.Pattern = xlNone
                Range(RA).Font.ColorIndex = xlAutomatic
            End If
        Next R
        AllRange = "A3:" & Chr(NumColumn + 64) & (NumSelected + NumUnselected + 102)
        ActiveSheet.AutoFilterMode = False
        Range(AllRange).Sort key1:=Range("A3"), order1:=xlAscending, key2:=Range("B3"), order2:=xlAscending, key3:=Range("D3"), order3:=xlAscending
        For R = 1 To NumSelected
            Cells(R + 2, 1).Value = R           ‘各序号刷新一遍
        Next R
        Cells(R1, 1).Select                     ‘焦点位置设置
    End If

End Sub

‘将选中志愿(不超过80项)保存到一个新的Excel工作簿,文档名称为:志愿导入表.xls,保存在预选文件相同的文件夹
Sub SaveAsExcel()
    Dim NewSheet As Worksheet, Wb As Workbook
    Dim OutputLines As Integer, OutputRange As String
    Dim FileName As String
        
    ‘计算导出项数:选择项小于80时,用实际项数;选择项大于80项,项数=80
    If MaxItem > NumSelected Then OutputLines = NumSelected Else OutputLines = MaxItem
    OutputRange = "b3:e" & (OutputLines + 2)
    ‘将Sheet1表中选中项目的前4列复制到新建表的A2开始的区域中
    Worksheets("sheet1").Range(OutputRange).Copy
    
    ‘创建新的工作薄
    Set Wb = Workbooks.Add
    ‘当前工作簿的Sheet1表名重命名、将粘贴板内容复制到新工作表中
    Set NewSheet = Sheets(1)
    NewSheet.Name = "志愿导入表"
    Worksheets("志愿导入表").Range("a2").PasteSpecial xlPasteValues
    
    ‘设置志愿导入表的各种属性:表头文字、列宽、表格线、字体、字号、行高
    Worksheets("志愿导入表").Cells(1, 1).Value = "院校代码"     ‘表头文字
    Worksheets("志愿导入表").Cells(1, 2).Value = "院校名称"     ‘表头文字
    Worksheets("志愿导入表").Cells(1, 3).Value = "专业代码"     ‘表头文字
    Worksheets("志愿导入表").Cells(1, 4).Value = "专业名称"     ‘表头文字
    Worksheets("志愿导入表").Columns("A:A").ColumnWidth = 12    ‘列宽
    Worksheets("志愿导入表").Columns("C:C").ColumnWidth = 12    ‘列宽
    Worksheets("志愿导入表").Columns("B:B").ColumnWidth = 35    ‘列宽
    Worksheets("志愿导入表").Columns("D:D").ColumnWidth = 50    ‘列宽
    Worksheets("志愿导入表").Cells.Select
    With Selection.Interior         ‘设置表格底纹。最终作用是取消表格线
        .Pattern = xlSolid
        .PatternColorIndex = xlAutomatic
        .ThemeColor = xlThemeColorDark1
        .TintAndShade = 0
        .PatternTintAndShade = 0
    End With
    Selection.Font.Name = "宋体"    ‘表格字体
    Selection.Font.Size = 12        ‘表格字号
    Selection.RowHeight = 20.1      ‘表格行高
    Selection.Locked = True                            ‘ 非志愿数据区锁定
    OutputRange = "A1:D" & (OutputLines + 1)
    Worksheets("志愿导入表").Range(OutputRange).Select     ‘志愿区域表格线
    With Selection.Borders
        .LineStyle = xlContinuous
        .ColorIndex = xlAutomatic
        .TintAndShade = 0
        .Weight = xlThin
    End With
    Worksheets("志愿导入表").Range(OutputRange).Select
    Selection.Locked = False                            ‘志愿数据区不锁定
    Worksheets("志愿导入表").Range("A1:D1").Select       ‘表头区域底纹
    With Selection.Interior
        .Pattern = xlSolid
        .PatternColorIndex = xlAutomatic
        .ThemeColor = xlThemeColorAccent6
        .TintAndShade = 0.799981688894314
        .PatternTintAndShade = 0
    End With
    Selection.HorizontalAlignment = xlCenter           ‘表头区域文字居中对齐
    Worksheets("志愿导入表").Select
    ActiveSheet.Protect DrawingObjects:=True, Contents:=True, Scenarios:=True    ‘设置除锁定区域外操作保护
    ActiveSheet.EnableSelection = xlUnlockedCells

    ‘首行冻结
    ActiveWindow.SplitRow = 1
    ActiveWindow.FreezePanes = True
    Worksheets("志愿导入表").Range("A2").Select         ‘新表格打开时焦点设置为A2单元格
    FileName = ThisWorkbook.Path + "\志愿导入表.xls"
    Application.DisplayAlerts = False                  ‘取消工作表保存时警告提示
    ‘工作簿另存为
    ActiveWorkbook.SaveAs FileName:=FileName, FileFormat:=xlNormal, Password:="", WriteResPassword:="", ReadOnlyRecommended:=False, CreateBackup:=False
    ActiveWorkbook.Close
    Application.DisplayAlerts = True                   ‘恢复工作表保存时警告提示
End Sub

[VBA源码] 2018模拟_普通类平行计划1_普通类平行录取_物理化学技术.xlsm

标签:测试   单元格   col   单元   select   special   mode   count   func   

原文地址:https://www.cnblogs.com/unixart/p/8992269.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!