Foros del Web » Programando para Internet » ASP Clásico »

Registros aleatorios no repetidos

Estas en el tema de Registros aleatorios no repetidos en el foro de ASP Clásico en Foros del Web. Necesito hacer un bucle para mostrar varios registros aleatorios NO REPETIDOS. Sé hacerlo para coger sólo uno, pero no para obtener varios no repetidos. Para ...

  #1 (permalink)  
Antiguo 17/03/2005, 13:35
Avatar de mrgubu  
Fecha de Ingreso: febrero-2002
Ubicación: Granada
Mensajes: 431
Antigüedad: 23 años, 2 meses
Puntos: 2
Registros aleatorios no repetidos

Necesito hacer un bucle para mostrar varios registros aleatorios NO REPETIDOS. Sé hacerlo para coger sólo uno, pero no para obtener varios no repetidos.

Para mostrar sólo uno creo que vale con esto

<%sql = "Select * from Productos "

Rs.open sql, objconn, 3,1
intTotalRecords = Rs.RecordCount
Randomize()
intRandomNumber = Int((intTotalRecords * Rnd))
Rs.Move intRandomNumber

Response.Write Rs("producto_nombre")%>
  #2 (permalink)  
Antiguo 17/03/2005, 15:18
Avatar de skatomundo  
Fecha de Ingreso: junio-2002
Ubicación: Santiago - CL
Mensajes: 2.532
Antigüedad: 22 años, 10 meses
Puntos: 125
sql = "Select distint * from Productos "
  #3 (permalink)  
Antiguo 17/03/2005, 18:10
Avatar de u_goldman
Moderador
 
Fecha de Ingreso: enero-2002
Mensajes: 8.031
Antigüedad: 23 años, 3 meses
Puntos: 98
Si, el select distinct sirve para no tomar repetidos, pero si quieres hacer un random, depende de tu base de datos, en SQL hay una funcion llamada NEWID que te regresa registros aleatorios creando un campo virtual y asignando valores arbitrarios, pero si estas utilizando otra base de datos, no lo se, por ejemplo con Access, no lo podras hacer, tendras que recurrir a programar un pequeno componente que te haga esta labor.

Salu2,
__________________
"El hombre que ha empezado a vivir seriamente por dentro, empieza a vivir más sencillamente por fuera."
-- Ernest Hemingway
  #4 (permalink)  
Antiguo 18/03/2005, 02:37
Avatar de mrgubu  
Fecha de Ingreso: febrero-2002
Ubicación: Granada
Mensajes: 431
Antigüedad: 23 años, 2 meses
Puntos: 2
Juer, no pensaba que esto sería tan difícil. A ver si podéis darme otra pistilla más práctica.
  #5 (permalink)  
Antiguo 18/03/2005, 04:13
Avatar de altraun  
Fecha de Ingreso: abril-2002
Mensajes: 129
Antigüedad: 23 años
Puntos: 0
chapuza

se que es una chapuza, porque no haces que cuando te selecciona un registro aleatorio , esa variable te la almacene con un bucle de 5 por ejemplo asi tendrias varias variables del tipo "variable 1 " variable2 " y asi tantas como tengas el limite, con ello solo tienes que llamar luego a esas variables porque los registros ya han sido almacenados y seleccionados antes.


otra opcion es que al randon que selecciona le añadas numeros asi te pilla el sigiente, ejemplo registro 100 pues si a eso le pones un +1 pues te pilla otro.

creo que eso lo hice en algo pero tengo que buscarlo asi que si lo encuentro te lo paso.
  #6 (permalink)  
Antiguo 18/03/2005, 11:24
Avatar de u_goldman
Moderador
 
Fecha de Ingreso: enero-2002
Mensajes: 8.031
Antigüedad: 23 años, 3 meses
Puntos: 98
Me parece que hay por ahi en la biblioteca de funciones una funcion que genera un numero aleatorio, lo que yo haria, seria establecer esa funcion para que regresara un numero entero de 4 digitos, ahora, abres tu recordset y dimensionas una matriz, guardas los id's de dicho recordset en cada uno de sus indices en col 1, y por cada uno de esos indices mandas llamar a la funcion y el numero que te regresa, lo guardas en col 0 de la matriz, despues, ordenas la matriz de acuerdo al indice de la columna 0, el resultado sera que tienes guardados todos los ids, ordenados de acuerdo a un numero aleatorio, o sea que eso es un random de registros, despues puedes regresar esa matriz para hacer una subconsulta de acuerdo al orden de ella.

Mis $0.02

Salu2,
__________________
"El hombre que ha empezado a vivir seriamente por dentro, empieza a vivir más sencillamente por fuera."
-- Ernest Hemingway
  #7 (permalink)  
