- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我是初学者,仍然学习有关对MS Excel VBA宏进行编程的知识。我需要社区的帮助,以使用excel上的宏代码解决我的问题。
Sub export_data()
With Application
.ScreenUpdating = False
.Calculation = xlManual 'sometimes excel calculates values before saving files
End With
Dim wsCopy As Worksheet
Dim wsDest As Worksheet
Dim wsDest2 As Worksheet
Dim lCopyLastRow As Long
Dim lDestLastRow As Long
Dim lDestLastRow2 As Long
Dim i As Long
Dim check As Long
'Set variables for copy and destination sheets
Set wsCopy = Workbooks("Book 1.xlsm").Worksheets("Sheet 1")
Set wsDest = Workbooks("Book 2.xls").Worksheets("Sheet 1")
Set wsDest2 = Workbooks("Book 2.xls").Worksheets("Sheet 2")
'1. Find last used row in the copy range based on data in column A
lCopyLastRow = wsCopy.Range("J10:J16").Find(what:="", LookIn:=xlValues).Offset(-1).Row
'2. Find first blank row in the destination range based on data in column A
'Offset property moves down 1 row
lDestLastRow = wsDest.Cells(wsDest.Rows.Count, "J").End(xlUp).Offset(1).Row
lDestLastRow2 = wsDest2.Cells(wsDest2.Rows.Count, "A").End(xlUp).Offset(1).Row
wsCopy.Unprotect "pass"
For i = 10 To 15
If Range("W" & i) <> "" And Range("S" & i) = "" Then
MsgBox "please fill column S"
GoTo protect
ElseIf Range("K" & i) <> "" And Range("X" & i) = "" Then
MsgBox "please fill column X"
GoTo protect
ElseIf Range("W" & i) <> "" And Range("Y" & i) = "" Then
MsgBox "please fill column Y"
GoTo protect
ElseIf Range("W" & i) <> "" And Range("AB" & i) = "" Then
MsgBox "please fill column AB"
GoTo protect
ElseIf Range("W" & i) <> "" And Range("AA" & i) = "" Then
MsgBox "please fill column AA"
GoTo protect
ElseIf Range("W" & i) <> "" And Range("AC" & i) = "" Then
MsgBox "please fill column AC"
GoTo protect
End If
Next i
If Range("W" & 10) <> "" And Range("AD" & 10) = "" Then
MsgBox "please fill column AD"
GoTo protect
End If
If WorksheetFunction.CountIf(wsDest2.Range("B10:B" & lDestLastRow2 - 1), wsCopy.Range("B10")) > 0 Then
check = MsgBox("Double?", _
vbQuestion + vbYesNo, "Double data")
If check = vbYes Then
GoTo export
Else
GoTo protect
End If
Else
GoTo export
End If
If Range("Q5") <> "" Then
check = MsgBox("sure?", _
vbQuestion + vbYesNo, "Manual override")
If check = vbYes Then
GoTo export
Else
GoTo protect
End If
Else
GoTo export
End If
With Application
.ScreenUpdating = True
.Calculation = xlCalculationAutomatic
End With
export:
'3. Copy & Paste Data
For Each cell In wsCopy.Range("AB10:AB15")
cell.Value = UCase(cell.Value)
Next cell
wsDest.Rows(lDestLastRow & ":" & lDestLastRow + lCopyLastRow - 10).Insert shift:=xlShiftDown
wsDest.Range("A" & lDestLastRow) = WorksheetFunction.Max(wsDest.Range("A10:A" & lDestLastRow)) + 1
wsDest.Range("L" & lDestLastRow - 1).Copy
wsDest.Range("L" & lDestLastRow).Resize(lCopyLastRow - 9, 1).PasteSpecial Paste:=xlPasteFormulas
wsDest.Range("R" & lDestLastRow - 1).Copy
wsDest.Range("R" & lDestLastRow).Resize(lCopyLastRow - 9, 1).PasteSpecial Paste:=xlPasteFormulas
wsCopy.Range("B10:K" & lCopyLastRow).Copy
wsDest.Range("B" & lDestLastRow).PasteSpecial Paste:=xlPasteValues
wsCopy.Range("B10:K" & lCopyLastRow).Copy
wsDest.Range("B" & lDestLastRow).PasteSpecial Paste:=xlPasteValues
wsCopy.Range("M10:Q" & lCopyLastRow).Copy
wsDest.Range("M" & lDestLastRow).PasteSpecial Paste:=xlPasteValues
wsCopy.Range("S10:AF" & lCopyLastRow).Copy
wsDest.Range("S" & lDestLastRow).PasteSpecial Paste:=xlPasteValues
For Each cell In wsDest.Range("B" & lDestLastRow & ":B" & lDestLastRow + lCopyLastRow - 10)
cell.Value = wsCopy.Range("B10").Value
Next cell
'COPY DATA for book 2 sheet 2
wsDest2.Rows(lDestLastRow2).Insert shift:=xlShiftDown
wsDest2.Range("A" & lDestLastRow2) = wsDest2.Range("A" & lDestLastRow2 - 1).Value + 1
wsCopy.Range("B10:C10").Copy
wsDest2.Range("B" & lDestLastRow2).PasteSpecial Paste:=xlPasteValues
wsCopy.Range("E10:Z10").Copy
wsDest2.Range("E" & lDestLastRow2).PasteSpecial Paste:=xlPasteValues
wsCopy.Range("AD10:AF10").Copy
wsDest2.Range("AD" & lDestLastRow2).PasteSpecial Paste:=xlPasteValues
Dim r As Range, tabel As Range, xTabel As Range
Dim x As Integer, xMax As Long
'y As Long, yMax As Long
Dim textTabel As String
Set tabel = wsCopy.Range("d10:d" & lCopyLastRow)
Set r = wsDest2.Range("d" & lDestLastRow2)
xMax = tabel.Rows.Count
For x = 1 To xMax
Set xTabel = tabel.Range(Cells(x, 1), Cells(x, 1))
textTabel = Trim(xTabel.Text)
If x = 1 Then
textTabel = textTabel
'r.Offset(x - 1, 0).ClearContents
Else
textTabel = "& " & textTabel
End If
r = r & textTabel
Next x
Dim r2 As Range, tabel2 As Range, xTabel2 As Range
Dim x2 As Integer, xMax2 As Long
'y As Long, yMax As Long
Dim textTabel2 As String
Set tabel2 = wsCopy.Range("AC10:AC" & lCopyLastRow)
Set r2 = wsDest2.Range("AC" & lDestLastRow2)
xMax2 = tabel2.Rows.Count
For x2 = 1 To xMax2
Set xTabel2 = tabel2.Range(Cells(x2, 1), Cells(x2, 1))
textTabel2 = Trim(xTabel2.Text)
If x2 = 1 Then
textTabel2 = textTabel2
'r.Offset(x - 1, 0).ClearContents
Else
textTabel2 = "& " & textTabel2
End If
r2 = r2 & textTabel2
Next x2
Dim r3 As Range, tabel3 As Range, xTabel3 As Range
Dim x3 As Integer, xMax3 As Long
'y As Long, yMax As Long
Dim textTabel3 As String
Set tabel3 = wsCopy.Range("AA10:AA" & lCopyLastRow)
Set r3 = wsDest2.Range("AA" & lDestLastRow2)
xMax3 = tabel3.Rows.Count
For x3 = 1 To xMax3
Set xTabel3 = tabel3.Range(Cells(x3, 1), Cells(x3, 1))
textTabel3 = Trim(xTabel3.Text)
If x3 = 1 Then
textTabel3 = textTabel3
'r.Offset(x - 1, 0).ClearContents
Else
textTabel3 = "& " & textTabel3
End If
r3 = r3 & textTabel3
Next x3
Dim r4 As Range, tabel4 As Range, xTabel4 As Range
Dim x4 As Integer, xMax4 As Long
'y As Long, yMax As Long
Dim textTabel4 As String
Set tabel4 = wsCopy.Range("AB10:AB" & lCopyLastRow)
Set r4 = wsDest2.Range("AB" & lDestLastRow2)
xMax4 = tabel4.Rows.Count
For x4 = 1 To xMax4
Set xTabel4 = tabel4.Range(Cells(x4, 1), Cells(x4, 1))
textTabel4 = Trim(xTabel4.Text)
If x4 = 1 Then
textTabel4 = textTabel4
'r.Offset(x - 1, 0).ClearContents
Else
textTabel4 = "& " & textTabel4
End If
r4 = r4 & textTabel4
Next x4
'Optional - Select the destination sheet
wsDest.Activate
GoTo protect
protect:
wsCopy.protect "pass", _
AllowFormattingCells:=True, _
DrawingObjects:=True, _
contents:=True, _
Scenarios:=True
Workbooks("Book 2.xls").Save
Exit Sub
End Sub
最佳答案
首先最简单的事情:
如果您打算进行VBA开发,请研究Rubberduckvba.com。它是一个外接程序,可以使编码容易得多,并且可以教您很多您不知道的知识。全面披露我是该小组的重要成员。Option Explicit
没有显示在您的代码中。另外,因为您的导出代码中有未声明的变量cell
,所以我假设您默认未打开该变量。在顶部工具>选项>编辑器选项卡>代码设置组>要求变量声明的菜单下,选中该框。这要求您具有Dim cell As Range
才能使用变量。启用该选项后,在运行代码之前,将得到未定义的变量的编译错误。这似乎不太重要,但是请打开此选项,因为以后可以避免头痛。
您正在使用check
作为消息框结果。不要将其声明为Long
,而是在键入Dim check As VbMsgBoxResult
时将其声明为check=
,这样您将获得智能感知和可用的枚举值。
您已将""
用作空字符串的占位符。请改用vbNullString
。这是一个内置常数,可以让您知道此检查是有意的。这是因为""
可能是或可能是具有值"CheckValue"
的字符串,该字符串中的单词已删除,仅留下了空引号。 vbNullString
是明确的。
我留下了大多数变量名,因此您可以更轻松地跟随我进行的重构。请注意,变量r,x,xMax不会提供有关其用途的任何有用信息。使用描述性的变量名。将来你会谢谢你的。描述性变量使代码可以自我记录,并且更易于阅读。
注释。评论可能是某些人的热门话题。我发现描述性变量需要的代码更少。代码本身应说明正在做什么。您的评论“'1.查找上次使用的行...”完全是在说一遍。 lastRowInCopyArea = copyWorksheet.Range().FooBar.Row
已经在说了。保存注释,说明执行某项操作的原因。从代码本身应该清楚什么。
不需要匈牙利表示法(HN)。集成开发环境(IDE)可以从菜单“编辑”>“快速信息Ctrl + I”中告诉您变量的类型。带有字母的类型会抑制可读性,并且是先前编码习惯的遗留物。好的变量名将自行修复很多此类问题。
您可以在导出部分的开头使用类型化的UCase$()
函数而不是通用的UCase()
函数,因为您正在处理字符串。
您正在隐式使用事物。您的Range(Foo)
隐式访问您所在的活动工作表。要查看此右键,请单击“范围”一词以打开上下文菜单,然后选择“定义”。
当您执行此操作时,您可能会看到一个对话框,指出“由于隐藏而无法跳转到'范围'”,现在在其下显示Object Browser(绿色)。单击确定关闭对话框。在“类”(红色)或“成员”(蓝色)窗格区域中右键单击,然后从上下文菜单中选择“显示隐藏的成员”。
通过单击右上角的内部关闭按钮关闭对象浏览器,或使用Ctrl + F4。现在将显示您的代码窗口。右键单击“范围”一词,再次打开上下文菜单,然后选择“显示定义”。您将被带到隐藏的Global类和Range成员。
红色框显示灰色的类名称Global
通常是隐藏的,而Range
成员是所访问的内容。为避免这种隐式访问,如果您确实要访问活动表,请使用工作表或ActiveSheet.Range(Foo)
完全限定范围。再次这样做是明确的,表明它是有意的。
我们有Range(Foo)
的左侧,现在另一侧呢?您还将隐式访问默认属性。您如何解决?在上图中,橙色框内的单词Range为绿色,表示它是链接。单击它,您将进入“类”窗格中的“范围”,如下所示。 Range对象具有可以访问的成员,即Methods(执行操作的对象)或Properties(有关范围的信息)。
“成员”窗格显示了您可以访问的这些成员。在“成员”窗格中向下滚动,直到显示_Default
成员。当您不包括IE访问Range(Foo)
的成员时,您就是在访问_Default
成员。由于您正在检查单元格的值,因此请使用Range(Foo).Value2
限定您的成员访问权限。
您的循环可以并且应该被合并。进行第一个循环并将其与其他循环进行比较。每当您复制/粘贴并将数字标识符添加到变量中时,您就会感觉到代码的味道。每一行的起始行均为10,只有该列会变化。
Dim r As Range, tabel As Range, xTabel As Range
Dim x As Integer, xMax As Long
'y As Long, yMax As Long
Dim textTabel As String
Set tabel = wsCopy.Range("d10:d" & lCopyLastRow)
Set r = wsDest2.Range("d" & lDestLastRow2)
xMax = tabel.Rows.Count
For x = 1 To xMax
Set xTabel = tabel.Range(Cells(x, 1), Cells(x, 1))
textTabel = Trim(xTabel.Text)
If x = 1 Then
textTabel = textTabel
'r.Offset(x - 1, 0).ClearContents
Else
textTabel = "& " & textTabel
End If
r = r & textTabel
Next x
ConcatenateLabelFrom
开始。我看到您的变量
r
在循环中每次都分配。仅在所有串联完成后,您才需要这样做。请记住,这将是用于目的地的范围。循环的逻辑可以浓缩为
Private Function ConcatenateLabelFrom(ByVal concatenateArea As Range) As String
Dim rowInArea As Integer
For rowInArea = 1 To concatenateArea.Rows.Count
Dim textTabel As String
textTabel = Trim(concatenateArea.Cells(rowInArea).Text)
If rowInArea = 1 Then
textTabel = textTabel
Else
textTabel = textTabel & "& " & textTabel
End If
Next
ConcatenateLabelFrom = textTabel
End Function
wsDest2.Cells(lDestLastRow2, "d").Value2 = ConcatenateLabelFrom( _
wsCopy.Range( _
wsCopy.Cells(10, "d"), _
wsCopy.Cells(lCopyLastRow, "d") _
) _
)
Application.ScreenUpdating/Calculation
属性。
Protect wsCopy, protectBook
调用。出口也可以做类似的事情。
Private Sub Protect(ByVal worksheetToProtect As Worksheet, ByVal workbookToSave As Workbook)
worksheetToProtect.Protect "pass", _
AllowFormattingCells:=True, _
DrawingObjects:=True, _
contents:=True, _
Scenarios:=True
workbookToSave.Save
End Sub
r
的评论吗?这就是其中的一部分。您可以使用
Application.Calculate计算所有打开的工作簿,然后再重新打开ScreenUpdating。与重构GoTo跳转一样,仔细考虑工作簿系列事件的发生方式并相应地进行编码。
关于excel - 停止闪烁/重构用于Excel ScreenUpdating false的代码复制粘贴到另一个工作表上,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55322307/
我正在编写一个应用程序,允许用户创建一个“问卷”,然后向其中添加问题。我正在使用核心数据来存储信息。我创建了一个问卷实体,并与问题实体建立了“一对多”关系。我的问题是,如果要允许用户复制(复制)整个调
有没有办法复制或复制 SharedPreference?或者我需要从一个变量中获取每个变量,然后将它们放入另一个变量中吗? 最佳答案 尝试这样的事情: //sp1 is the shared pref
下面的(A)和(B)有区别吗? (假设 NON ARC,如果重要的话) // --- (A) --- @interface Zoo : NSObject{} @property (copy) Dog
我正在尝试将 mysql SELECT 查询保存到文件中,如下所示: $result = mysqli_query($db,$sql); $out = fopen('tmp/csv.csv', 'w'
我需要创建一个 CVPixelBufferRef 的副本,以便能够使用副本中的值以按位方式操作原始像素缓冲区。我似乎无法使用 CVPixelBufferCreate 或 CVPixelBufferCr
我在 Source 文件夹中有一个 Active wave 录音 wave-file.wav。我需要使用新名称 wave-file-copy.wav 将此文件复制到 Destination 文件夹。
在使用 GNU Autotools 构建的项目中,我有一个脚本需要通过 make 修改以包含安装路径。这是一个小例子: configure.ac: AC_INIT(foobar, 1.0) AC_PR
我想将 SQL 的行复制到同一个表中。但是在我的表中,我有一个“文本”列。 使用此 SQL: CREATE TEMPORARY TABLE produit2 ENGINE=MEMORY SELECT
谁能给我解释一下 df2 = df1 df2 = df1.copy() df3 = df1.copy(deep=False) 我已经尝试了所有选项并执行了以下操作: df1 = pd.DataFram
Hazelcast 是否具有类似于 Ehcache 的复制? http://www.ehcache.org/generated/2.9.0/pdf/Ehcache_Replication_Guide.
我有以下拓扑。一个 Ubuntu 16.04。运行我的全局 MySQL 服务器的 Amazon AWS 上的实例。我想将此服务器用作许多本地主服务器(Windows 机器 MySQL 服务器)的从服务
使用 SQLyog,我正在测试表中是否设置了正确的值。我尝试过 SELECT type_service FROM service WHERE email='test@gmail.com' 因此,只输出
有人可以提供一些关于如何配置 ElasticSearch 进行复制的说明。我在 Windows 中运行 ES,并且了解如果我在同一台服务器上多次运行 bat 文件,则会启动一个单独的 ES 实例,并且
一 点睛 ThreadGroup 复制线程的两个方法。 public int enumerate(Thread list[]) // 会将 ThreadGroup 中的 active 线程全部复制到
一 点睛 ThreadGroup 复制线程组的两个方法。 public int enumerate(ThreadGroup list[]) // 相对于 enumerate(list,true) pu
官方documentation Cassandra 说: Configure the keyspace and create the new datacenter: Use ALTER KEYSPAC
This question already has answers here: How to weight smoothing by arbitrary factor in ggplot2? (2个答
我们有一个表格来表明对各种俱乐部的兴趣。输出将数据记录在 Excel 电子表格中,其中列有他们的首选姓名、姓氏、电子邮件、代词,以及他们感兴趣的俱乐部的相应列中的“1”(下面的模型)。 我们希望为俱乐
This question already has answers here: Closed 8 years ago. Possible Duplicate: In vim, how do I get
如何复制形状及其所在的单元格?当我手动复制时,形状会跟随单元格,但是当我使用宏进行复制时,我会得到除形状之外的所有其他内容。 Cells(sourceRow, sourceColumn).Copy C
我是一名优秀的程序员,十分优秀!