【问题标题】:How can I improve my Current Region selector?如何改进我的当前区域选择器?
【发布时间】:2019-06-24 23:01:56
【问题描述】:

我做了一个简单的宏分配给一个热键来选择当前区域,然后删除标题行。问题是我们使用的范围通常充满空白单元格,这会阻止选择器捕获依赖于活动单元格的整个表格。

我想过可能只是创建一个循环,偏移 ActiveCell 并重试,直到它达到非法范围,但我对这种方法有一种不好的感觉。

Sub multieditSelect()
Dim tbl As Range
If ActiveCell.Value = "" Then
    MsgBox "Select a cell with something in it, you bastard"
    Exit Sub
End If
Call startNoUpdates
Set tbl = ActiveCell.CurrentRegion
tbl.Offset(1, 0).Resize(tbl.Rows.Count - 1, _
tbl.Columns.Count).Select
Call endNoUpdates
Selection.Copy
End Sub

有没有办法让它更可靠?

编辑:让我为这个问题添加更多的复杂性/细节......

我们使用数据库和大量编辑记录需要将它们导出到 excel 中,然后将它们复制/粘贴回 Web 界面,因此我们通常使用工作表处理大量不同大小的表像记事本一样存储和修改它们。

我想创建一个 sub 来选择当前区域,而不管它在工作表上的哪个位置,很可能这是粘贴到同一张工作表上的第三个或第四个表。

这使得按最后一列或最后一行太不灵活了。 CurrentRegion 是理想的,如果它不是偶尔无法检测到表...所以我想我需要构建自己的 CurrentRegion 版本来克服它的缺点。

Edit2:我想出了一个懒惰的解决方案。 由于这些表总是有一个标题,我只会让 activecell 偏移直到它碰到一些东西,如果一个空列是起点,希望这将是标题。

我认为如果桌子中间有一袋被空单元格包围的单元格,这仍然是不可靠的。

Sub multieditSelect2()
Dim tbl As Range
On Error GoTo errmsg
startNoUpdates
Do While ActiveCell.Value = ""
    ActiveCell.Offset(-1, 0).Activate
Loop
startNoUpdates
Set tbl = ActiveCell.CurrentRegion
tbl.Offset(1, 0).Resize(tbl.Rows.Count - 1, _
tbl.Columns.Count).Select
endNoUpdates
Selection.Copy
Exit Sub

errmsg:
endNoUpdates
errMsgBox = MsgBox("Couldn't find a table!", vbCritical, "Error!")
End Sub

Edit3:这是我的代码调用的示例:

即使在测试区域中的单元格是活动单元格的情况下,我也希望它能够捕获表格......但是如何?

【问题讨论】:

  • 如果可能始终有至少 1 列包含数据(即 ID/Names 列),那么您可以从中获取最后一行,并从标题中获取最后一列。有了它,您可以在不使用CurrentRegion 的情况下构建您的范围。不确定您要通过上述方式实现什么,但通常您应该避免使用.Select / Selection
  • 不确定您要获得什么,但当前区域是由空白行和空白列的任意组合限定的范围。所以根据定义 currentregion 不是你想要的。你能举例说明你有什么和你想要什么吗?
  • 添加了更多细节!
  • 为什么不每次粘贴数据库中的数据时都添加一张新工作表(而不是随处添加数据并希望您的选择不会失败),然后粘贴到“A1”... .那么你总是有一个起点。或者,您应该在粘贴数据时捕获数据的大小,这样做肯定会比...希望您的选择不会失败...
  • 我只是想把一些万无一失的东西放在一起,并且可以在活动单元恰好在桌子上的任何地方使用。我和一群不喜欢快捷键之类复杂的东西的老技术恐惧症患者一起工作,所以想尽可能地完善它。

标签: excel vba


【解决方案1】:

除了我的评论,看看这是否有助于改进你的逻辑(更多细节参见代码中的 cmets):

Sub multieditSelect()

Dim ws As Worksheet
Set ws = ActiveWorkbook.Sheets("Sheet1") 'use a variable for the sheet you want to use

Dim tbl As Range
Dim lRow As Long, lCol As Long

lRow = ws.Cells(Rows.Count, 1).End(xlUp).Row 'last row at column 1
lCol = ws.Cells(1, Columns.Count).End(xlToLeft).Column 'last column at row 1

Set tbl = ws.Range(ws.Cells(2, l), ws.Cells(lRow, lCol)) 'Set the range starting at row 2, column 1, until last row, last col

Call endNoUpdates(tbl) 'pass your range as a parameter if you require this specific range in your other sub

tbl.Copy Destination:=tbl.Offset(0, 20)  'copy 20 columns to the right

'Alternative
ws.Range("W1").Resize(tbl.Rows.Count, tbl.Columns.Count).Value = tbl.Value 'copy values to specific range

End Sub

Sub endNoUpdates(tbl As Range)

    'do something with this range, i.e.:
    Debug.Print tbl.address

End Sub

【讨论】:

    猜你喜欢
    • 2016-09-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-10-13
    • 1970-01-01
    • 1970-01-01
    • 2012-03-17
    相关资源
    最近更新 更多