I need to make the loop close somehow.
I was thinking in making While Rec.FieldText NOT FIN do begin (the user stops adding info when FIN is typed).
Okay... first things first.
I see you will be using a procedure for encode_date and not a function. That is your choice but I hope you know the difference between a procedure and a function. If not, then that's one of the things you might want to read up on.
The second thing is this:
encode_date ( fecha,Year,Month,Day,y_offset );
myWriteWord (Header.Date); //fecha
You give Year, Month and y_offset as parameter to this procedure. Why? You don't use it anywhere in the rest of your program. That leads me to my second suggestion for "homework". You might want to lean what "local variables" are. You keep putting your variables (which we already declared in the function in our examples) at the top of your program. You need to learn that if you only use variables within a procedure or function you need to declare them there (or at least it's better coding). For instance that Len variable you use in myWriteString. You only use it in myWriteString so you can declare it in myWriteString itself (as I originally did with myReadString). Don't do it at the top of your program. The same goes for Year, Month and y_offset. In that case you don't even need to have these as parameter for the call.
Then those lines above again:
encode_date ( fecha,Year,Month,Day,y_offset );
myWriteWord (Header.Date); //fecha
You have fecha, which is calculated in the encode_date. What do you do with it??? I don't see you using it. You go on writing Header.Date, but that's not initialized yet. You need to put the value fecha into Header.Date before you write Header.Date to the file.
Next part:
for nrs := 0 to Header.Fieldnrs - 1 do
begin
Writeln ('Ingrese Nombre de dato numero:', nrs+1);
myWriteWord (Fields[nrs].Fieldnr);
ReadLn (Fields[nrs].Fieldname);
end;
You read Header.Fieldnrs from user input. Ok. Next you loop the variable nrs to get the name of all the fields. But you writeout Fields[nrs].Fieldnr, which hasn't any value yet. So first put the nrs value in Fields[nrs].Fieldnr before writing it to disk. Next you read the Fields[nrs].Fieldname. Shouldn't you write that to disk too???
Then the next part:
cant_reg:=0;
Writeln ('Ingrese datos de contactos o escriba FIN para finalizar');
After this you go on reading the contacts themselves. But according to the documentation you need to first write the number of contacts you're going to write. So first ask the user how many contacts (s)he's going to enter and write that number to disk.
Then your problem line:
While Rec[I].FieldText NOT FIN do begin
I'm not sure what you're trying to do here.
If it's something that a user can enter "FIN" then you should've done this
While Rec[I].FieldText <> 'FIN' do begin
But... that's not going to work in your case. Because the user FIRST needs to enter the number of contacts (s)he's going to enter, ending with "FIN" doesn't work.
You need to loop (for/next) for NumberOfContacts the user entered. The user can't break off the input before (s)he's has entered all contacts.
So above the for I := 0 to Header.Fieldnrs - 1 you need to do something like this:
for J := 1 to NumberOfContacts do
begin
for I := 0 to Header.Fieldnrs - 1 do
begin
//....
I hope you take my suggestion of learning the difference in procedure and function and working with local variables to heart and you can do something useful with the notes I gave above.