Excel精英培训网

 找回密码
 注册
查看: 4254|回复: 10

[通知] 【VBA字典数组201301班】C组-第二讲作业上交处

[复制链接]
发表于 2013-11-11 21:48 | 显示全部楼层 |阅读模式
本帖最后由 无聊的疯子 于 2013-11-13 22:26 编辑

本贴为 C组 第二讲作业上交专用贴,其它组员勿入

本次作业的要求:
1.要求添加注释(不要求每行都添加,涉及到关键的部分必须有)
2.代码缩进
3.要求变量强制声明(在模块的顶端已添加 option explicit,不得修改),声明变量时对变量的类型不做要求。

上交作业时,直接贴代码即可,
为方便统计,请在回贴时输入 ID与编号
如 :C02:monicaj
发表于 2013-11-11 22:43 | 显示全部楼层
本帖最后由 xdragon 于 2013-11-13 09:19 编辑

C08:xdragon
以下只贴填空处,并非完整代码。
练习一:
  1. Dim arr, brr(), a, brrrow As Long, brrcol As Integer
  2. arr = rgSource.Value '如果选择是多个区域的话,利用默认只将第一个区域赋值给数组的特性,可以去除后面的多选区域

  3. '判断是否为数组(考虑只选择一个单元格的情况)
  4. If IsArray(arr) = False Then
  5.    rgDest.Resize(1).Value = arr
  6.    Exit Sub
  7. End If
  8. 'brrrow为brr的行号;brrcol为列号
  9. brrrow = 1
  10. ReDim brr(1 To bGroupCount, 1 To UBound(arr) * UBound(arr, 2) / bGroupCount)'根据输入的行高设置新数组的第二维上限
  11. For Each a In arr
  12.    brrcol = brrcol + 1
  13.    If brrcol > UBound(brr, 2) Then brrcol = 1: brrrow = brrrow + 1'当brrcol大于brr第二维上限时,重置brrcol为1,行序号+1(相当于换行输入)
  14.    brr(brrrow, brrcol) = a
  15. Next
  16. '防止数据太少但行数设置过大,导出空值覆盖其他的数据(比如选择了10个数据,行数设置20行)
  17. If brrcol = 1 And brrrow < bGroupCount Then
  18.    rgDest.Resize(brrrow).Value = brr
  19. Else
  20.    rgDest.Resize(UBound(brr), UBound(brr, 2)).Value = brr
  21. End If
复制代码
练习二(数组+replace+split)
  1. strText = Mid(strText, i) '定位到网页中符合查询条件的部分
  2. With Sheet4
  3.    .[a1] = strText '将查询到的网页代码导入单元格
  4.    .Range("A1").Replace "<*>", "", xlPart '利用excel的模糊替换功能把html符号都删除
  5. Dim tmp() As String, brr() As String, counter As Integer, m As Byte
  6. tmp = Split(Replace(.[a1].Value, " ", ""), Chr(10)) '将空白字符替换,并且按换行符切割字符串
  7. m = 1: ReDim brr(1 To 6, 1 To 1) '定义导出数据的数组brr,并初始赋值列变量m
  8. For i = 3 To UBound(tmp) '利用每6个元素有两个空单元格的特性做以下循环,当每6个元素的第一个不是日期格式的时候跳出循环
  9.    counter = counter + 1
  10.    If counter > 6 Then
  11.       i = i + 2
  12.       If IsDate(Left(tmp(i), Len(tmp(i)) - 1)) = False Then Exit For
  13.       counter = 1
  14.       m = m + 1
  15.       ReDim Preserve brr(1 To 6, 1 To m)
  16.    End If
  17.    brr(counter, m) = Left(tmp(i), Len(tmp(i)) - 1)
  18. Next
  19. '清空原数据区域,将数组brr导入单元格
  20.    .UsedRange.Clear
  21.    .Range("A1") = strFind
  22.    .Range("A2").Resize(UBound(brr, 2), UBound(brr)) = Application.Transpose(brr)
  23. End With
复制代码
练习二(正则):
  1. strText = Mid(strText, i) '截取从查找月份以后的网页内容
  2. Dim match, matches, arr(), arow As Integer, acol As Byte
  3. With CreateObject("vbscript.regexp") '正则引用
  4.    .Pattern = ">[^<].*?(?=<)" '匹配HTML网页标记(以">"开头且至少一个非"<"的字符,以"<"结尾的内容)
  5.    .Global = True '全局匹配
  6.    Set matches = .Execute(strText) '匹配结果导出到matches
  7. End With
  8. ReDim arr(1 To 6, 1 To Day(CDate(Format(CLng(strDate) + 1, "0000-00") & "-01") - 1) + 1) '定义一个当月的最后一天+1(列标签+当月天数)为列宽,行高是6的二维数组
  9. acol = 1 '设置数组初始列号
  10. For Each match In matches
  11.    arow = arow + 1
  12.    If arow > 6 Then '当大于行高6时换行(重置arow=1,且列号递增1)
  13.       If IsDate(Mid(match, 2)) = False Then Exit For '判断matches中每隔6个元素是否为日期格式,不是则跳出循环
  14.       arow = 1
  15.       acol = acol + 1
  16.    End If
  17.    arr(arow, acol) = Mid(match, 2)
  18. Next
  19. With Sheets("作业二结果") '清空原区域并导入数组arr到单元格
  20.    .UsedRange.ClearContents
  21.    .Range("A1") = strFind
  22.    .Range("A2").Resize(UBound(arr, 2), UBound(arr)) = Application.Transpose(arr)
  23. End With
复制代码

