| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
共有 779 人关注过本帖
标题:人工智能都错在哪儿啊?请修改一下
只看楼主 加入收藏
jinanshui
Rank: 2
等 级:论坛游民
帖 子:308
专家分:67
注 册:2009-10-6
收藏
 问题点数:0 回复次数:11 
人工智能都错在哪儿啊?请修改一下
vfp环境,字段-学号,前两位为年级,再两位班级,后两位为学号,例如230926,为年级23,班级09,学号26,现在求一个新表字段分别为,学号,姓名,语文,语文年级名次,语文班级名次,......,生物,生物年级名次,生物班级名次,总分,总分年级名次,总分班级名次,
名次采用,假设分数分别为100,100,98,97,90,90,87....,则名次分别为1,1,3,4,5,5,7....
计算名次,尽量不用SELECT 命令,而是构造一个排序函数或取名次的函数。
如果某学生某科没有分数记为0分,
第1次
* ===============================================================
* VFP 终极数组全排位方案 (完全不依赖表记录指针和索引,彻底解决FOF/Exclusive问题)
* ===============================================================
SET SAFETY OFF
SET TALK OFF
SET EXCLUSIVE ON

CLOSE DATA ALL

* 1. 读取原表数据到二维数组
USE cj.dbf
lnCount = RECCOUNT()
IF lnCount = 0
    MESSAGEBOX("原表是空的!", 16, "错误")
    RETURN
ENDIF

* 数组结构:1:原记录号, 2:学号, 3:姓名, 4-9:6科成绩
DIMENSION aSource[lnCount, 9]
COPY TO ARRAY aSource FIELDS RECNO(), 学号, 姓名, 语文, 数学, 外语, 物理, 化学, 生物
USE

* 2. 创建最终结果表 (含所有年级/班级名次列)
CREATE TABLE cj_final ( ;
    学号 C(10), 姓名 C(8), ;
    语文 N(5,1), 语文_年名 N(4,0), 语文_班名 N(4,0), ;
    数学 N(5,1), 数学_年名 N(4,0), 数学_班名 N(4,0), ;
    外语 N(5,1), 外语_年名 N(4,0), 外语_班名 N(4,0), ;
    物理 N(5,1), 物理_年名 N(4,0), 物理_班名 N(4,0), ;
    化学 N(5,1), 化学_年名 N(4,0), 化学_班名 N(4,0), ;
    生物 N(5,1), 生物_年名 N(4,0), 生物_班名 N(4,0), ;
    总分 N(5,1), 总分_年名 N(4,0), 总分_班名 N(4,0) )

* ===============================================================
* 3. 自定义冒泡排序跳号函数 (传入分数数组,返回对应名次数组)
FUNCTION GetJumpRank(arrScores, nTotal)
    DIMENSION arrRanks[nTotal]
    LOCAL i, j, nTemp, nRank, nCount, nLastScore
   
    * 冒泡排序 (降序)
    FOR i = 1 TO nTotal - 1
        FOR j = i + 1 TO nTotal
            IF arrScores[i] < arrScores[j]
                nTemp = arrScores[i]
                arrScores[i] = arrScores[j]
                arrScores[j] = nTemp
            ENDIF
        ENDFOR
    ENDFOR
   
    * 计算1,1,3,4,5,5,7...并列跳号
    nRank = 0
    nCount = 0
    nLastScore = -9999
    FOR i = 1 TO nTotal
        nCount = nCount + 1
        IF arrScores[i] <> nLastScore
            nRank = nCount
        ENDIF
        nLastScore = arrScores[i]
        arrRanks[i] = nRank
    ENDFOR
   
    RETURN arrRanks
ENDFUNC

* ===============================================================
* 4. 主循环:计算并回填名次
DIMENSION arrScores[lnCount], arrRecno[lnCount], arrResult[lnCount, 15] && 存放所有计算结果名次
STORE 0 TO arrResult

FOR i = 1 TO 7 && 外层循环:7个指标(语数外物化生总分)
    * 取出所有学生该项的分数,顺便保存对应原记录号
    FOR j = 1 TO lnCount
        arrRecno[j] = aSource[j, 1] && 记录号回填用
        DO CASE
            CASE i = 1
                arrScores[j] = aSource[j, 4] && 语文
            CASE i = 2
                arrScores[j] = aSource[j, 5] && 数学
            CASE i = 3
                arrScores[j] = aSource[j, 6] && 外语
            CASE i = 4
                arrScores[j] = aSource[j, 7] && 物理
            CASE i = 5
                arrScores[j] = aSource[j, 8] && 化学
            CASE i = 6
                arrScores[j] = aSource[j, 9] && 生物
            CASE i = 7
                * 计算总分:六科相加 (缺考0分直接加即可)
                arrScores[j] = aSource[j, 4] + aSource[j, 5] + aSource[j, 6] + ;
                               aSource[j, 7] + aSource[j, 8] + aSource[j, 9]
        ENDCASE
    ENDFOR
   
    * 调函数,获取名次数组 (注意顺序是排过序的!)
    arrTmpRanks = GetJumpRank(@arrScores, lnCount)
   
    * 核心:把排完序的名次,按原记录号回填到 arrResult 里面!
    FOR j = 1 TO lnCount
        * arrRecno 在第1步提取分数时,和 arrScores 是按 1:1 对应同步的
        * 此时 arrRecno[j] 就是排序后,第j名那个学生的原始记录号
        arrResult[ arrRecno[j] , i ] = arrTmpRanks[j]
    ENDFOR
ENDFOR

