做题多维表格 - 正确查题方法
本文是 102关于把WPS多维表作为数据源的问题 的操作篇——连上 WPS 之后,具体怎么查题、怎么出题、怎么滚动复习。
配套技能文件:
.workbuddy/skills/fuxi/SKILL.md(复习出题 SOP)
多维表格信息
- 文件 ID:
cosfegN7gkek - 链接: https://www.kdocs.cn/l/cosfegN7gkek
成语学习复习计划文档
- 文件名: 成语学习复习计划.otl
- 链接: https://www.kdocs.cn/l/ci4hCErALzqt
- 说明: 包含成语辨析(第1-43组)、复习计划表、艾宾浩斯复习间隔、每日学习记录
数据表结构
| sheet_id | 表名 | 说明 |
|---|---|---|
| 1 | 题目表 | 存储所有题目(题干、选项、答案、解析等) |
| 4 | 做题记录表 | 每次做题的记录 |
| 5 | 考点表 | 考点分类 |
| 9 | 复习计划表 | 间隔复习计划(全自动公式表) |
复习计划表字段 (sheet_id=9)
| 字段名 | 类型 | 说明 |
|---|---|---|
| 关联题目 | OneWayLink→sheet1 | 链接到题目表 |
| 复习阶段 | Number | 0.01~0.05,对应5轮复习 |
| 本阶段完成时间 | Formula | 自动计算,改阶段时自动刷新为今天 |
| 间隔 | Formula | 自动计算,根据阶段映射 [1,2,4,7,15] |
| 复习时间 | Formula | 自动计算 = 本阶段完成时间 + 间隔 |
| 已毕业 | Checkbox | 打勾后退出待复习队列 |
⚠️ 本阶段完成时间、间隔、复习时间三个字段都是公式字段,自动计算,不要手动修改!
题目表字段 (sheet_id=1)
| 字段名 | 字段ID | 类型 |
|---|---|---|
| 题干 | B | MultiLineText |
| 序号 | C | AutoNumber |
| 选项A | a | MultiLineText |
| 选项B | b | MultiLineText |
| 选项C | c | MultiLineText |
| 选项D | d | MultiLineText |
| 答案 | e | MultiLineText |
| 章节 | g | MultiLineText |
| 解析 | i | MultiLineText |
| 来源 | j | MultiLineText |
| 中类 | Bs | SingleSelect |
| 大类 | Bt | SingleSelect |
⚠️ 关键注意事项
1. 出题时必须从题库读取原始内容
禁止凭记忆或之前读取的数据出题! 每次出题前,必须用以下方法从题库中读取该题目的完整内容。
2. 正确查题方法
方法 A:按序号查题(推荐)
# 1. 生成查询 JSON
cat > /tmp/search_question.json << 'EOF'
{
"file_id": "cosfegN7gkek",
"sheet_id": 1,
"page_size": 10,
"filter": {
"mode": "AND",
"criteria": [
{
"field": "序号",
"op": "Equals",
"values": ["539"]
}
]
}
}
EOF
# 2. 执行查询
export PATH="/root/.local/bin:$PATH"
kdocs-cli dbsheet list_records --file /tmp/search_question.json --compact 2>/dev/null > /tmp/question_result.json
# 3. 解析结果
python3 << 'PYEOF'
import json
with open('/tmp/question_result.json') as f:
data = json.load(f)
records = data.get('data',{}).get('detail',{}).get('records',[])
if not records:
records = data.get('data',{}).get('records',[])
for r in records:
f = r.get('fields','')
if isinstance(f, str):
f = json.loads(f)
print(f"序号: {f.get('序号','')}")
print(f"题干: {f.get('题干','')}")
print(f"A: {f.get('选项A','')}")
print(f"B: {f.get('选项B','')}")
print(f"C: {f.get('选项C','')}")
print(f"D: {f.get('选项D','')}")
print(f"答案: {f.get('答案','')}")
print(f"解析: {f.get('解析','')}")
print(f"中类: {f.get('中类','')}")
print(f"章节: {f.get('章节','')}")
print(f"来源: {f.get('来源','')}")
print(f"记录ID: {r.get('id','')}")
PYEOF
方法 B:按记录 ID 查题(已知 record_id 时)
cat > /tmp/search_by_id.json << 'EOF'
{
"file_id": "cosfegN7gkek",
"sheet_id": 1,
"records": ["Bq3"]
}
EOF
export PATH="/root/.local/bin:$PATH"
kdocs-cli dbsheet records_search --file /tmp/search_by_id.json --compact 2>/dev/null
3. 获取今日待复习题目(每日限5题策略)
3.1 复习策略(必须遵守)
每日做题上限:5题,防止脑力过载。题目按优先级排序,选前5道。
优先级排序规则(从高到低):
- 逾期的低阶段题(阶段0.01/0.02 且 复习时间 < 今天)— 记忆最脆弱,最危险
- 今天到期的低阶段题(阶段0.01/0.02 且 复习时间 = 今天)— 不能拖
- 逾期的高阶段题(阶段0.03/0.04/0.05 且 复习时间 < 今天)— 晚几天影响小
- 今天到期的高阶段题(阶段0.03/0.04/0.05 且 复习时间 = 今天)— 可推迟
原因:低阶段(0.01/0.02)记忆最不牢固,延迟复习影响最大;高阶段(0.04/0.05)记忆已较稳定,晚1-2天影响小。
注意:复习时间字段是公式字段(本阶段完成时间+间隔),无法直接修改。 积压的题会自动排到后续日期,每天只取前5道做,积压自然消化。
3.2 完整查题脚本
# 1. 从复习计划表(sheet_id=9)获取所有未毕业记录
cat > /tmp/query_review.json << 'EOF'
{
"file_id": "cosfegN7gkek",
"sheet_id": 9,
"page_size": 500
}
EOF
export PATH="/root/.local/bin:$PATH"
kdocs-cli dbsheet list_records --file /tmp/query_review.json --compact 2>/dev/null > /tmp/review_records.json
# 2. 筛选待复习题目并按优先级排序,取前5题
python3 << 'PYEOF'
import json
from datetime import datetime
with open('/tmp/review_records.json') as f:
data = json.load(f)
records = data.get('data',{}).get('detail',{}).get('records',[])
if not records:
records = data.get('data',{}).get('records',[])
today = datetime(2026, 8, 18) # ← 改成当天日期
today_str = today.strftime('%Y/%m/%d')
pending = []
for r in records:
f = r.get('fields',{})
if isinstance(f, str):
f = json.loads(f)
if f.get('已毕业', False):
continue
review_date_str = f.get('复习时间', '')
stage = f.get('复习阶段', 0)
try:
review_date = datetime.strptime(review_date_str, '%Y/%m/%d')
except:
continue
is_overdue = review_date < today
is_today = review_date_str == today_str
is_low_stage = stage in [0.01, 0.02]
if is_overdue and is_low_stage:
priority = 1
elif is_today and is_low_stage:
priority = 2
elif is_overdue and not is_low_stage:
priority = 3
elif is_today and not is_low_stage:
priority = 4
else:
continue
q_id = f.get('关联题目', [])
if isinstance(q_id, list) and q_id:
q_id = q_id[0]
elif not isinstance(q_id, str):
q_id = str(q_id)
pending.append({
'review_id': r.get('id',''),
'question_id': q_id,
'stage': stage,
'review_date': review_date_str,
'priority': priority,
'is_overdue': is_overdue
})
pending.sort(key=lambda x: (x['priority'], -x['stage']))
print(f"待复习总数: {len(pending)} 题")
print(f"逾期题数: {sum(1 for p in pending if p['is_overdue'])} 题")
print()
top5 = pending[:5]
print(f"今日做题({len(top5)}题):")
for i, p in enumerate(top5, 1):
overdue_tag = " ⚠逾期" if p['is_overdue'] else ""
print(f" {i}. 阶段{p['stage']} | 复习日期:{p['review_date']}{overdue_tag} | 题目ID:{p['question_id']} | 复习记录ID:{p['review_id']}")
q_ids = [p['question_id'] for p in top5]
print(f"\n题目ID列表: {q_ids}")
print(f"复习记录ID列表: {[p['review_id'] for p in top5]}")
PYEOF
# 3. 用 records_search 批量读取题目内容
cat > /tmp/batch_questions.json << 'EOF'
{
"file_id": "cosfegN7gkek",
"sheet_id": 1,
"records": ["BqI", "BqS", "Bq1"]
}
EOF
export PATH="/root/.local/bin:$PATH"
kdocs-cli dbsheet records_search --file /tmp/batch_questions.json --compact 2>/dev/null > /tmp/batch_result.json
# 4. 解析题目内容并展示
python3 << 'PYEOF'
import json
with open('/tmp/batch_result.json') as f:
data = json.load(f)
records = data.get('data',{}).get('detail',{}).get('records',[])
if not records:
records = data.get('data',{}).get('records',[])
for r in records:
f = r.get('fields','')
if isinstance(f, str):
f = json.loads(f)
print(f"===== 序号 {f.get('序号','')} =====")
print(f"题干: {f.get('题干','')}")
print(f"A: {f.get('选项A','')}")
print(f"B: {f.get('选项B','')}")
print(f"C: {f.get('选项C','')}")
print(f"D: {f.get('选项D','')}")
print(f"答案: {f.get('答案','')}")
print(f"解析: {f.get('解析','')}")
print(f"中类: {f.get('中类','')} | 章节: {f.get('章节','')}")
print(f"记录ID: {r.get('id','')}")
print()
PYEOF
4. 做完题目后更新复习阶段
核心铁律:答对只改"复习阶段",答错什么都不改。
# 做完题目后,只需更新复习阶段,系统会自动计算"本阶段完成时间"和"下次复习时间"
#
# 阶段升级映射:
# 0.01 → 0.02
# 0.02 → 0.03
# 0.03 → 0.04
# 0.04 → 0.05
# 0.05 → 设为已毕业(已毕业=true)
#
# ⚠️ 只更新"复习阶段"字段,不要手动改"本阶段完成时间"和"复习时间",那些是自动计算的
python3 << 'PYEOF'
import json
stage_map = {
0.01: 0.02,
0.02: 0.03,
0.03: 0.04,
0.04: 0.05,
0.05: None
}
review_data = [
{"id": "xxx", "stage": 0.02},
{"id": "yyy", "stage": 0.02}
]
records = []
for item in review_data:
new_stage = stage_map.get(item["stage"], 0.02)
if new_stage is None:
records.append({"id": item["id"], "fields": {"已毕业": True}})
else:
records.append({"id": item["id"], "fields": {"复习阶段": new_stage}})
payload = {
"file_id": "cosfegN7gkek",
"sheet_id": 9,
"records": records
}
with open("/tmp/update_review.json", "w", encoding="utf-8") as f:
json.dump(payload, f, ensure_ascii=False)
PYEOF
export PATH="/root/.local/bin:$PATH"
kdocs-cli dbsheet update_records --file /tmp/update_review.json --compact
⚠️ 做完每道题后必须立即更新阶段,不能等全部做完再更新!否则同一道题可能再次出现在复习队列中。 ⚠️ 只更新"复习阶段"字段,"本阶段完成时间"和"复习时间"是系统自动计算的,不要手动修改!
艾宾浩斯滚动复习模型
| 阶段 | 间隔 | 说明 |
|---|---|---|
| 0.01 | 1天 | 第1轮复习 |
| 0.02 | 2天 | 第2轮复习 |
| 0.03 | 4天 | 第3轮复习 |
| 0.04 | 7天 | 第4轮复习 |
| 0.05 | 15天 | 第5轮复习(完成后毕业) |
- 间隔模型:相对间隔(本次完成日 + 该阶段间隔),非从录入日累加
- 答对:只改
复习阶段升一阶,WPS 自动刷新完成时间=今天、重算间隔与下次复习时间 - 答错:什么都不改,复习时间不变仍 ≤ 之后每天,错题明天自动还在队列再撞
- 毕业:升到 0.05 且答对 → 给
已毕业打勾,退出待复习队列 - 今日待复习口径:
复习时间 ≤ 今天 且 已毕业 ≠ true
出题时的检查清单
- [ ] 从题库读取了题目原始内容(不是凭记忆)
- [ ] 题干完整无误
- [ ] 选项 A/B/C/D 与题库一致
- [ ] 标注了序号、来源、章节
- [ ] 不提前透露答案
常见错误
| 错误 | 原因 | 解决 |
|---|---|---|
| 选项内容与题库不符 | 凭记忆出题 | 每次出题前重新读取 |
| 选项数量不对 | 没读取完整字段 | 检查选项A/B/C/D都有值 |
| 序号与题目不匹配 | 记录ID混淆 | 用序号查询而非记录ID |
| 答案错误 | 同上 | 从题库读取答案字段 |
| 手动改了完成时间 | 不理解公式字段 | 只改复习阶段,其余自动算 |
更新解析到题库
python3 << 'PYEOF'
import json
analysis = "解析内容..."
payload = {
"file_id": "cosfegN7gkek",
"sheet_id": 1,
"records": [
{
"id": "记录ID",
"fields": {
"解析": analysis
}
}
]
}
with open("/tmp/update_analysis.json", "w", encoding="utf-8") as f:
json.dump(payload, f, ensure_ascii=False)
PYEOF
export PATH="/root/.local/bin:$PATH"
kdocs-cli dbsheet update_records --file /tmp/update_analysis.json --compact