评分

参与人数 1金币 +20 收起 理由
无聊的疯子 + 20 结果正确,第二题还用了两个方法不错不错

查看全部评分

回复

使用道具 举报

发表于 2013-11-12 08:26 | 显示全部楼层
C05:箫风
Sub DataPacket(rgSource As Range, rgDest As Range, bGroupCount As Byte)
'rgSource:源单元格
'rgdest:写入单元格
'数据分组的行数
'-----------过程的声明不得修改--------------
Dim arr
Dim i As Integer, j As Integer, k As Integer
On Error Resume Next
arr = rgSource
If IsArray(arr) Then
    k = UBound(arr) * UBound(arr, 2)
    ReDim arr1(1 To k)
    ReDim arr2(1 To bGroupCount, 1 To Application.WorksheetFunction.RoundUp(k / bGroupCount, 0))
        '以下双层循环将选定区域数据写入一维数组中
        For i = LBound(arr, 2) To UBound(arr, 2)
            For j = LBound(arr) To UBound(arr)
                arr1((i - 1) * UBound(arr) + j) = arr(j, i)
            Next j
        Next i
        '以下双层循环将前面生成的一维数组中的数据写入新的二维数组中
        For i = LBound(arr2) To UBound(arr2)
            For j = LBound(arr2, 2) To UBound(arr2, 2)
                arr2(i, j) = arr1((i - 1) * UBound(arr2, 2) + j)
            Next j
        Next i
    rgDest.Resize(i - 1, j - 1) = arr2
    Erase arr
    Erase arr1
    Erase arr2
Else
    rgDest = arr
End If
End Sub

Sub 查询天气()

    Dim strDate$
    Dim strUrl$
    Dim strText$
    Dim strFind$
    Dim i As Long


    strUrl = "http://lishi.tianqi.com/wuhan/"
    '查询的网址

    strDate = Application.InputBox("请输入要查询的年月格式为YYYYMM" & vbCr & vbCr & "例如:201102" & vbCr & vbCr, , Format(DateAdd("m", -1, Now), "yyyymm"), , , , , 2)
    '查询的年月,输入格式为YYYYMM

    Dim httpRequest As Object
    Set httpRequest = CreateObject("Msxml2.XMLHTTP.3.0")
    '创建XMLHTTP对象,获取网页数据
    '网页数据存储在变量 strText 中
    With httpRequest
        .Open "GET", strUrl & strDate & ".html", False
        .send
        strText = .responseText
    End With

    strFind = "武汉" & Left(strDate, 4) & "年" & Val(Right(strDate, 2)) & "月份天气详情"
    '检测输入的日期是否合格
    i = InStr(strText, strFind)
    If i = 0 Then
        MsgBox "查询月份不对"
        Exit Sub
    End If

    '-------------------------代码需完成部分---------------------------
    '上面的代码和声明部分不得修改
    '代码完成部分所需要的变量声明均写在此行下方即可,方便学委评分
    Sheets("作业二结果").Cells.ClearContents
    Dim arr1() As String, arr2() As String, arr3()
    Dim j As Integer
    '以下通过三重SPLIT函数的使用截取网页源数据中所需要的部分
    arr1 = Split(Split(Split(strText, "<ul class=""t1"">")(1), "</div>")(0), "</li>")
    '对截取的源数据进行处理
    ReDim arr2(UBound(arr1) - 1)
    For i = LBound(arr1) To UBound(arr1) - 1
      If i > 0 And i Mod 6 = 0 Then
        arr2(i) = VBA.Left(Split(arr1(i), ">")(4), 10)
      Else
        arr2(i) = Split(arr1(i), ">")(1)
      End If
    Next i
    '将源数据一维数组转换成所需要的二维数组
    ReDim arr3(1 To (UBound(arr2) + 1) / 6, 1 To 6)
    For i = LBound(arr3) To UBound(arr3)
        For j = LBound(arr3, 2) To UBound(arr3, 2)
            arr3(i, j) = arr2((i - 1) * UBound(arr3, 2) + j - 1)
        Next j
    Next i
    '将表题及存放结果的二维数组写入目标工作表相应区域
    Sheets("作业二结果").Range("A1") = strFind
    Sheets("作业二结果").Range("A2").Resize(i - 1, j - 1) = arr3
    '------------------------------------------------------------------
    MsgBox "提取完成"
End Sub

评分

参与人数 1金币 +20 收起 理由
无聊的疯子 + 20 不错不错~~

查看全部评分

回复

使用道具 举报

发表于 2013-11-12 09:10 | 显示全部楼层
本帖最后由 hoogle 于 2013-11-12 09:14 编辑

C09:hoogle
第一题:
  1. Sub DataPacket(rgSource As Range, rgDest As Range, bGroupCount As Byte)
  2. 'rgSource:源单元格
  3. 'rgdest:写入单元格
  4. '数据分组的行数
  5. '-----------过程的声明不得修改--------------
  6. On Error GoTo handle
  7. Dim temp, i, j, T, m, n, arrRes()
  8. n = bGroupCount
  9. temp = rgSource.Areas(1).Value
  10. If Not IsArray(temp) Then
  11.   rgDest = temp
  12.   Exit Sub
  13. ElseIf UBound(temp) Then
  14.     T = UBound(temp, 2)
  15. End If
  16. If rgSource.Areas(1).Count < bGroupCount Then n = rgSource.Areas(1).Count
  17. m = Application.RoundUp(rgSource.Areas(1).Count / n, 0)
  18. ReDim arrRes(1 To n, 1 To m)
  19.     m = 1: n = 0
  20.     For i = 1 To UBound(temp)
  21.             For j = 1 To T
  22.                 If n < UBound(arrRes, 2) Then
  23.                     n = n + 1
  24.                     arrRes(m, n) = temp(i, j)
  25.                 Else
  26.                     m = m + 1: n = 1
  27.                     arrRes(m, n) = temp(i, j)
  28.                 End If
  29.                
  30.             Next
  31.     Next
  32.     rgDest.Resize(UBound(arrRes), UBound(arrRes, 2)) = arrRes
  33. handle:
  34.   T = 1
  35.   Resume Next
  36. End Sub