Antiguo 18/03/2005, 11:45
Avatar de pempas  
Fecha de Ingreso: diciembre-2003
Ubicación: Barcelona
Mensajes: 985
Antigüedad: 21 años, 4 meses
Puntos: 6
yo solo quiero intervenir para alabar esa imagen que tiene puesta mrgubu, VIVA EL JAMÓN, LOS CERDOS Y EL SUR!!!

Y eso que soy de Barcelona, pero mi familia es de allí!!
  #8 (permalink)  
Antiguo 23/03/2005, 13:01
Avatar de mrgubu  
Fecha de Ingreso: febrero-2002
Ubicación: Granada
Mensajes: 431
Antigüedad: 23 años, 2 meses
Puntos: 2
u_goldman, necesito ver planteado en código ASP lo que explicas estupendamente en lenguaje castellano. Si no, no soy capaz de empezar a armarlo.
  #9 (permalink)  
Antiguo 23/03/2005, 13:57
Avatar de u_goldman
Moderador
 
Fecha de Ingreso: enero-2002
Mensajes: 8.031
Antigüedad: 23 años, 3 meses
Puntos: 98
Bueno...ya que no quieres comenzar con la idea, aqui te dejo el inicio:

Código:
<!--#include file = "../datastore.asp"-->
<%
Class RandomRS
	'==========================================================
	Private Function RandomPwd ( length, repeat )

	'----------------------------------------------------------
	Dim vPass(), I, J ' our vector plus two counters
	Dim vNumbers()	  ' vector to store
	Dim n, bRep		  
	Dim vChars	  ' vector where possible chars are

	vChars = Array("1", "2", "3", "4", "5", "6", "7", "8", "9", "0")

	'Vector's length
	Redim vPass(Length-1)
	'Y del vector auxiliar que guarda los caracteres ya escogidos
	Redim vNumbers(Length-1)
	I = 0
	'Starting random
	Randomize
	'Till if finds all of the chars
	do until I = length
		'Finding a numbre between 0 & the maximum number
		' from the char's vector
		n = int(rnd*Ubound(vChars))
		'If can't repeat...
		if not Repeat then
			bRep = False
			'Looking for the number among the chosen ones
			for J = 0 to UBound(vNumbers)
				if n = vNumbers(J) then
				'If it's there, we point it
					bRep = True
				end if
			next
			'If it was there, we need to repeat it
			
			if bRep then 
				I = I - 1
			else
				vNumbers(I) = n
				vPass(I) = vChars(n)	
			end if
		else
		'I don't care if it's repeated
			vNumbers(I) = n
			vPass(I) = vCaracteres(n)
		end if
	'Next Char!
	I = I + 1
	loop

	'Returning the string. Joining the array's indexes
	'Let's use the second parameter as a separator, nothing in this case -> "".
	RandomPwd = Join(vPass, "")

	End Function 'Random Pwd
	'==========================================================

	Public Function GetRandomRS(qry)
		Dim ObjConn
		Dim rs 
		Dim cmd
		Dim arrRandom 
		Dim mtxRandom
		Dim j
		
		Set ObjConn = Server.CreateObject("ADODB.Connection")
		Set rs = Server.CreateObject("ADODB.Recordset")
		Set cmd = Server.CreateObject("ADODB.Command")
		ObjConn.Open strConnect
		cmd.ActiveConnection = ObjConn
		cmd.CommandType = adCmdText
		cmd.CommandText = qry
		rs.CursorType = 3
		rs.Open cmd
		if not rs.EOF then
			arrRandom = rs.GetRows()
			Redim mtxRandom(uBound(arrRandom,2), 1)
			For j = 0 to uBound(arrRandom,2)
				mtxRandom(j,0) = RandomPwd(4, false)
				mtxRandom(j,1) = arrRandom(0,j)
			Next
			arrRandom = mtxRandom
			erase mtxRandom
		else
			arrRandom = ""
		end if
		GetRandomRS = arrRandom
	End Function

End Class

Set ObjRandom = New RandomRS
ds = ObjRandom.GetRandomRS("SELECT notice_id FROM tbl_notice WHERE notice_live=1")
if isArray(ds) then
	For i = 0 to uBound(ds)
		Response.Write(ds(i,0) & " | " & ds(i,1) & "<br>")
	Next
else
	response.Write("no")
end if
%>
El include solo tiene el string de conexion
hice una clase para que sea mas facil de modificar, son basicamente dos funciones, la primera la tome hace mucho tiempo no me acuerdo de donde je je, pero es la que tiene el chiste de randomizar numeros, recibe la longitud del numero y un booleano, si se repite o no.

La segunda funcion recibira el query para ejecutar el recordset, despues creamos el recordset, utilizamos un vector mediante getrows y mediante el uso de una matriz llenamos sus dos columnas, en la columna 0, un numero aleatorio, en la columna 1, el id del recordset en turno.

