Modify

Opened 11 years ago

Closed 11 years ago

#2993 closed Bug (Fixed)

_Excel_RangeFind returns only last occurrence of string found Rather than ALL

Reported by: ricrat51@… Owned by: water
Milestone: 3.3.13.21 Component: Standard UDFs
Version: 3.3.12.0 Severity: None
Keywords: Cc:

Description

It appears that the routine returns only the last occurrence of string rather than all occurrences
Modified as follows and it appear to work
Func _Excel_RangeFind($oWorkbook, $sSearch, $vRange = Default, $iLookIn = Default, $iLookAt = Default, $bMatchcase = Default)

If Not IsObj($oWorkbook) Or ObjName($oWorkbook, 1) <> "_Workbook" Then Return SetError(1, 0, 0)
If StringStripWS($sSearch, 3) = "" Then Return SetError(2, 0, 0)
If $iLookIn = Default Then $iLookIn = $xlValues
If $iLookAt = Default Then $iLookAt = $xlPart
If $bMatchcase = Default Then $bMatchcase = False
Local $oMatch, $sFirst = "", $bSearchWorkbook = False, $oSheet
If $vRange = Default Then

$bSearchWorkbook = True
$oSheet = $oWorkbook.Sheets(1)
$vRange = $oSheet.UsedRange

ElseIf IsString($vRange) Then

$vRange = $oWorkbook.Parent.Range($vRange)
If @error Then Return SetError(3, @error, 0)

EndIf
;;;;;Local $aResult[100][6], $iIndex = 0, $iIndexSheets = 1
Local $aResult[100][6], $iIndex = -1, $iIndexSheets = 1;;;; FIXED by RIC
While 1

$oMatch = $vRange.Find($sSearch, Default, $iLookIn, $iLookAt, Default, Default, $bMatchcase)
If @error Then Return SetError(4, @error, 0)
If IsObj($oMatch) Then

$sFirst = $oMatch.Address
While 1

$iIndex = $iIndex + 1;;;; FIXED by RIC
$aResult[$iIndex][0] = $oMatch.Worksheet.Name
$aResult[$iIndex][1] = $oMatch.Name.Name
$aResult[$iIndex][2] = $oMatch.Address
$aResult[$iIndex][3] = $oMatch.Value
$aResult[$iIndex][4] = $oMatch.Formula
$aResult[$iIndex][5] = $oMatch.Comment.Text
$oMatch = $vRange.Findnext($oMatch)
If Not IsObj($oMatch) Or $sFirst = $oMatch.Address Then ExitLoop
;;;;;$iIndex = $iIndex + 1;;;; FIXED by RIC
If Mod($iIndex, 100) = 0 Then ReDim $aResult[UBound($aResult, 1) + 100][6]

WEnd

EndIf
If Not $bSearchWorkbook Then ExitLoop
$iIndexSheets = $iIndexSheets + 1
$sFirst = ""
$oSheet = $oWorkbook.Sheets($iIndexSheets)
If @error Then ExitLoop
$vRange = $oSheet.UsedRange

WEnd
ReDim $aResult[$iIndex + 1][6]
Return $aResult

EndFunc ;==>_Excel_RangeFind

Attachments (0)

Change History (4)

comment:1 by water, 11 years ago

Component: AutoItStandard UDFs

comment:2 by water, 11 years ago

The problem was caused by exiting the loop to search in the next sheet before increasing the index. Thus the first hit of the next sheet was overwriting the last hit of the previous sheet.
This should work as well. Can you please confirm?

Func _Excel_RangeFind($oWorkbook, $sSearch, $vRange = Default, $iLookIn = Default, $iLookAt = Default, $bMatchcase = Default)
	If Not IsObj($oWorkbook) Or ObjName($oWorkbook, 1) <> "_Workbook" Then Return SetError(1, 0, 0)
	If StringStripWS($sSearch, 3) = "" Then Return SetError(2, 0, 0)
	If $iLookIn = Default Then $iLookIn = $xlValues
	If $iLookAt = Default Then $iLookAt = $xlPart
	If $bMatchcase = Default Then $bMatchcase = False
	Local $oMatch, $sFirst = "", $bSearchWorkbook = False, $oSheet
	If $vRange = Default Then
		$bSearchWorkbook = True
		$oSheet = $oWorkbook.Sheets(1)
		$vRange = $oSheet.UsedRange
	ElseIf IsString($vRange) Then
		$vRange = $oWorkbook.Parent.Range($vRange)
		If @error Then Return SetError(3, @error, 0)
	EndIf
	Local $aResult[100][6], $iIndex = 0, $iIndexSheets = 1
	While 1
		$oMatch = $vRange.Find($sSearch, Default, $iLookIn, $iLookAt, Default, Default, $bMatchcase)
		If @error Then Return SetError(4, @error, 0)
		If IsObj($oMatch) Then
			$sFirst = $oMatch.Address
			While 1
				$aResult[$iIndex][0] = $oMatch.Worksheet.Name
				$aResult[$iIndex][1] = $oMatch.Name.Name
				$aResult[$iIndex][2] = $oMatch.Address
				$aResult[$iIndex][3] = $oMatch.Value
				$aResult[$iIndex][4] = $oMatch.Formula
				$aResult[$iIndex][5] = $oMatch.Comment.Text
				$iIndex = $iIndex + 1 ; <== increasing index before exiting the loop
				If Mod($iIndex, 100) = 0 Then ReDim $aResult[UBound($aResult, 1) + 100][6]
				$oMatch = $vRange.Findnext($oMatch)
				If Not IsObj($oMatch) Or $sFirst = $oMatch.Address Then ExitLoop
			WEnd
		EndIf
		If Not $bSearchWorkbook Then ExitLoop
		$iIndexSheets = $iIndexSheets + 1
		$sFirst = ""
		$oSheet = $oWorkbook.Sheets($iIndexSheets)
		If @error Then ExitLoop
		$vRange = $oSheet.UsedRange
	WEnd
	ReDim $aResult[$iIndex][6]
	Return $aResult
EndFunc   ;==>_Excel_RangeFind

comment:3 by water, 11 years ago

Owner: set to water
Status: newaccepted

comment:4 by water, 11 years ago

Milestone: 3.3.13.21
Resolution: Fixed
Status: acceptedclosed

Fixed by revision [11251] in version: 3.3.13.21

Modify Ticket

Action
as closed The owner will remain water.

Add Comment


E-mail address and name can be saved in the Preferences .
 
Note: See TracTickets for help on using tickets.