复制代码
第二题:
  1. Sub 查询天气()

  2.     Dim strDate$
  3.     Dim strUrl$
  4.     Dim strText$
  5.     Dim strFind$
  6.     Dim i As Long


  7.     strUrl = "http://lishi.tianqi.com/wuhan/"
  8.     '查询的网址

  9.     strDate = Application.InputBox("请输入要查询的年月格式为YYYYMM" & vbCr & vbCr & _
  10.       "例如:201102" & vbCr & vbCr, , Format(DateAdd("m", -1, Now), "yyyymm"), , , , _
  11.       , 2)
  12.     '查询的年月,输入格式为YYYYMM

  13.     Dim httpRequest As Object
  14.     Set httpRequest = CreateObject("Msxml2.XMLHTTP.3.0")
  15.     '创建XMLHTTP对象,获取网页数据
  16.     '网页数据存储在变量 strText 中
  17.     With httpRequest
  18.         .Open "GET", strUrl & strDate & ".html", False
  19.         .send
  20.         strText = .responseText
  21.     End With

  22.     strFind = "武汉" & Left(strDate, 4) & "年" & Val(Right(strDate, 2)) & "月份天气详情"
  23.     '检测输入的日期是否合格
  24.     i = InStr(strText, strFind)
  25.     If i = 0 Then
  26.         MsgBox "查询月份不对"
  27.         Exit Sub
  28.     End If

  29.     '-------------------------代码需完成部分---------------------------
  30.     '上面的代码和声明部分不得修改
  31.     '代码完成部分所需要的变量声明均写在此行下方即可,方便学委评分
  32.    
  33.    Dim arrData, arrRes(1 To 33, 1 To 6), temp, j, m, temp2  '定义了一些变量
  34.    m = 1                                                    '初赋值
  35.    arrRes(1, 1) = strFind                                   '这个是输出结果的第一行,也是初赋值
  36.    arrData = Split(strText, "<ul>")                         'split 把网页分数据成数组
  37.    For i = 0 To UBound(arrData)                             '循环
  38.         If InStr(arrData(i), "<div class=""tqtongji2"">") > 0 Then '判断
  39.           temp2 = Split(arrData(i), "<li>")                  '数据放入临时数组
  40.           m = m + 1                                          '这里是结果的表头数据
  41.           arrRes(m, 1) = Split(temp2(10), "<")(0)           '写到结果数组
  42.           arrRes(m, 2) = Split(temp2(11), "<")(0)           '同上
  43.           arrRes(m, 3) = Split(temp2(12), "<")(0)           '同上
  44.           arrRes(m, 4) = Split(temp2(13), "<")(0)           '同上
  45.           arrRes(m, 5) = Split(temp2(14), "<")(0)           '同上
  46.           arrRes(m, 6) = Split(temp2(15), "<")(0)           '同上
  47.         End If                                              '结束判断
  48.         If InStr(arrData(i), "级") > 0 And InStr(arrData(i), "风") Then   '判断是否为所需的数据行
  49.           m = m + 1                                          '写下一行数据
  50.           temp = Split(arrData(i), "<")                      '分割
  51.           arrRes(m, 1) = Split(temp(2), ">")(1)           '写到结果数组
  52.           arrRes(m, 2) = Split(temp(5), ">")(1)           '同上
  53.           arrRes(m, 3) = Split(temp(7), ">")(1)           '同上
  54.           arrRes(m, 4) = Split(temp(9), ">")(1)           '同上
  55.           arrRes(m, 5) = Split(temp(11), ">")(1)           '同上
  56.           arrRes(m, 6) = Split(temp(13), ">")(1)           '同上
  57.         End If                                             '结束判断
  58.    Next                                                    '结束循环
  59.   Sheet4.Range("a1").Resize(33, 6) = arrRes                '往工作表里赋值
  60.   Sheet4.Columns("A:A").NumberFormatLocal = "yyyy/m/d;@"  '设置下日期数据的格式
  61.     '------------------------------------------------------------------
  62.     MsgBox "提取完成"
  63. End Sub
复制代码

评分

参与人数 1金币 +18 收起 理由
无聊的疯子 + 18 作业1没有写注释,扣掉2分

查看全部评分

回复

使用道具 举报

发表于 2013-11-12 10:13 | 显示全部楼层
C06雪舞子 交作业

