Board logo

標題: [發問] 請教語法是哪裡出問題? [打印本頁]

作者: skyutm    時間: 2012-8-21 13:15     標題: 請教語法是哪裡出問題?

各位論壇的先進大家好,小弟從學習vba語法以來將近有半個月的時間了,目的是為了設計一套成績計算系統。多虧論壇上多位熱心人士的幫忙,得以解決許多問題。也因為如此,所以有些語法一知半解。有勞各位熱心的大大出手相助。
        小弟最近遇到了一個問題,原本我已經寫好了語法,目的是保護sheet2和sheet3的部分資料,而且前幾天也已經執行成功,可是今天又執行時,卻又出現了錯誤訊息「物件不支援此屬性或方法」而此列反黃   .Selection.Locked = True  老實說,我也不知哪裡出錯,所以來這兒尋求協助,是不是自己有些盲點沒發現。
語法
Sub Worksheet_Activate()
    With Worksheets("期中評量")
    .Range("A1:v2").Select
    .Range("a3", cells(3, 1).End(xlDown)).Select
    .Selection.Locked = True
    .Selection.FormulaHidden = True
    .ActiveSheet.Protect DrawingObjects:=True, Contents:=True, Scenarios:=True
    End With
    End Sub
Sub Worksheet_Deactivate()
    With Worksheets("期中評量")
    .cells.Select
    .Selection.Locked = False
    .Selection.FormulaHidden = True
    .ActiveSheet.Protect DrawingObjects:=True, Contents:=True, Scenarios:=True
    End With
    End Sub
作者: kevin681024    時間: 2012-8-21 14:09

本帖最後由 kevin681024 於 2012-8-21 14:11 編輯

回復 1# skyutm
試試看這樣呢?
  1. Sub Worksheet_Activate()
  2. With Worksheets("期中評量")
  3.     With Union(.Range("A1:V2"), .Range("a3", Cells(3, 1).End(xlDown)))
  4.         .Locked = True
  5.         .FormulaHidden = True
  6.     End With
  7.     .Protect DrawingObjects:=True, Contents:=True, Scenarios:=True
  8. End With
  9. End Sub
複製代碼

作者: GBKEE    時間: 2012-8-21 14:21

本帖最後由 GBKEE 於 2012-8-21 14:25 編輯

回復 2# kevin681024
少一的 .
With Union(.Range("A1:V2"), .Range("a3", .Cells(3, 1).End(xlDown)))

回復 1# skyutm
Selection 屬性   如果是 Application 物件,則傳回現用視窗中的選定物件,如果是 Windows 物件,則傳回指定視窗。
  1. Option Explicit
  2. Sub Worksheet_Activate()
  3.     'Worksheet_Activate: 選擇 **此工作表**的所觸動的事件程序
  4.     '---如有開啟2個視窗-------------------------------------------------
  5.     'MsgBox Windows(2).Selection.Address(, , , 1)  '第二個視窗 使用中儲存格
  6.     '--------------------------------------------------------------------
  7.     MsgBox Selection.Address(, , , 1)         '使用中視窗的 使用中儲存格
  8.    
  9.     'Worksheets("期中評量") 是物件  沒有Selection 這屬性
  10.    
  11.     With Worksheets("期中評量") '如不是**此工作表**
  12.         
  13.         .Activate
  14.         'Activate: 轉到"期中評量"  <--** 因有.Select 不然會出錯
  15.         .Range("A1:v2").Select
  16.         .Range("a3", .Cells(3, 1).End(xlDown)).Select
  17.         '.Selection.Locked = True
  18.         '.Selection.FormulaHidden = True
  19.         Selection.Locked = True
  20.         Selection.FormulaHidden = True
  21.         .Protect DrawingObjects:=True, Contents:=True, Scenarios:=True
  22.         'Protect: 是工作表的方法 前面加上 . 無須指定 ActiveSheet
  23.     End With
  24. End Sub
複製代碼

作者: skyutm    時間: 2012-8-21 21:50

這是我所拜訪過,回應速度最快,態度最熱心的程式論壇,(只因我是用撥號上網56k,所以久久才能上來一次)
作者: skyutm    時間: 2012-8-21 22:35

抱歉!有勞兩位又讓小弟上了一課。原來發現是自己的問題。問題在這裡,為了保護成績單的標題列,所以我寫了(當然是兩位修正的)下列語法:
Option Explicit
Sub Worksheet_Activate()
    With Worksheets("期中成績")
        .Activate
        .Range("b1").Select
        .Range("A3:j3").Select
        .Range("a5", .cells(5, 1).End(xlDown)).Select
        Selection.Locked = True
        Selection.FormulaHidden = True
        .Protect DrawingObjects:=True, Contents:=True, Scenarios:=True, Password:=6323
    End With
