excel - 如果输入的时间段多于 EXCEL-VBA 中的特定值,如何复制最后一个特定数量的值
问题描述
我创建了一个代码,将数据从“选定文件”工作表复制到已创建的名为“数据”的工作表中。该代码允许用户在名为“SelectFile”的单独工作表中输入国家名称(“B2”)、开始日期(“B3”)和结束日期(“B4”)。单击按钮...用户允许选择 excel 文件,然后将数据拉入“数据”工作表,仅包括所选国家/地区的这些日期之间的记录(包括开始日期和结束日期)。所以,我需要一个帮助来添加一个命令,如果用户输入的开始日期和结束日期的时间超过 40 天,VBA 只会复制最后 40 天。
所选文件有许多国家,并附在此链接中https://data.humdata.org/hxlproxy/api/data-preview.csv?url=https%3A%2F%2Fraw.githubusercontent.com%2FCSSEGISandData%2FCOVID-19 %2Fmaster%2Fcsse_covid_19_data%2Fcsse_covid_19_time_series%2Ftime_series_covid19_confirmed_global.csv&filename=time_series_covid19_confirmed_global.csv 输入第一张“SelectFile”图像附在https://i.stack.imgur.com/OQhqN.png
我的代码已附上
Sub Get_Data_From_File()
Dim FileToOpen As Variant
Dim OpenBook As Workbook
Dim countryName As Variant
Dim Lastrow As Long
Dim Lastcolumn As Long
Dim mainFile As Workbook
Dim mainsheet As Worksheet
Dim dataSheet As Worksheet
Dim sht As Worksheet
Dim selectedRow As Long
Dim dSDate As Date, dEDate As Date
Dim lRowStart As Long, lRowEnd As Long
Dim aData() As Variant
Dim i As Long
Dim y As Long
Set mainFile = ThisWorkbook
Sheets("SelectFile").Activate
Set mainsheet = ActiveSheet
countryName = Range("B2").Value
dSDate = Range("B3").Value
dEDate = Range("B4").Value
Sheets("Data").Activate
Set dataSheet = ActiveSheet
Range("A2:G1000").Clear
FileToOpen = Application.GetOpenFilename(Title:="Browse for your File & Import Range", FileFilter:="Excel Files (*.xls*),*xls,(*.csv*),*csv*")
If FileToOpen <> False Then
Set OpenBook = Application.Workbooks.Open(FileToOpen)
Set sht = ActiveSheet
Lastrow = sht.Cells(sht.Rows.Count, "B").End(xlUp).Row
Lastcolumn = sht.Cells(1, sht.Columns.Count).End(xlToLeft).Column
For i = 1 To Lastrow
If Cells(i, 2) = countryName Then
selectedRow = i
Exit For
End If
Next i
For y = 1 To Lastcolumn
If Cells(1, y) = dSDate Then
lRowStart = y
Debug.Print "Start row = " & lRowStart
Exit For
End If
Next y
For y = 1 To Lastcolumn
If Cells(1, y) = dEDate Then
lRowEnd = y
Debug.Print "End row = " & lRowEnd
Exit For
End If
Next y
OpenBook.Sheets(1).Range(Cells(selectedRow, lRowStart), Cells(selectedRow, lRowEnd)).Copy
mainFile.Activate
dataSheet.Activate
Range("C2").Select
Selection.PasteSpecial Paste:=xlPasteAll, Operation:=xlNone, SkipBlanks:= _
False, Transpose:=True
Application.DisplayAlerts = False
OpenBook.Close False
Application.DisplayAlerts = True
End If
Application.ScreenUpdating = True
结束子
解决方案
如果期间超出您的需要,请调整开始日期。
If dtEnd - dtStart > 39 Then
dtStart = dtEnd - 39
ElseIf dtEnd < dtStart Then
dtEnd = dtStart
End If
尽可能使用明确的工作簿和工作表引用来避免使用激活/选择时出现问题。
Option Explicit
Sub Get_Data_From_File()
Dim wb As Workbook, wbSource As Workbook
Dim ws As Worksheet, wsData As Worksheet, wsSource As Worksheet
Dim rngCopy As Range
Dim iLastRow As Long, iLastCol As Integer
Dim iColStart As Integer, iColEnd As Integer, c As Integer, r As Long
Dim sCountry As String, sFileToOpen
Dim dtStart As Date, dtEnd As Date
Set wb = ThisWorkbook
Set ws = wb.Sheets("SelectFile")
Set wsData = wb.Sheets("Data")
With ws
sCountry = Trim(.Range("B2").Value)
dtStart = CDate(.Range("B3"))
dtEnd = CDate(.Range("B4"))
End With
' constrain dates
If dtEnd - dtStart > 39 Then
dtStart = dtEnd - 39
ElseIf dtEnd < dtStart Then
dtEnd = dtStart
End If
' open data file
sFileToOpen = Application.GetOpenFilename( _
Title:="Browse for your File & Import Range", _
FileFilter:="Excel Files (*.xls*),*xls,(*.csv*),*csv*")
If sFileToOpen = "" Then
MsgBox "No file chosen", vbCritical
Exit Sub
End If
Set wbSource = Application.Workbooks.Open(sFileToOpen, False, True) 'read only
Set wsSource = wbSource.Sheets(1)
With wsSource
iLastRow = .Cells(Rows.Count, "B").End(xlUp).Row
iLastCol = .Cells(1, Columns.Count).End(xlToLeft).Column
For c = 1 To iLastCol
If .Cells(1, c) = dtStart Then
iColStart = c
'Debug.Print dtStart, " Col = " & c
End If
If .Cells(1, c) = dtEnd Then
iColEnd = c
'Debug.Print dtEnd, " Col = " & c
End If
Next
End With
' check dates found
If iColStart = 0 Or iColEnd = 0 Then
MsgBox "Date not found '" & dtStart & "' or '" & dtEnd & "'", vbCritical
Exit Sub
End If
'search for country
With wsSource
For r = 1 To iLastRow
If LCase(Trim(Cells(r, 2))) = LCase(sCountry) Then
Set rngCopy = wsSource.Range(.Cells(r, iColStart), .Cells(r, iColEnd))
Exit For
End If
Next
End With
' country not found
If rngCopy Is Nothing Then
MsgBox "Country not found '" & sCountry & "'", vbCritical
Exit Sub
End If
' transpose data into row
wsData.Range("A2:G1000").Clear
rngCopy.Copy
wsData.Range("C2").PasteSpecial Paste:=xlPasteAll, _
Operation:=xlNone, SkipBlanks:=False, Transpose:=True
Application.CutCopyMode = False
wsData.Activate
wsData.Range("C2").Select
MsgBox rngCopy.Columns.Count & " values copied from " & rngCopy.Address & vbCrLf & _
"For " & dtStart & " to " & dtEnd, vbInformation
wbSource.Close False
End Sub
推荐阅读
- c# - 语言总是英文 asp.net core 3.1
- amazon-web-services - 为使用 AWS Fargate 运行的任务分配动态 IP
- amazon-web-services - 我想知道如何使用 aws cli 检查 DatabaseConnections。?
- javascript - 在 JavaScript 中调用类内部的方法
- javascript - 检查数字是否为回文的Javascript函数
- sql - 如何计算重复值的小时数
- javascript - Deviceorientaion 事件在 Android 上的 Chrome 上不起作用
- r - 将 R 函数形式从代码作为字符串应用/映射到新函数体中
- git - git push origin master 缺少或无效的凭据
- ruby - 查找所有子目录和长路径