作业一
  1. Sub 按钮1_Click()
  2.     Dim rgSource As Range
  3.     Dim rgDest As Range
  4.     Dim bGroupCount
  5.    
  6.     On Error Resume Next
  7.     Set rgSource = Application.InputBox("请选择需要分组的单元格区域", "选择", Type:=8)
  8.     '通过对话框选择要分组的单元格区域
  9.     If rgSource Is Nothing Then
  10.         MsgBox "没有选择要分组的单元格区域"
  11.         Exit Sub
  12.     End If


  13.     Set rgDest = Application.InputBox("请选择分组数据写入的位置", "选择", Type:=8)
  14.     '通过对话框选择分组后的数据需写入的单元格
  15.     If rgDest Is Nothing Then
  16.         MsgBox "没有选择要分组的单元格区域"
  17.         Exit Sub
  18.     End If

  19.     bGroupCount = Application.InputBox("请输入要分成的行数(>=1)", "选择", Default:=2, Type:=2)
  20.     '通过对话框输入数据要分成的行数
  21.     If Val(bGroupCount) < 1 Then
  22.         '检测行数的合法性
  23.         MsgBox prompt:="输入的行数不对" & String(2, vbCrLf) & "没有点击确定", Title:="亲,出错了"
  24.         Exit Sub
  25.     End If

  26.     Call DataPacket(rgSource, rgDest, Val(bGroupCount))
  27.     '调用分组过程
  28. End Sub

  29. Sub DataPacket(rgSource As Range, rgDest As Range, bGroupCount As Byte)
  30. 'rgSource:源单元格
  31. 'rgdest:写入单元格
  32. '数据分组的行数
  33. '-----------过程的声明不得修改--------------
  34. Dim arr, brr(), ar, h%, k%, cl%, rw%, i%, j%
  35. If rgSource.Count = 1 Then rgDest = rgSource.Value: Exit Sub  '处理单个格格
  36.     arr = rgSource                              '建立源数组
  37.     k = UBound(arr) * UBound(arr, 2)
  38.     h = Val(bGroupCount)
  39.     cl = Int(k / h) - (k / h > Int(k / h))      '计算目标数组列
  40.     rw = Int(k / cl) - (k / cl > Int(k / cl))   '计算目标数组行
  41.     ReDim brr(1 To rw, 1 To cl)                 '重新定义目标数组
  42.     i = 1
  43.         For Each ar In arr
  44.             j = j + 1
  45.             brr(i, j) = ar                       '源值赋目标数组
  46.             If j = cl Then j = 0: i = i + 1
  47.         Next
  48.     rgDest.Resize(rw, cl) = brr                  '写入单元格
  49. End Sub
复制代码
作业二
  1. Sub 查询天气()

  2.     Dim strDate$
  3.     Dim strUrl$
  4.     Dim strText$
  5.     Dim strFind$
  6.     Dim i As Long
  7.    

  8.     strUrl = "http://lishi.tianqi.com/wuhan/"
  9.     '查询的网址

  10.     strDate = Application.InputBox("请输入要查询的年月格式为YYYYMM" & vbCr & vbCr & "例如:201102" & vbCr & vbCr, , Format(DateAdd("m", -1, Now), "yyyymm"), , , , , 2)
  11.     '查询的年月,输入格式为YYYYMM

  12.     Dim httpRequest As Object
  13.     Set httpRequest = CreateObject("Msxml2.XMLHTTP.3.0")
  14.     '创建XMLHTTP对象,获取网页数据
  15.     '网页数据存储在变量 strText 中
  16.     With httpRequest
  17.         .Open "GET", strUrl & strDate & ".html", False
  18.         .send
  19.         strText = .responseText
  20.     End With

  21.     strFind = "武汉" & Left(strDate, 4) & "年" & Val(Right(strDate, 2)) & "月份天气详情"
  22.     '检测输入的日期是否合格
  23.     i = InStr(strText, strFind)
  24.     If i = 0 Then
  25.         MsgBox "查询月份不对"
  26.         Exit Sub
  27.     End If

  28.     '-------------------------代码需完成部分---------------------------
  29.     '上面的代码和声明部分不得修改
  30.     '代码完成部分所需要的变量声明均写在此行下方即可,方便学委评分

  31. Dim brr(1 To 32, 1 To 6), strfx$, reg As Object, mat, m, k%, l%

  32.     Set reg = CreateObject("vbscript.regexp")           '建立正则法则
  33.     strfx = Left(Split(strText, "月份天气详情</h3></div>")(1), InStr(Split(strText, "月份天气详情</h3></div>")(1), "/div>"))
  34.     '截取天气数据(以"月份天气详情</h3></div>"分界,截取split第二段 开始至"/div>"一段数据)
  35.     With reg
  36.          .Global = True
  37.          .Pattern = "[一-龢\d]+[一-龢-\d+~]*(?=</)"     '正则表达式
  38.         k = 1
  39.         Set mat = .Execute(strfx)                       '符合正则表达式的值全部赋给mat
  40.             For Each m In mat                           '分别取出mat值赋给m
  41.                 l = l + 1
  42.                 brr(k, l) = m                           '天气数据赋给结果数组(32行6列)
  43.                 If l = 6 Then l = 0: k = k + 1
  44.             Next
  45.         Sheet4.[a2].CurrentRegion.ClearContents
  46.         Sheet4.[a1] = strFind                           '写标题
  47.         Sheet4.[a2].Resize(32, 6) = brr                 '数组数据写入工作表
  48.     End With

  49.     '------------------------------------------------------------------
  50.     MsgBox "提取完成"
  51. End Sub
