如何摆脱这个VBA编译器错误?无法分配给read_only属性

时间:2015-11-10 01:45:30

标签: excel vba excel-vba

所以我对整个编程事物都是全新的,尤其是涉及到VBA时。我正在尝试制作这份Excel工作表,其中包含库存清单和库存需求库的零件清单,并向我(以及其他同事)发送一封电子邮件,说明库存库存小于或等于库存需求时等于手头库存的需要。以下是我到目前为止(这是通过我已经研究过的其他工作):哦,所以发生的事情是我有点工作,但我收到消息框中的错误,无法弄清楚如何解决它。谢谢你的帮助。

代码:

Sub SendEmailOnPart()

'Move rows to new sheet for either TRUE or FALSE (needs ordered or does not)
  Dim firstrow, lastrow, r, torow As Integer
  Dim fromsheet, tosheet As Worksheet
  firstrow = 1
  Set fromsheet = ActiveSheet
  lastrow = ActiveSheet.Cells(Rows.Count, "H").End(xlUp).Row
  For r = firstrow To lastrow
    If fromsheet.Cells(r, "H") <> "" Then  'skip rows where column H is empty
      On Error GoTo make_new_sheet
      Set tosheet = Worksheets("" & fromsheet.Cells(r, "H"))
      On Error GoTo 0
      GoTo copy_row
make_new_sheet:
      Set tosheet = Worksheets.Add(After:=Worksheets(Worksheets.Count))
      tosheet.Name = fromsheet.Cells(r, "H")
copy_row:
      torow = tosheet.Cells.SpecialCells(xlCellTypeLastCell).Row + 1
      fromsheet.Cells(r, 1).EntireRow.Copy
      tosheet.Cells(torow, 1).PasteSpecial Paste:=xlPasteValues
    End If
  Next r
  Application.CutCopyMode = False
  fromsheet.Activate

' Go to the false worksheet

 Sheet ["FALSE"].Select

 ' Send Email of parts that need ordered

Dim olApp As Outlook.Application
Set olApp = CreateObject("Outlook.Application")

    Dim olMail As Outlook.MailItem
    Set olMail = olApp.CreateItem(olMailItemItem)

    olMail.To = "Josh.Emory@techii.com"
    olMail.Subject = "Part Room"
    olMail.Body = ""
    olMail.Send

' Delete sheet after sending email

Application.DisplayAlerts = False
ActiveSheet.Delete
Application.DisplayAlerts = True

Sheet ["TRUE"].Select

Application.DisplayAlerts = False
ActiveSheet.Delete
Application.DisplayAlerts = True

End Sub

:代码

1 个答案:

答案 0 :(得分:4)

olMailItemItem无效。使用Option Explicit可以帮助您避免这样的拼写错误。

这些行会导致错误:

Sheet ["FALSE"].Select    
Sheet ["TRUE"].Select    

使用Long数据类型而不是整数,Worksheet行超出Integer类型的限制。

每个变量都需要一个类型赋值,Dim i, j, k as Long实际上与Dim i as Variant, j as Variant, k as Long相同。这可能会产生意想不到的副作用。

从样式的角度来看,内联声明多个变量会使代码变得不那么清晰,我也建议不要使用它。

在自己的行上声明每个var,并声明所有变量。使用Option Explicit有助于强制执行后者。

如果你正在使用适当的对象变量(你是),则无需“激活”工作表。您只能使用两个工作表:fromsheettosheet。而不是激活工作表,然后删除活动表,只需直接删除工作表(例如,fromsheet.delete等)

这至少应该让你开始,但正如你从上面的文字墙上看到的那样,它充满了错误,毫无疑问我错过了其中的一些。

Option Explicit
Sub SendEmailOnPart()
'1. Declare all variables on their own line
'2. Use Long data type instead of integer for your counter variables
'3. Put all of your declarations at the top of module, also for readability
'4. Declare ALL variables and use Option Explicit
'5. Get rid of "GoTo" spaghetti code & replace with more proper local Error handler
  Dim firstrow As Long
  Dim lastrow As Long
  Dim r as Long
  Dim torow As Long  
  Dim fromsheet As Worksheet
  Dim tosheet As Worksheet
  Dim olApp As Object 'Outlook.Application 
  Dim olMail as Object 'Outlook.MailItem
  Const olMailItem as Long = 0 'In case of late-binding

  firstrow = 1
  Set fromsheet = ActiveSheet

  'You've assigned ActiveSheet to variable fromsheet, so use it correctly:
  lastrow = fromsheet.Cells(fromsheet.Rows.Count, "H").End(xlUp).Row
  For r = firstrow To lastrow
    If fromsheet.Cells(r, "H") <> "" Then  'skip rows where column H is empty
      On Error Resume Next  '## Not ideal, but this is an OK place to use On Error Resume Next
      Set tosheet = Worksheets("" & fromsheet.Cells(r, "H"))
      If Err.Number <> 0 Then
      '# If there was an error, then create the new sheet
          Set tosheet = Worksheets.Add(After:=Worksheets(Worksheets.Count))
          tosheet.Name = fromsheet.Cells(r, "H")
      End If
      On Error GoTo 0

      torow = tosheet.Cells.SpecialCells(xlCellTypeLastCell).Row + 1

      fromsheet.Cells(r, 1).EntireRow.Copy
      tosheet.Cells(torow, 1).PasteSpecial Paste:=xlPasteValues
    End If
  Next r
  Application.CutCopyMode = False

' Go to the false worksheet
 Sheet["FALSE"].Select  '<~~ This line is going to cause an error  ####

 ' Send Email of parts that need ordered
 Set olApp = CreateObject("Outlook.Application")

    Set olMail = olApp.CreateItem(olMailItem)
    olMail.To = "Josh.Emory@techii.com"
    olMail.Subject = "Part Room"
    olMail.Body = ""
    olMail.Send

End Sub