Al final evaluamos si es arreglo lo que devolvio la funcion, e imprimimos sus indices para ver la randomizacion(esa palabra no existe creo nunca acabare de aprender el ingles y el espanol se me esta olvidando), bueno, lo que faltaria es mediante un algoritmo ordenar los indices, por ahi hay posts del master AZ utilizando quicksort, el resultado es que tendras una matriz ordenada de acuerdo a un numero aleatorio, con los indices de tu recordset...

Felices lineas! je je je
__________________
"El hombre que ha empezado a vivir seriamente por dentro, empieza a vivir más sencillamente por fuera."
-- Ernest Hemingway
  #10 (permalink)  
Antiguo 23/03/2005, 16:10
Avatar de mrgubu  
Fecha de Ingreso: febrero-2002
Ubicación: Granada
Mensajes: 431
Antigüedad: 23 años, 2 meses
Puntos: 2
Guau, Goldman, para qué te voy a mentir, no sé muy bien manejarme con ese pedaso de código. Para empezar, me da error en la línea
cmd.CommandType = adCmdText,
me da la impresión de que adCmdText es una variable no definida, pero no estoy seguro.
  #11 (permalink)  
Antiguo 23/03/2005, 16:36
Avatar de u_goldman
Moderador
 
Fecha de Ingreso: enero-2002
Mensajes: 8.031
Antigüedad: 23 años, 3 meses
Puntos: 98
Si, es una constante, seguramente debe venir en adodbVB.inc o como se llame, no importa, cambia la manera de ejecutar el recordset y listo...o busca en Google por el equivalente numerico de esta constante. Ahora me fije que dentro de la segunda funcion no estoy destruyendo objetos, tambien puedes agregar eso para mayor performance.

Salu2,
__________________
"El hombre que ha empezado a vivir seriamente por dentro, empieza a vivir más sencillamente por fuera."
-- Ernest Hemingway
  #12 (permalink)  
Antiguo 23/03/2005, 17:22
Avatar de mrgubu  
Fecha de Ingreso: febrero-2002
Ubicación: Granada
Mensajes: 431
Antigüedad: 23 años, 2 meses
Puntos: 2
He conseguido hacerlo funcionar, y utilizando al final una sql del tipo sql = "select id from tabla" obtengo diez rows con dos parejas de valores, el primero un random de 4 cifras y el segundo las últimas ids de la tabla.

¿He conseguido algo? ¿Qué hago con esto?
  #13 (permalink)  
Antiguo 23/03/2005, 18:18
Avatar de u_goldman
Moderador
 
Fecha de Ingreso: enero-2002
Mensajes: 8.031
Antigüedad: 23 años, 3 meses
Puntos: 98
Busca en este foro entre los posts del master AZ, la funcion que mediante quicksort ordena un arreglo, tienes que ordenarlo por el indice 0 de tu matriz que es el numero aleatorio que generamos para cada uno de los registros, modificala para trabajar con una matriz, tendras que ordenar dos indices por fila(0,1), al final tendras una matriz ordenada, la cual solo tienes que recorrer en el indice de 1, que sera como el recordset aleatorio, esa columna contiene la ordenacion aleatorio de los indices resultantes de tu recordset.

Salu2,
__________________
"El hombre que ha empezado a vivir seriamente por dentro, empieza a vivir más sencillamente por fuera."
-- Ernest Hemingway
  #14 (permalink)  
Antiguo 24/03/2005, 10:17
Avatar de mrgubu  
Fecha de Ingreso: febrero-2002
Ubicación: Granada
Mensajes: 431
Antigüedad: 23 años, 2 meses
Puntos: 2
Uff, he buscado en el foro quicksort y sólo me salen dos post de ASP, éste y otro sobre encontrar la mediana.

No sé cómo manipular el array resultante de la función de ugoldman para utilizarlo para conseguir obtener registros aleatorios de la tabla. Una ayudita más pliiiis.
  #15 (permalink)  
Antiguo 24/03/2005, 11:46
Avatar de u_goldman
Moderador
 
Fecha de Ingreso: enero-2002
Mensajes: 8.031
Antigüedad: 23 años, 3 meses
Puntos: 98
Incorpora la funcion que proporciono AZ dentro de la clase

