VBA导致键入的信息转到不正确的工作表

我正在创build一个电子表格,它在第一个工作表(称为数据库,用于类似于数据库)上创build一个引用号并生成一个新的工作表。 然后在新工作表上给出一个参考编号,以便它们连接在一起。 这是通过在用户窗体上按“新build”来完成的。

一旦完成,它应该转到新创build的工作表,并突出显示单元格C7。 完成此操作后,应closures用户窗体并允许用户在新工作表上键入单元格C7,而无需进一步的步骤。

这工作正常,如果我使用F8来逐步通过过程,但是如果我closures代码窗口,并通过该过程作为用户将运行,因为它应该不工作。

C7突出显示,但是一旦你input了它并按下Enter键进入下面的单元格,你input的内容就会完全消失,而且你在新生成的工作表上input的内容实际上是在另一个工作表上input的。

我有一个单独的工作表,其中包含一个button来打开用户窗体,并在新生成的工作表上input的所有数据错误地转到此工作表。

我的代码在下面,都在UserForm的代码中。 我已经在下面留下了ComboBox代码,但这与新工作表的生成无关。 所有这一切都是列出创build的选项卡,以便用户可以从UserForm中select一个工作表,并直接在那里,而不必滚动横向。

我正在使用Excel 2013.我不是一个VBA老兵,所以任何帮助将不胜感激!

谢谢!

Private Sub UserForm_Initialize() Me.ComboBox1.List = Worksheets("Database").Range("A2:A10000").Value End Sub Private Sub CreateNewIdea_Click() CopySheet End Sub Sub CopySheet() Dim LastRow As Long NewReference LastRow = Sheets("Database").Range("A" & Rows.Count).End(xlUp).Row - 1 ReturnValue = LastRow Sheets("Idea Template").Copy After:=Sheets(Sheets.Count) ActiveSheet.Name = LastRow Range("C3").Value = LastRow Me.ComboBox1.List = Worksheets("Database").Range("A2:A10000").Value Range("C7").Select Unload Home End Sub Sub NewReference() Dim LastRow As Long LastRow = Sheets("Database").Range("A" & Rows.Count).End(xlUp).Row Sheets("Database").Cells(LastRow + 1, "A").Value = Sheets("Database").Cells(LastRow, "A").Value + 1 End Sub Private Sub ComboBox1_Change() Worksheets(ComboBox1.Text).Select End Sub 

为了更大的灵活性,我冒昧地编辑和重写了你写的代码。

 Option Explicit 'Forces the variable to be declared, undeclared variables are not allowed Dim DatabaseTable As ListObject 'Makes the variable usable for the entire module Dim Lastrow As Long Private Sub UserForm_Initialize() Set DatabaseTable = ThisWorkbook.Worksheets("Database").ListObjects("References") 'I'm assuming you've formatted the data on the worksheet as a table and named the table "References" Dim i As Long Dim DatabaseRows As Long DatabaseRows = DatabaseTable.ListRows.Count With Me.ComboBox1 .Value = Empty .Clear For i = 1 To DatabaseRows .AddItem DatabaseTable.DataBodyRange(i, 1) Next i End With End Sub Private Sub CreateNewIdea_Click() Set DatabaseTable = ThisWorkbook.Worksheets("Database").ListObjects("References") Call CopySheet End Sub Sub CopySheet() 'Are you calling Sub CopySheet() from other subs besides Private Sub CreateNewIdea_Click()? Call NewReference Dim ReturnValue As Long 'I'm declaring this variable because I'm using the option explicit and that doesn't allow undeclared variables ReturnValue = Lastrow 'Unless ReturnValue is a public variable, it's not doing much here. ThisWorkbook.Worksheets("Idea Template").Copy After:=ThisWorkbook.Worksheets(Worksheets.Count) ThisWorkbook.Worksheets("Idea Template (2)").name = Lastrow ThisWorkbook.Worksheets(CStr(Lastrow)).Cells(1, 3).Value = Lastrow 'Cstr(lastrow) is needed because we want the sheet with the name of the last row, not the nth sheet which is what happens with WorkSheets(Lastrow) as lastrow is a number Call UserForm_Initialize 'Calls the procedure which fills ComboBox1, if the unload home refers to this form, then this line is redundant since the combobox is filled again when the form is initialized. ThisWorkbook.Worksheets(CStr(Lastrow)).Cells(7, 3).Select Unload Home 'If the name of this form is home, you can just 'Unload Me' End Sub Sub NewReference() 'Are you calling Sub NewReference from other subs besides Sub CopySheet()? DatabaseTable.ListRows.Add AlwaysInsert:=False 'Adds a new row to the table on the worksheet "Database" Lastrow = DatabaseTable.ListRows.Count If Lastrow = 2 And IsEmpty(DatabaseTable.DataBodyRange(1, 1)) Then 'This if determines if a row was added while the first row does not contain a reference DatabaseTable.DataBodyRange(Lastrow, 1).Value = 1 'First reference, can be anything you want really DatabaseTable.ListRows(1).Delete 'First row is deleted, otherwise you'd have an empty first row Lastrow = Lastrow - 1 Else DatabaseTable.DataBodyRange(Lastrow, 1).Value = DatabaseTable.DataBodyRange(Lastrow - 1, 1) + 1 End If End Sub Private Sub ComboBox1_Change() If Not Me.ComboBox1 = Empty Then Worksheets(CStr(Me.ComboBox1)).Select End If End Sub 

修改答案

查看@tomjo提供的文档并尝试解决问题后,发现问题是由表单上的button引起的。 使用的button是表单控件而不是ActiveX控件。

一个macros被分配给窗体控件macros被定义在一个模块中,就像你期望的那样。 macros只调用来显示相关的表单。 看起来好像所select的纸张,无论是通过表单上的菜单,还是从表格中创build新的纸张之后,都没有正确地激活,并且input到表单中的信息实际上是以最后手动select的formsinput的。 单步执行代码我发现,通过Debug.Print ThisWorkbook.ActiveSheet.Name, ThisWorkbook.ActiveSheet.ActiveCell.Address通过表单进行select后,正确的工作表和单元格处于活动状态。 我没有发现为什么,当正确的工作表和单元格处于活动状态时,信息被input到最后手动select的工作表和单元格中。

为了validation问题不是由文件造成的,我试图用一个全新的文件来重现问题。 再次出现这样的问题,当屏幕显示正确的表单和单元格被选中时(通过表单select,由模块中的一个子表单调用,由表单控件调用),信息实际上被input到最后手动select的表格和单元格中。

– – 编辑 – –

从function区中的“开发人员”选项卡下的“macros”button运行Showformmacros(调用要显示的窗体),而不是单击具有分配给它的ShowFormmacros的窗体控件button不会创build问题。

—-编辑完—-

然后,我只删除了Form控件,调用了显示窗体的子模块,并在工作表和相关的Sheet模块上创build了一个ActiveX控件(CommandButton):

 Private Sub CommandButton1_Click() Form.Show End Sub 

如果不进一步编辑代码,则没有关于在最后手动select的工作表和单元格上input的信息的其他问题,而不是屏幕显示为选定的工作表和单元格。

编辑文件 (该链接将在有限的时间内生效)