Classroom API在函数中的不同行为(如果是单独调用或从循环调用)>

问题描述 投票:1回答:1

这是我面临的一个复杂而奇怪的问题,我希望任何人都可以带给我,即使不是解决问题的方法,也可以避开它。从一开始,我是一所学校的管理员,该学校使用Google Suite for Education和Classroom管理与学生的课程作业,特别是现在我们被迫在家工作。

[我们认为使用Classroom API来更好地了解学生的工作及其整体评分是一个好主意。因此,我们制作了一个电子表格和一个脚本以获取报告,该报告显示了学生所参加的所有科目(“课堂”中的课程)及其所有课程的成绩。到目前为止,在解决了对API的一些误解之后,我们设法编写了脚本。

[此后,我们尝试放大脚本,以便一次可以为一组学生报告,这是一大进步,因为单独编写30份报告非常耗时。并不是很困难,因为我们在工作表中列出了所有学生和小组的列表,并且或多或少是通过循环完成的。它奏效了,我们可以获得小组中所有学生的完整报告,包括他们在所有学科中的所有课程工作。

但是问题出在我们开始运行此脚本时,我们在某些小组,某些学生中遇到错误,我们不知道为什么。经过一些调查,我们发现对Classroom.Courses.list(optionalArgs)

的调用提供了430门课程,尽管我们在报告中为学生使用了一个过滤器。 430门课程的数量不是很高,但是所有课程的循环,即使考虑到该学生尚未入学,也要花费1800 s以上的时间,并且脚本会出现“超时错误”。

令人惊讶的是,如果我在该组的循环内运行相同的函数,但直接调用,则该函数可以正常工作,并且没有错误。在这种情况下,给出上一个错误的学生没有参加任何课程,因此对Classroom.Courses.list(optionalArgs)

的调用使我获得了一组空课程,并且该函数几乎立即返回而未进行任何报告。

我正在显示完整的脚本代码,但是其中有趣的部分并不长。它有很多部分可以支持任务,例如从其他工作表获取数据或在屏幕上显示HTML对话框。

最好的问候拉斐尔

P.S。对不起,我的内容很长,但是代码更长了,我认为解释这种情况可以改善对我们问题的理解。

    // Menu
    function onOpen() {
      var ui = SpreadsheetApp.getUi();
      ui.createMenu('Functions')
          .addItem('Group report','fReportGroupHtml')
          .addItem('Student report','fStudentReportHtml')
          .addToUi();
    }

//------------------------------------------------------------------------
// Report for 1 student
//  Opens HTML dialog to select group and student
//------------------------------------------------------------------------
function fStudentReportHtml()
{
  // Html dialog
  try {
    var output = HtmlService.createHtmlOutputFromFile('SelecStudent');
    SpreadsheetApp.getUi().showModalDialog(output,'Select student');
  }
  catch(err) {
    Logger.log(err);
    return;
  }
}

//---------------------------------------------------------------------------
// Report for 1 student
//  Receives information from dialog and makes report
//------------------------------------------------------------------------
function fStudentReport(form_data)
{
  // Form information
  var nameStudent=form_data.student;

  // Split students name and surname
  var posco=nameStudent.indexOf(',');
  var surname=nameStudent.substring(0,posco);
  var name=nameStudent.substring(posco+2);

  // Gets student email
  var idStudent=getUserEmail(name,surname);

  // List student coursework
  var ssCourses=SpreadsheetApp.getActive();
  var hWorks=ssCourses.getSheetByName("StWork");
  fListStudentWork(idStudent,hWorks,nameStudent);
}

//---------------------------------------------------------------------------
// Report for all students in a group
//  Opens HTML dialog to select group
function fReportGroupHtml()
{
  // Html dialog
  try {
    var output = HtmlService.createHtmlOutputFromFile('SelecGroup');
    SpreadsheetApp.getUi().showModalDialog(output,'Select group');
  }
  catch(err) {
    Logger.log(err);
    return;
  }
}

//---------------------------------------------------------------------------
// Report for all students in a group
//  Receives information from dialog and makes report
function fReportGroup(form_data)
{
  var idStudents="1wvjqUFZcRwjTKSspjyQOE1JHio33f7seyx8xCO8qHBQ";
  var idTemplateInf="1K6YgZvh195eo4b-DLtRHuvjFdG3SOBJILodzS4CUnBs";
  var idCarpInf="16nH3BhAwHPP3BcAUK9eW_FQdWRM6B87T";
  var valAlu=[[]];

  // Opens students sheet
  var ss = SpreadsheetApp.openById(idStudents);
  var coursesSS = ss.getSheetByName("Students");
  var lastrow=coursesSS.getLastRow();
  var rangeA=coursesSS.getRange(2,2,lastrow-1,3).getValues();

  // First student in the group
  for(var ii=0; ii<lastrow-1; ii++)
  {
    if (rangeA[ii][2]==form_data.groupAlu)
      break;
  }
  var ini=ii;

  // Opens sheet for messaging
  var ssClass = SpreadsheetApp.getActive();

  // Copies template sheet into a new file
  var idNewFileInf = DriveApp.getFileById(idTemplateInf).makeCopy(idCarpInf).getId();
  DriveApp.getFileById(idNewFileInf).setName('Report '+form_data.groupAlu);

  // Opens new sheet and writes general information
  var ssInf = SpreadsheetApp.openById(idNewFileInf);
  var hjInfAlu = ssInf.getSheetByName("Students");
  hjInfAlu.getRange(2,1).setValue("GRUPO: "+form_data.groupAlu);
  var dateToday=new Date();
  hjInfAlu.getRange(3,1).setValue("FECHA: "+Utilities.formatDate(dateToday,"GMT+1","dd/MM/yyyy"));

  // All students in the group
  var iiAlu=1;
  while(rangeA[ii][2]==form_data.groupAlu)
  {
    // Gets student's information
    var surname=rangeA[ii][0];
    var name=rangeA[ii][1];
    var nameStudent=surname+", "+name;

    // Gets student email
    var idStudent=getUserEmail(name,surname);

    // Copies sheet
    var hjInfWork = ssInf.getSheetByName("Works").copyTo(ssInf).setName(nameStudent);

    // Makes report of student's work and submissions
    var mens="Creando informe de student: "+nameStudent;
    ssClass.toast(mens, "Informe de tareas",-1);
    var states=fListStudentWork(idStudent,hjInfWork,nameStudent);

    // Writes student information in first sheet
    valAlu[0][0]=iiAlu;
    valAlu[0][1]=nameStudent;
    valAlu[0][2]=states[0];
    valAlu[0][3]=states[1];
    valAlu[0][4]=states[2];
    hjInfAlu.getRange(iiAlu+5, 1, 1, 5).setValues(valAlu);
    ii++;
    iiAlu++;
  }

  // Deletes sheet 'Works'
  ssInf.deleteSheet(ssInf.getSheetByName("Works"));

  // Final message
  ssClass.toast("Fin del informe", "Informe de tareas",5);
}

//---------------------------------------------------------------------------
// List coursework for a student
function fListStudentWork(idStudent, dataSheet, nameStudent)
{
  // Variables
  var ii=0;
  var lWorks=[[]];
  var stateWork=[0,0,0];
  var pageToken = null;
  var pageToken2 = null;
  var colorCourse1= "#ddffdd";
  var colorCourse2= "#f9e9b0";
  var iiColor=0;
  var optionalArgs=
  {
    pageToken: pageToken,
    courseStates: 'ACTIVE',
    studentId: idStudent,
    pageSize: 0
  };
  var optionalArgs2=
  {
    userId: idStudent,
    pageSize: 0
  };

  // Date today
  var now = new Date();
  var year=now.getFullYear();
  var month=now.getMonth();

  // Date starting term
  if (month>=8) 
    var cadfecha="September 1, "+year.toString();
  else
    var cadfecha="September 1, "+(year-1).toString();  
  var fechaini=new Date(cadfecha);

  // Empty sheet
  var rowWorks=dataSheet.getLastRow();
  var colWorks=dataSheet.getLastColumn();
  if (rowWorks>3)
  {
    var rnWorks=dataSheet.getRange(4, 1, rowWorks-3, colWorks);
    rnWorks.clearContent().clearFormat();
  }

  // General information in sheet
  if (!nameStudent)
    nameStudent=getUserName(idStudent);
  Logger.log("INI: "+nameStudent);
  dataSheet.getRange(1, 1).setValue("ENTREGAS DEL ALUMNO: "+nameStudent);
  var dateToday=new Date();
  dataSheet.getRange(2, 1).setValue("FECHA: "+Utilities.formatDate(dateToday,"GMT+1","dd/MM/yyyy"));

  // First: courses for the student
  var response = Classroom.Courses.list(optionalArgs);
  var courses = response.courses;
  if (!courses || courses.length === 0)
    dataSheet.getRange(4, 2).setValue("No hay clases");
  else 
  {
    Logger.log(" courses: "+courses.length);
    for (course in courses)
    {
      var fechaCourse=new Date(courses[course].creationTime);

      if (fechaCourse>=fechaini)
      {
        // Information from the course
        var idCourse=courses[course].id;
        var nomprof=getUserName(courses[course].ownerId);
        var colorCourse=(iiColor==0)? colorCourse1 : colorCourse2;
        iiColor=1-iiColor;

        // Gets coursework from the course
        var responseT = Classroom.Courses.CourseWork.list(idCourse);
        var works = responseT.courseWork;
        if (!works || works.length === 0)
          dataSheet.getRange(4, 2).setValue("No hay información");
        else 
        {
          for (work in works)
          {
            var idWork=works[work].id;
            var maxPoints=(works[work].maxPoints==null)? "" : works[work].maxPoints;

            // Gets submissions
            try
            {
              var responseE = Classroom.Courses.CourseWork.StudentSubmissions.list(idCourse, idWork, optionalArgs2);
              var submis = responseE.studentSubmissions;
            }
            catch(ee)
            {
              var submis=null;
            }
            if (submis && submis.length >0)
            {
              for (subm in submis)
              {
                lWorks[0][0]=ii+1;
                lWorks[0][1]=courses[course].name;
                lWorks[0][2]=nomprof;
                lWorks[0][3]=works[work].title;
                var dateWork=works[work].dueDate;
                if (dateWork==null)
                  lWorks[0][4]="--/--/----";
                else 
                  lWorks[0][4]=dateWork.day+"/"+dateWork.month+"/"+dateWork.year;
                var points=(submis[subm].assignedGrade==null)? "" : submis[subm].assignedGrade; 
                lWorks[0][5]=points+" / "+maxPoints;
                var dateSubmis=submis[entrega].creationTime;
                if (dateSubmis==null)
                  lWorks[0][6]="--/--/----";
                else lWorks[0][6]=Utilities.formatDate(new Date(dateSubmis), "GMT+1","dd/MM/yyyy");
                var state=submis[subm].state;

                // Gets state of submission
                var cState="";
                var lateSubmis=0;
                if ((state=="RETURNED")||(state=="TURNED_IN"))
                {
                  cState="ENTREGADO";
                  stateWork[0]++;
                }
                else
                {
                  // Checks if late or not handed
                  if (dateWork!=null)
                  {
                    var dateEnd=new Date(dateWork.year,dateWork.month-1,dateWork.day);
                    if (dateEnd.valueOf()<dateToday.valueOf())
                    {
                      cState="NO ENTREGADO";
                      stateWork[1]++;
                      lateSubmis=1;
                    }
                    else
                      stateWork[2]++;
                  }
                }

                lWorks[0][7]=cState;              
                dataSheet.getRange(ii+4, 1, 1, 8).setValues(lWorks).setBackground(colorCourse);
                if (lateSubmis)
                  dataSheet.getRange(ii+4, 8).setFontColor("red").setFontWeight("bold");
                else
                  dataSheet.getRange(ii+4, 8).setFontColor("black").setFontWeight("normal");
                ii++;
              }
            }
          }  
        }
      }
    }
  }

  return(stateWork);
}

/////////////////////////////////////////////////////////////////////////////

//------------------------------------------------------------------------
// Gets list of groups
function listGroups()
{
  var idStudents="1wvjqUFZcRwjTKSspjyQOE1JHio33f7seyx8xCO8qHBQ";

  try 
  {
    // Opens students sheet
    var ss = SpreadsheetApp.openById(idStudents);
    var coursesSS = ss.getSheetByName("Students");
    var lastrow=coursesSS.getLastRow();
    var rangeA=coursesSS.getRange(2,4,lastrow-1,1).getValues();
    var courses = [];
    var courseant="";
    for(var ii=0; ii<lastrow-1; ii++) 
    {
      if (rangeA[ii][0]!=courseant)
      {
        courseant=rangeA[ii][0];
        courses.push(courseant);
      }
    }

    return courses;
  }
  catch(err) {
    Logger.log(err);
  }
}

//------------------------------------------------------------------------
// Gets list of students in group
function listStudents(group) 
{
  var idStudents="1wvjqUFZcRwjTKSspjyQOE1JHio33f7seyx8xCO8qHBQ";

  try 
  {
    // Opens students sheet
    var ss = SpreadsheetApp.openById(idStudents);
    var coursesSS = ss.getSheetByName("Students");
    var lastrow=coursesSS.getLastRow();
    var rangeA=coursesSS.getRange(2,1,lastrow-1,4).getValues();

    // First student
    for(var ii=0; ii<lastrow-1; ii++) 
    {
      if (rangeA[ii][3]==group)
        break;
    }
    var ini=ii;

    // Last student
    while(rangeA[ii][3]==group)
      ii++;

    // Gets array of students
    var students=coursesSS.getRange(2+ini,2,ii-ini,2).getValues();
    return students;
  }
  catch(err) {
    Logger.log(err);
  }
}

//------------------------------------------------------------------------
// Gets list of courses
function listCourses()
{
  try 
  {
    // Opens courses sheet
    var ss = SpreadsheetApp.getActive();
    var coursesSS = ss.getSheetByName("Courses");
    var lastrow=coursesSS.getLastRow();
    var courses=coursesSS.getRange(3,2,lastrow-2,4).getValues();
    return courses;
  }
  catch(err) {
    Logger.log(err);
  }
}

//---------------------------------------------------------------------------
// Gets user name from ID
function getUserName(usid)
{
  var result = AdminDirectory.Users.get(usid, {fields:'name'});
  var fullname = result.name.fullName;
  return fullname;
}

//----------------------------------------------------------------------------
// Gets user email from name
function getUserEmail(name,surname)
{
  var userIds = AdminDirectory.Users.list({domain:"iesciudadjardin.com",
                                           query:"givenName:'"+name+"' familyName:'"+surname+"'"}).users;
  if ((userIds==undefined)||(userIds.length!=1))
    return null;
  else
    return userIds[0].primaryEmail;
}

附加信息

我知道问题太大,所以我将尝试用尽可能少的代码来解释问题。本质上,我的代码有效。有时它与一些学生一起挂起。它的主要部分是函数fListStudentWork

// List coursework for a student
function fListStudentWork(idStudent, dataSheet, nameStudent)
{
  var optionalArgs=
  {
    pageToken: pageToken,
    courseStates: 'ACTIVE',
    studentId: idStudent,
    pageSize: 0
  };

  // First: courses for the student
  var response = Classroom.Courses.list(optionalArgs);
  var courses = response.courses;
  if (!courses || courses.length === 0)
    // NO COURSES
  else 
  {
   // MAKE REPORT
  }
}

现在,如果我和一个特殊的学生一起打电话,它会工作,返回空的课程集,因为约翰·史密斯没有参加任何课程(也有参加某些课程的学生也发生过:]

function OneStudentReport()
{
  fListStudentWork("[email protected]",mySheet,"John Smith");
}

但是如果我和一组学生一起循环,约翰·史密斯是其中的一员,以前的所有学生报告都可以,当循环到达他时,它将返回我学校的所有课程,并且脚本会随着时间的流逝而中止错误。

function fReportGroup(form_data)
{
  // All students in the group
  while(StudentGroup=="MYGROUP")
  {
    // Gets student's information
    var surname=rangeA[ii][0];
    var name=rangeA[ii][1];
    var nameStudent=surname+", "+name;

    // Gets student email
    var idStudent=getUserEmail(name,surname);

    // Makes report of student's work and submissions
    var states=fListStudentWork(idStudent,MySheet,nameStudent);
  }
}

P.S。如果管理员认为我由于太长而应该删除带有完整代码的消息的第一部分,请告诉我。谢谢

这是我面临的一个复杂而奇怪的问题,我希望任何人都可以带给我,即使不是解决问题的方法,也可以避开它。从头开始,我是......>

google-apps-script google-classroom
1个回答
© www.soinside.com 2019 - 2024. All rights reserved.