End Sub
但是成績單的號碼列必須跟隨基本資料欄(就是填班級、人數就會自動出現所有座號)這時語法就會出現錯誤,因為無法更動。所以我又寫了
Sub Worksheet_Deactivate()
    Worksheets("期中成績").Unprotect
    End Sub
但是這樣的話,一離開這個工作表,訊息列就會問我解開的密碼,所以:1.該怎麼解決呢?2.或是有其他可以保護標題列的語法嗎?(又要麻煩了)
作者: skyutm    時間: 2012-8-21 23:01

真是抱歉!我自己在書上找到答案了。我想改用scrollarea(限制移動範圍語法)
作者: skyutm    時間: 2012-8-26 00:56     標題: 兩個有問題的語法,煩請協助看一下,謝謝!

抱歉又來打擾了,這應該是簡單的語法,可能是我腦袋打結了,所以一直無法執行,構想如下;sheet1(基本設定)是設定科目加權,然後sheet2(期中評量)的標題列,我想秀出各科的加權比例,如國語加權是7,我想秀出國語x7,但是失敗了,不知語法哪裡出問題,再麻煩各位了。   
   
    '月考科目加權'
    Dim chall As Integer, enall As Integer, maall As Integer, naall As Integer, soall As Integer
    chall = Worksheets("基本設定").Range("d2").Value
    enall = Worksheets("基本設定").Range("d3").Value
    maall = Worksheets("基本設定").Range("d4").Value
    naall = Worksheets("基本設定").Range("d5").Value
    soall = Worksheets("基本設定").Range("d6").Value
    Worksheets("期中評量").Range("c2").Value = "國語x" & "chall"
    Worksheets("期中評量").Range("d2").Value = "英語x" & "enall"
    Worksheets("期中評量").Range("e2").Value = "數學x" & "maall"
    Worksheets("期中評量").Range("f2").Value = "自然x" & "naall"
    Worksheets("期中評量").Range("g2").Value = "社會x" & "soall"

(與考人數)是調查有幾人參加考試,所以我想出了下列的語法,看似沒問題,結果執行時,如果開頭第一個資料欄位(如c3、d3)只要是空的,電腦就會顯示找不到儲存格,如果有輸入就不會,哪ㄟ安捏?

    '與考人數'
    Dim aa As Integer, bb As Integer, cc As Integer, dd As Integer, ee As Integer
    aa = Worksheets("期中評量").Range("c3", Range("c3").End(xlDown)).SpecialCells(xlCellTypeConstants, xlNumbers).Count
    bb = Worksheets("期中評量").Range("d3", Range("d3").End(xlDown)).SpecialCells(xlCellTypeConstants, xlNumbers).Count
    cc = Worksheets("期中評量").Range("e3", Range("e3").End(xlDown)).SpecialCells(xlCellTypeConstants, xlNumbers).Count
    dd = Worksheets("期中評量").Range("f3", Range("f3").End(xlDown)).SpecialCells(xlCellTypeConstants, xlNumbers).Count
    ee = Worksheets("期中評量").Range("g3", Range("g3").End(xlDown)).SpecialCells(xlCellTypeConstants, xlNumbers).Count
    Worksheets("期中統計").Range("d4").Value = aa
    Worksheets("期中統計").Range("h4").Value = bb
    Worksheets("期中統計").Range("l4").Value = cc
    Worksheets("期中統計").Range("p4").Value = dd
    Worksheets("期中統計").Range("t4").Value = ee
作者: GBKEE    時間: 2012-8-26 06:12

本帖最後由 GBKEE 於 2012-8-26 06:22 編輯

回復 1# skyutm
SpecialCells(xlCellTypeConstants, xlNumbers)  沒有傳回指定的儲存格會有錯誤
工作表函數 Count  :計算含有數字的儲存格數量
工作表函數 CountA :計算不是空白的儲存格數量
  1. Sub Ex()
  2. Dim chall, aa
  3. chall = Worksheets("基本設定").Range("d2").Value
  4. With Worksheets("期中評量")
  5. .Range("c2").Value = "國語x" & chall
  6. aa = Application.Count(.Range("c3", .Range("c3").End(xlDown)))
  7. End With
  8. Worksheets("期中統計").Range("d4").Value = aa
  9. End Sub
複製代碼

作者: skyutm    時間: 2012-8-26 07:35

回復 8# GBKEE
原來版主也是早起的鳥兒,再次感謝。不過小弟還是有些疑問想提出:1.dim chall,aa 這兒是不是省略了什麼?書上說要定義變數2.application後面所加的函數是不是excel工作表使用的函數?
作者: GBKEE    時間: 2012-8-26 07:58