* ===============================================================
* 5. 写入最终表 cj_final
FOR j = 1 TO lnCount
    SELECT cj_final
    APPEND BLANK
    REPLACE 学号 WITH aSource[j, 2], 姓名 WITH aSource[j, 3]
    REPLACE 语文 WITH aSource[j, 4], 数学 WITH aSource[j, 5]
    REPLACE 外语 WITH aSource[j, 6], 物理 WITH aSource[j, 7]
    REPLACE 化学 WITH aSource[j, 8], 生物 WITH aSource[j, 9]
    REPLACE 总分 WITH aSource[j,4]+aSource[j,5]+aSource[j,6]+aSource[j,7]+aSource[j,8]+aSource[j,9]
   
    * 填入刚刚算好的七个指标的名次 (1-7 依次对应 语数外物化生总分)
    REPLACE 语文_年名 WITH arrResult[j, 1]
    REPLACE 数学_年名 WITH arrResult[j, 2]
    REPLACE 外语_年名 WITH arrResult[j, 3]
    REPLACE 物理_年名 WITH arrResult[j, 4]
    REPLACE 化学_年名 WITH arrResult[j, 5]
    REPLACE 生物_年名 WITH arrResult[j, 6]
    REPLACE 总分_年名 WITH arrResult[j, 7]
ENDFOR

* ===============================================================
* 6. 展示成果
SELECT cj_final
BROWSE TITLE "最终结果: cj_final (已包含全年级名次,含并列跳号规则)"
? "处理完成!"
SET SAFETY ON


cj.rar (11.82 KB)
搜索更多相关主题的帖子: 语文 REPLACE WITH 学号 总分 
2026-07-31 04:23
jinanshui
Rank: 2
等 级:论坛游民
帖 子:308
专家分:67
注 册:2009-10-6
收藏
得分:0 
第2次

* =============================================================
* 终极全自动版:生成新表 (包含年级名次、班级名次,无路径依赖)
* 运行说明:请在 VFP 命令窗口输入 DO 程序2.prg 并回车
* =============================================================
SET TALK OFF
SET SAFETY OFF
CLOSE DATA ALL

* 1. 检查并加载原表 cj.dbf
IF !FILE("cj.dbf")
    MESSAGEBOX("当前目录下没有找到 cj.dbf 原表!", 16, "错误")
    RETURN
ENDIF

USE cj.dbf EXCLUSIVE
lnCount = RECCOUNT()
IF lnCount = 0
    MESSAGEBOX("原表为空,请检查数据!", 16, "警告")
    RETURN
ENDIF

* 2. 读取原表数据到 二维数组 (彻底脱离表索引影响)
DIMENSION aData[lnCount, 9]
* 【已修复】:RECNO() 必须带括号
COPY TO ARRAY aData FIELDS RECNO(), 学号, 姓名, 语文, 数学, 外语, 物理, 化学, 生物
USE  && 关闭原表

* 3. 创建一个纯净的目标新表 (防止旧表污染)
* 强制删除可能存在的旧 cj_final.dbf,防止报错提示
IF FILE("cj_final.dbf")
    DELETE FILE cj_final.dbf
ENDIF
IF FILE("cj_final.fpt")
    DELETE FILE cj_final.fpt
ENDIF

CREATE TABLE cj_final ( ;
    学号 C(10), 姓名 C(8), ;
    语文 N(5,1), 语文_年名 N(4), 语文_班名 N(4), ;
    数学 N(5,1), 数学_年名 N(4), 数学_班名 N(4), ;
    外语 N(5,1), 外语_年名 N(4), 外语_班名 N(4), ;
    物理 N(5,1), 物理_年名 N(4), 物理_班名 N(4), ;
    化学 N(5,1), 化学_年名 N(4), 化学_班名 N(4), ;
    生物 N(5,1), 生物_年名 N(4), 生物_班名 N(4), ;
    总分 N(5,1), 总分_年名 N(4), 总分_班名 N(4) )

* ------------------------------------------------
* 4. 自定义计算并排跳号名次的函数 (通用)
* ------------------------------------------------
PROCEDURE GetRanking
    PARAMETERS arrScore, arrRecno, arrOutRank, lnTotal
    LOCAL lnI, lnJ, lnTemp, lnRank, lnCount, lnLastScore
   
    * 冒泡排序降序 (分数高在前),并同步移动记录号
    FOR lnI = 1 TO lnTotal - 1
        FOR lnJ = lnI + 1 TO lnTotal
            IF arrScore[lnI] < arrScore[lnJ]
                lnTemp = arrScore[lnI]
                arrScore[lnI] = arrScore[lnJ]
                arrScore[lnJ] = lnTemp
               
                lnTemp = arrRecno[lnI]
                arrRecno[lnI] = arrRecno[lnJ]
                arrRecno[lnJ] = lnTemp
            ENDIF
        ENDFOR
    ENDFOR
   
    * 计算并列跳号: 1,1,3,4,5,5,7...
    lnRank = 0
    lnCount = 0
    lnLastScore = -9999
    FOR lnI = 1 TO lnTotal
        lnCount = lnCount + 1
        IF arrScore[lnI] <> lnLastScore
            lnRank = lnCount
        ENDIF
        lnLastScore = arrScore[lnI]
        arrOutRank[ arrRecno[lnI] ] = lnRank  && 将名次回填到对应的原始记录号位置
    ENDFOR
ENDPROC

* ------------------------------------------------
* 5. 开始内存计算 7 个指标的年级名次
* ------------------------------------------------
DIMENSION arrScore[lnCount], arrRecno[lnCount], arrFinalRank[lnCount]
DIMENSION arrSubjects[7]
arrSubjects[1] = "语文" ; arrSubjects[2] = "数学" ; arrSubjects[3] = "外语"
arrSubjects[4] = "物理" ; arrSubjects[5] = "化学" ; arrSubjects[6] = "生物" ; arrSubjects[7] = "总分"

* 为了后面能直接写表,我们扩展一下 aData 数组,用来在内存中暂存名次
* 第10列~第16列:存放年级名次 (语文~总分)
* 第17列~第23列:存放班级名次 (语文~总分)
DIMENSION aData[lnCount, 24]