复制代码
  1. Sub 查询天气()

  2.     Dim strDate$
  3.     Dim strUrl$
  4.     Dim strText$
  5.     Dim strFind$
  6.     Dim i As Long
  7.    

  8.     strUrl = "http://lishi.tianqi.com/wuhan/"
  9.     '查询的网址

  10.     strDate = Application.InputBox("请输入要查询的年月格式为YYYYMM" & vbCr & vbCr & "例如:201102" & vbCr & vbCr, , Format(DateAdd("m", -1, Now), "yyyymm"), , , , , 2)
  11.     '查询的年月,输入格式为YYYYMM

  12.     Dim httpRequest As Object
  13.     Set httpRequest = CreateObject("Msxml2.XMLHTTP.3.0")
  14.     '创建XMLHTTP对象,获取网页数据
  15.     '网页数据存储在变量 strText 中
  16.     With httpRequest
  17.         .Open "GET", strUrl & strDate & ".html", False
  18.         .send
  19.         strText = .responseText
  20.     End With

  21.     strFind = "武汉" & Left(strDate, 4) & "年" & Val(Right(strDate, 2)) & "月份天气详情"
  22.     '检测输入的日期是否合格
  23.     i = InStr(strText, strFind)
  24.     If i = 0 Then
  25.         MsgBox "查询月份不对"
  26.         Exit Sub
  27.     End If

  28.     '-------------------------代码需完成部分---------------------------
  29.     '上面的代码和声明部分不得修改
  30.     '代码完成部分所需要的变量声明均写在此行下方即可,方便学委评分

  31. Dim arr, crr, brr(0 To 31, 0 To 5), strfx$, m%, k%, l%
  32.     strfx = Left(Split(strText, "月份天气详情</h3></div>")(1), InStr(Split(strText, "月份天气详情</h3></div>")(1), "/div>"))
  33.         '截取天气数据(以"月份天气详情</h3></div>"分界,截取split第二段 开始至"/div>"一段数据)
  34.     arr = Split(strfx, "</ul>")
  35.         '按天数据分段
  36.         For k = 0 To UBound(arr) - 1
  37.         crr = Split(arr(k), "</li>")
  38.             '天气类别数据分段
  39.             For l = 0 To UBound(crr) - 1
  40.                 m = InStr(crr(l), "<li>")
  41.                    '提取数据
  42.                 If l = 0 And Right(crr(l), 1) = ">" Then m = Len(crr(l)) - 17
  43.                    '日期数据处理
  44.                 brr(k, l) = Mid(crr(l), m + 4, 10)
  45.                    '提取后的天气数据存入数组 brr()
  46.             Next
  47.         Next
  48.     Sheet4.[a2].CurrentRegion.ClearContents
  49.     Sheet4.[a1] = strFind                           '写标题
  50.     Sheet4.[a2].Resize(32, 6) = brr                 '数组数据写入工作表
  51.     '------------------------------------------------------------------
  52.     MsgBox "提取完成"
  53. End Sub
复制代码

评分

参与人数 1金币 +20 收起 理由
无聊的疯子 + 20 第二题用了2个解法,不错不错

查看全部评分

回复

使用道具 举报

发表于 2013-11-12 19:37 | 显示全部楼层
C03:hrpotter
  1. Option Explicit

  2. Sub 按钮1_Click()
  3.     Dim rgSource As Range
  4.     Dim rgDest As Range
  5.     Dim bGroupCount, brr

  6.     On Error Resume Next
  7.     Set rgSource = Application.InputBox("请选择需要分组的单元格区域", "选择", Type:=8)
  8.     '通过对话框选择要分组的单元格区域
  9.     If rgSource Is Nothing Then
  10.         MsgBox "没有选择要分组的单元格区域"
  11.         Exit Sub
  12.     End If


  13.     Set rgDest = Application.InputBox("请选择分组数据写入的位置", "选择", Type:=8)
  14.     '通过对话框选择分组后的数据需写入的单元格
  15.     If rgDest Is Nothing Then
  16.         MsgBox "没有选择要分组的单元格区域"
  17.         Exit Sub
  18.     End If

  19.     bGroupCount = Application.InputBox("请输入要分成的行数(>=1)", "选择", Default:=2, Type:=2)
  20.     '通过对话框输入数据要分成的行数
  21.     If Val(bGroupCount) < 1 Then
  22.         '检测行数的合法性
  23.         MsgBox prompt:="输入的行数不对" & String(2, vbCrLf) & "没有点击确定", Title:="亲,出错了"
  24.         Exit Sub
  25.     End If

  26.     Call DataPacket(rgSource, rgDest, Val(bGroupCount))
  27.     '调用分组过程
  28. End Sub

  29. Sub DataPacket(rgSource As Range, rgDest As Range, bGroupCount As Byte)
  30. 'rgSource:源单元格
  31. 'rgdest:写入单元格
  32. '数据分组的行数
  33. '-----------过程的声明不得修改--------------
  34.     Dim arr(), rng As Range, rg As Range                '定义变量
  35.     Dim i As Long, j As Long, k As Long
  36.     Set rng = Range(Split(rgSource.Address, ",")(0))    '当选择的单元格是多重区域时,只考虑第一个区域分组。
  37.     If rng.Count = 1 Then                               '如果选择的单元格为单个单元格时
  38.         rgDest = rng.Value                              '写入单元格直接等于源单元格
  39.         Exit Sub                                        '跳出过程
  40.     End If
  41.     i = -Int(-rng.Count / bGroupCount)                  '计算分行所需的列数
  42.     ReDim arr(1 To bGroupCount, 1 To i)                 '重新定义结果数组
  43.     For Each rg In rng                                  '将源单元格数据依次写入结果数组
  44.         i = Int(k / UBound(arr, 2)) + 1
  45.         j = k Mod UBound(arr, 2) + 1
  46.         arr(i, j) = rg.Value
  47.         k = k + 1
  48.     Next
  49.     rgDest.Resize(UBound(arr), UBound(arr, 2)) = arr    '将结果数组写入要求位置
  50. End Sub

  51. Sub 查询天气()

  52.     Dim strDate$
  53.     Dim strUrl$
  54.     Dim strText$
  55.     Dim strFind$
  56.     Dim i As Long


  57.     strUrl = "http://lishi.tianqi.com/wuhan/"
  58.     '查询的网址

  59.     strDate = Application.InputBox("请输入要查询的年月格式为YYYYMM" & vbCr & vbCr & "例如:201102" & vbCr & vbCr, , Format(DateAdd("m", -1, Now), "yyyymm"), , , , , 2)
  60.     '查询的年月,输入格式为YYYYMM

  61.     Dim httpRequest As Object
  62.     Set httpRequest = CreateObject("Msxml2.XMLHTTP.3.0")
  63.     '创建XMLHTTP对象,获取网页数据
  64.     '网页数据存储在变量 strText 中
  65.     With httpRequest
  66.         .Open "GET", strUrl & strDate & ".html", False
  67.         .send
  68.         strText = .responseText
  69.     End With

  70.     strFind = "武汉" & Left(strDate, 4) & "年" & Val(Right(strDate, 2)) & "月份天气详情"
  71.     '检测输入的日期是否合格
  72.     i = InStr(strText, strFind)
  73.     If i = 0 Then
  74.         MsgBox "查询月份不对"
  75.         Exit Sub
  76.     End If

  77.     '-------------------------代码需完成部分---------------------------
  78.     '上面的代码和声明部分不得修改
  79.     '代码完成部分所需要的变量声明均写在此行下方即可,方便学委评分
  80.     Dim str As String, arr, brr, crr(), j As Long   '定义变量
  81.     str = Split(strText, "tqtongji2")(1)
  82.     str = Left(str, InStr(str, "</div>") - 1)       '取出天气详情表格所在的文本串
  83.     arr = Split(str, "</ul>")                       '将天气详情表格每行数据分割放入一维数组中
  84.     ReDim crr(1 To UBound(arr), 1 To 6)             '重新定义结果数组
  85.     crr(1, 1) = "日期"                              '将标题放入数组
  86.     crr(1, 2) = "最高气温"
  87.     crr(1, 3) = "最低气温"
  88.     crr(1, 4) = "天气"
  89.     crr(1, 5) = "风向"
  90.     crr(1, 6) = "风力"
  91.     For i = 1 To UBound(arr) - 1
  92.         brr = Split(arr(i), "<li>")
  93.         crr(i + 1, 1) = Mid(brr(1), InStr(brr(1), ">") + 1, 10)  '将日期取出放入数组第一列
  94.         For j = 2 To 6
  95.             crr(i + 1, j) = Left(brr(j), InStr(brr(j), "<") - 1)    '将其他相关数据放入数组的二到六列
  96.         Next
  97.     Next
  98.     With Sheet4
  99.         .Range("a1:f33").ClearContents                           '清空结果表原有数据
  100.         .Range("a1") = strFind                                   '将结果表标题写入a1单元格
  101.         .Range("a2").Resize(UBound(crr), 6) = crr                '将结果数组写入
  102.     End With
  103.     '------------------------------------------------------------------
  104.     MsgBox "提取完成"
  105. End Sub
