Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Mike Lewis on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Sending Cursor to Email Recipient 1

Status
Not open for further replies.

dantheinfoman

Programmer
May 5, 2015
131
US
Hi All,

Looking for recommendations for the best method to send out daily summary emails to several salespeople. I have a cursor with their emails and details for each record. I'd like to just be able to transform this cursor as text or table in an email and send. Not sure how to do that. I tried messing with TEXT ENDTEXT, but it doesn't allow me to perform SCAN function to traverse the cursor. Then I wondered about DEBUGOUT, as I thought I've seen people put a bunch of stuff in there and then later copy it all to somewhere else, such as an email. The email message would be really simple, just showing the contents of the cursor, like:

Date Prospect Email Comment
01/01/2000 ABC Company dan@123.com This person wants to buy!
06/08/2016 ZBA Industries lala@test.net Left VM. Will cb tomorrow.

I welcome all ideas and thank you!

Dan
 
>I tried TEXT ENDTEXT, but it doesn't allow me to perform SCAN function to traverse the cursor
What did you try?

Code:
CREATE CURSOR crsZoltan (dDate D, cCode C(3), vPrediction V(80))
INSERT INTO crsZoltan VALUES (DATE()+7,"ABC","Genesis")
INSERT INTO crsZoltan VALUES (DATE()+14,"XYZ","Armageddon")

lcMailBody=""
Scan
Text To lcMailBody noshow textmerge ADDITIVE
<<dDate>> <<cCode>> <<vPrediction>>

EndText
EndScan

? lcMailBody

Did you try SCAN..ENDSCAN within TEXT..ENDTEXT?

Bye, Olaf.
 
You could try something like the following:

Code:
cCRLF = CHR(13) + CHR(10)

SELECT EmailInfo
SET ORDER TO Email  && This assumes that you have an Index on the Email field
SCAN
  cEmailAddress = EmailInfo.Email
  cBodyText = ""
  DO WHILE Email = cEmailAddress;
       AND !EOF()
     cBodyText = cBodyText + DTOC(Date) + ALLTRIM(Prospect) + Comment + cCRLF
     SKIP
  ENDDO
  SendEmail(cEmailAddress, cBodyText)
  SKIP -1
ENDSCAN

* ------------------------
FUNCTION SendEmail
PARAMETERS cEmailAddr, cBody
<do whatever you need to do to send this out>
RETURN .T.

Good Luck,
JRB-Bldr
 
Thanks, Olaf. Yes, I was putting SCAN inside the TEXT function, because I'm apparently very simple. . . You make everything look easy, buddy. Thank you!!

JRB, I probably would have done something like that initially, but I think I was afraid the variable would be maxed out at 255 characters and I have memo fields. Perhaps it wouldn't?!

Here's what I've got now that is working:

Code:
SELECT c_emadds
	SCAN 		
	
		lcMailBody="" 
		SELECT cur_emails
		SCAN FOR CUR_EMAILS.E_MAIL=C_EMADDS.E_MAIL
*!*				SELECT CUR_EMAILS
*!*				SELECT CUR_EMAILS.* FROM CUR_EMAILS WHERE CUR_EMAILS.E_MAIL=C_EMADDS.E_MAIL inTO CURSOR blah1 READWRITE 
			
			
			Scan
				Text To lcMailBody noshow textmerge ADDITIVE
PROSPECT: <<PROSPECT>>
STATE: <<STATE>>
CONTACT: <<CONTACT_1>>TITLE: <<TITLE_1>>
DATE: <<DATE>>
TYPE: <<CTYPE>> <<TYPEDESC>>
TOPIC: <<COMTOP>>
COMMENT: <<SHCOMM>>
--------------------


				EndText
			EndScan
***********************************************************
* Start Email
***********************************************************

Thanks guys, you are awesome!

Dan
 
String Variables can hold any length:

Code:
Local lcString
lcString = ""
t0 = Seconds()
Do while Seconds()-t0<3
  lcString = lcString + Space(16*10^6)
EndDo 
? Transform(Len(lcString),"@R 9,999,999,999")

So string variables are rather like MEMO fields, which makes sense, as you can also scatter memos into variables

The help chapter of system capacities talks of a string length limit of 16,777,184 Bytes, but that's only a limit for some functions handling strings, not for strings themselves. For example ? Len(Space(16777185)) is failing, while ? Len(Space(16777184)) works. Binary this means 0xffffe0, I can't tell you what the 0x20 bytes are used for, perhaps for a struct about the string. Maybe 16MB is the max memory block VFP is reserving for strings at any time, but strings can grow larger, see above.

255 characters is a limit for string literals. TEXT..ENDTEXT is nothing else but a string delimiter for multiline strings and though that also makes text inside it a string literal it can be longer, too, so the 255 char limit is for the classic delimiters ".' and [] only. Because it is just another string delimiter set, you can't run code inside it, you can have textmerge expressions, if you use the TETMERGE option. That's working just like the TextMerge() function works.

So in the end the 254/255 limits you are afraid of is for char fields and string literals. Seems the meaning of literals is lost. Literals are what you write in source code literally, eg in var=42 the 42 is a literal number instead of an expression. So what is a literal string? It's a string you literally write into source code - as inline constant, so to say. So that limit rather is a limit of the parser/lexer/compiler only waiting for at max 255 characters for the string end delimiter. Assuming you'll never write longer code lines than perhaps 80 chars, 255 is quite no limit from that point of view. It allows to write lines wider than your display needing scrolling to read, that limit could even be reduced and be no harm for any decent program.

Bye, Olaf.
 
Just by the way, I tried to see what may happen at faster computers than I have. I'm quite confident 3 seconds of adding +16MB strings does not cause an overflow or out of memory exception, though it could. I limited my loop on 3 seconds running.

What I see is a degradation of speed, if I modify this. Please only try this on a new session of the VFP IDE and not while you are working in any project:
Code:
Local lcString
lcString = ""
Do while .T.
  lcString = lcString + Space(16*10^6)
  ? Time(), Transform(Len(lcString),"@R 9,999,999,999")
EndDo

I intentionally ran this on my older Win7 PC with just a 1.6GHz CPU, and though it has 8GB of which the OS can use 7.6 and the VFP IDE could take 2GB, it stops at about 500MB:
outofmemory_kchxli.png


Instead of this error - from which you can recover - you might also get a crash like the following:
crash_bmn5lm.png

This would translate to "Microsoft Visual Foxpro has stopped working ...", the more user friendly C5 typpe of crash. So again the warning don't try this as a little aside copy&past of prg code and run it while you are in development of your project, you might lose your last work on somthing else.

One interesting thing of this is how macroscopic long it becomes to add the same amount of bytes. It's due to the fact the new 16,000,000 Spaces are not appended to already reserved memroy, VFP has to allocate a new memory section for the variable each time you add something. That's also a reason you shouldn't work with strings longer than about 16MB anyway. I'd even lower that limit, as operations on strings get sluggish earlier in comparison with other programming languages. You would process longer files via chunks of perhaps just a few KB only, far below a MB, surely not via STRTOFILE(), especially when working with the string more than just one operation. You naturally do it with records of a DBF in contrast to STRTOFILE() of a DBF, you work on the small chunks of Recsize() bytes, as that is one unit of the DBF.

Anyway the length of an email text would not be a problem at all.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top