Zoros (Talk | contribs)
(-)
Newer edit →

Revision as of 23:33, 23 October 2012

// fet2xls extract tables from FET timetable (.csv)
// and returns several tables in .csv format to import in a spreadsheet program
// Copyright Fabio Zorba 2012
// Rev.1.0 2012-10-24
 
// This program is free software; you can redistribute it and/or modify it
// under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License,
// or (at your option) any later version. 
 
Uses strings, sysutils;
{$H+}
 
const
	MAX = 200;
 
var
	//input file
	csv_file : text;
	csv_input_name : string;
        ActivityId, Day, Hour, Students, Subject, Teacher, ActivityTags, Room , Comments : string;
 
	linea : string;
 
	//Note: search procedure uses upcase Day field string
	lessonDays : array [1..6] of string;
 
	//result table
	weektab : array [1..MAX,1..7,1..7] of string;
 
	//result table
	weektab3 : array [1..MAX*3,1..36] of string;
 
	//this will be filled with all Hour string found in .csv input file;
	lessonhours : array [1..7] of string;
	maxlessonhour : integer;
 
	//this will be filled with all names of classes found in .csv input file
	classes : array [1..MAX] of string;
	maxclasses : integer;
 
	//this will be filled with all names of teachers found in .csv input file
	teachers : array [1..MAX] of string;
	maxteachers : integer;
 
	//this will be filled with all names of rooms found in .csv input file
	rooms : array [1..MAX] of string;
	maxrooms : integer;
 
//get string field at dist position in string textline
function find_next (textline : string; separator : char; var pos : integer; dist : integer) : string;
var
	result, temp : string;
	n : integer;
 
begin
	find_next := '';
	if pos >= length (textline) then exit;
 
	n := 1;
 
	while (n < dist) do
	begin
		while (pos <= length (textline)) and (textline[pos] <> separator) do pos := pos + 1;
		if (textline[pos] = separator) then pos := pos + 1;
		n := n + 1;
	end;
 
	result := '';
	while (pos <= length (textline)) and (textline[pos] <> separator) do
	begin
		result := result + textline[pos];
		pos := pos + 1;
	end;
 
	temp := '';
	for n := 1 to length (result) do
	 if (result [n] <> '"') then temp := temp + result [n];
 
	if (textline[pos] = separator) then pos := pos + 1;
 
	find_next := temp;
end;
 
//return true if str1 is substring of str2
function is_inside (str1,str2 : string) : boolean;
var
	n : integer;
	tmp : string;
begin
 
 is_inside := false;
 
 if (length (str1) = length (str2)) then exit;
 
 for n := 1 to length (str2) - length (str1) + 1 do
 begin
	tmp := copy (str2,n,length (str1));
	if (tmp = str1) then is_inside := true;
 end;
 
end;
 
procedure get_all_field_in_line (linea : string);
var
	count : integer;
begin
 count := 1;
 
 ActivityId := find_next (linea, ',', count, 1);
 Day := find_next (linea, ',', count, 1);
 Hour := find_next (linea, ',', count, 1);
 Students := find_next (linea, ',', count, 1);
 Subject := find_next (linea, ',', count, 1);
 Teacher := find_next (linea, ',', count, 1);
 ActivityTags := find_next (linea, ',', count, 1);
 Room := find_next (linea, ',', count, 1);
 Comments := find_next (linea, ',', count, 1);
 
 Day := uppercase (copy (Day, 1, length (lessonDays[1])));
end;
 
procedure show_table (maxelements : integer);
var
	i, n, k : integer;
begin
 for k := 1 to maxelements do
 begin
	writeln;
	writeln (classes [k]);
	writeln;
	for i := 1 to 7 do
	begin
		for n := 1 to 7 do write (weektab [k,i,n],' ':15-length(weektab [k,i,n]));
		writeln;
 	end;
 end;
end;
 
procedure find_all_lesson_hours;
var
	n, count : integer;
	tmpstr : string;
	hour_finded, sorted : boolean;
 
begin
 //search all Hour strings
 Assign(csv_file, csv_input_name + '.csv'); 
 Reset (csv_file);
 
 readln (csv_file,linea);
 
 maxlessonhour := 0;
 
 while not eof (csv_file) do
 begin
 
  readln (csv_file,linea);
 
  //third field is Hour name
  count := 1;
  Hour := find_next (linea, ',', count, 3);
 
  hour_finded := false;
  for n := 1 to maxlessonhour do if (lessonhours [n] = Hour) then hour_finded := true;
 
  if not hour_finded then
  begin
	maxlessonhour := maxlessonhour + 1;
	lessonhours [maxlessonhour] := Hour;
  end;
 end;
 
 close (csv_file);
 
 repeat
 	sorted := true;
 	for n := 2 to maxlessonhour do
 	begin
		if (lessonhours [n-1] > lessonhours [n]) then
		begin
			tmpstr := lessonhours [n-1];
			lessonhours [n-1] := lessonhours [n];
			lessonhours [n] := tmpstr;
			sorted := false;
		end;
	end;
 until sorted;
 
 //for count := 1 to maxlessonhour do writeln (lessonhours [count]);