Código:
Sub QuickSort(vec,loBound,hiBound)
  Dim pivot,loSwap,hiSwap,temp

  '== This procedure is adapted from the algorithm given in:
  '==    Data Abstractions & Structures using C++ by
  '==    Mark Headington and David Riley, pg. 586
  '== Quicksort is the fastest array sorting routine for
  '== unordered arrays.  Its big O is  n log n


  '== Two items to sort
  if hiBound - loBound = 1 then
    if vec(loBound) > vec(hiBound) then
      temp=vec(loBound)
      vec(loBound) = vec(hiBound)
      vec(hiBound) = temp
    End If
  End If

  '== Three or more items to sort
  pivot = vec(int((loBound + hiBound) / 2))
  vec(int((loBound + hiBound) / 2)) = vec(loBound)
  vec(loBound) = pivot
  loSwap = loBound + 1
  hiSwap = hiBound
  
  do
    '== Find the right loSwap
    while loSwap < hiSwap and vec(loSwap) <= pivot
      loSwap = loSwap + 1
    wend
    '== Find the right hiSwap
    while vec(hiSwap) > pivot
      hiSwap = hiSwap - 1
    wend
    '== Swap values if loSwap is less then hiSwap
    if loSwap < hiSwap then
      temp = vec(loSwap)
      vec(loSwap) = vec(hiSwap)
      vec(hiSwap) = temp
    End If
  loop while loSwap < hiSwap
  
  vec(loBound) = vec(hiSwap)
  vec(hiSwap) = pivot
  
  '== Recursively call function .. the beauty of Quicksort
    '== 2 or more items in first section
    if loBound < (hiSwap - 1) then Call QuickSort(vec,loBound,hiSwap-1)
    '== 2 or more items in second section
    if hiSwap + 1 < hibound then Call QuickSort(vec,hiSwap+1,hiBound)

End Sub  'QuickSort
Revisala, basicamente la parte que querras modificar es donde hace el cambio de valores, si es menor que el otro, los intercambia, adaptala para que reciba una matriz y compare en matriz(x, 0), ya que lo que necesitamos es ordenar de acuerdo a nuestro numero aleatorio, pero que haga los cambios en (x,0) y (x,1) para que no se pierda el orden que necesitaremos.

Salu2,
__________________
"El hombre que ha empezado a vivir seriamente por dentro, empieza a vivir más sencillamente por fuera."
-- Ernest Hemingway
  #16 (permalink)  
Antiguo 25/03/2005, 06:26
Avatar de mrgubu  
Fecha de Ingreso: febrero-2002
Ubicación: Granada
Mensajes: 431
Antigüedad: 23 años, 2 meses
Puntos: 2
Goldman, muchas gracias, pero me pierdo en el manejo de estos pedasos de arrays. No sé como acoplar el código primero con este nuevo que has puesto.
  #17 (permalink)  
Antiguo 25/03/2005, 06:59
Avatar de meru-kun  
Fecha de Ingreso: noviembre-2002
Ubicación: Madrid
Mensajes: 854
Antigüedad: 22 años, 5 meses
Puntos: 0
Creo que u_goldman tiene razón en eso de que en la Biblioteca ASP (si lo llamamos igual al thread que hay más arriba), está esto. De hehco, lo postee yo.

Mira, te dejo el link: http://www.forosdelweb.com/showpost....1&postcount=81

En realidad lo que hacen esas funcione es sacarte numeros aleatorios no repetidos, pero se puede adaptar a lo que tú quieres (que es para lo que lo uso yo) muy facilmente. Haces un COUNT a los campos que tienes, y entonces ejecutas el script entre 1 y COUNT . Luego, simplemente, haces un mr.move(valor_aleatorio), y listo (valor_aleatorio es uno de los nº que te saca la función).

Un saludo :P
__________________
Tu portal de manga y anime.
  #18 (permalink)  
Antiguo 25/03/2005, 10:40
Avatar de lexus  
Fecha de Ingreso: enero-2002
Ubicación: Cali - Colombia
Mensajes: 2.234
Antigüedad: 23 años, 3 meses
Puntos: 4
hola he probado tu codigo y al parecer se queda en un ciclo infinito porque nunca termina de cargar la pagina, porfa que puede ser?
<%
'####################
'# Funciónes creadas por Isaí/Meruelo
'# Optimizadas por meruelo
'####################
Function RanNum(inicio, fin)
Randomize()
RanNum = Int((fin - inicio + 1) * Rnd + inicio)
End Function

Function chkRan(num, pos)
p = val_inicial
Do while p <= val_final
For d=0 To d=9
If arreglo(d)=num then
arreglo(pos) = RanNum(val_inicial, val_final)
p = 1
Else
chkRan = num
p = p + 1
End if
Next
Loop
End Function

Function getArray(val_inicial, val_final)
indice_elem_actual=0
Do While indice_elem_actual<=numero_elementos
numero=RanNum(val_inicial,val_final)
For j=0 To (numero_elementos)
If arreglo(j)=numero Then
numero=RanNum(val_inicial,val_final)
j=0
End If
Next
arreglo(indice_elem_actual)=chkRan(numero, pos)
indice_elem_actual=indice_elem_actual+1
Loop
End Function
%>





<%
'Despues, simplemente, definir el arreglo


Dim arreglo()



'Y, como ejemplo, crear un bucle para mostrar todos los números que saca



i = 0
numero_elementos= 4
Redim arreglo(numero_elementos)
call getArray(1, numero_limite)
Do While i < numero_elementos
response.write arreglo(i)
i = i + 1
Loop


%>
__________________
Control de Visitantes, Control de Accesos, Minutas digitales, Manejo de Correspondencia
http://www.controldevisitantes.com
  #19 (permalink)  
