通過excel vba 實現艾賓浩斯遺忘曲線的復習提醒


1、實現原理:

艾賓浩斯seid一個知識點學習后要復習8次后可達到永久記憶(這個還有待驗證。。。),其復習間隔時間分別為1d、2d、4d、7d、15d、30d、90d、180d。

2、實現效果:

在一個sheet【學習清單】里按日期記錄每天的學習內容(如圖1),在另外一個sheet【當日復習清單】里提供日期選擇功能,並根據選擇日期切換顯示當日需要復習的內容(如圖2)。

 

圖1:

 

 圖2:

 

 3、用到的知識點:

3.1 二分查找算法:

隨着記錄的學習內容漸漸多,需要節省查找時間。使用這個算法的前提是每天的學習內容是按日期升序排序的。

3.2 vba返回單元格的3種方式:

sheet1.range("b2:d4");sheet1.cells(3,4);sheet1.[a2:d6]。因為涉及不同sheet表之間的取值,所以需要標明sheet頁名稱。

3.3 返回一列單元格有數據的最后一行:

Worksheets("學習清單").Range("a1048576").End(3).Row

Range("a1048576").End(3) 代表從 a1048576單元格往前查找到的第一個有數據的單元格。
Range("a1048576").End(3).Row 表示A列單元格最下面一個有數據的單元格的行號。

End(3)這個3代表常量 xlup,表示向上搜索。
2003版本后一張Excel工作表,最多可以包括1048576行和16384列。

3.4 vba中實現數值改變單元格后觸發事件:

假設要判斷的值在A1,則代碼為:
Dim oldval
Private Sub Worksheet_Activate()
    oldval = [a1]
End Sub
Private Sub Worksheet_Change(ByVal Target As Range)
    If oldval <> [a1] Then
        oldval = [a1]
        '在此輸入操作代碼
    End If
End Sub

4、全部vba代碼如下:

 1 Dim date_select '選擇的復習日期
 2 Dim array_a(8) '存儲復習間隔,共8個間隔
 3 
 4 Private Sub Worksheet_Activate()
 5     date_select = Worksheets("當日復習清單").[b1]
 6     array_a(8) = 1
 7     array_a(7) = 2
 8     array_a(6) = 4
 9     array_a(5) = 7
10     array_a(4) = 15
11     array_a(3) = 30
12     array_a(2) = 90
13     array_a(1) = 180
14 End Sub
15 Private Sub Worksheet_Change(ByVal Target As Range)
16     If date_select <> Worksheets("當日復習清單").[b1] Then
17         date_select = Worksheets("當日復習清單").[b1]
18         Worksheets("當日復習清單").[a4:d1048576] = ""
19         
20         Dim array_b(8) '存儲所選擇的復習日期對應的學習日期,共8個
21         Dim hang_all, hang_half '學習日期的有數據的最后行號和中間行號
22         Dim find_begin, find_end '查找學習日期時的開始行號和結束行號
23 
24         Dim hang_now '存儲復習內容的長度,每次選擇日期后會更新為0
25         hang_now = 0
26         
27         hang_all = Worksheets("學習清單").Range("a1048576").End(3).Row '返回一列單元格有數據的最后一行
28         hang_half = Int(hang_all / 2)
29         
30         For i = 1 To 8 '計算學習日期
31             array_b(i) = date_select - array_a(i)
32             
33             If Worksheets("學習清單").Cells(hang_half, 1) <= array_b(i) Then '利用二分查找算法提高查找效率
34                 Do While Worksheets("學習清單").Cells(hang_half, 1) = Worksheets("學習清單").Cells(hang_half - 1, 1)
35                     hang_half = hang_half - 1
36                 Loop '解決:中間行號的學習日期和前后日期相等的情況
37                 find_begin = hang_half
38                 find_end = hang_all
39                 Else
40                 Do While Worksheets("學習清單").Cells(hang_half, 1) = Worksheets("學習清單").Cells(hang_half + 1, 1)
41                     hang_half = hang_half + 1
42                 Loop '解決:中間行號的學習日期和前后日期相等的情況
43                 find_begin = 2
44                 find_end = hang_half
45             End If
46             
47             For j = find_begin To find_end '根據學習日期返回復習內容
48                 If Worksheets("學習清單").Cells(j, 1) = array_b(i) Then
49                     hang_now = hang_now + 1
50                     Worksheets("當日復習清單").Cells(hang_now + 3, 1) = hang_now
51                     Worksheets("當日復習清單").Cells(hang_now + 3, 2) = Worksheets("學習清單").Cells(j, 2) '復習內容
52                     Worksheets("當日復習清單").Cells(hang_now + 3, 3) = Worksheets("學習清單").Cells(j, 3) '時長
53                     Worksheets("當日復習清單").Cells(hang_now + 3, 4) = Worksheets("學習清單").Cells(j, 1) '學習日期
54                 End If
55             Next j
56             find_find = j '因為要找的學習日期是升序存儲的,所以查找下一個學習日期時可以把查找的開始行號改為j
57         Next i
58         Dim time_sum
59         time_sum = Application.WorksheetFunction.Sum(Worksheets("當日復習清單").Range("c:c"))
60         Worksheets("當日復習清單").[a2] = "共需復習" & hang_now & "個內容,共需" & time_sum & "分鍾"
61     End If
62 End Sub

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM