Menú

Mostrar Mensajes

Esta sección te permite ver todos los mensajes escritos por este usuario. Ten en cuenta que sólo puedes ver los mensajes escritos en zonas a las que tienes acceso en este momento.

Mostrar Mensajes Menú

Mensajes - Eleкtro

#6841
Windows / Re: Problema con un dll
18 Julio 2014, 16:08 PM
Estaba claro que no era una librería nativa, pero aun así no deja de ser extraño xD.

Página de Ayuda y Soporte:
· http://spain.ni.com - Contact Us

Formulario de Servicio al cliente:
· Contacte con National Instruments

Otros medios de contacto:
Citar28290 LasRozas Madrid,España
tel:91 640 0085
Fax:91 640 0533

Saludos.
#6842
.NET (C#, VB.NET, ASP) / Re: Milisegundos
18 Julio 2014, 15:22 PM
La propiedad Timer.Interval se mide en milisegundos, la instrucción que has mostrado no requiere ninguna conversión ni del DataType ni a milisegundos, ya que el DataType del Timer.Interval es Integer y el DataType del NumericUpDown.Value es Decimal pero si no usas un formato decimal y lo asignas como un Integer se procesará como un Integer, por eso digo que no entiendo tu duda y era necesario que detallases dicha información.

· Timer.Interval Property

...Si estás usando un Valor Decimal con decimales a pesar de todo (Ej: 100,50), ya sea por haber asignado la propiedad DecimalPlaces al NumericUpDown o simplemente porque quisiste usar un Decimal con decimales en la propiedad NumericUpDown.Value, en ese caso podrías realizar la conversión de la siguiente manera:

Código (vbnet) [Seleccionar]
Dim Value As Integer = CInt(Math.Truncate(NumericUpDown1.Value))
Timer1.Interval = If(Value > 0I, Value, 1I)


Saludos.
#6843
El código anterior de VBS, traducido a Batch podría ser algo como esto:

PD: Pero ya sabes mi opinión, la diferencia de tiempo de ejecución solamente para generar 100-1.000 combinaciones sin repetición en Batch es... ABISMAL (para mal, obvio).

@Echo Off & (CHCP 1252)>Nul & SetLocal EnableDelayedExpansion
Title By .:: Elektro ::.

:: El indicador de máximas combinaciones.
Set /A "MaxCombos=10" - 1

:: El indicador de máxima longitud por combinación.
Set /A "MaxComboLen=10" - 1

:: El valor máximo del rango aleatorio (el valor mínimo es estático, un "0").
Set /A "MaxValue=9" + 1

:: El delimitador de valores.
Set "ValueDelimiter=, "

:: La variable donde cachearé cada combinación por separado.
:: Cada valor estará separado por el delimitador específicado (,).
Set "Combo="

:: El archivo donde guardaré las combinaciones generadas.
:: Nota: En principio iba a usar una variable para simular un Array,
::       Pero luego recordé que la capacidad de Batch está limitado a un Int16 (32.767)
::       Y ese sería el limitado número de caracteres que podría almacenar el "Array".
Set "CombosFile=%Temp%\Combos.txt"

:: El índice inicial de dígito de la combinación,
:: para usarlo en el parámetro del "For Range" (/L)
Set /A "StartIndex=0"



:Main
REM Genero los combos en el archivo de Combos.
Call :DoCombos

REM Ejemplo de como ver el archivo de Combos:
Type "%CombosFile%"
Pause&CLS

REM Ejemplo de como procesar cada valor de cada combo:
For /F "Delims= UseBackQ" %%c IN ("%CombosFile%") Do (

Set "Combo=%%c"
Echo Combinacion: !Combo!
For %%v IN (!Combo!) Do (
Echo Valor: %%v
)
Echo+
)

Pause&Exit /B 0



:DoCombos
REM Elimino posibles restos del archivo de Combos.
REM Creo un nuevo archivo de Combos, vacío.
(
Del /Q "%CombosFile%"
FSUtil.exe File CreateNew "%CombosFile%" 0
)1>Nul 2>&1

REM Genero los Combos hasta llegar a "X" cantidad de Combos.
For /L %%_ In (
0, 1, %MaxCombos%
) Do (
Call :SetCombo
)
Goto:EOF



:SetCombo
For /L %%x In (
!StartIndex!, 1, %MaxComboLen%
) Do (

REM Le añado un dígito aleatorio a la combinación.
REM El valor del rango inicial de la expresión aritmética es "0".
Set /A "Value=!Random! %%!MaxValue!"

REm Compruebo si el dígito existe en la combinación.
(Echo "!Combo!"|Find.exe "%ValueDelimiter%!Value!")1>Nul && (

REM Dígito encontrado.

REM Regreso al método 'SetCombo',
REM Modificando el índice inicial para
REM proseguir el String por el índice del dígito repetido.
Call Set /A "StartIndex=%%x"
Goto :SetCombo

) || (

REM Dígito NO encontrado.

REM Añado el dígito a la combinación.
Set "Combo=!Combo!%ValueDelimiter%!Value!"
REM :: Debug
REM Echo !Combo!

)
)

REM Le hago un arreglo al String para darle el formato correcto.
Set "Combo=!Combo:~2!"
REM :: Debug
REM Echo !Combo!

REm Compruebo si el Combo existe en archivo de Combos.
(Type "!CombosFile!"|Find.exe "!Combo!")1>Nul && (

REM Combo encontrado.

REM Vuelta a empezar, a generar el combo desde Cero.
Call Set /A "StartIndex=0"
Goto :SetCombo

) || (

REM Combo NO encontrado.

REM Añado el combo al archivo de Combos.
(Echo !Combos!%ComboDelimiter%!Combo!)>>"%CombosFile%"
REM :: Debug
REM Echo !Combo!

)

REM Reseteo el valor de las variables.
Set /A "StartIndex=0"
Set /A "Value=0"
Set "Combo="

REM Vuelvo al punto de llamada.
Goto:EOF


Output del archivo de Combos:
2, 9, 6, 0, 3, 7, 8, 1, 4, 5
4, 2, 1, 9, 5, 6, 0, 3, 7, 8
2, 0, 8, 5, 6, 3, 1, 7, 4, 9
3, 8, 1, 5, 6, 9, 4, 2, 0, 7
9, 3, 6, 8, 4, 0, 5, 2, 7, 1
2, 6, 3, 5, 1, 7, 8, 0, 9, 4
8, 4, 2, 9, 5, 1, 6, 3, 7, 0
5, 8, 1, 0, 2, 3, 9, 7, 6, 4
8, 7, 0, 2, 4, 3, 9, 1, 6, 5
7, 8, 3, 1, 0, 6, 5, 2, 4, 9


Output del ejemplo de ayuda (" REM Ejemplo de como procesar cada valor de cada combo"):
Combinacion: 2, 9, 6, 0, 3, 7, 8, 1, 4, 5
Valor: 2
Valor: 9
Valor: 6
Valor: 0
Valor: 3
Valor: 7
Valor: 8
Valor: 1
Valor: 4
Valor: 5
#6844
La cosa es así, Batch es tan... tan... ¡manco! que un programador deberá recurrir a la utilización de otros lenguajes (porque Batch, cuesta calificarlo como "Lenguaje") para llevar a cabo ciertas tareas, o bien porque Batch no ofrece los medios, o bien porque en otro lenguaje va a resultar más cómodo el desarrollo y el rendimiento resultante será mucho mejor ...que sin duda, lo es.  


Cita de: JoakoDS en 17 Julio 2014, 20:17 PMDe todas maneras Eleкtro, aunque logre entender la gran mayoria del codigo, no termino de entender como pasar los 'combos' a un archivo de texto, o mostrarlos en la pantalla; desconozco el tema de los VBS, ahora mismo pienso leer rapidamente el tutorial que esta rondando por acá.

Añade este método al script de arriba:

Código (vb) [Seleccionar]
Sub WriteTextFile(ArrayCollection, FilePath, Delimiter)

   Set ObjTxt = CreateObject("Scripting.FileSystemObject"). _
                OpenTextFile(FilePath, 2, True)

   For Each arr In ArrayCollection

       ObjTxt.Writeline(Join(arr, Delimiter))

   Next

  ObjTxt.Close

End Sub


Y luego, antes de finalizar la ejecución del Script, justo después de la instrucción "DoCombos()", añades esto:
Código (vb) [Seleccionar]
WriteTextFile Combos, ".\Combos.txt", ";"

El resultado será un archivo de texto plano con este contenido:

3;0;5;6;4;9;7;2;8;1
1;7;6;8;5;0;9;2;3;4
3;0;2;4;7;1;8;6;5;9
1;2;5;9;6;8;3;7;4;0
4;2;1;6;5;3;0;8;9;7
0;3;4;6;7;2;8;9;5;1
0;1;4;5;3;9;7;6;2;8
1;3;5;0;2;7;9;4;6;8
4;9;6;0;3;2;7;8;1;5
4;8;6;5;7;9;0;3;1;2
etc...

(No habrá combinaciones repetidas)

PD: El formato del delimitador lo puedes modificar en el parámetro "Delimiter" al llamar al método.




He modificado el método "DoCombos" (ahora lo llamé "FillWithCombos") ya que el control de errores estaba incompleto y provocaba que algunos elementos del Array quedasen vacíos, ya no es necesario un error-handling (otra cosa de la que Batch carece, y VBS en parte también).

Aquí tienes la modificación del código:

Nota: Le añadí el parámetro "AllowDuplicates" al método "FillWithCombos" para hacerlo más liviano, ya que un Array de 100.000 combinacions sin repetición tarda unos pocos segundos en generarse (en Batch eso sería una eternidad, 5-10 min), pero sin repetición tardará muchísimo más ya que tiene que hacer iteraciones al array para comprobar si existe la combinación, esto en un lenguaje como VBS sigue siendo imperfecto, como ya dije tampoco es muy potente, está falto de recursos.
Mi sugerencia, si no te importa que hayan combinaciones duplicadas, puedes hacer las que quieras, será bien rápido, pero si quieres que no hayan duplicados, no sobrepases las 2.000 combinaciones en el Array o irá muy lento.

Código (vb) [Seleccionar]
' El máximo número de combinaciones posibles con un rango de '0-9' y sin repetición son '3.628.800',
' Fuente: www.mathsisfun.com/combinatorics/combinations-permutations-calculator.html
'
' Pero ese colosal valor disminuiría el rendimiento del código,
' y no creo que un jugador pueda llegar a hacer más de '1.000' partidas por sesión.
Dim Combos(999)

' Un Array con los valores que permutar.
CharSet = Array(0, 1, 2, 3, 4, 5, 6, 7, 8, 9)

' Llamo al método principal.
Main()

' El método principal.
Sub Main

   On Error Resume Next

   ' Lleno el Array con combos.
   Call FillWithCombos(Combos, CharSet, 0, False)

   ' Escribo las combinaciones generadas del Array, en un archivo de texto.
   Call WriteTextFile(Combos, ".\Combos.txt", ";")

   ' Si hubo algún error...
   If Err.Number <> 0 Then
       ' Envio el código de error a la consola,
       ' el cual puedes procesar checkando la variable dinámica %ERRORLEVEL%.
       WScript.Echo "ExitCode: " & Err.Number & vbNewLine & _
                    "Source: " & Err.Source & vbNewLine & _
                    "Description: " &  Err.Description
       WScript.Quit(Err.Number)

   Else ' Si no hubo ningún error...
       ' Envio un código de salida satisfactorio a la consola,
       ' el cual puedes procesar checkando la variable dinámica %ERRORLEVEL%.
       WScript.Quit(0)

   End If

End Sub

' Función que desordena los elementos de un array.
Randomize
Function RandomizeArray(ByVal arr)

  tmpArray   = arr
  firstIndex = LBound(tmpArray)
  itemCount  = (UBound(tmpArray) - LBound(tmpArray)) + 1

  For index = UBound(tmpArray) To (LBound(tmpArray) + 1) Step -1

      ' evaluate a random index from LBound to INDEX
      newIndex = (firstIndex + Int(Rnd * itemCount))

      ' swap the two items
      tmpValue           = tmpArray(index)
      tmpArray(index)    = tmpArray(newIndex)
      tmpArray(newIndex) = tmpValue

      ' prepare for next iteration
      itemCount = itemCount - 1

  Next

  RandomizeArray = tmpArray

End Function

' Método que rellena un Array con combinaciones elatorias,
' sin repetición de combinaciones.
Sub FillWithCombos(Byref Arr, _
                  Byval Values, _
                  Byval StartIndex, _
                  Byval AllowDuplicates)

   ' Recorro los elementos del Array para llenarlos.
   For X = StartIndex To (UBound(Arr))
 
      ' Un flag Booleano que determina si una combinación está repetida en el Array.
      IsRepeated = False

      ' Gerero la siguiente combinación aleatoria.
      Combo = RandomizeArray(Values)

     
      ' Si no está permitido añadir combinaciones duplicadas...
       If Not AllowDuplicates Then

          ' Si el primer elemento del Array no está vacio...
          If Not IsEmpty(Arr(0)) Then

             ' Determino si ya existe la combinación generada en el Array.
             For Y = 0 To (X - 1)

                 If Join(Arr(Y), "") = Join(Combo, "") Then
                    IsRepeated = True
                    Exit For
                 End If

             Next 'Y

          End If 'IsEmpty(Arr(0))

          ' Si la combinación no está repetida...
          If Not IsRepeated Then
             ' Añado la combinación al Array de combinaciones.
             Arr(X) = Combo

           ' Si la combinación está repetida...
           Elseif IsRepeated Then
             call FillWithCombos(Combos, Values, X, AllowDuplicates)

           End If 'Not IsRepeated

       Else ' Si está permitido añadir combinaciones duplicadas...
           ' Añado la combinación al Array de combinaciones.
           Arr(X) = Combo

       End If ' Not AllowDuplicates

   Next 'X

End Sub

' Método que escribe los Arrays de un Array, en un archivo de texto.
Sub WriteTextFile(ByVal ArrayCollection, _
                 ByVal FilePath, _
                 ByVal Delimiter)

   Set ObjTxt = CreateObject("Scripting.FileSystemObject"). _
                OpenTextFile(FilePath, 2, True)

   For Each arr In ArrayCollection
       ObjTxt.Writeline(Join(arr, Delimiter))
   Next

  ObjTxt.Close

End Sub


Como ya te dije esto lo puedes usar desde Batch, solo tienes que escribir el contenido del script VBS dede tu Batch-Script a un archivo externo, y ejecutarlo.

Código (dos) [Seleccionar]

@Echo OFF

(

Echo Dim Combos^(999^)
Echo CharSet = Array^(0, 1, 2, 3, 4, 5, 6, 7, 8, 9^)
Echo Main()
Echo Sub Main
Echo     Call FillWithCombos^(Combos, CharSet, 0, False^)
Echo     Call WriteTextFile^(Combos, ".\Combos.txt", ";"^)
Echo     WScript.Quit^(0^)
Echo End Sub
Echo etc...
Echo etc...
Echo etc...

)>"%TEMP%\Script.vbs"

CScript.exe /NoLogo "%TEMP%\Script.vbs"
If %ErrorLevel% EQU 0 (
 Echo Todo OK.
 REM Procesar las combinaciones del archivo de texto resultante...
)


Saludos.
#6845
Cita de: softer2 en 17 Julio 2014, 16:58 PMespero su ayuda , recien ando aprendiendo esto del VBS

Puedes hacer una query a WMI para obtener la versión NT del Windows operativo actual.

San-Google está lleno de ejemplos como este, y como este otro:

Código (vb) [Seleccionar]
Set dtmConvertedDate = CreateObject("WbemScripting.SWbemDateTime")
strComputer = "."
Set objWMIService = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
Set oss = objWMIService.ExecQuery ("Select * from Win32_OperatingSystem")

For Each os in oss
   Wscript.Echo "Caption: " & os.Caption
   Wscript.Echo "Version: " & os.Version
Next


+ List of Microsoft Windows versions

Así pues, si la versión NT empieza por "5.1" o "5.2", será XP, si empieza por "6.1" será Win7, y si empieza por "6.2" o "6.3" será Windows 8/8.1.

+ VBScript Left Function
Código (vb) [Seleccionar]
If Left(os.Version, 2) = "5.1" Then ...

PD: El nombre a mostrar del OS puede variar, pero la versión NT no, por eso te sugiero evitar parsear el Caption.

Saludos
#6846
Pues solo hay 2 posibles causas:
Cita de: http://msdn.microsoft.com/en-us/library/system.io.ports.serialport.open%28v=vs.110%29.aspxIOException   
The port is in an invalid state.
- or -
An attempt to set the state of the underlying port failed. For example, the parameters passed from this SerialPort object were invalid.

Según MSDN, la propiedad "StopBits" y/o "Parity" pueden lanzar una excepción de tipo IOException.

En lugar de asignar los valores de los parámetros (y por ende de esas propiedades) mediante el Constructor, usa el constructor por defecto (sin parámetros): http://msdn.microsoft.com/en-us/library/system.io.ports.serialport%28v=vs.110%29.aspx

Y asigna el valor a las propiedades manualmente, quizás no sirva de nada, pero por probar, ya que en los ejemplos que veo en el MSDN siempre asignan la propiedad Handshake y los Timeouts también, y no he verificado cuales serán sus valores por defecto con el ctor que usaste.

Algo así (VB.NET):
Código (vbnet) [Seleccionar]
    Dim _serialPort As New SerialPort()

    With _serialPort

   .PortName = "COM2"
   .BaudRate = 9600I
   .Parity = Parity.None
   .DataBits = 8I
   .StopBits = StopBits.One
   .Handshake = Handshake.None

   .ReadTimeout = 500I
   .WriteTimeout = 500I

    End With

   _serialPort.Open()


PD: ¿Te sirvió?

Saludos
#6847
Scripting / Re: indetectable
17 Julio 2014, 16:56 PM
La ofuscación/cifrado del código es algo que te podría ser de utilidad, puedes utilizar la herramienta Windows Script Encoder en caso, y solo en caso de que tuvieras un windows antiguo cuyo motor WHS (WindowsScriptHost) no disponga del objeto "Scripting.Encoder" de forma natural:
http://download.microsoft.com/download/0/0/7/0073477f-bbf9-4510-86f9-ba51282531e3/sce10en.exe

Cita de: http://gallery.technet.microsoft.com/scriptcenter/16439c02-3296-4ec8-9134-6eb6fb599880
Código (vb) [Seleccionar]
Option Explicit

dim oEncoder, oFilesToEncode, file, sDest
dim sFileOut, oFile, oEncFile, oFSO, i
dim oStream, sSourceFile

set oFilesToEncode = WScript.Arguments
set oEncoder = CreateObject("Scripting.Encoder")
For i = 0 to oFilesToEncode.Count - 1
   set oFSO = CreateObject("Scripting.FileSystemObject")
   file = oFilesToEncode(i)
   set oFile = oFSO.GetFile(file)
   Set oStream = oFile.OpenAsTextStream(1)
   sSourceFile=oStream.ReadAll
   oStream.Close
   sDest = oEncoder.EncodeScriptFile(".vbs",sSourceFile,0,"")
   sFileOut = Left(file, Len(file) - 3) & "vbe"
   Set oEncFile = oFSO.CreateTextFile(sFileOut)
   oEncFile.Write sDest
   oEncFile.Close
Next

Ejemplo de uso:
Código (vb) [Seleccionar]
WScript.exe "Crypter.vbs" "ToEncrypt.vbs"

+ http://blog.nanomuelle.com/2013/09/17/vbscript-encoded-obfuscated/
(ese no lo he probado)

Saludos.
#6848
Cita de: softer2 en 16 Julio 2014, 19:50 PM
lo que quiero es borrar todo el contenido del archivo hosts y añadir recien mis lineas

Cuando instancies el objeto, asigna el valor correcto para el parámetro IOmode (ForWriting).
http://msdn.microsoft.com/en-us/library/314cz14s%28v=vs.84%29.aspx

Ejemplo:
Código (vb) [Seleccionar]
CreateObject("Scripting.FileSystemObject").OpenTextFile(HostsFile, 2, True)

Entonces, cuando uses el método Write/WriteLine, se reemplazará el contenido existente del archivo, y podrás seguír utilizando dicho método para continuar escribiendo, hasta que liberes el objeto con el método Close.

Ejemplo:
Código (vb) [Seleccionar]
Const HostsFile  = "C:\Windows\System32\Drivers\etc\Hosts"
Set objHosts     = CreateObject("Scripting.FileSystemObject"). _
                  OpenTextFile(HostsFile, 2, True)

With objHosts

   .Writeline(vbNewLine)
   .Writeline("127.0.0.1" & vbtab & "www.1.com")
   .Writeline("127.0.0.2" & vbtab & "www.2.com")
   .Writeline("127.0.0.3" & vbtab & "www.3.com")

   .Close

End With


Saludos.
#6849
.NET (C#, VB.NET, ASP) / Re: Milisegundos
17 Julio 2014, 16:14 PM
Buenas

· ¿Donde está tu código?

· ¿Puedes describir con mayor calidad de detalles lo que pretendes hacer, para que se entienda?.

Saludos.
#6850
¿Tiene que ser puro Batch, o se permite la utilización de un script-Batch hibrido que genere un código VBS?

Sincéramente, en mi opinión, deberías ir al profesor y decirle que has preferido evitar el uso de una herramienta simplista como Batch para generar la lógica del algoritmo de aletoriedad, ya que Batch es ineficiente y carece de lógica en ese aspecto, y aparte de quedar como un "Pro", estarías haciendo lo mejor, aunque yo directamente te diría que lo hicieras en Python, Ruby, u otros xD pero entiendo que eso ya es pedir demasiado (porque la clase es de Batch).

Digo esto porque la lógica aleatoria de Batch no permite seleccionar una serie de números distintos dentro de un rango, y que el número elegido sea distinto cada vez, mucho menos permite la utilización de Arrays, así que lo más propable es que el mismo numero aleatorio se repita varias veces y debas corregirlo, es decir, seguir obteniendo otro dígito aleatorio hasta que sea distinto al dígito anterior, y esto, medido en tiempo de ejecución puede tardar bastante para conseguir un 0, y luego un 1, dígitos distintos y que no se repitan entre si.

No merece la pena realizar esa cutrez en Batch, pero si quieres hacerlo, puedes utilizar la variable dinámica %Random%, y hacerle un Substring al String resultante para quedarte con un valor que tenga una longitud de un dígito, y luego hacer las comparaciones necesarias (¿es un 0?, ¿es un 1?, etc),
también se podría hacer de otra forma relacionada, que sería simulando un Array como parámetro de un For ("1 2 3 4 5 6 7 8 9 0"), o como parámetro de un For /L (0, 1, 9), y desordenar las posiciones de los elementos recurriendo a los resultados de la variable %Random%, sea como sea cualquiera de esas técnicas es una completa cutrez.

Te muestro un ejemplo en VBS (el cual puedes llamar/usar desde Batch), VBS tampoco ofrece demasiada libertad, no es un lenguaje muy potente ni muy eficiente pero sin duda es mucho más liviano de lo que sería en Batch.

Código (vb) [Seleccionar]
Randomize

' El máximo número de combinaciones posibles con un rango de '0-9' y sin repetición son '3.628.800',
' Fuente: www.mathsisfun.com/combinatorics/combinations-permutations-calculator.html
'
' Pero ese colosal valor disminuiría el rendimiento del código,
' y no creo que un jugador pueda llegar a hacer más de '1.000' partidas por sesión.
Dim Combos(1000)

' Un Array con los valores que permutar.
Values = Array(0, 1, 2, 3, 4, 5, 6, 7, 8, 9)

' Gerero y asigno la primera combinación aleatoria.
Combos(0) = RandomizeArray(Values)

' Genero el resto de combos.
DoCombos()
' Escribir los combos en un archivo de texto
' O enviarlos a la salida de la consola para procesarlos con un For en Batch.
' Como se prefiera.
WScript.Echo("Fin")

Sub DoCombos()

' Recorro los espacios vaciós del Array para llenarlos.
For X = 0 To (UBound(Combos) - 1)

IsRepeated = False

   ' Gerero la siguiente combinación aleatoria.
   Combo = RandomizeArray(Values)

   ' Compruebo que la combinación no existe en el Array de combos.
   For Y = 0 To (X)

    On Error Resume Next

       If Join(Combos(Y), "") = Join(Combo, "") Then
          IsRepeated = True
          Exit For
       End If

   Next

   ' Añado la combinación al Araay de combinaciones.
   If Not IsRepeated Then
      Combos(X + 1) = Combo
   End If
   
Next

End Sub

' Función que desordena los elementos de un array.
Function RandomizeArray(arr)

   tmpArray   = arr
   firstIndex = LBound(tmpArray)
   itemCount  = (UBound(tmpArray) - LBound(tmpArray)) + 1
   
   For index = UBound(tmpArray) To (LBound(tmpArray) + 1) Step -1
       
       ' evaluate a random index from LBound to INDEX
       newIndex = (firstIndex + Int(Rnd * itemCount))
       
       ' swap the two items
       tmpValue           = tmpArray(index)
       tmpArray(index)    = tmpArray(newIndex)
       tmpArray(newIndex) = tmpValue
       
       ' prepare for next iteration
       itemCount = itemCount - 1
 
   Next

   RandomizeArray = tmpArray

End Function