for loop ending early

Get help with using AutoHotkey (v1.1 and older) and its commands and hotkeys
SchenkerAHK
Posts: 1
Joined: 09 May 2024, 15:15

for loop ending early

09 May 2024, 15:30

I have some code to look through all the emails in an inbox, then check for and remove attachments from them and after that they are sorted into designated mailboxes. The issue is the main for loop I am using does not always iterate through all emails and will terminate after just going through about half of them at a time. Am I doing something wrong here or is there a better strategy for me to use?

Code: Select all


; Initialize Outlook application
Outlook := ComObjCreate("Outlook.Application")
Namespace := Outlook.GetNamespace("MAPI")
Sleep, 50

; Access the Inbox folder
;Inbox := Namespace.GetDefaultFolder(6) ; 6 corresponds to olFolderInbox
Inbox := Namespace.Folders(;redacted)
Sleep, 50

; Access the "Test" subfolder within the Inbox
TestFolder := Inbox.Folders("Inbox")
Sleep, 50
ManualReview := Inbox.Folders("Inbox").Folders("Manual Review")
Sleep, 50
Archive := Inbox.Folders("Archive")
Sleep, 50

; Loop through all items in the "Test" subfolder
for i in TestFolder.Items
{
    ; Check if the item is a mail item
	if (i.Class = 43) ; 43 corresponds to olMail (Outlook Mail Item)
	{
		Sleep, 50
          ;Access mail properties
		;internal email
		if i.SenderEmailType = "EX"
		{
			SenderEmailAddress := i.Sender.GetExchangeUser().PrimarySmtpAddress
			SenderEmailAddress := SenderEmailAddress . ";;;" . i.Subject . ";"
			SenderEmailAddress := StrReplace(SenderEmailAddress, "/", "")
			SenderEmailAddress := StrReplace(SenderEmailAddress, "\", "")
			SenderEmailAddress := StrReplace(SenderEmailAddress, "FW: ", "")
		}
		;external email
		else
		{
			SenderEmailAddress := i.SenderEmailAddress
		}
		Attachments := i.Attachments
		AttachmentCount := i.Attachments.count
		relocate := 0
		
		if true
		{
			;Loop through attachments
			for j, Attachment in Attachments
			{

				if SenderEmailAddress = ;redacted
				{
					path := ;redacted
				}
				else if SenderEmailAddress = ;redacted
				{
					path := ;redacted
				}
				else
				{
					path := ;redacted
				}
				
				;get the file extention
				if SubStr(path, -4, 5) = ".xlsx"
				{
					; Save attachment to a specified folder with sender's email address as the filename
					j.SaveAsFile(path)   
					relocate := 1
				}
				else if SubStr(fileExtention, -3, 4) = ".xls"
				{
					relocate := 2
				}
				;send emails with non-excel attachments to a manual review folder
				else 
				{
					if (relocate = 0)
					{
						relocate := 2
					}
					;move the email to a new folder
				}	
			}
		}
		;if there are no attachments then move the email to a manual review folder
		if (AttachmentCount = 0)
		{
			relocate := 2
		}
		if relocate = 1
		{
			i.Move(Archive)
			Sleep, 50
		}
		else if relocate = 2
		{
			i.Move(ManualReview)
			Sleep, 50
		}
		
	}
}

MsgBox, done
ExitApp

User avatar
Datapoint
Posts: 301
Joined: 18 Mar 2018, 17:06

Re: for loop ending early

09 May 2024, 17:07

It's probably because as you are looping through an object you are also removing items from the object. When an item is removed from the object the remaining item indexes get shifted by one.

One solution is to loop though the array in reverse order. Compare the following for-loop to the while-loop:

Code: Select all

o := ["a", "b", "c", "d"]
for k, v in o {
    MsgBox % "item number: " k "`nvalue: " v
    o.RemoveAt(k)
}

Code: Select all

o := ["a", "b", "c", "d"]
len := o.length()
while len {
    MsgBox % "item number: " len "`nvalue: " o[len]
    o.RemoveAt(len)
    len--
}

Return to “Ask for Help (v1)”

Who is online

Users browsing this forum: Bing [Bot], oldbrother, peter_ahk and 105 guests