Antiguo 25/03/2005, 11:04
Avatar de sjam7  
Fecha de Ingreso: diciembre-2001
Ubicación: Guadalajara, Mexico
Mensajes: 3.672
Antigüedad: 23 años, 4 meses
Puntos: 16
en donde le das es valor a val_final?
con el que se compara el bucle:

Do while p <= val_final
For d=0 To d=9
If arreglo(d)=num then
arreglo(pos) = RanNum(val_inicial, val_final)
p = 1
Else
chkRan = num
p = p + 1
End if
  #20 (permalink)  
Antiguo 25/03/2005, 11:21
Avatar de u_goldman
Moderador
 
Fecha de Ingreso: enero-2002
Mensajes: 8.031
Antigüedad: 23 años, 3 meses
Puntos: 98
Cita:
Goldman, muchas gracias, pero me pierdo en el manejo de estos pedasos de arrays. No sé como acoplar el código primero con este nuevo que has puesto.
Bueno, bueno, dame un par de horas, porque estoy un poco ocupado, pero al rato lo posteo por aca

Salu2,
__________________
"El hombre que ha empezado a vivir seriamente por dentro, empieza a vivir más sencillamente por fuera."
-- Ernest Hemingway
  #21 (permalink)  
Antiguo 25/03/2005, 11:23
Avatar de mrgubu  
Fecha de Ingreso: febrero-2002
Ubicación: Granada
Mensajes: 431
Antigüedad: 23 años, 2 meses
Puntos: 2
Perdonad mi torpeza, pero yo sigo sin poner en marcha lo que quiero, que es sacar n registros aleatorios no repetidos de una tabla.

He probado tb por separado el código de lexus y tampoco consigo hacerlo correr
  #22 (permalink)  
Antiguo 25/03/2005, 11:40
Avatar de u_goldman
Moderador
 
Fecha de Ingreso: enero-2002
Mensajes: 8.031
Antigüedad: 23 años, 3 meses
Puntos: 98
Código:
%>
<!--#include file = "../datastore.asp"-->
<%
Class RandomRS
	'=================================================  =========
	Private Function RandomPwd ( length, repeat )

	'----------------------------------------------------------
	Dim vPass(), I, J ' our vector plus two counters
	Dim vNumbers()	  ' vector to store
	Dim n, bRep		  
	Dim vChars	  ' vector where possible chars are

	vChars = Array("1", "2", "3", "4", "5", "6", "7", "8", "9", "0")

	'Vector's length
	Redim vPass(Length-1)
	'Y del vector auxiliar que guarda los caracteres ya escogidos
	Redim vNumbers(Length-1)
	I = 0
	'Starting random
	Randomize
	'Till if finds all of the chars
	do until I = length
		'Finding a numbre between 0 & the maximum number
		' from the char's vector
		n = int(rnd*Ubound(vChars))
		'If can't repeat...
		if not Repeat then
			bRep = False
			'Looking for the number among the chosen ones
			for J = 0 to UBound(vNumbers)
				if n = vNumbers(J) then
				'If it's there, we point it
					bRep = True
				end if
			next
			'If it was there, we need to repeat it
			
			if bRep then 
				I = I - 1
			else
				vNumbers(I) = n
				vPass(I) = vChars(n)	
			end if
		else
		'I don't care if it's repeated
			vNumbers(I) = n
			vPass(I) = vCaracteres(n)
		end if
	'Next Char!
	I = I + 1
	loop

	'Returning the string. Joining the array's indexes
	'Let's use the second parameter as a separator, nothing in this case -> "".
	RandomPwd = Join(vPass, "")

	End Function 'Random Pwd
	'=================================================  =========
	
	'Funcion para ordenar arreglo, metodo de la burbuja
	Function OrdenaArreglo(arreglo)
		Dim x, y, temp
		If isArray(arreglo) Then
			'Dim temp
			For x = 0 to uBound(arreglo)
				For y = x + 1 to uBound(arreglo)		
					If arreglo(x, 0) > arreglo(y, 0) Then
						temp = arreglo(x, 0)
						temp2 = arreglo(x, 1)
						arreglo(x, 0) = arreglo(y, 0)
						arreglo(x, 1) = arreglo(y, 1)
						arreglo(y, 0) = temp
						arreglo(y, 1) = temp2
					End If
				Next
			Next
		Else
			OrdenaArreglo = Null
		End If
		OrdenaArreglo = arreglo
	End Function

	
	Public Function GetRandomRS(qry)
		Dim ObjConn
		Dim rs 
		Dim cmd
		Dim arrRandom 
		Dim mtxRandom
		Dim j
		
		Set ObjConn = Server.CreateObject("ADODB.Connection")
		Set rs = Server.CreateObject("ADODB.Recordset")
		Set cmd = Server.CreateObject("ADODB.Command")
		ObjConn.Open strConnect
		cmd.ActiveConnection = ObjConn
		cmd.CommandType = adCmdText
		cmd.CommandText = qry
		rs.CursorType = 3
		rs.Open cmd
		if not rs.EOF then
			arrRandom = rs.GetRows()
			Redim mtxRandom(uBound(arrRandom,2), 1)
			For j = 0 to uBound(arrRandom,2)
				mtxRandom(j,0) = RandomPwd(4, false)
				mtxRandom(j,1) = arrRandom(0,j)
			Next
			arrRandom = mtxRandom
			erase mtxRandom
			arrRandom = OrdenaArreglo(arrRandom)
		else
			arrRandom = ""
		end if
		GetRandomRS = arrRandom
	End Function