复制代码

评分

参与人数 1金币 +20 收起 理由
无聊的疯子 + 20 不错不错,

查看全部评分

回复

使用道具 举报

发表于 2013-11-13 00:53 | 显示全部楼层
   先交一题,愧对老师
Dim arr, arr1, strtext1
   Dim k, i1
   Dim str1, str2
   str1 = "武汉" & Left(strDate, 4) & "年" & Val(Right(strDate, 2)) & "月份天气统计"     '设定截取字段   "武汉2013年10月份天气统计"
   strtext1 = Mid(strText, i, InStr(strText, str1) - i)     '提取表格字段
   
   
   
   strtext1 = Replace(strtext1, Chr(9), "")     '替换提取字符中的空格及表格字符
   strtext1 = Replace(strtext1, Chr(10), "")
   strtext1 = Replace(strtext1, Chr(13), "")
   strtext1 = Replace(strtext1, Chr(32), "")
   strtext1 = Replace(strtext1, "</a>", "")
   str2 = "</li></ul></div><divstyle=""clear:both""></div></div><divclass=""lishicity03""><script>lishicity_index_03();</script></div><divid=""tianqi_stat""class=""box-basem7""><divclass=""box-hd""><h3class=""box-t-l"">"
    strtext1 = Replace(strtext1, str2, "")  '替换提取字段末尾多余字节
   

   arr = Split(strtext1, "</li></ul><ul><li><ahref=""http://wuhan.tianqi.com/")     '将字段拆分成数组
            For i1 = 0 To UBound(arr)                                       '数组ARR循环
                arr1 = Split(arr(i1), "</li><li>")                          '将数组内的元素拆分成日期,最高气温,最低气温,天气,风向,风力
                k = k + 1                                                   '循环将拆分的字段写入表格中
                Sheets("作业二结果").Range("a" & k).Resize(1, 6) = arr1
                Sheets("作业二结果").Range("a" & k) = Right(arr1(0), 10)    '将日期字段提取成年-月-日,去除多余字节
            
            Next
Sheets("作业二结果").Range("a1") = "日期"  '替换第一个数组中的多余字符

评分

参与人数 1金币 +9 收起 理由
无聊的疯子 + 9 最后处理一下,用数组一次写入数据就更好了

查看全部评分

回复

使用道具 举报

发表于 2013-11-13 16:27 | 显示全部楼层
本帖最后由 sayloveyou2010 于 2013-11-13 16:47 编辑

