|

楼主 |
发表于 2024-10-11 09:17:11
|
显示全部楼层
这一段Python代码,缺少原VBA代码的以下功能:
1,获取某个sheet的A1单元格的值。我需要这个功能,假设是要获取Py程序同目录下的【工具.xlsm】的sheet【期初数据】,从A列【基金代码】中依次选取;
2,清空工作表中所有单元格内容。我需要清空【工具.xlsm】的sheet【基金净值】。
3,构建基金数据API的Url,这个需要重新加进去。
4,页码计数器+1,准备下一页数据,这个也是需要加进去的。
5,将获取到的数据写入工作表指定区域,即前面提到的sheet【基金净值】。
我再发一下代码,请你逐行比对着改写一下。
- Sub GetUrlData()
- Dim sURL As String, sCode As String, oRegExp As Object, nPage As Long, nPages As Long, nRecords As Long, sResponseText As String
- Dim vData As Variant, nI As Long, nJ As Long, oReg As Object, vFill As Variant, nRow As Double, nCol As Long, ws As Worksheet
-
- ' 关闭屏幕更新和警告,提高代码执行效率
- Application.ScreenUpdating = False
- Application.DisplayAlerts = False
- ' 设置引用到【基金净值】工作表
- Set ws = ThisWorkbook.Worksheets("基金净值")
- ' 获取A1单元格的值,并转换为字符串
- sCode = CStr(ws.Range("A1").Value)
- ' 使用字符串函数Left和String来确保sCode是6位数字
- ' 如果不足6位,则在前面补0
- sCode = String(6 - Len(sCode), "0") & sCode
- ' 创建正则表达式对象,用于字符串匹配
- Set oRegExp = CreateObject("VBSCRIPT.REGEXP")
- ' 设置正则表达式为全局匹配模式
- oRegExp.Global = True
- ' 清空工作表中的所有单元格内容
- Cells.Clear
- ' 初始化页面计数器
- nPage = 1
- ' 构建基金数据API的URL,其中[Page]是页码占位符
- sURL = "http://fund.eastmoney.com/f10/F10DataApi.aspx?type=lsjz&code=" & sCode & "&page=[Page]&per=2000"
- ' 创建XMLHTTP对象,用于发送网络请求
- With CreateObject("msXML2.ServerXMLHttp")
- ' 循环直到所有页面都被请求和处理
- Do While nPage = 1 Or nPage <= nPages
- ' 发送GET请求,替换URL中的[Page]为当前页码
- .Open "GET", Replace(sURL, "[Page]", nPage), True
- ' 发送请求
- .Send
- ' 等待请求完成
- While .ReadyState <> 4
- DoEvents
- Wend
-
- ' 获取响应文本
- sResponseText = .ResponseText
- ' 使用正则表达式解析响应文本
- With oRegExp
- ' 如果还未获取总记录数和总页数,则先进行匹配
- If nPages = 0 Then
- ' 设置正则表达式模式,匹配记录数和页数
- .Pattern = "records[^\d]+(\d+)[^\d]+pages[^\d]+(\d+)"
- ' 执行匹配
- Set oReg = .Execute(sResponseText)
- ' 如果匹配到结果,则提取记录数和页数
- If oReg.Count > 0 Then
- nRecords = Val(oReg(0).SubMatches(0))
- nPages = Val(oReg(0).SubMatches(1))
- End If
- ' 设置正则表达式模式,匹配表头
- .Pattern = "<th([^>]+)?>([^<]+)<"
- ' 执行匹配
- Set oReg = .Execute(sResponseText)
- ' 如果匹配到结果,则初始化数据数组
- If oReg.Count > 0 Then
- ReDim vFill(1 To nRecords + 1, 1 To oReg.Count + 1)
- ' 在数据数组的第1行第1列存储基金代码
- vFill(1, 1) = sCode
- ' 遍历匹配到的表头,存储在数据数组的第1行
- For nCol = 1 To oReg.Count
- vFill(1, nCol + 1) = oReg(nCol - 1).SubMatches(1)
- Next
- End If
- ' 初始化列和行计数器
- nCol = 8
- nRow = 1
- ' 设置正则表达式模式,匹配表格数据
- .Pattern = "<td([^>]+)?>([^<]+)?<"
- End If
- ' 使用正则表达式匹配响应文本中的数据
- Set oReg = .Execute(sResponseText)
- ' 如果匹配到数据
- If oReg.Count > 0 Then
- ' 初始化循环计数器
- nI = 0
- ' 循环遍历匹配到的数据
- Do While nI + 1 < oReg.Count
- ' 获取当前匹配的数据
- sCode = oReg(nI).SubMatches(1)
- ' 检查数据是否是日期格式(假设日期格式为"年-月-日")
- If sCode Like "*-*-*" Then
- ' 如果是日期,则列计数器重置为2,表示日期列
- nCol = 2
- ' 行计数器加1,准备写入下一行的数据
- nRow = nRow + 1
- ' 在数据数组的第1列存储行号(假设第1列用于存储序号)
- vFill(nRow, 1) = nRow - 1
- Else
- ' 如果不是日期,则列计数器加1,准备写入下一列的数据
- nCol = nCol + 1
- End If
- ' 在数据数组中存储当前匹配的数据
- vFill(nRow, nCol) = oReg(nI).SubMatches(1)
- ' 循环计数器加1
- nI = nI + 1
- Loop
- End If
- End With
- ' 页码计数器加1,准备请求下一页数据
- nPage = nPage + 1
- Loop
- End With
-
- ' 将数据数组写入工作表的指定区域
- With [A1].Resize(UBound(vFill), UBound(vFill, 2))
- ' 设置日期列的格式为"年-月-日"
- .Offset(, 1).Resize(, 1).NumberFormatLocal = "yyyy-m-d"
- ' 设置数值列的格式为千分位分隔,保留4位小数
- .Offset(, 2).Resize(, 2).NumberFormatLocal = "_ * #,##0.0000_ ;_ * -#,##0.0000_ ;_ * ""-""????_ ;_ @_ "
- ' 设置百分比列的格式为百分比,保留2位小数
- .Offset(, 4).Resize(, 1).NumberFormatLocal = "0.00%"
- ' 将数据数组的内容写入工作表
- .Formula = vFill
- ' 自动调整列宽以适应内容
- .EntireColumn.AutoFit
- ' 设置水平对齐方式为居中
- .HorizontalAlignment = xlCenter
- ' 设置垂直对齐方式为底部对齐
- .VerticalAlignment = xlBottom
- End With
- ' 重新开启屏幕更新和警告
- Application.ScreenUpdating = True
- Application.DisplayAlerts = True
- End Sub
复制代码 |
|