--- loncom/interface/Attic/lonspreadsheet.pm 2002/11/15 18:19:10 1.140
+++ loncom/interface/Attic/lonspreadsheet.pm 2002/11/26 14:58:41 1.150
@@ -1,5 +1,5 @@
#
-# $Id: lonspreadsheet.pm,v 1.140 2002/11/15 18:19:10 matthew Exp $
+# $Id: lonspreadsheet.pm,v 1.150 2002/11/26 14:58:41 matthew Exp $
#
# Copyright Michigan State University Board of Trustees
#
@@ -1149,7 +1149,7 @@ sub exportdata {
sub update_student_sheet{
- my ($sheet,$c) = @_;
+ my ($sheet,$r,$c) = @_;
# Load in the studentcalc sheet
&readsheet($sheet,'default_studentcalc');
# Determine the structure (contained assessments, etc) of the sheet
@@ -1157,7 +1157,7 @@ sub update_student_sheet{
# Load in the cached sheets for this student
&cachedssheets($sheet);
# Load in the (possibly cached) data from the assessment sheets
- &loadstudent($sheet,$c);
+ &loadstudent($sheet,$r,$c);
# Compute the sheet
&calcsheet($sheet);
}
@@ -1186,17 +1186,45 @@ sub get_row {
########################################################################
sub sort_indicies {
my $sheet = shift;
- #
- # Sort the rows in some manner
- #
- my @sortby=();
my @sortidx=();
- # Skip row 0
- for (my $row=1;$row<=$sheet->{'maxrow'};$row++) {
- push (@sortby, $sheet->{'safe'}->reval('$f{"A'.$row.'"}'));
- push (@sortidx, $row);
+ #
+ if ($sheet->{'sheettype'} eq 'classcalc') {
+ my @sortby=(undef);
+ # Skip row 0
+ for (my $row=1;$row<=$sheet->{'maxrow'};$row++) {
+ my (undef,$sname,$sdom,$fullname,$section,$id) =
+ split(':',$sheet->{'rowlabel'}->{$sheet->{'f'}->{'A'.$row}});
+ push (@sortby, lc($fullname));
+ push (@sortidx, $row);
+ }
+ @sortidx = sort { $sortby[$a] cmp $sortby[$b]; } @sortidx;
+ } elsif ($sheet->{'sheettype'} eq 'studentcalc') {
+ my @sortby1=(undef);
+ my @sortby2=(undef);
+ # Skip row 0
+ for (my $row=1;$row<=$sheet->{'maxrow'};$row++) {
+ my (undef,$symb,$uname,$udom,$mapid,$resid,$title) =
+ split(':',$sheet->{'rowlabel'}->{$sheet->{'f'}->{'A'.$row}});
+ $symb = &Apache::lonnet::unescape($symb);
+ my ($sequence) = ($symb =~ /\/([^\/]*\.sequence)/);
+ if ($sequence eq '') {
+ $sequence = $symb;
+ }
+ push (@sortby1, $sequence);
+ push (@sortby2, $title);
+ push (@sortidx, $row);
+ }
+ @sortidx = sort { $sortby1[$a] cmp $sortby1[$b] ||
+ $sortby2[$a] cmp $sortby2[$b] } @sortidx;
+ } else {
+ my @sortby=(undef);
+ # Skip row 0
+ for (my $row=1;$row<=$sheet->{'maxrow'};$row++) {
+ push (@sortby, $sheet->{'safe'}->reval('$f{"A'.$row.'"}'));
+ push (@sortidx, $row);
+ }
+ @sortidx = sort { $sortby[$a] cmp $sortby[$b]; } @sortidx;
}
- @sortidx=sort { lc($sortby[$a]) cmp lc($sortby[$b]); } @sortidx;
return @sortidx;
}
@@ -1289,7 +1317,7 @@ END
# Print out template row
####################################
my ($rowlabel,@rowdata) = &get_row($sheet,'-');
- my $row_html = '
'.&format_html_rowlabel($rowlabel).'
';
+ my $row_html = '
'.&format_html_rowlabel($sheet,$rowlabel).'
';
my $num_cols_output = 0;
foreach my $cell (@rowdata) {
if ($num_cols_output++ < $num_uneditable) {
@@ -1307,7 +1335,7 @@ END
# Print out summary/export row
####################################
my ($rowlabel,@rowdata) = &get_row($sheet,'0');
- $row_html = '
'.&format_html_rowlabel($rowlabel).'
';
+ $row_html = '
'.&format_html_rowlabel($sheet,$rowlabel).'
';
$num_cols_output = 0;
foreach my $cell (@rowdata) {
if ($num_cols_output++ < 26) {
@@ -1332,6 +1360,20 @@ END
foreach my $rownum (@Rows) {
my ($rowlabel,@rowdata) = &get_row($sheet,$rownum);
next if ($rowlabel =~ /^\s*$/);
+ next if (($sheet->{'sheettype'} eq 'assesscalc') &&
+ (! $ENV{'form.showall'}) &&
+ ($rowdata[0]->{'value'} =~ /^\s*$/));
+ if (! $ENV{'form.showall'} &&
+ $sheet->{'sheettype'} =~ /^(studentcalc|classcalc)$/) {
+ my $row_is_empty = 1;
+ foreach my $cell (@rowdata) {
+ if ($cell->{'value'} !~ /^\s*$/) {
+ $row_is_empty = 0;
+ last;
+ }
+ }
+ next if ($row_is_empty);
+ }
#
my $defaultbg='#E0FF';
#
@@ -1339,11 +1381,11 @@ END
'';
#
if ($sheet->{'sheettype'} eq 'classcalc') {
- $row_html.='
'.&format_html_rowlabel($rowlabel).'
';
+ $row_html.='
'.&format_html_rowlabel($sheet,$rowlabel).'
';
# Output links for each student?
# Nope, that is already done for us in format_html_rowlabel (for now)
} elsif ($sheet->{'sheettype'} eq 'studentcalc') {
- $row_html.='
';
}
#
my $shown_cells = 0;
@@ -1427,7 +1469,7 @@ sub outsheet_csv {
foreach my $rownum (@Rows) {
my ($rowlabel,@rowdata) = &get_row($sheet,$rownum);
next if ($rowlabel =~ /^\s*$/);
- push (@Values,&format_csv_rowlabel($rowlabel));
+ push (@Values,&format_csv_rowlabel($sheet,$rowlabel));
foreach my $cell (@rowdata) {
push (@Values,'"'.$cell->{'value'}.'"');
}
@@ -1488,15 +1530,14 @@ A link to the spreadsheet will be availa
END
$r->rflush();
my $starttime = time;
- foreach (keys(%f)) {
- next if ($_!~/^A(\d+)/ || $1 == 0 || ($f{$_}=~/^[!~-]/));
+ foreach my $rownum (&sort_indicies($sheet)) {
$count++;
- my ($sname,$sdom) = split(':',$f{$_});
+ my ($sname,$sdom) = split(':',$f{'A'.$rownum});
my $student_excel_worksheet=$workbook->addworksheet($sname.'@'.$sdom);
# Create a new spreadsheet
my $studentsheet = &makenewsheet($sname,$sdom,'studentcalc',undef);
# Read in the spreadsheet definition
- &update_student_sheet($studentsheet,$c);
+ &update_student_sheet($studentsheet,$r,$c);
# Stuff the sheet into excel
&export_sheet_as_excel($studentsheet,$student_excel_worksheet);
my $totaltime = int((time - $starttime) / $count * $sheet->{'maxrow'});
@@ -1597,7 +1638,7 @@ sub export_sheet_as_excel {
# Write the summary/export row #
####################################
my ($rowlabel,@rowdata) = &get_row($sheet,'0');
- my $label = &format_excel_rowlabel($rowlabel);
+ my $label = &format_excel_rowlabel($sheet,$rowlabel);
$cols_output = 0;
$worksheet->write($rows_output,$cols_output++,$label);
foreach my $cell (@rowdata) {
@@ -1612,9 +1653,20 @@ sub export_sheet_as_excel {
# Loop through the rows and output them one at a time
foreach my $rownum (@Rows) {
my ($rowlabel,@rowdata) = &get_row($sheet,$rownum);
- next if ($rowlabel =~ /^\s*$/);
+ next if ($rowlabel =~ /^[\s]*$/);
$cols_output = 0;
- my $label = &format_excel_rowlabel($rowlabel);
+ my $label = &format_excel_rowlabel($sheet,$rowlabel);
+ if ( ! $ENV{'form.showall'} &&
+ $sheet->{'sheettype'} =~ /^(studentcalc|classcalc)$/) {
+ my $row_is_empty = 1;
+ foreach my $cell (@rowdata) {
+ if ($cell->{'value'} !~ /^\s*$/) {
+ $row_is_empty = 0;
+ last;
+ }
+ }
+ next if ($row_is_empty);
+ }
$worksheet->write($rows_output,$cols_output++,$label);
if (ref($label)) {
$cols_output = (scalar(@$label));
@@ -1641,7 +1693,7 @@ sub outsheet_xml {
## Outsheet - calls other outsheet_* functions
##
sub outsheet {
- my ($r,$sheet)=@_;
+ my ($sheet,$r)=@_;
if (! exists($ENV{'form.output'})) {
$ENV{'form.output'} = 'HTML';
}
@@ -1753,7 +1805,8 @@ sub readsheet {
if ($fh=Apache::File->new($includedir.'/'.$dfn)) {
$sheetxml=join('',<$fh>);
} else {
- $sheetxml='"Error"';
+ # $sheetxml='"Error"';
+ $sheetxml='';
}
%f=%{&parse_sheet(\$sheetxml)};
} elsif($fn=~/\/*\.spreadsheet$/) {
@@ -1999,18 +2052,22 @@ sub parmval {
## Row label formatting routines ##
##################################################################
sub format_html_rowlabel {
+ my $sheet = shift;
my $rowlabel = shift;
return '' if ($rowlabel eq '');
my ($type,$labeldata) = split(':',$rowlabel,2);
my $result = '';
if ($type eq 'symb') {
- my ($symb,$uname,$udom,$mapid,$resid,$title) = split(':',$labeldata);
+ my ($symb,$mapid,$resid,$title) = split(':',$labeldata);
$symb = &Apache::lonnet::unescape($symb);
$result = ''.$title.'';
} elsif ($type eq 'student') {
my ($sname,$sdom,$fullname,$section,$id) = split(':',$labeldata);
+ if ($fullname =~ /^\s*$/) {
+ $fullname = $sname.'@'.$sdom;
+ }
$result ='';
$result.=$section.' '.$id." ".$fullname.'';
@@ -2023,12 +2080,13 @@ sub format_html_rowlabel {
}
sub format_csv_rowlabel {
+ my $sheet = shift;
my $rowlabel = shift;
return '' if ($rowlabel eq '');
my ($type,$labeldata) = split(':',$rowlabel,2);
my $result = '';
if ($type eq 'symb') {
- my ($symb,$uname,$udom,$mapid,$resid,$title) = split(':',$labeldata);
+ my ($symb,$mapid,$resid,$title) = split(':',$labeldata);
$symb = &Apache::lonnet::unescape($symb);
$result = $title;
} elsif ($type eq 'student') {
@@ -2044,12 +2102,13 @@ sub format_csv_rowlabel {
}
sub format_excel_rowlabel {
+ my $sheet = shift;
my $rowlabel = shift;
return '' if ($rowlabel eq '');
my ($type,$labeldata) = split(':',$rowlabel,2);
my $result = '';
if ($type eq 'symb') {
- my ($symb,$uname,$udom,$mapid,$resid,$title) = split(':',$labeldata);
+ my ($symb,$mapid,$resid,$title) = split(':',$labeldata);
$symb = &Apache::lonnet::unescape($symb);
$result = $title;
} elsif ($type eq 'student') {
@@ -2161,7 +2220,7 @@ sub get_student_rowlabels {
my %assesslist;
foreach ('Feedback','Evaluation','Tutoring','Discussion') {
my $symb = '_'.lc($_);
- $assesslist{$symb} = join(':',('symb',$symb,$uname,$udom,0,0,$_));
+ $assesslist{$symb} = join(':',('symb',$symb,0,0,$_));
}
#
while (my ($key,$srcf) = each(%course_db)) {
@@ -2174,8 +2233,7 @@ sub get_student_rowlabels {
&Apache::lonnet::declutter($course_db{'map_id_'.$mapid}).
'___'.$resid.'___'.&Apache::lonnet::declutter($srcf);
$assesslist{$symb}='symb:'.&Apache::lonnet::escape($symb).':'
- .$uname.':'.$udom.':'.$mapid.':'.$resid.':'.
- $course_db{'title_'.$id};
+ .$mapid.':'.$resid.':'.$course_db{'title_'.$id};
}
}
untie(%course_db);
@@ -2263,7 +2321,8 @@ sub updatestudentassesssheet {
$sheet->{'maxrow'} = 0;
my %existing=();
# Now obsolete rows
- while (my ($cell, $formula) = each (%f)) {
+ foreach my $cell (keys(%f)) {
+ my $formula = $f{$cell};
next if ($cell !~ /^A(\d+)/);
$sheet->{'maxrow'} = $1 if ($1 > $sheet->{'maxrow'});
my ($usy,$ufn)=split(/__&&&\__/,$formula);
@@ -2311,7 +2370,8 @@ sub loadstudent{
undef @tmp;
#
my @assessdata=();
- while (my ($cell,$value) = each (%formulas)) {
+ foreach my $cell (keys(%formulas)) {
+ my $value = $formulas{$cell};
if(defined($c) && ($c->aborted())) {
last;
}
@@ -2323,18 +2383,15 @@ sub loadstudent{
$sheet->{'udom'},
'assesscalc',$usy,$ufn,$r);
my $index=0;
- foreach ('A','B','C','D','E','F','G','H','I','J','K','L','M',
- 'N','O','P','Q','R','S','T','U','V','W','X','Y','Z') {
+ foreach my $col ('A','B','C','D','E','F','G','H','I','J','K','L','M',
+ 'N','O','P','Q','R','S','T','U','V','W','X','Y','Z') {
if (defined($assessdata[$index])) {
- my $col=$_;
if ($assessdata[$index]=~/\D/) {
$constants{$col.$row}="'".$assessdata[$index]."'";
} else {
$constants{$col.$row}=$assessdata[$index];
}
- unless ($col eq 'A') {
- $formulas{$col.$row}='import';
- }
+ $formulas{$col.$row}='import' if ($col ne 'A');
}
$index++;
}
@@ -2597,7 +2654,11 @@ sub loadrows {
sub checkthis {
my ($keyname,$time)=@_;
- return ($time<$expiredates{$keyname});
+ if (! exists($expiredates{$keyname})) {
+ return 0;
+ } else {
+ return ($time<$expiredates{$keyname});
+ }
}
sub forcedrecalc {
@@ -2631,6 +2692,7 @@ sub forcedrecalc {
#
sub exportsheet {
my ($sheet,$uname,$udom,$stype,$usymb,$fn,$r)=@_;
+ my $flag = 0;
$uname = $uname || $sheet->{'uname'};
$udom = $udom || $sheet->{'udom'};
$stype = $stype || $sheet->{'sheettype'};
@@ -2699,14 +2761,24 @@ sub exportsheet {
[$key],
$sheet->{'cdom'},$sheet->{'cnum'});
if ($tmp[0]!~/^error/) {
- %currentlystored = @tmp;
+ # We only got one key, so we will access it directly.
+ foreach (split('___&___',$tmp[1])) {
+ my ($key,$value) = split('___=___',$_);
+ $key = '' if (! defined($key));
+ $currentlystored{$key} = $value;
+ }
}
} else {
my @tmp = &Apache::lonnet::get('nohist_calculatedsheets_'.
$sheet->{'cid'},[$key],
$sheet->{'udom'},$sheet->{'uname'});
if ($tmp[0]!~/^error/) {
- %currentlystored = @tmp;
+ # We only got one key, so we will access it directly.
+ foreach (split('___&___',$tmp[1])) {
+ my ($key,$value) = split('___=___',$_);
+ $key = '' if (! defined($key));
+ $currentlystored{$key} = $value;
+ }
}
}
#
@@ -2725,17 +2797,19 @@ sub exportsheet {
#
# Store away the new value
#
+ my $timekey = $key.'.time';
if ($stype eq 'studentcalc') {
- &Apache::lonnet::put('nohist_calculatedsheets',
- { $key => $newstore,
- $key.time => $now },
- $sheet->{'cdom'},$sheet->{'cnum'});
- } else {
- &Apache::lonnet::put('nohist_calculatedsheets_'.$sheet->{'cid'},
- { $key => $newstore,
- $key.time => $now },
- $sheet->{'udom'},
- $sheet->{'uname'})
+ my $result = &Apache::lonnet::put('nohist_calculatedsheets',
+ { $key => $newstore,
+ $timekey => $now },
+ $sheet->{'cdom'},
+ $sheet->{'cnum'});
+ } else {
+ my $result = &Apache::lonnet::put('nohist_calculatedsheets_'.$sheet->{'cid'},
+ { $key => $newstore,
+ $timekey => $now },
+ $sheet->{'udom'},
+ $sheet->{'uname'});
}
return @exportarr;
}
@@ -3115,7 +3189,7 @@ ENDSCRIPT
# Write the modified worksheet
$r->print('Current sheet: '.$sheet->{'filename'}.'');
&tmpwrite($sheet);
- if ($sheet->{'sheettype'} eq 'studentcalc') {
+ if ($sheet->{'sheettype'} eq 'assesscalc') {
$r->print('
Show rows with empty A column: ');
} else {
$r->print('
Show empty rows: ');
@@ -3147,13 +3221,18 @@ ENDSCRIPT
}
$r->print('>'.$mode.''."\n");
}
- if ($sheet->{'sheettype'} eq 'classcalc') {
- $r->print('\n");
- }
+#
+# Mulit-sheet excel takes too long and does not work at all for large
+# classes. Future inclusion of this option may be possible with the
+# Spreadsheet::WriteExcel::Big and speed improvements.
+#
+# if ($sheet->{'sheettype'} eq 'classcalc') {
+# $r->print('\n");
+# }
$r->print("\n");
#
if ($sheet->{'sheettype'} eq 'classcalc') {
@@ -3171,7 +3250,7 @@ ENDSCRIPT
#value='Insert Row Bottom'>
#ENDINSERTBUTTONS
# Print out sheet
- &outsheet($r,$sheet);
+ &outsheet($sheet,$r);
$r->print('