C01:sayloveyou2010
第一题:

  1. Sub DataPacket(rgSource As Range, rgDest As Range, bGroupCount As Byte)
  2. 'rgSource:源单元格
  3. 'rgdest:写入单元格
  4. '数据分组的行数
  5. '-----------过程的声明不得修改--------------
  6.     Dim arr(), Mycol%, brr(), mm, i% '定义相关变量
  7.     If rgSource.Count > 1 Then '如果所选区域不是单个单元格,那么
  8.         arr = rgSource.Value '将选区数据装入数组arr
  9.         Mycol = Application.RoundUp(UBound(arr, 1) * UBound(arr, 2) / bGroupCount, 0) '根据行求出列数
  10.         ReDim brr(1 To bGroupCount, 1 To Mycol) '重新定义结果数组brr
  11.         For Each mm In arr '遍历数据源数组Arr
  12.             i = i + 1 '计数器
  13.             brr(Int((i - 1) / Mycol) + 1, ((i - 1) Mod Mycol) + 1) = mm '将数据源的数据写入结果数组brr
  14.         Next mm
  15.         rgDest.Resize(UBound(brr), UBound(brr, 2)) = brr '读出brr
  16.     Else
  17.         rgDest = rgSource '如果所选区域是单个单元格,则直接读出
  18.     End If
  19.     Erase arr, brr
  20. End Sub
复制代码
第二题:

  1. sub 天气查询()
  2.     Dim arr, brr(), crr(), arr1(), x%, y%, y1%, m%, n%, v, Z% '定义相关变量
  3.     arr = Split(strText, "<li>风力</li>") '以<li>风力</li>将数据源分成两段
  4.     arr = Split(arr(1), "<div style=""clear:both""></div>") '以<div style=""clear:both""></div>切分
  5.     arr = Split(arr(0), ".html"">") '以.html"">切分,找到想要的部分
  6.     ReDim  brr(1 To UBound(arr)) '重新定义数组brr
  7.     ReDim  arr1(1 To UBound(arr)) '重新定义数组arr1
  8.     ReDim  crr(1 To UBound(arr), 1 To 5) '重新定义数组crr
  9.     For x = 1 To UBound(arr) '循环arr
  10.         m = InStr(arr(x), "<") '找到<的位置
  11.         brr(x) = Left(arr(x), m - 1) '找到日期
  12.         arr1(x) = Split(arr(x), "<li>") '以<li>分列
  13.     Next x
  14.     For y = 1 To UBound(arr1)
  15.         For y1 = 1 To 5
  16.             n = InStr(arr1(y)(y1), "<") '找到<的位置
  17.             crr(y, y1) = Left(arr1(y)(y1), n - 1) '将结果写入数组crr
  18.         Next y1
  19.     Next y
  20.     With Worksheets("作业二结果")
  21.         .Cells.ClearContents '清空
  22.         .[A1] = strFind '写标题
  23.         .Range("A2:F2") = Array("日期", "最高气温", "最低气温", "天气", "风向", "风力")
  24.         .Range("A3").Resize(UBound(brr), 1) = Application.Transpose(brr) '读出日期
  25.         .Range("B3").Resize(UBound(crr), UBound(crr, 2)) = crr '读出crr
  26.     End With
  27.     Erase arr, brr, crr, arr1
  28.    '------------------------------------------------------------------
  29.     MsgBox "提取完成"
  30. End Sub
复制代码

评分

参与人数 1金币 +20 收起 理由
无聊的疯子 + 20 结果正确

查看全部评分

回复

使用道具 举报