FOR lnI = 1 TO 7
    FOR lnJ = 1 TO lnCount
        arrRecno[lnJ] = aData[lnJ, 1]
        DO CASE
            CASE lnI = 1  && 语文
                arrScore[lnJ] = aData[lnJ, 4]
            CASE lnI = 2  && 数学
                arrScore[lnJ] = aData[lnJ, 5]
            CASE lnI = 3  && 外语
                arrScore[lnJ] = aData[lnJ, 6]
            CASE lnI = 4  && 物理
                arrScore[lnJ] = aData[lnJ, 7]
            CASE lnI = 5  && 化学
                arrScore[lnJ] = aData[lnJ, 8]
            CASE lnI = 6  && 生物
                arrScore[lnJ] = aData[lnJ, 9]
            CASE lnI = 7  && 总分
                arrScore[lnJ] = aData[lnJ,4] + aData[lnJ,5] + aData[lnJ,6] + ;
                                 aData[lnJ,7] + aData[lnJ,8] + aData[lnJ,9]
        ENDCASE
    ENDFOR
   
    * 执行排序
    = GetRanking(@arrScore, @arrRecno, @arrFinalRank, lnCount)
   
    * 将年级名次存储到 aData 的扩展列中 (10~16)
    FOR lnJ = 1 TO lnCount
        aData[lnJ, 9 + lnI] = arrFinalRank[ aData[lnJ, 1] ]
    ENDFOR
ENDFOR

* ------------------------------------------------
* 6. 计算 7 个指标的班级名次
* ------------------------------------------------
* 找出所有不重复的班级(学号第3-4位)
DIMENSION arrClassNames[1]
SELECT DISTINCT SUBSTR(学号,3,2) FROM cj INTO ARRAY arrClassNames
lnClassCount = _TALLY

FOR lnI = 1 TO 7 && 对于 7 个科目
    FOR lnJ = 1 TO lnClassCount && 对于每个班级
        lcClass = arrClassNames[lnJ]
        lnClassMember = 0
        
        * 第一步:找出这个班级的学生,把他们的分数和记录号抽出来
        DIMENSION arrClassScore[lnCount], arrClassRec[lnCount]
        STORE 0 TO arrClassScore, arrClassRec
        
        FOR lnK = 1 TO lnCount
            IF SUBSTR(aData[lnK, 2], 3, 2) == lcClass
                lnClassMember = lnClassMember + 1
                arrClassRec[lnClassMember] = aData[lnK, 1]
                DO CASE
                    CASE lnI = 1:  arrClassScore[lnClassMember] = aData[lnK, 4]
                    CASE lnI = 2:  arrClassScore[lnClassMember] = aData[lnK, 5]
                    CASE lnI = 3:  arrClassScore[lnClassMember] = aData[lnK, 6]
                    CASE lnI = 4:  arrClassScore[lnClassMember] = aData[lnK, 7]
                    CASE lnI = 5:  arrClassScore[lnClassMember] = aData[lnK, 8]
                    CASE lnI = 6:  arrClassScore[lnClassMember] = aData[lnK, 9]
                    CASE lnI = 7:  arrClassScore[lnClassMember] = aData[lnK,4] + aData[lnK,5] + aData[lnK,6] + aData[lnK,7] + aData[lnK,8] + aData[lnK,9]
                ENDCASE
            ENDIF
        ENDFOR
        
        * 第二步:如果班级有人,就排序并算出名次
        IF lnClassMember > 0
            DIMENSION arrClassRank[lnCount]
            STORE 0 TO arrClassRank
            = GetRanking(@arrClassScore, @arrClassRec, @arrClassRank, lnClassMember)
            
            * 第三步:将算出的班级名次,写回主数组 aData 的扩展列中 (17~23)
            FOR lnK = 1 TO lnCount
                IF SUBSTR(aData[lnK, 2], 3, 2) == lcClass
                    aData[lnK, 16 + lnI] = arrClassRank[ aData[lnK, 1] ]
                ENDIF
            ENDFOR
        ENDIF
    ENDFOR
ENDFOR

* ------------------------------------------------
* 7. 将内存里的最终数据,一次性写入物理表 cj_final
* ------------------------------------------------
SELECT cj_final
FOR lnJ = 1 TO lnCount
    APPEND BLANK
    REPLACE 学号 WITH aData[lnJ, 2]
    REPLACE 姓名 WITH aData[lnJ, 3]
    REPLACE 语文 WITH aData[lnJ, 4]
    REPLACE 数学 WITH aData[lnJ, 5]
    REPLACE 外语 WITH aData[lnJ, 6]
    REPLACE 物理 WITH aData[lnJ, 7]
    REPLACE 化学 WITH aData[lnJ, 8]
    REPLACE 生物 WITH aData[lnJ, 9]
    REPLACE 总分 WITH aData[lnJ,4] + aData[lnJ,5] + aData[lnJ,6] + aData[lnJ,7] + aData[lnJ,8] + aData[lnJ,9]
   
    * 填入年级名次
    REPLACE 语文_年名 WITH aData[lnJ, 10]
    REPLACE 数学_年名 WITH aData[lnJ, 11]
    REPLACE 外语_年名 WITH aData[lnJ, 12]
    REPLACE 物理_年名 WITH aData[lnJ, 13]
    REPLACE 化学_年名 WITH aData[lnJ, 14]
    REPLACE 生物_年名 WITH aData[lnJ, 15]
    REPLACE 总分_年名 WITH aData[lnJ, 16]
   
    * 填入班级名次
    REPLACE 语文_班名 WITH aData[lnJ, 17]
    REPLACE 数学_班名 WITH aData[lnJ, 18]
    REPLACE 外语_班名 WITH aData[lnJ, 19]
    REPLACE 物理_班名 WITH aData[lnJ, 20]
    REPLACE 化学_班名 WITH aData[lnJ, 21]
    REPLACE 生物_班名 WITH aData[lnJ, 22]
    REPLACE 总分_班名 WITH aData[lnJ, 23]