End Class

Set ObjRandom = New RandomRS
ds = ObjRandom.GetRandomRS("SELECT notice_id FROM tbl_notice WHERE notice_live=1")
if isArray(ds) then
	For i = 0 to uBound(ds)
		Response.Write(ds(i,0) & " | " & ds(i,1) & "<br>")
	Next
else
	response.Write("no")
end if
%>
Solo incorpore una funcion para ordenar el arreglo mediante el metodo de la burbuja aunque tal vez lo quieran hacer por otro metodo mas eficiente, al final, como te dije, solo necesitas los valores en el indice de matriz(x, 1).
No esta super probado, pero ya pos tu depuralo.

Salu2,
__________________
"El hombre que ha empezado a vivir seriamente por dentro, empieza a vivir más sencillamente por fuera."
-- Ernest Hemingway
  #23 (permalink)  
Antiguo 25/03/2005, 12:49
Avatar de mrgubu  
Fecha de Ingreso: febrero-2002
Ubicación: Granada
Mensajes: 431
Antigüedad: 23 años, 2 meses
Puntos: 2
he sustituido el sql que viene en el código de u_goldman por uno del tipo 'select id from mi tabla' y unas veces funciona y otras no:

Cuando funciona, parece que obtengo en la segunda columna dekl array los ids ordenados aleatoriamente.

Sin embargo, luego aplico el mismo código a otras tablas y me da el error:
'El subíndice está fuera del intervalo: 'I' '.
El error lo da en la linea Response.Write(ds(i,0) & " | " & ds(i,1) & "<br>").

Supongo que en caso de hacerlo funcionar, correctamente, luego habría que hacer otro sql obteniendo los campos que necesito mostrar, ordenandolo a partir de los ids aleatorios de la segunda columna del array. ¿Pero cómo hago esto?
  #24 (permalink)  
Antiguo 25/03/2005, 13:18
Avatar de meru-kun  
Fecha de Ingreso: noviembre-2002
Ubicación: Madrid
Mensajes: 854
Antigüedad: 22 años, 5 meses
Puntos: 0
Lexus, en ese código concreto, no está definida la variable "numero_limite", mira, haz así:

Código:
 i = 0
numero_elementos= 4 ' Nº de elementos aleatorios que saca
numero_limite = 50  ' Cota superior para sacar valores
Redim arreglo(numero_elementos)
call getArray(1, numero_limite)
Do While i < numero_elementos
response.write arreglo(i)
i = i + 1
Loop
__________________
Tu portal de manga y anime.
  #25 (permalink)  
Antiguo 25/03/2005, 16:45
Avatar de u_goldman
Moderador
 
Fecha de Ingreso: enero-2002
Mensajes: 8.031
Antigüedad: 23 años, 3 meses
Puntos: 98
mrgubu, hay que debugear la aplicacion, pero al menos pon algo de voluntad si te da ese error es porque se pasa en el numero de indices que tiene el arreglo, depuralo, para eso es!! dije que habia que probarlo, por eso precisamente no te postee antes el ordenamiento, para que tu lo echaras a andar, no me lo tomes a mal, pero al menos me gustaria que trataras de depurarlo. La logica esta puesta...

Salu2,
__________________
"El hombre que ha empezado a vivir seriamente por dentro, empieza a vivir más sencillamente por fuera."
-- Ernest Hemingway
  #26 (permalink)  
Antiguo 26/03/2005, 03:34
Avatar de mrgubu  
Fecha de Ingreso: febrero-2002
Ubicación: Granada
Mensajes: 431
Antigüedad: 23 años, 2 meses
Puntos: 2
u_goldman, no te , ya me gustaría a mí darte el gustazo de echar a andar la aplicación a la primera, pero la verdad es que este código se me va de las manos.

No sé realmente qué hacen exactamente las funciones, por eso soy incapaz de manejarlas. Conseguí ponerlas en marcha por pura intuición, pero no por conocimiento real de su funcionamiento. Con decirte que la función arreglo no sé lo que arregla, pues te lo digo todo. ¿que significa eso del "método de la bubuja"?

No pensaba que esto del randomismo fuera tan complicado.