发表于 2013-11-13 18:11 | 显示全部楼层
C10:sellby
  1. Sub DataPacket(rgSource As Range, rgDest As Range, bGroupCount As Byte)
  2. 'rgSource:源单元格
  3. 'rgdest:写入单元格
  4. '数据分组的行数
  5. '-----------过程的声明不得修改--------------
  6.     Dim bGroupCol As Byte, i As Byte, j As Byte, n As Byte
  7.     Dim Arr(), rgsArr
  8.     Dim a, Bln As Boolean
  9.    
  10.     bGroupCol = (rgSource.Count - 1) \ bGroupCount + 1 '分组的列数
  11.     ReDim Arr(1 To bGroupCount, 1 To bGroupCol) '声明一个放入分组数据的数组
  12.     '===============
  13.         rgsArr = rgSource.Value '获得数据源第一区域的数据
  14.         
  15.         '=====判断获得的数据是否数组
  16.         If IsArray(rgsArr) Then
  17.             '=====如果是数组,进行遍历
  18.             For Each a In rgsArr
  19.                 '=====对分组数组进行循环,将数据写入分组的数组内
  20.                 For i = 1 To bGroupCount
  21.                     For j = 1 To bGroupCol
  22.                         If IsEmpty(Arr(i, j)) Then
  23.                             Arr(i, j) = a
  24.                             Bln = True
  25.                             Exit For '写入后跳出循环
  26.                         End If
  27.                         If Bln Then Exit For
  28.                     Next j
  29.                     If Bln Then Exit For
  30.                 Next i
  31.                 Bln = False
  32.             Next
  33.         Else
  34.             '====如果不是数组,直接赋值
  35.             Arr(1, 1) = rgsArr
  36.         End If
  37.         
  38.     '=====写入指定单元格
  39.     rgDest.Resize(bGroupCount, bGroupCol) = Arr
  40. End Sub
  41. Sub DataPacket2(rgSource As Range, rgDest As Range, bGroupCount As Byte) '多区域时,全部显示
  42. 'rgSource:源单元格
  43. 'rgdest:写入单元格
  44. '数据分组的行数
  45. '-----------过程的声明不得修改--------------
  46.     Dim bGroupCol As Byte, i As Byte, j As Byte, n As Byte
  47.     Dim Arr(), rgsArr
  48.     Dim a, Bln As Boolean
  49.     bGroupCol = (rgSource.Count - 1) \ bGroupCount + 1 '分组的列数
  50.     ReDim Arr(1 To bGroupCount, 1 To bGroupCol) '声明一个放入分组数据的数组
  51.     '===============
  52.     '对数据源区域进行循环
  53.     For n = 1 To rgSource.Areas.Count
  54.         rgsArr = rgSource.Areas.item(n) '获得数据源一区域的数据
  55.         '=====判断获得的数据是否数组
  56.         If IsArray(rgsArr) Then
  57.             '=====如果是数组,进行遍历
  58.             For Each a In rgsArr
  59.                 '=====对分组数组进行循环,将数据写入分组的数组内
  60.                 For i = 1 To bGroupCount
  61.                     For j = 1 To bGroupCol
  62.                         If IsEmpty(Arr(i, j)) Then
  63.                             Arr(i, j) = a
  64.                             Bln = True
  65.                             Exit For '写入后跳出循环
  66.                         End If
  67.                         If Bln Then Exit For
  68.                     Next j
  69.                     If Bln Then Exit For
  70.                 Next i
  71.                 Bln = False
  72.             Next
  73.         Else
  74.             '====如果不是数组,直接赋值
  75.             Arr(1, 1) = rgsArr
  76.         End If
  77.     Next n
  78.     '=====写入指定单元格
  79.     rgDest.Resize(bGroupCount, bGroupCol) = Arr
  80. End Sub

  81. Sub 查询天气()

  82.     Dim strDate$
  83.     Dim strUrl$
  84.     Dim strText$
  85.     Dim strFind$
  86.     Dim i As Long


  87.     strUrl = "http://lishi.tianqi.com/wuhan/"
  88.     '查询的网址

  89.     strDate = Application.InputBox("请输入要查询的年月格式为YYYYMM" & vbCr & vbCr & "例如:201102" & vbCr & vbCr, , Format(DateAdd("m", -1, Now), "yyyymm"), , , , , 2)
  90.     '查询的年月,输入格式为YYYYMM

  91.     Dim httpRequest As Object
  92.     Set httpRequest = CreateObject("Msxml2.XMLHTTP.3.0")
  93.     '创建XMLHTTP对象,获取网页数据
  94.     '网页数据存储在变量 strText 中
  95.     With httpRequest
  96.         .Open "GET", strUrl & strDate & ".html", False
  97.         .send
  98.         strText = .responseText
  99.     End With

  100.     strFind = "武汉" & Left(strDate, 4) & "年" & Val(Right(strDate, 2)) & "月份天气详情"
  101.     '检测输入的日期是否合格
  102.     i = InStr(strText, strFind)
  103.     If i = 0 Then
  104.         MsgBox "查询月份不对"
  105.         Exit Sub
  106.     End If

  107.     '-------------------------代码需完成部分---------------------------
  108.     '上面的代码和声明部分不得修改
  109.     '代码完成部分所需要的变量声明均写在此行下方即可,方便学委评分



  110.     Dim Arr, Brr, tempArr
  111.       Dim dCount As Byte, j&   
  112.       Arr = Split(strText, "<ul class=" & """t1""" & ">") '将代码第一次分列,得到二个元素的数组
  113.     Arr = Split(Arr(1), "</div>", 2) '对第二个元素再进行分列
  114.     Arr = Split(Arr(0), """" & ">")  '对第一个元素进行分列,得到一组天气的原始数组,其中第一个元素为标题,每天的天气数据
  115.    
  116.     dCount = UBound(Arr)
  117.    
  118.      ReDim Brr(0 To dCount, 0 To 5) '声明一个二维数组,用来放天气数据
  119.    
  120.     For i = 0 To dCount '对天气的原始数据进行循环
  121.         tempArr = Split(Arr(i), "<li>") '分列
  122.         For j = 0 To 5 '对分列得到的数据进行循环
  123.             If i = 0 Then
  124.                 Brr(0, j) = Split(tempArr(j + 1), "<")(0) '对标题行分列,取第一个元素
  125.             Else
  126.                 Brr(i, j) = Split(tempArr(j), "<")(0) '对气象数据分列,取第一个元素
  127.             End If
  128.         Next j
  129.     Next i
  130.     With Sheets("作业二结果")
  131.         .Cells.Clear
  132.         .Range("a1") = strFind '写入标题
  133.         .Range("a2").Resize(dCount + 1, 6) = Brr '写入天气详情
  134.     End With
  135.     '------------------------------------------------------------------
  136.     MsgBox "提取完成"
  137. End Sub
复制代码

评分

参与人数 1金币 +20 收起 理由
无聊的疯子 + 20 不错不错

查看全部评分

回复

使用道具 举报

发表于 2013-11-13 19:29 | 显示全部楼层
以为是明后天交作业,时间赶不及了,弄一点是一点。

C04-笨熊猫-作业二.rar

55.93 KB, 下载次数: 5

评分

参与人数 1金币 +9 收起 理由
无聊的疯子 + 9 注释只第一行写了,第二题没做

查看全部评分

回复

使用道具 举报

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

本版积分规则

小黑屋|手机版|Archiver|Excel精英培训 ( 豫ICP备11015029号 )

GMT+8, 2024-5-4 09:52 , Processed in 0.378433 second(s), 24 queries , Gzip On, Yac On.

Powered by Discuz! X3.4

Copyright © 2001-2020, Tencent Cloud.

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