本帖最後由 GBKEE 於 2012-8-27 06:04 編輯

回復 9# skyutm
Dim  變數  As  型態(或 物件)   (沒有指明就是  Variants型態)
並非所有工作表函數皆可用於VBA
圖中可選用V BA可用之工作表函數

[attach]12295[/attach]

上圖 須有此設定

[attach]12296[/attach]
作者: skyutm    時間: 2012-8-26 21:57

回復 10# GBKEE
感謝版主,我又學了一課。
作者: skyutm    時間: 2012-8-28 21:42

回復 11# skyutm
問題又來了,又有一個解不開的問題,在秀出中文字時,是不是在中文加上""就可以了,然後加上&就可以連結變數,連結一個變數沒問題,可是我要再加第二個變數時,就顯示語法錯誤?不懂,煩請解惑,不勝感激!(我想秀出?年?班)

    '期中成績標題'
    Dim a1, a2
    a1 = Sheets("基本設定").Range("j1").Value
    a2 = Sheets("基本設定").Range("j2").Value
    With Sheets("期中成績")
    .Range("b2").Value = "新路國民小學" & a1&"年"
作者: GBKEE    時間: 2012-8-29 06:34

本帖最後由 GBKEE 於 2012-8-29 06:35 編輯

回復 12# skyutm
& 運算子與前後的字串或變數須空一格
&與前面連接的字串或變數空一格 , 系統會自動在&後空一格
A= B &C                 系統會自動在&後空一格    A= B & C
A=B &C &D &E   系統會只會 在&後空一格    A= B & C & D & E
作者: skyutm    時間: 2012-8-29 19:08

回復 13# GBKEE
感謝版主大大,我又學到了一課。原來只是一個空格之差。從學習vba以來,我的心得就是:別人寫的不算,自己要試過才知道,當頭腦打結時,就要趕快問人,不然會原地打轉!
作者: skyutm    時間: 2012-8-29 23:48

回復 13# GBKEE
抱歉!我又來打擾了。上次有討論過。但是這一次有做修正,卻出現問題
語法如下:
    Dim a11 As Integer, b11 As Integer, c11 As Integer, d11 As Integer, e11 As Integer, f11 As Integer, x11 As Integer
    a11 = b11 = c11 = d11 = e11 = f11 = 0
    myrowcount = Sheets("基本設定").Range("j3").Value + 5
    For x11 = 6 To myrowcount
    Set myrange = Sheets("期中成績").Range("c" & x11)
    Select Case myrange
        Case 100
            a11 = a11 + 1
        Case 90 To 99
            b11 = b11 + 1
        Case 80 To 89
            c11 = c11 + 1
        Case 70 To 79
            d11 = d11 + 1
        Case 60 To 69
            e11 = e11 + 1
        Case 0 To 59
            f11 = f11 + 1
    End Select
    Next x11
    Sheets("期中成績").Range("c108").Value = a11
    Sheets("期中成績").Range("c109").Value = b11
    Sheets("期中成績").Range("c110").Value = c11
    Sheets("期中成績").Range("c111").Value = d11
    Sheets("期中成績").Range("c112").Value = e11
    Sheets("期中成績").Range("c113").Value = f11
修正的地方,是把0~9 10~19 20~29 30~39 40~49 50~59 全部改成0~59 ,問題在於顯示100有幾人的地方會出現-1
作者: luhpro    時間: 2012-8-30 00:15

抱歉!我又來打擾了。上次有討論過。但是這一次有做修正,卻出現問題
語法如下:
    Dim  ...
skyutm 發表於 2012-8-29 23:48


經測試的結果,
若執行過 a11 = b11 = c11 = d11 = e11 = f11 = 0 以後,
a11 固定會被改成 -1
我猜有可能是該指令被解晰成 :
a11= (a11 = 0) (中間的指令都被直接忽略掉了)
會這樣判斷是因為上式若改為 = 1 或 = 5 時,
a11 都會 = 0
而若變更中間參數名稱則那些參數值都不會變. (然而若有非事先定義的參數名稱出現,則會新增該參數出來)

偷懶的方法是在該行後再加上一個 :
a11 = 0

或是將該行改成 :
a11 = 0 : b11 = 0 : c11 = 0 : d11 = 0 : e11 = 0 : f11 = 0

其實不跑該行也是可以的,
因為整數於 Dim 後初值本來就是 0

C 的語法有些是不能在 Basic 上用的,
因為可能會造成非我們所預期的結果.
作者: GBKEE    時間: 2012-8-30 06:45