De todas formas, ugoldman, te agradezco enormemente el esfuerzo que has hecho para intentar solucionar este post. Tu trabajo y el de los demás auténticos másters que hay por estos foros es realmente extraordinario. Por eso los forosdelweb son cada día más populares.
  #27 (permalink)  
Antiguo 26/03/2005, 23:56
Avatar de u_goldman
Moderador
 
Fecha de Ingreso: enero-2002
Mensajes: 8.031
Antigüedad: 23 años, 3 meses
Puntos: 98
mrbugu:
No me molesta para nada que no puedas despues de tratar, lo que me molesta es que no intentes hacer las cosas, te puse la ultima función casi de inmediato, aunque te había dicho que lo pondría en dos horas, después regresaste y pusiste el tuyo de que no te funcionó, cabe destacar que esta clase, justo como la puse, la tengo corriendo en un site, y funciona bien, es muy posible que sí, tenga uno que otro bug que no he descubierto, pues la modifico de cuando en cuando y la he utilizado para diversas cosas, pero la lógica es la misma que te mencioné desde mi primera intervención en este post.
Comentaré el código para que te familiarices con el, pero una vez que haya hecho esto, no quiero que regreses el mismo día a decir que no lo pudiste implementar solo por hacer copy & paste y que no funcione a las primeras de cambio, quiero que te tomes tu tiempo para pensar acerca del modelo planteado en esta solución y que realmente tengas la apertura para comprenderlo, no es nada del otro mundo e incluso es suceptible a muchos cambios.
La función que regresa números aleatorios ya está comentada, así que no hay necesidad de recomentarla.
Por cierto, el método de la burbuja es uno de los métodos probados y conocidos para el ordenamiento de arreglos, encuentras muchos algoritmos por toda la red, aunque es conocido también por no ser un método muy eficiente en cuanto a tiempo/recursos, pues tiene dos ciclos, el for externo servirá para recorrer tantos elementos tenga el array, y el for interno servirá para comparar por pares de valores, pero iterará 1 vez menos que el índice mayor del array, por lo tanto el número de iteraciones es exponencial, por eso comentaba que quizás convendría implementarlo con quicksort, AZ, proprcionó una subrutina en ASP, la cual también viene dentro de este post.

Código:
	'Funcion para ordenar arreglo, metodo de la burbuja, recibe un arreglo
	Function OrdenaArreglo(arreglo)
		Dim x, y, temp
                'Si es arreglo el valor que recibe la función
		If isArray(arreglo) Then
			'Dim temp
                        'Desde que x vale 0 hasta el máximo índice del arreglo
			For x = 0 to uBound(arreglo)
                                Desde y = índice del arreglo en x + 1, hasta  el máximo índice del arreglo
				For y = x + 1 to uBound(arreglo)	
                                        'Si matriz en fila de x, columna 0 es mayor que fila de y, columna 0	
					If arreglo(x, 0) > arreglo(y, 0) Then
                                                'Guarda valores temporales
						temp = arreglo(x, 0)
						temp2 = arreglo(x, 1)
                                                'Intercambia los valores, se manejan dos columnas, 0 y 1, ya que estamos trabajando con una matriz
						arreglo(x, 0) = arreglo(y, 0)
						arreglo(x, 1) = arreglo(y, 1)
						arreglo(y, 0) = temp
						arreglo(y, 1) = temp2
					End If
				Next
			Next
                'Si no es arreglo, regresa un nulo
		Else
			OrdenaArreglo = Null
		End If
                'La función regresa a la matriz ordenada, de acuerdo a la columna 0
		OrdenaArreglo = arreglo
	End Function

	'Función que recibe una sentencia SQL, intenta regresar una matriz con la columna 0, un valor aleatorio, columna 1, el índice resultante de un recordset
	Public Function GetRandomRS(qry)
                'Dimensionamos las variables necesarias
		Dim ObjConn
		Dim rs 
		Dim cmd
		Dim arrRandom 
		Dim mtxRandom
		Dim j
		
                'Instanciamos los objetos necesarios, utilizaremos un comando parametrizado para abrir el recordset
		Set ObjConn = Server.CreateObject("ADODB.Connection")
		Set rs = Server.CreateObject("ADODB.Recordset")
		Set cmd = Server.CreateObject("ADODB.Command")
		ObjConn.Open strConnect
		cmd.ActiveConnection = ObjConn
		cmd.CommandType = adCmdText
		cmd.CommandText = qry
		rs.CursorType = 3
                'Ejecutamos el comando al abrir el recordset
		rs.Open cmd
                'Si se encontraron registros entonces
		if not rs.EOF then
                         'utilizamos el método GetRows del recordset para trabajar con un arreglo
			arrRandom = rs.GetRows()
                        'Redimensionamos un arreglo y lo convertimos en la matriz, con esta matriz trabajaremos durante todo el proceso
			Redim mtxRandom(uBound(arrRandom,2), 1)
                        'Desde j =0 hasta el número de filas de nuestra matriz anterior
			For j = 0 to uBound(arrRandom,2)
                                'Matriz actual(fila de j, columna 0) = número aleatorio regresado de la función RandomPwd
				mtxRandom(j,0) = RandomPwd(4, false)
                                'Matriz actual(fila de j, columna de 1 = getrows en fila de 0, columna de j)
				mtxRandom(j,1) = arrRandom(0,j)
                        'Itera
			Next
                        'Solo por consistencia trasladamos nuestra matriz a arrRandom
			arrRandom = mtxRandom
                         'Borramos la matriz mtxRandom, no la necesitamos mas
			erase mtxRandom
                         'Envíamos la matriz a ordenarse de acuerdo al índice de 0, que es nuestro valor aleatorio
			arrRandom = OrdenaArreglo(arrRandom)
                 'Si no hay registros, regresamos un string vacio, en realidad por consistencia de la aplicación podríamos regresar un nulo
		else
			arrRandom = ""
		end if
                 'Regresamos nuestra matriz ordenada
		GetRandomRS = arrRandom
	End Function