ENDFOR

* ------------------------------------------------
* 8. 展示与收尾
* ------------------------------------------------
USE
? "处理成功!"
? "当前目录下已生成新表:cj_final.dbf"
? "包含了6科及总分的年级名次和班级名次。"
? "规则:100,100,98,97 => 名次 1, 1, 3, 4"

* 建议最后单独浏览一下看结果:
SELECT cj_final
BROWSE
SET SAFETY ON
2026-07-31 04:24
jinanshui
Rank: 2
等 级:论坛游民
帖 子:308
专家分:67
注 册:2009-10-6
收藏
得分:0 
第3次
程序代码:
* [color=#808080]=============================================================[/color]
* VFP [color=#800000]9.0 特供版:全自动生成带年级/班级排名的新表[/color]
* 彻底去除了 DIMENSION 数组声明,采用 SQL 导入数组,[color=#800000]100% 防报错[/color]
* [color=#808080]=============================================================[/color]
SET TALK OFF
SET SAFETY OFF
CLOSE DATA ALL
CLEAR ALL
RELEASE ALL  && 清除 VFP9 缓存,严防残留变量冲突

* [color=#800000]1. 打开原表并检查[/color]
IF !FILE("cj.dbf")
    MESSAGEBOX("当前目录下没有找到 cj.dbf 原表!", 16, "错误")
    RETURN
ENDIF

USE cj.dbf EXCLUSIVE
lnCount = RECCOUNT()
IF lnCount = 0
    MESSAGEBOX("原表为空!", 16, "警告")
    USE
    RETURN
ENDIF

* [color=#800000]2. 【核心改动】用 VFP9 最强语法读取数据到数组 (绝不报错)[/color]
* 直接用 SQL [color=#0000FF]SELECT INTO ARRAY 创建数组,完全绕过 DIMENSION 的冲突检查[/color]
SELECT RECNO() as ori_no, 学号, 姓名, 语文, 数学, 外语, 物理, 化学, 生物 ;
    FROM cj ;
    INTO ARRAY aData
USE

* [color=#800000]3. 创建纯净的新表结构[/color]
IF FILE("cj_final.dbf")
    DELETE FILE cj_final.dbf
ENDIF
IF FILE("cj_final.fpt")
    DELETE FILE cj_final.fpt
ENDIF

CREATE TABLE cj_final ( ;
    学号 C(10), 姓名 C(8), ;
    语文 N(5,1), 语文_年名 N(4), 语文_班名 N(4), ;
    数学 N(5,1), 数学_年名 N(4), 数学_班名 N(4), ;
    外语 N(5,1), 外语_年名 N(4), 外语_班名 N(4), ;
    物理 N(5,1), 物理_年名 N(4), 物理_班名 N(4), ;
    化学 N(5,1), 化学_年名 N(4), 化学_班名 N(4), ;
    生物 N(5,1), 生物_年名 N(4), 生物_班名 N(4), ;
    总分 N(5,1), 总分_年名 N(4), 总分_班名 N(4) )

* [color=#008080]------------------------------------------------
[/color]* 4. 并列跳号排名函数 (1,1,3,4,5,5,7...)
* [color=#008080]------------------------------------------------
[/color]PROCEDURE GetJumpRank
    PARAMETERS arrScore, arrOriRec, arrResultRank, lnTotal
    PRIVATE i, j, nTemp, nRank, nCount, nLastScore
    
    * 冒泡排序 (分数从高到低)
    FOR i = 1 TO lnTotal - 1
        FOR j = i + 1 TO lnTotal
            IF arrScore[i] < arrScore[j]
                nTemp = arrScore[i]
                arrScore[i] = arrScore[j]
                arrScore[j] = nTemp
                
                nTemp = arrOriRec[i]
                arrOriRec[i] = arrOriRec[j]
                arrOriRec[j] = nTemp
            ENDIF
        ENDFOR
    ENDFOR
    
    * 计算名次
    nRank = 0
    nCount = 0
    nLastScore = -9999
    FOR i = 1 TO lnTotal
        nCount = nCount + 1
        IF arrScore[i] <> nLastScore
            nRank = nCount
        ENDIF
        nLastScore = arrScore[i]
        arrResultRank[ arrOriRec[i] ] = nRank
    ENDFOR
ENDPROC

* [color=#008080]------------------------------------------------
[/color]* 5. 计算各科目及总分(由于 aData 已经通过 SQL 生成,无需 DIMENSION)
* [color=#008080]------------------------------------------------
[/color]PRIVATE arrScore, arrRecno, arrFinalRank, arrSubjects
DIMENSION arrScore[lnCount], arrRecno[lnCount], arrFinalRank[lnCount]
DIMENSION arrSubjects[7]
arrSubjects[1] = "语文" ; arrSubjects[2] = "数学" ; arrSubjects[3] = "外语"
arrSubjects[4] = "物理" ; arrSubjects[5] = "化学" ; arrSubjects[6] = "生物" ; arrSubjects[7] = "总分"

* 扩展主数组,第 [color=#800000]10-16 格放年级名次,第 17-23 格放班级名次[/color]
DIMENSION aData[lnCount, 24]

FOR lnI = 1 TO 7
    FOR lnJ = 1 TO lnCount
        arrRecno[lnJ] = aData[lnJ, 1] && 原始记录号
        DO CASE
            CASE lnI = 1: arrScore[lnJ] = aData[lnJ, 4]
            CASE lnI = 2: arrScore[lnJ] = aData[lnJ, 5]
            CASE lnI = 3: arrScore[lnJ] = aData[lnJ, 6]
            CASE lnI = 4: arrScore[lnJ] = aData[lnJ, 7]
            CASE lnI = 5: arrScore[lnJ] = aData[lnJ, 8]
            CASE lnI = 6: arrScore[lnJ] = aData[lnJ, 9]
            CASE lnI = 7: arrScore[lnJ] = aData[lnJ,4] + aData[lnJ,5] + aData[lnJ,6] + aData[lnJ,7] + aData[lnJ,8] + aData[lnJ,9]
        ENDCASE
    ENDFOR
    = GetJumpRank(@arrScore, @arrRecno, @arrFinalRank, lnCount)
    
    FOR lnJ = 1 TO lnCount
        aData[lnJ, 9 + lnI] = arrFinalRank[ aData[lnJ, 1] ] && 存年级名次
    ENDFOR
ENDFOR

* [color=#008080]------------------------------------------------
[/color]* 6. 计算班级名次
* [color=#008080]------------------------------------------------
[/color]PRIVATE arrClassNames
SELECT DISTINCT SUBSTR(学号,3,2) FROM cj INTO ARRAY arrClassNames
lnClassCount = _TALLY

FOR lnI = 1 TO 7
    FOR lnJ = 1 TO lnClassCount
        lcClass = arrClassNames[lnJ]
        lnClassMember = 0
        PRIVATE arrClassScore, arrClassRec
        DIMENSION arrClassScore[lnCount], arrClassRec[lnCount]
        STORE 0 TO arrClassScore, arrClassRec
        
        FOR lnK = 1 TO lnCount
            IF SUBSTR(aData[lnK, 2], 3, 2) == lcClass
                lnClassMember = lnClassMember + 1
                arrClassRec[lnClassMember] = aData[lnK, 1]
                DO CASE
                    CASE lnI = 1: arrClassScore[lnClassMember] = aData[lnK, 4]
                    CASE lnI = 2: arrClassScore[lnClassMember] = aData[lnK, 5]
                    CASE lnI = 3: arrClassScore[lnClassMember] = aData[lnK, 6]
                    CASE lnI = 4: arrClassScore[lnClassMember] = aData[lnK, 7]
                    CASE lnI = 5: arrClassScore[lnClassMember] = aData[lnK, 8]
                    CASE lnI = 6: arrClassScore[lnClassMember] = aData[lnK, 9]
                    CASE lnI = 7: arrClassScore[lnClassMember] = aData[lnK,4] + aData[lnK,5] + aData[lnK,6] + aData[lnK,7] + aData[lnK,8] + aData[lnK,9]
                ENDCASE
            ENDIF
        ENDFOR
        
        IF lnClassMember > 0
            PRIVATE arrClassRank
            DIMENSION arrClassRank[lnCount]
            STORE 0 TO arrClassRank
            = GetJumpRank(@arrClassScore, @arrClassRec, @arrClassRank, lnClassMember)
            
            FOR lnK = 1 TO lnCount
                IF SUBSTR(aData[lnK, 2], 3, 2) == lcClass
                    aData[lnK, 16 + lnI] = arrClassRank[ aData[lnK, 1] ] && 存班级名次
                ENDIF
            ENDFOR
        ENDIF
    ENDFOR
ENDFOR

* [color=#008080]------------------------------------------------
[/color]* 7. 将数据写入 cj_final 新表
* [color=#008080]------------------------------------------------
[/color]SELECT cj_final
FOR lnJ = 1 TO lnCount
    APPEND BLANK
    REPLACE 学号 WITH aData[lnJ, 2], 姓名 WITH aData[lnJ, 3]
    REPLACE 语文 WITH aData[lnJ, 4], 数学 WITH aData[lnJ, 5]
    REPLACE 外语 WITH aData[lnJ, 6], 物理 WITH aData[lnJ, 7]
    REPLACE 化学 WITH aData[lnJ, 8], 生物 WITH aData[lnJ, 9]
    REPLACE 总分 WITH aData[lnJ,4]+aData[lnJ,5]+aData[lnJ,6]+aData[lnJ,7]+aData[lnJ,8]+aData[lnJ,9]
    
    * 写入年级名次
    REPLACE 语文_年名 WITH aData[lnJ, 10], 数学_年名 WITH aData[lnJ, 11]
    REPLACE 外语_年名 WITH aData[lnJ, 12], 物理_年名 WITH aData[lnJ, 13]
    REPLACE 化学_年名 WITH aData[lnJ, 14], 生物_年名 WITH aData[lnJ, 15]
    REPLACE 总分_年名 WITH aData[lnJ, 16]
    
    * 写入班级名次
    REPLACE 语文_班名 WITH aData[lnJ, 17], 数学_班名 WITH aData[lnJ, 18]
    REPLACE 外语_班名 WITH aData[lnJ, 19], 物理_班名 WITH aData[lnJ, 20]
    REPLACE 化学_班名 WITH aData[lnJ, 21], 生物_班名 WITH aData[lnJ, 22]
    REPLACE 总分_班名 WITH aData[lnJ, 23]
ENDFOR

* [color=#008080]------------------------------------------------
[/color]* 8. 完成
* [color=#008080]------------------------------------------------
[/color]USE
? "处理成功!"
? "当前目录下已生成新表:cj_final.dbf"
? "包含所有学科的年级名次和班级名次 (跳号规则 1,1,3,4,5,5,7...)"

SELECT cj_final
BROWSE
SET SAFETY ON


2026-07-31 04:28
jinanshui
Rank: 2
等 级:论坛游民
帖 子:308
专家分:67
注 册:2009-10-6
收藏
得分:0 
第4次
程序代码:
CLOSE DATA ALL
SET SAFETY OFF
CLEAR ALL
* [color=#800000]1. 基础表带总分[/color]
SELECT 学号, 姓名, 语文, 数学, 外语, 物理, 化学, 生物, ;
       (语文 + 数学 + 外语 + 物理 + 化学 + 生物) as 总分 ;
FROM cj ;
INTO TABLE step1

* [color=#800000]2. 用 ALTER 为表加上 14 个明确定义宽度的列[/color]
ALTER TABLE step1 ADD COLUMN 语文_年名 N(4,0)
ALTER TABLE step1 ADD COLUMN 语文_班名 N(2,0)
ALTER TABLE step1 ADD COLUMN 数学_年名 N(4,0)
ALTER TABLE step1 ADD COLUMN 数学_班名 N(2,0)
ALTER TABLE step1 ADD COLUMN 外语_年名 N(4,0)
ALTER TABLE step1 ADD COLUMN 外语_班名 N(2,0)
ALTER TABLE step1 ADD COLUMN 物理_年名 N(4,0)
ALTER TABLE step1 ADD COLUMN 物理_班名 N(2,0)
ALTER TABLE step1 ADD COLUMN 化学_年名 N(4,0)
ALTER TABLE step1 ADD COLUMN 化学_班名 N(2,0)
ALTER TABLE step1 ADD COLUMN 生物_年名 N(4,0)
ALTER TABLE step1 ADD COLUMN 生物_班名 N(2,0)
ALTER TABLE step1 ADD COLUMN 总分_年名 N(4,0)
ALTER TABLE step1 ADD COLUMN 总分_班名 N(2,0)
* 定义要计算的科目
DIMENSION aSubj[7]
aSubj[1] = "语文"
aSubj[2] = "数学"
aSubj[3] = "外语"
aSubj[4] = "物理"
aSubj[5] = "化学"
aSubj[6] = "生物"
aSubj[7] = "总分"

USE step1 EXCLUSIVE

FOR i = 1 TO 7
    lcF = aSubj[i]
    lcFYear = lcF + "_年名"
    lcFClass = lcF + "_班名"
    
    ? "正在计算:" + lcF
    
    * 1. 先将这科的所有名次清零,防止残留影响
    REPLACE ALL &lcFYear WITH 0, &lcFClass WITH 0
    
    * 2. 计算年级名次 (用自连接找出比自己高的人+1)
    SELECT a.学号, (COUNT(b.学号) + 1) as 排名 ;
    FROM step1 a, step1 b ;
    WHERE a.&lcF < b.&lcF OR (a.&lcF = b.&lcF AND a.学号 > b.学号) ;
    GROUP BY a.学号 ;
    INTO TABLE tmp_year_rank
    
    * 3. 利用 VFP 最稳定的物理更新法更新年级名次
    SELECT step1
    SET ORDER TO 学号  && 确保排序
    SELECT tmp_year_rank
    INDEX ON 学号 TAG xh
    SELECT step1
    SET RELATION TO 学号 INTO tmp_year_rank
    REPLACE ALL &lcFYear WITH tmp_year_rank.排名
    SET RELATION TO
    
    * 4. 计算班级名次 (增加 SUBSTR 条件)
    SELECT a.学号, (COUNT(b.学号) + 1) as 排名 ;
    FROM step1 a, step1 b ;
    WHERE (a.&lcF < b.&lcF OR (a.&lcF = b.&lcF AND a.学号 > b.学号)) ;
      AND SUBSTR(a.学号,3,2) = SUBSTR(b.学号,3,2) ;
    GROUP BY a.学号 ;
    INTO TABLE tmp_class_rank
    
    * 5. 利用 VFP 最稳定的物理更新法更新班级名次
    SELECT step1
    SELECT tmp_class_rank
    INDEX ON 学号 TAG xh
    SELECT step1
    SET RELATION TO 学号 INTO tmp_class_rank
    REPLACE ALL &lcFClass WITH tmp_class_rank.排名
    SET RELATION TO
ENDFOR

* 收尾:拷贝成最终结果
COPY TO cj_final
USE

? "计算完成!请打开 cj_final 查看。"
2026-07-31 04:29
jinanshui
Rank: 2
等 级:论坛游民
帖 子:308
专家分:67
注 册:2009-10-6
收藏
得分:0 
第5次
程序代码:
CLOSE DATA ALL
SET SAFETY OFF
CLEAR ALL
* [color=#800000]1. 基础表带总分[/color]
SELECT 学号, 姓名, 语文, 数学, 外语, 物理, 化学, 生物, ;
       (语文 + 数学 + 外语 + 物理 + 化学 + 生物) as 总分 ;
FROM cj ;
INTO TABLE step1

* [color=#800000]2. 用 ALTER 为表加上 14 个明确定义宽度的列[/color]
ALTER TABLE step1 ADD COLUMN 语文_年名 N(4,0)
ALTER TABLE step1 ADD COLUMN 语文_班名 N(2,0)
ALTER TABLE step1 ADD COLUMN 数学_年名 N(4,0)
ALTER TABLE step1 ADD COLUMN 数学_班名 N(2,0)
ALTER TABLE step1 ADD COLUMN 外语_年名 N(4,0)
ALTER TABLE step1 ADD COLUMN 外语_班名 N(2,0)
ALTER TABLE step1 ADD COLUMN 物理_年名 N(4,0)
ALTER TABLE step1 ADD COLUMN 物理_班名 N(2,0)
ALTER TABLE step1 ADD COLUMN 化学_年名 N(4,0)
ALTER TABLE step1 ADD COLUMN 化学_班名 N(2,0)
ALTER TABLE step1 ADD COLUMN 生物_年名 N(4,0)
ALTER TABLE step1 ADD COLUMN 生物_班名 N(2,0)
ALTER TABLE step1 ADD COLUMN 总分_年名 N(4,0)
ALTER TABLE step1 ADD COLUMN 总分_班名 N(2,0)
* 定义要计算的科目
DIMENSION aSubj[7]
aSubj[1] = "语文"
aSubj[2] = "数学"
aSubj[3] = "外语"
aSubj[4] = "物理"
aSubj[5] = "化学"
aSubj[6] = "生物"
aSubj[7] = "总分"

USE step1 EXCLUSIVE

FOR i = 1 TO 7
    lcF = aSubj[i]
    lcFYear = lcF + "_年名"
    lcFClass = lcF + "_班名"
    
    ? "正在计算:" + lcF
    
    * 1. 先将这科的所有名次清零,防止残留影响
    REPLACE ALL &lcFYear WITH 0, &lcFClass WITH 0
    
    * 2. 计算年级名次 (用自连接找出比自己高的人+1)
    SELECT a.学号, (COUNT(b.学号) + 1) as 排名 ;
    FROM step1 a, step1 b ;
    WHERE a.&lcF < b.&lcF OR (a.&lcF = b.&lcF AND a.学号 > b.学号) ;
    GROUP BY a.学号 ;
    INTO TABLE tmp_year_rank
    
    * 3. 利用 VFP 最稳定的物理更新法更新年级名次
    SELECT step1
    SET ORDER TO 学号  && 确保排序
    SELECT tmp_year_rank
    INDEX ON 学号 TAG xh
    SELECT step1
    SET RELATION TO 学号 INTO tmp_year_rank
    REPLACE ALL &lcFYear WITH tmp_year_rank.排名
    SET RELATION TO
    
    * 4. 计算班级名次 (增加 SUBSTR 条件)
    SELECT a.学号, (COUNT(b.学号) + 1) as 排名 ;
    FROM step1 a, step1 b ;
    WHERE (a.&lcF < b.&lcF OR (a.&lcF = b.&lcF AND a.学号 > b.学号)) ;
      AND SUBSTR(a.学号,3,2) = SUBSTR(b.学号,3,2) ;
    GROUP BY a.学号 ;
    INTO TABLE tmp_class_rank
    
    * 5. 利用 VFP 最稳定的物理更新法更新班级名次
    SELECT step1
    SELECT tmp_class_rank
    INDEX ON 学号 TAG xh
    SELECT step1
    SET RELATION TO 学号 INTO tmp_class_rank
    REPLACE ALL &lcFClass WITH tmp_class_rank.排名
    SET RELATION TO
ENDFOR

* 收尾:拷贝成最终结果
COPY TO cj_final
USE

? "计算完成!请打开 cj_final 查看。"
2026-07-31 04:30
schtg
Rank: 13Rank: 13Rank: 13Rank: 13
来 自:USA
等 级:贵宾
威 望:67
帖 子:2723
专家分:4967
注 册:2012-2-29
收藏
得分:0 
2026-07-31 06:54
sych
Rank: 8Rank: 8
等 级:蝙蝠侠
威 望:7
帖 子:646
专家分:761
注 册:2019-10-11
收藏
得分:0 
SET talk OFF
SET SAFETY OFF
CLOSE all
USE cj
CREATE TABLE cj_final ( ;
    学号 C(10), 姓名 C(8), ;
    语文 N(5,1), 语文_年名 N(4), 语文_班名 N(4), ;
    数学 N(5,1), 数学_年名 N(4), 数学_班名 N(4), ;
    外语 N(5,1), 外语_年名 N(4), 外语_班名 N(4), ;
    物理 N(5,1), 物理_年名 N(4), 物理_班名 N(4), ;
    化学 N(5,1), 化学_年名 N(4), 化学_班名 N(4), ;
    生物 N(5,1), 生物_年名 N(4), 生物_班名 N(4), ;
    总分 N(5,1), 总分_年名 N(4), 总分_班名 N(4) )
APPEND FROM cj
REPLACE ALL 总分 WITH 语文+数学+外语+物理+化学+生物
DIMENSION bj1(22),bj2(22,2),nj(3)  &&假设有22个班级
FOR i=1 TO 7
    bj1=10^9  &&随意指定一个超过单科最高分数的大数
    bj2=1
    nj(1)=10^9  &&随意指定一个超过总分最高分数的大数
    nj(2)=1  &&当前排名
    nj(3)=1  &&实际排名
    zd=FIELD(3*i)  &&字段
    INDEX ON &zd TAG px desc
    SCAN
        xh=VAL(SUBSTR(学号,3,2))  &&当前班级
        fs=EVALUATE(zd)  &&当前分数
        **年级排名
        njm=IIF(fs<nj(1),nj(3),nj(2))
        nj(1)=fs
        nj(2)=njm
        nj(3)=nj(3)+1
        **班级排名
        bjm=IIF(fs<bj1(xh),bj2(xh,2),bj2(xh,1))
        bj1(xh)=fs
        bj2(xh,1)=bjm
        bj2(xh,2)=bj2(xh,2)+1
        REPLACE (zd+"_班名") WITH bjm,(zd+"_年名") WITH njm
    endscan
NEXT
DELETE TAG px


[此贴子已经被作者于2026-8-1 07:46编辑过]

2026-07-31 08:55
chychychy
Rank: 4
等 级:业余侠客
帖 子:625
专家分:220
注 册:2015-4-18
收藏
得分:0 
回复 7楼 sych
简洁高效,学习了
2026-07-31 11:47
chychychy
Rank: 4
等 级:业余侠客
帖 子:625
专家分:220
注 册:2015-4-18
收藏
得分:0 
参考论坛排列位次代码,以前以前不会循环处理各科目是一科一科“硬处理”的,借助了一下ai,修改测试后如下,但是ai给的代码太繁琐了,抛砖引玉,请指教
修正了一下,原来数据表 ALTER TABLE tjb ADD COLUMN &s N(4),长度不够,INDEX ON 年级-STR(1000-总分) TAG px,这一处也会因为有小数点导致排序错误
图片附件: 游客没有浏览图片的权限,请 登录注册

cjkmb.rar (227 Bytes)
,这个如下图
图片附件: 游客没有浏览图片的权限,请 登录注册


程序代码:
**第一部分 生成统计用表tjb.dbf
SET TALK OFF
SET SAFETY OFF
SET DELETED ON
CLOSE DATABASES ALL
CLEAR

* 打开科目表,获取有效科目
SELECT 0
USE cjkmb ALIAS kmb
SELECT kmmc FROM kmb ;
    WHERE NOT DELETED() AND kmmc != '总分' ;
    ORDER BY xh ;
    INTO CURSOR curtemp
*BROWSE &&&测试用,完成去掉
* 删除旧表,测试用完成可以去掉
IF FILE('tjb.dbf')
    DELETE FILE tjb.DBF
ENDIF

* 创建统计表
CREATE TABLE tjb ( 姓名 C(8),学号 C(6), 年级 C(2), 班级 C(2))

SELECT curtemp
SCAN
    s = TRIM(kmmc)
    ALTER TABLE tjb ADD COLUMN &s N(5,1)        && 添加科目字段
    ALTER TABLE tjb ADD COLUMN &s.班次 N(4)   && 添加科目班级名次
    ALTER TABLE tjb ADD COLUMN &s.校次 N(4)   && 添加科目年级名次
ENDSCAN
ALTER TABLE tjb ADD COLUMN 总分 N(5,1)
ALTER TABLE tjb ADD COLUMN 总分班次 N(4)
ALTER TABLE tjb ADD COLUMN 总分校次 N(4)

* 导入原始成绩
SELECT 0
USE cj ALIAS cj          && 打开原始成绩表
SELECT tjb
APPEND FROM cj

* 动态构建总分求和表达式
SELECT curtemp
lcTotalExpr = ""
SCAN
    lcTotalExpr = IIF(EMPTY(lcTotalExpr), TRIM(kmmc), lcTotalExpr + "+" + TRIM(kmmc))
ENDSCAN

SELECT tjb
REPLACE ALL 年级 WITH LEFT(ALLTRIM(学号),2),;
            班级 WITH SUBSTR(ALLTRIM(学号),3,2) ,;
            总分 WITH IIF(EMPTY(lcTotalExpr), 0, &lcTotalExpr)

MESSAGEBOX('数据导入完成!总分及年级/班级已填充。', 64, '完成')
SELECT tjb
BROWSE

***第二部分,计算成绩位次

**---- 总分校次 ----
*INDEX ON 年级-STR(1000-总分) TAG px
INDEX ON 年级 + STR(1000-总分, 6, 1) TAG px
mc=1
nzf=0
cbj=""
nrs=1
SCAN
    IF ALLTRIM(年级)!=cbj
        STORE 1 TO nrs,mc
    ELSE
        IF 总分!=nzf
            mc=nrs
        ENDIF
    ENDIF
    REPLACE 总分校次 WITH mc
    nrs=nrs+1
    nzf=总分
    cbj=ALLTRIM(年级)
ENDSCAN
DELETE TAG ALL

**---- 总分班次 ----
*INDEX ON 班级-STR(1000-总分) TAG px
INDEX ON 班级 + STR(1000-总分, 6, 1) TAG px
mc=1
nzf=0
cbj=""
nrs=1
SCAN
    IF ALLTRIM(班级)!=cbj
        STORE 1 TO nrs,mc
    ELSE
        IF 总分!=nzf
            mc=nrs
        ENDIF
    ENDIF
    REPLACE 总分班次 WITH mc
    nrs=nrs+1
    nzf=总分
    cbj=ALLTRIM(班级)
ENDSCAN
DELETE TAG ALL

**---- 循环处理所有科目(校次 + 班次) ----
SELECT curtemp
SCAN
    s = TRIM(kmmc)                     && 科目名称

* 校次(年级内排名)
    SELECT tjb
    *Ckm = "年级-STR(1000-" + s + ")" && 构建索引
    Ckm = "年级 + STR(1000-" + s + ", 6, 1)"
    INDEX ON &Ckm TAG px
    mc=1
    nzf=0
    cbj=""
    nrs=1
    SCAN
        IF ALLTRIM(年级)!=cbj
            STORE 1 TO nrs,mc
        ELSE
            IF EVALUATE(s) != nzf
                mc = nrs
            ENDIF
        ENDIF
        REPLACE (s+"校次") WITH mc
        nrs = nrs + 1
        nzf = EVALUATE(s)
        cbj = ALLTRIM(年级)
    ENDSCAN
    DELETE TAG ALL  &&删除产生索引文件

* 班次(班级内排名)
    *Ckm = "班级-STR(1000-" + s + ")"
    Ckm = "班级 + STR(1000-" + s + ", 6, 1)"
    INDEX ON &Ckm TAG px
    mc=1
    nzf=0
    cbj=""
    nrs=1
    SCAN
        IF ALLTRIM(班级)!=cbj
            STORE 1 TO nrs,mc
        ELSE
            IF EVALUATE(s) != nzf
                mc = nrs
            ENDIF
        ENDIF
        REPLACE (s+"班次") WITH mc
        nrs = nrs + 1
        nzf = EVALUATE(s)
        cbj = ALLTRIM(班级)
    ENDSCAN
    DELETE TAG ALL  &&删除产生索引文件

ENDSCAN

MESSAGEBOX('总分及各科目年级/班级位次计算完成。', 64, '完成')

*按班级升序,总分降序查看结果
SELECT tjb
INDEX ON 班级 + STR(1000-总分,4) TAG px
SET ORDER TO TAG px
BROWSE

*清理
USE IN kmb
USE IN curtemp
USE IN cj
DELETE TAG ALL  &&删除产生索引文件
DELETE FILE tjb.bak &&删除产生的备份文件




[此贴子已经被作者于2026-7-31 16:54编辑过]

2026-07-31 11:51
jinanshui
Rank: 2
等 级:论坛游民
帖 子:308
专家分:67
注 册:2009-10-6
收藏
得分:0 
第9楼老师
图片附件: 游客没有浏览图片的权限,请 登录注册
2026-07-31 15:23
快速回复:人工智能都错在哪儿啊?请修改一下
数据加载中...
 
   
关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.026487 second(s), 10 queries.
Copyright©2004-2026, BCCN.NET, All Rights Reserved