end;
 
procedure find_all_classes;
var
	n, count : integer;
	tmpstr : string;
	found, sorted : boolean;
begin
 //search all classe names
 Assign(csv_file, csv_input_name + '.csv'); 
 Reset (csv_file);
 
 readln (csv_file,linea);
 
 maxclasses := 0;
 
 while not eof (csv_file) do
 begin
 
  readln (csv_file,linea);
 
  //fourth field is classes name
  count := 1;
  Students := find_next (linea, ',', count, 4);
 
  count := 1;
  tmpstr := find_next (Students, '+', count, 2);
  if tmpstr <> '' then Students := tmpstr;
 
  if Students = '' then writeln ('Warning, a Students field is blank')
  else
  begin
 
  found := false;
  for n := 1 to maxclasses do if (classes [n] = Students) then found := true;
 
  if not found then
  begin
	maxclasses := maxclasses + 1;
	classes [maxclasses] := Students;
  end;
  end;
 
 end;
 
 close (csv_file);
 
 repeat
 	sorted := true;
 	for n := 2 to maxclasses do
 	begin
		if (classes [n-1] > classes [n]) then
		begin
			tmpstr := classes [n-1];
			classes [n-1] := classes [n];
			classes [n] := tmpstr;
			sorted := false;
		end;
	end;
 until sorted;
 
 //for count := 1 to maxclasses do writeln (classes [count]);
end;
 
procedure find_all_teachers;
var
	n, count : integer;
	tmpstr : string;
	found, sorted : boolean;
begin
 //search all classe names
 Assign(csv_file, csv_input_name + '.csv'); 
 Reset (csv_file);
 
 readln (csv_file,linea);
 
 maxteachers := 0;
 
 while not eof (csv_file) do
 begin
 
  readln (csv_file,linea);
 
  //sixth field is classes name
  count := 1;
  Teacher := find_next (linea, ',', count, 6);
 
  count := 1;
  tmpstr := find_next (Teacher, '+', count, 2);
  if tmpstr <> '' then Teacher := tmpstr;
 
  if Teacher = '' then writeln ('Warning, a Teacher field is blank')
  else
  begin
 
  found := false;
  for n := 1 to maxteachers do if (teachers [n] = Teacher) then found := true;
 
  if not found then
  begin
	maxteachers := maxteachers + 1;
	teachers [maxteachers] := Teacher;
  end;
  end;
 
 end;
 
 close (csv_file);
 
 repeat
 	sorted := true;
 	for n := 2 to maxteachers do
 	begin
		if (teachers [n-1] > teachers [n]) then
		begin
			tmpstr := teachers [n-1];
			teachers [n-1] := teachers [n];
			teachers [n] := tmpstr;
			sorted := false;
		end;
	end;
 until sorted;
 
 //for count := 1 to maxteachers do writeln (teachers [count]);
end;
 
procedure find_all_rooms;
var
	n, count : integer;
	tmpstr : string;
	found, sorted : boolean;
begin
 //search all classe names
 Assign(csv_file, csv_input_name + '.csv'); 
 Reset (csv_file);
 
 readln (csv_file,linea);
 
 maxrooms := 0;
 
 while not eof (csv_file) do
 begin
 
  readln (csv_file,linea);
 
  //forth field is classes name
  count := 1;
  Room := find_next (linea, ',', count, 8);
 
  count := 1;
  tmpstr := find_next (Room, '+', count, 2);
  if tmpstr <> '' then Room := tmpstr;
 
 
  found := false;
  for n := 1 to maxrooms do if (rooms [n] = Room) then found := true;
 
  if not found and (Room <> '') then
  begin
	maxrooms := maxrooms + 1;
	rooms [maxrooms] := Room;
  end;
 
 end;
 
 close (csv_file);
 
 repeat
 	sorted := true;
 	for n := 2 to maxrooms do
 	begin
		if (rooms [n-1] > rooms [n]) then
		begin
			tmpstr := rooms [n-1];
			rooms [n-1] := rooms [n];
			rooms [n] := tmpstr;
			sorted := false;
		end;
	end;
 until sorted;
 
 //for count := 1 to maxrooms do writeln (rooms [count]);
