Suponemos que en el Form tenemos:
- Una lista de números telefónicos almacenados en un grid con varias columnas (en la columna 3 está el número de teléfono donde hay que enviar el SMS),
- Un TButton con el siguiente procedimiento asociado al evento OnClick, su función es ir leyendo fila a fila el grid obteniendo el número de teléfono y el texto a enviar, que en este caso he puesto un texto fijo, pero que si lo que queréis es enviar un texto diferente a cada número de teléfono, se almacenaría en la columna 1 para leerlo de esta forma TEXTO:= grid3.Cells[0, i];
PROCEDURE TForm1.Button6Click(Sender: TObject); VAR texto, CeldaX, Nombre,telefono: ansistring; i: integer; BEGIN TRY Application.processmessages; Label1.caption := 'ENVIANDO SMS...'; FOR i := 1 TO grid3.rowcount - 1 DO BEGIN grid3.SetFocus; grid3.Row := i; BEGIN TEXTO := 'Este es el texto del SMS'; Telefono:= grid3.Cells[2, i]; EnviarSMS(telefono,texto, Rdo, CodigoError); IF ansipos(chr(13) + chr(10) + '+CMGS:', Rdo) > 0 THEN BEGIN // Si el envío es correcto pone en la columna 5 del grid un OK+Fecha grid3.cells[4, i] := 'OK: ' + DateTostr(now); END ELSE grid3.cells[4, i] := '===ERROR===' END; END; FINALLY Application.processmessages; Label1.caption := 'ENVÍO TERMINADO'; END; END; PROCEDURE tForm1.EnviarSMS(Telefono, texto: ansistring; VAR Rdo: ansistring; VAR CodigoError: Integer); BEGIN enviar('AT+CMGS="' + telefono + '"', Rdo, CodigoError); //Después del comando at+cmgs el modem devuelve: > IF ansipos('>', Rdo) > 0 THEN BEGIN enviar('"' + texto + '"' + ^Z, Rdo, CodigoError); END; END;
El procedimiento "enviar" es el mismo que anteriores posts, pero lo pongo para facilitar la comprensión del procedimiento anterior
PROCEDURE tform1.enviar(at: ANSISTRING; VAR Rdo: ansistring; VAR CodigoError: integer); BEGIN CodigoError := 0; Edit1.TExt := ''; rdo := ''; Terminado := False; Segundos := 0; IF (FStatusTrigger = 0) THEN BEGIN FStatusTrigger := ApdComPort1.AddStatusTrigger(stLine); ApdComPort1.SetStatusTrigger(FStatusTrigger, lsOverrun OR lsParity OR lsFraming OR lsBreak, True); END; memo1.Lines.add('>>' + at + chr(13)); timer1.Enabled := true; ApdComPort1.OutPut := at + chr(13); REPEAT delay(2000) UNTIL Terminado; END; Procedimiento del objeto ApdComPort1, que se dispara para recoger los caracteres del buffer PROCEDURE TForm1.ApdComPort1TriggerAvail(CP: TObject; Count: Word); {Event OnTriggerAvail - Example how OnTriggerAvail works} VAR I: Word; C: Char; S, s1: STRING; BEGIN FOR I := 1 TO Count DO BEGIN C := ApdComPort1.GetChar; s1 := c; Rdo := Rdo + s1; END; memo1.lines.add(Rdo); IF ansipos(chr(13) + chr(10) + 'OK' + chr(13) + chr(10), Rdo) > 0 THEN BEGIN application.processmessages; edit1.Text := Rdo; END; END;
Si queremos leer todos los mensajes almacenados en la SIM y copiarlos en el Grid1 tendremos que utilizar el comando AT+CMGL=all de la siguiente forma:
PROCEDURE TForm1.Button2Click(Sender: TObject); VAR linea1, linea2: ansistring; contador, contadorfila: integer; HayParametros: boolean; BEGIN contador := 2; contadorfila := 1; HayParametros := false; //Lee todos los mensajes de la SIM enviar('AT+CMGL=all', Rdo, CodigoError); REPEAT //captura el token nº “contador” de la cadena RDO, separada por el carácter chr(13)) linea1 := gettoken(Rdo, chr(13), contador); IF ansipos('+CMGL:', linea1) > 0 THEN BEGIN inc(contadorFila); Grid1.Cells[0, contadorFila] := gettoken(linea1, ',', 1); Grid1.Cells[1, contadorFila] := gettoken(linea1, ',', 2); Grid1.Cells[2, contadorFila] := gettoken(linea1, ',', 3); Grid1.Cells[4, contadorFila] := gettoken(linea1, ',', 4); Grid1.Cells[5, contadorFila] := gettoken(linea1, ',', 5); Grid1.Cells[6, contadorFila] := gettoken(linea1, ',', 6); Grid1.Cells[7, contadorFila] := gettoken(linea1, ',', 7); Grid1.Cells[8, contadorFila] := gettoken(linea1, ',', 8); HayParametros := true; END ELSE BEGIN IF HayParametros THEN BEGIN Grid1.Cells[9, contadorFila] := linea1; END; HayParametros := false; END; inc(contador); UNTIL (ansipos('OK', LINEA1) > 0) OR (ansipos('OK', LINEA2) > 0) OR (contador > 100); END;
Para borrar todos los mensajes de la SIM tendremos que usar el comando AT+CMGD=numero del mensaje
PROCEDURE TForm1.Button1Click(Sender: TObject); VAR I: INTEGER; BEGIN FOR I := 0 TO Grid1.rowcount - 1 DO BEGIN application.processmessages; label7.caption := 'Borrando mensaje: ' + inttostr(i); application.processmessages; enviar('AT+CMGD=' + inttoStr(i), Rdo, CodigoError); END; END;
Una vez que se muestran todos los mensajes en la rejilla podremos borrar un mensaje cualquiera haciendo doble clic sobre una fila , utilizando el siguiente procedimiento:
PROCEDURE TForm1.Grid1DblClick(Sender: TObject); VAR NumeroDeMensaje: ansistring; i: integer; BEGIN IF MessageDlg('Eliminar mensaje ?' + grid1.Cells[0, FilaSeleccionada], mtConfirmation, [mbYes, mbNo], 0) = mryes THEN BEGIN NumeroDeMensaje := gettoken(grid1.Cells[0, FilaSeleccionada], ':', 2); enviar('AT+CMGD=' + NumeroDeMensaje, Rdo, CodigoError); IF CodigoError = 0 THEN BEGIN FOR i := 0 TO grid1.ColCount - 1 DO grid1.Cells[i, FilaSeleccionada] := ''; END; END; END;
Relacionados:
Cómo enviar un SMS desde cero ( I )
Cómo enviar un SMS desde cero ( II )