本帖最後由 GBKEE 於 2012-8-30 07:01 編輯

回復 15# skyutm
這些變數 a11 , b11, c11, d11, e11, f11    Dim   As Integer  程序尚未給值時 都為 0     
這式是多此一舉  a11 = b11 = c11 = d11 = e11 = f11 = 0   傳回   True 或 False   (++=+ ,  +-=- , --=+)
  1. Option Explicit
  2. Sub Ex()
  3. Dim xlBoolean As Boolean
  4. Dim a11 As Integer, b11 As Integer, c11 As Integer, d11 As Integer, e11 As Integer, f11 As Integer
  5. a11 = b11
  6. xlBoolean = a11
  7. Debug.Print xlBoolean & " " & a11 '即時運算視窗終可察看
  8. a11 = b11 = c11
  9. xlBoolean = a11
  10. Debug.Print xlBoolean & " " & a11
  11. a11 = b11 = c11 = d11
  12. xlBoolean = a11
  13. Debug.Print xlBoolean & " " & a11
  14. a11 = b11 = c11 = d11 = e11
  15. xlBoolean = a11
  16. Debug.Print xlBoolean & " " & a11
  17. a11 = b11 = c11 = d11 = e11 = f11
  18. xlBoolean = a11
  19. Debug.Print xlBoolean & " " & a11
  20. a11 = b11 = c11 = d11 = e11 = f11 = 0
  21. xlBoolean = a11
  22. Debug.Print xlBoolean & " " & a11
  23. End Sub
複製代碼

Boolean 資料型態Boolean 變數係以 16 位元( 2 個位元組)數字的形式儲存,但只能是 True 或是 False。Boolean 變數的值不是 True 就是 False ( 在使用 Print 的時候 ),或是 #TRUE# 和 #FALSE# ( 在使用 Write # 的時候 )。使用關鍵字 True 與 False 可將 Boolean 變數指定為這兩個狀態中的一個。
當轉換其他的數值型態為 Boolean 時,0 會轉成 False,而所有其他的值則變成 True。當轉換 Boolean 值為其他的資料型態,時,False 成為 0 ,而 True 成為 -1。

作者: skyutm    時間: 2012-8-30 22:29

回復 17# GBKEE
抱歉又打擾了!因為最近遇到一些結解不開。所以就把語法重新整理一下,因為當初多是靠別人幫忙的,所以有些一知半解,知道版主功力深厚,特來請教一下,如有叼擾,還請見諒。就是這一句
    '期中評量自動輸入座號↓'  (這我知道)
    If Intersect(Target, [J1:J3]) Is Nothing Or [j3] = 0 Then Exit Sub  (我只知道後面:如果沒填資料或j3是0 語法就不執行,但前面不懂)
    ReDim ar(1 To [j3])    (不懂)
    YC = [j1] & Format([j2], "00")   (不懂)
    For i = 1 To [j3]   (瞭解)
    ar(i) = YC & Format(i, "00")  (不懂)
    Next   (瞭解)
    With Sheets("期中評量")    (瞭解)
    .Cells.Rows.Hidden = False  (所有儲存格不隱藏)
    .Cells.Columns.Hidden = False  (所有儲存格不隱藏)
    .[A:A] = ""  (不懂)
    .[a3].Resize([j3], 1) = Application.Transpose(ar)  (不懂)
    .Range("W1", .Cells(1, .Columns.Count)).EntireColumn.Hidden = True(w1到總計幾列都隱藏)
    .Range(.[a3].Offset([j3], 0), .Cells(Rows.Count, 1)).EntireRow.Hidden = True  (不懂)
    .Range("a1").Value = "座號"   (瞭解)
    End With   (瞭解)
    '期中評量自動輸入座號↑'  (瞭解)
作者: GBKEE    時間: 2012-8-31 10:08

回復 18# skyutm
Application.Transpose(ar) 是使用工作表 轉置函數  本帖 10# 已有介紹如何使用工作表
對於不懂的VBA  方法, 屬性, 函數 可多看 VBA中的說明練習它的範例 會進步的
這有整理   新手 VBA 入門常見問題
作者: skyutm    時間: 2012-9-3 20:49

回復 19# GBKEE
報告版主大人,小弟我又遇到瓶頸了,因為在個人成績單輸出方面遇到問題,總成績單已經完成,也就是說資料如下:
座號  姓    名  國語  英語  數學  自然  社會
001  某某某   90      100    85      75     90
但在次頁的個人成績單,我想輸出成為a4頁大小,每頁有8筆資料,我知道最簡單卻麻煩的方法,就是把每筆成績,利用相對應的位置,輸入到個人成績欄位,但是無法控制資料的數量,因為有幾筆成績,是由「基本設定」工作表的班級人數欄控制的,該怎麼辦呢?有沒有其他的構想呢?附上檔案以便參考!
作者: skyutm    時間: 2012-9-4 22:53