end;
 
procedure reset_results_table (max_elements : integer);
var
	i, n, j, k : integer;
begin
 for k := 1 to max_elements do
 begin
 
 for i := 1 to 7 do
  for n := 1 to 7 do weektab [k,i,n] := '';
 
 //fill Days header
 for j := 1 to length (lessonDays) do weektab [k,1,1+j] := lessonDays [j];
 
 //fill Hours header
 for j := 1 to maxlessonhour do weektab [k,1+j,1] := lessonhours [j];
 
 end;
 
end;
 
procedure make_results_table_per_classes (switch : char);
var
	i,k,n, row, col : integer;
begin
 reset_results_table (maxclasses);
 
 for k := 1 to maxclasses do
 begin
 
 weektab [k,1,1] := classes [k];
 
 Assign(csv_file, csv_input_name + '.csv'); 
 Reset (csv_file);
 
 readln (csv_file,linea);
 
 while not eof (csv_file) do
 begin
 
 readln (csv_file,linea);
 
 get_all_field_in_line (linea);
 
 col := 0;
 row := 0;
 if ((Students = classes [k]) or is_inside (classes [k], Students)) then
 //if (students = classes [k]) then
 begin
	for n := 2 to 7 do if (Day = weektab [k,1,n]) then col := n;
	for i := 2 to 7 do if (Hour = weektab [k,i,1]) then row := i;
 end;
 
 if ((col > 0) and (row > 0)) then
	case upcase (switch) of
		'S' : weektab [k,row,col] := Subject;
		'T' : weektab [k,row,col] := Teacher;
		'R' : weektab [k,row,col] := Room;
	end;
 end;
 
 close (csv_file)
 
 end;
 
end;
 
procedure make_results_table_per_teachers;
var
	i,k,n, row, col : integer;
begin
 reset_results_table (maxteachers);
 
 for k := 1 to maxteachers do
 begin
 
 weektab [k,1,1] := teachers [k];
 
 Assign(csv_file, csv_input_name + '.csv'); 
 Reset (csv_file);
 
 readln (csv_file,linea);
 
 while not eof (csv_file) do
 begin
 
 readln (csv_file,linea);
 
 get_all_field_in_line (linea);
 
 col := 0;
 row := 0;
 if ((Teacher = teachers [k]) or is_inside (teachers [k], Teacher)) then
 begin
	for n := 2 to 7 do if (Day = weektab [k,1,n]) then col := n;
	for i := 2 to 7 do if (Hour = weektab [k,i,1]) then row := i;
 end;
 
 if ((col > 0) and (row > 0)) then weektab [k,row,col] := Students;
 
 end;
 
 close (csv_file)
 
 end;
 
end;
 
procedure make_results_table_per_rooms;
var
	i,k,n, row, col : integer;
begin
 reset_results_table (maxrooms);
 
 for k := 1 to maxrooms do
 begin
 
 weektab [k,1,1] := rooms [k];
 
 Assign(csv_file, csv_input_name + '.csv'); 
 Reset (csv_file);
 
 readln (csv_file,linea);
 
 while not eof (csv_file) do
 begin
 
 readln (csv_file,linea);
 
 get_all_field_in_line (linea);
 
 col := 0;
 row := 0;
 if ((Room = rooms [k]) or is_inside (rooms [k], Room)) then
 begin
	for n := 2 to 7 do if (Day = weektab [k,1,n]) then col := n;
	for i := 2 to 7 do if (Hour = weektab [k,i,1]) then row := i;
 end;
 
 if ((col > 0) and (row > 0)) then weektab [k,row,col] := Students;
 
 end;
 
 close (csv_file)
 
 end;
 
end;
 
procedure fill_long_table3 (pos : integer);
var
	i, n, k, j : integer;
begin
 
 for k := 0 to maxclasses-1 do
 begin
	 j := 1;
 
	for i := 2 to 7 do
	begin
		for n := 2 to 7 do
		begin
			weektab3 [k*3+1+pos,j] := weektab [k+1,n,i];
			j := j + 1;
		end;
 	end;
 
 end;
end;
 
procedure csv_result_output_table (elements : integer; file_name : string);
var
	i, n, k : integer;