Ahora si, lo que sigue solo es instanciar la clase y trabajar con las funciones, como puedes ver, no es la gran cosa, y no nos salimos del plan original, crear una matriz, generar números aleatorios, poblar la matriz con estos números en pares con los ID's de tu recordset y ordenar la matriz en base a los números aleatorios, entonces si, despues solo tienes que recorrer la matriz en la columna 1, que es la que tiene los IDS, para trabajar con ella, de manera secuencial te puede dar justo lo que tu necesitas y la idea de trabajar con la clase, es que dentro de la misma clase te crees un método ObtenerRegistros(intID) que te regrese todas las propiedades(campos) para un id dado(intID), investiga sobre la creación de propierades en VB, básicamente necesitarás Property Get y Property Let, una externa y otra interna respectivamente, además de crear una variable interna Private variable para manejar la propiedad.

Ok, mr, como puedes ver tienes un buen reto por delante, no solo hacerlo sino hacerlo mejor, de todo esto, te aseguro que si lo consigues, no solo obtendrás una gran satisfacción, sino que también el aprendizaje adquirido será súmamente significativo.

Salu2, y cualquier cosa que necesites para eso estamos, siempre y cuando quieras liarte primero un poco con el código, a mi por lo menos no me gusta dar completas las soluciones(si es que las tengo), pues no motivas la investigación y se pierde el objetivo de AYUDA dentro de una comunidad.

AZ, cuantos caracteres tengo en este?? , a lo mejor podría haber dicho la respuesta antes de mi discurso

Salú y felices líneas
__________________
"El hombre que ha empezado a vivir seriamente por dentro, empieza a vivir más sencillamente por fuera."
-- Ernest Hemingway
  #28 (permalink)  
Antiguo 27/03/2005, 09:36
Avatar de AlZuwaga
Colaborador
 
Fecha de Ingreso: febrero-2001
Ubicación: 34.517 S, 58.500 O
Mensajes: 14.550
Antigüedad: 24 años, 2 meses
Puntos: 535
u_g, mi Guord se colgó antes de terminar de contar la cantidad de caracteres de tu respuesta ;)

Saludos
__________________
...___...
  #29 (permalink)  
Antiguo 27/03/2005, 10:56
Avatar de mrgubu  
Fecha de Ingreso: febrero-2002
Ubicación: Granada
Mensajes: 431
Antigüedad: 23 años, 2 meses
Puntos: 2
u_g, muchas gracias de nuevo, voy a intentar hacer funcionar el código, y te aseguro que no voy a parar hasta conseguirlo, nada más que por el interés que te has tomado.

Eso sí, no te garantizo que la respuesta sea rápida, porque echar a andar el código este creo que me va a costar todavía un poco.

Saludos,
  #30 (permalink)  
Antiguo 27/03/2005, 12:18
Avatar de mrgubu  
Fecha de Ingreso: febrero-2002
Ubicación: Granada
Mensajes: 431
Antigüedad: 23 años, 2 meses
Puntos: 2
Bueno, ya descubierto cuál era el error, o sea ya consigo hacer funcionar el recordset ds en cualquier tabla con un select del tipo 'select id from tabla'. El fallo que me daba en algunas tablas era porque la tabla no llegaba a 10 registros.... qué tontería ¿verdad?

Y ahora....

Cita:
Iniciado por u_goldman
mrbugu:
dentro de la misma clase te crees un método ObtenerRegistros(intID) que te regrese todas las propiedades(campos) para un id dado(intID), investiga sobre la creación de propierades en VB, básicamente necesitarás Property Get y Property Let, una externa y otra interna respectivamente, además de crear una variable interna Private variable para manejar la propiedad.


Estooo..........alguna ideilla para empezar a montar esto?

Por favor u_goldman no te pero soy incapaz de armar desde cero lo que propones. Prometo ir mirando estos días manuales de VB a ver si consigo avanzar algo.
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 11:53.