抱歉!分享一下,我想出來的語法是這樣,結果試了也沒問題。
Sub Worksheet_Activate()
    '個人成績單標題列↓'
    Dim a, b, c, x, y
    a = Sheets("基本設定").Range("j1").Value
    b = Sheets("基本設定").Range("j2").Value
    c = Sheets("基本設定").Range("j3").Value
    d = Fix(c / 2)
    For i = 0 To d
    x = Sheets("期中評量").Range("a" & 3 + i * 2).Value
    y = Sheets("期中評量").Range("b" & 3 + i * 2).Value
    x1 = Sheets("期中評量").Range("a" & 4 + i * 2).Value
    y1 = Sheets("期中評量").Range("b" & 4 + i * 2).Value
    Sheets("期中成績單").Range("a" & 1 + 12 * i).Value = a & "年" & b & "班 期中評量 成績單" & "(" & x & ")" & y
    Sheets("期中成績單").Range("o" & 1 + 12 * i).Value = a & "年" & b & "班 期中評量 成績單" & "(" & x1 & ")" & y1
    Next i
    '個人成績單標題列↑'
End Sub
作者: luhpro    時間: 2012-9-8 09:29

回復 21# skyutm
善用 With 與 縮排(次一級區塊內的程式左方多幾個空格) 會讓程式更容易閱讀與維護:
  1. Sub Worksheet_Activate()
  2.     '個人成績單標題列↓'
  3.     Dim a, b, c, x, y
  4.    
  5.     With Sheets("基本設定")
  6.       a = .Range("j1").Value
  7.       b = .Range("j2").Value
  8.       c = .Range("j3").Value
  9.     End With
  10.    
  11.     d = Fix(c / 2)
  12.    
  13.     For i = 0 To d
  14.       With Sheets("期中評量")
  15.         x = .Range("a" & 3 + i * 2).Value
  16.         y = .Range("b" & 3 + i * 2).Value
  17.         x1 = .Range("a" & 4 + i * 2).Value
  18.         y1 = .Range("b" & 4 + i * 2).Value
  19.       End With
  20.    
  21.       With Sheets("期中成績單")
  22.         .Range("a" & 1 + 12 * i).Value = a & "年" & b & "班 期中評量 成績單" & "(" & x & ")" & y
  23.         .Range("o" & 1 + 12 * i).Value = a & "年" & b & "班 期中評量 成績單" & "(" & x1 & ")" & y1
  24.       End With
  25.     Next i
  26.     '個人成績單標題列↑'
  27. End Sub
複製代碼

作者: skyutm    時間: 2012-9-8 23:02

回復 22# luhpro


    恩!果然看起來舒服多了
作者: skyutm    時間: 2012-9-8 23:04

請教一下,這算是vba的語法嗎?因為裡面有中文字?這是我從vba專案裡頭複製出來的一部份
Sub Worksheet_Deactivate()
     原年級 = Val(Cells(12, 2))
     新年級 = Val(Cells(1, 18))
     Cells(12, 2) = 新年級
  If 新年級 > 2 And Cells(14, 20) <> 0 Then '強迫3~6年級時,基本工作表 T14儲存格值為0
     Cells(14, 20) = 0
  End If
作者: c_c_lai    時間: 2012-9-9 09:46

本帖最後由 c_c_lai 於 2012-9-9 09:47 編輯

回復 24# skyutm
沒錯!變數或者是函式是可以以中文字來表現的, 譬如:
  1. Option Explicit
  2. Public Ar, 圖表底色
  3. Public Const 資料數區 = "A8:F8"
  4. 'Public Const 圖表底色 = 6

  5. Private Sub Auto_Open()
  6.     Sheets("Omega").Activate
  7.     控制項
  8. End Sub

  9. Private Sub Auto_Close()
  10.     Sheets("Omega").Activate
  11.     控制項
  12.     ThisWorkbook.Save
  13. End Sub

  14. Private Sub 控制項()
  15.     ' ...........
  16. End Sub
複製代碼
是比較易於清晰易懂,但如果該程式用於其它國家地域的話
會造成困擾的 (變成亂碼)。
作者: skyutm    時間: 2012-9-9 22:35

我又學到一招了,我一直以為中文字要加""才行,不然電腦會出現錯誤!




歡迎光臨 麻辣家族討論版版 (http://forum.twbts.com/)