begin
 assign (csv_file, file_name);
 rewrite (csv_file);
 
 for k := 1 to elements do
 if not is_inside ('+', classes [k]) then
 begin
	//write (csv_file,classes [k]);
 
	for i := 1 to 7 do
	begin
		for n := 1 to 6 do write (csv_file,weektab [k,i,n], ',');
		writeln (csv_file, weektab [k,i,7]);
 	end;
	writeln (csv_file);
 end;
 
 close (csv_file);
end;
 
procedure csv_result_output_teachers_long (file_name : string);
var
	i, n, k : integer;
begin
 assign (csv_file, file_name);
 rewrite (csv_file);
 
 write (csv_file, ',');
 
 for i := 2 to 7 do write (csv_file, weektab [1,1,i],',,,,,,');
 
 writeln (csv_file);
 
 for i := 2 to 7 do
 begin
	for n := 1 to 6 do write (csv_file, ',', n:1);
 end;
 
 writeln (csv_file);
 
 for i := 2 to 7 do
 begin
	for n := 2 to 7 do write (csv_file, ',', weektab [1,n,1]);
 end;
 
 writeln (csv_file);
 
 for k := 1 to maxteachers do
 //if not is_inside ('+', classes [k]) then
 begin
	//Teacher name
	write (csv_file,weektab [k,1,1]);
 
	for i := 2 to 7 do
	begin
		for n := 2 to 7 do write (csv_file, ',', weektab [k,n,i]);
//		writeln (csv_file, weektab [k,i,7]);
 	end;
	writeln (csv_file);
 end;
 
 close (csv_file);
end;
 
procedure csv_result_output_classes_long (file_name : string);
var
	i, n, k : integer;
begin
 assign (csv_file, file_name);
 rewrite (csv_file);
 
 write (csv_file, ',');
 
 for i := 2 to 7 do write (csv_file, weektab [1,1,i],',,,,,,');
 
 writeln (csv_file);
 
 for i := 2 to 7 do
 begin
	for n := 1 to 6 do write (csv_file, ',', n:1);
 end;
 
 writeln (csv_file);
 
 for i := 2 to 7 do
 begin
	for n := 2 to 7 do write (csv_file, ',', weektab [1,n,1]);
 end;
 
 writeln (csv_file);
 
 for k := 0 to maxclasses-1 do
 
 begin
	//Classes name
	write (csv_file,classes [k+1]);
	for i := 1 to 36 do write (csv_file, ',', weektab3 [k*3+1,i]);
	writeln (csv_file);
 
	//write (csv_file, ',');
	for i := 1 to 36 do write (csv_file, ',', weektab3 [k*3+2,i]);
	writeln (csv_file);
 
	//write (csv_file, ',');
	for i := 1 to 36 do write (csv_file, ',', weektab3 [k*3+3,i]);
	writeln (csv_file);
 end;
 
 close (csv_file);
end;
 
 
begin
 
 if (paramcount = 0) then
 begin
  writeln ('Usage:   fet2xls [weekdays] fet-timetable-file (without .csv)');
  writeln;
  writeln ('example: fet2xls MON TUE WED THU FRI SAT myhighschool-2012');
  writeln;
  exit;
 end;
 
 if paramcount < 7 then
 begin
  writeln ('Error, you must define 6 weekdays');
  writeln;
  exit;
 end;
 
 LessonDays [1] := paramstr (1);
 LessonDays [2] := paramstr (2);
 LessonDays [3] := paramstr (3);
 LessonDays [4] := paramstr (4);
 LessonDays [5] := paramstr (5);
 LessonDays [6] := paramstr (6);
 
 csv_input_name := paramstr (7);
 
 find_all_lesson_hours;
 
 find_all_classes;
 
 find_all_teachers;
 
 find_all_rooms;
 
 make_results_table_per_classes ('S');
 fill_long_table3 (0);
 csv_result_output_table (maxclasses, csv_input_name + '-classes-subject.csv');
 
 make_results_table_per_classes ('T');
 fill_long_table3 (1);
 csv_result_output_table (maxclasses, csv_input_name + '-classes-teachers.csv');
 
 make_results_table_per_teachers;
 csv_result_output_table (maxteachers, csv_input_name + '-teachers.csv');
 csv_result_output_teachers_long (csv_input_name + '-teachers-long.csv');
 
 make_results_table_per_rooms;
 csv_result_output_table (maxrooms, csv_input_name + '-rooms.csv');
 
 make_results_table_per_classes ('R');
 fill_long_table3 (2);
 csv_result_output_table (maxclasses, csv_input_name + '-classes-rooms.csv');
 
 csv_result_output_classes_long (csv_input_name + '-timeline-long.csv');
 
end.
Retrieved from "http://www.zoros.org/wiki/index.php?title=Fet2calc_source_code"