hola Claudia,
espero que ya hayas podido resolver tus dudas, pero por si acso no fuese asi, te comento algunas cosas por si te pueden ser utiles:
Cita:
|
el rango puede variar solo tengo donde comienza pero no sabia donde terminaria alguien sabe como puedo lograr eso
|
existe bastantes formas de averiguar cual es la ultima celda y/o fila y/o columna de una lista
NOTA: solo como dato, por si lo desconocieras, para manejar listas en excel como si fuesen bases de datos, no conviene que haya filas vacias entre la fila de titulos y la 1ª de datos. De hecho, si no me equivoco, para que excel cosidere realmente una lista como uan BD esta debe contener titulos, y estos comenzar en la 1ª celda de la hoja [a1], y por supuesto no debe haber filas vacias entre estos y los datos.
De todas formas no quita para poder trabajar como si de BD se tratara aunque no se cumplan exactamente estos requisitos. Aunque ayudan y facilitan bastante las cosas
.- Pej.:
.-> si conoces cual es la fila y/o la columna mas larga (pej. la fila de titulos si los tiene y/o un campo clave si lo hay. Una buena opcion seria la primera celda de la lista, titulos incluidos de haberlos)). Podrias usar alguna de las siguientes formas, usando las propiedades 'End', 'CurrentRegion', y alguna mas del objeto Range
la mayoria de los ej. suponen que la lista empezase en A1 de la hoja activa y tanto la columna A como la fila 1 van a contener datos al menos igual o mas que el resto, aunque son validos o se pueden adaptar para casi cualquier rango,
decantarse por unas u otras dependera de cada situacion
(aunque los ej. van dentro de un proc. sub, es solo para facilitarteel copiado/pegado, pero el procedimiento realmente no hace nada)
Código:
Sub FormasObtenerUltimasFilasColumnasCeldas()
With ActiveSheet
'
''**** para la columna A ************
'
''---- la ultima celda con datos ----
Dim UltCeldaA As Range
Set UltCeldaA = .Cells(.Rows.Count, 1).End(xlUp)
'
''---- la 1ª celda vacia ------------
Dim PrCeldaVaciaA As Range
Set PrCeldaVaciaA = .Cells(.Rows.Count, 1).End(xlUp).Offset(1)
'
''---- la ultima fila con datos -----
Dim UltFila As Long
UltFila = .Cells(.Rows.Count, 1).End(xlUp).Row
'
''---- la 1ª fila vacia ------------
Dim PrFilaVacia As Long
PrFilaVacia = .Cells(.Rows.Count, 1).End(xlUp).Row + 1
'
''**** para la fila 1 ****************
'
''---- la ultima celda con datos ----
Dim UltCeldaF1 As Range
Set UltCeldaF1 = .Cells(1, .Columns.Count).End(xlToLeft)
'
''---- la 1ª celda vacia ------------
Dim PrCeldaVaciaF1 As Range
Set PrCeldaVaciaF1 = .Cells(1, .Columns.Count).End(xlToLeft).Offset(, 1)
'
''---- la ultima fila con datos -----
Dim UltCol As Long
UltCol = .Cells(1, .Columns.Count).End(xlToLeft).Column
'
''---- la 1ª fila vacia ------------
Dim PrColVacia As Long
PrColVacia = .Cells(1, .Columns.Count).End(xlToLeft).Column + 1
'
''******** para la ultima celda de la lista *****
''
'' OJO: no tiene por que contener datos, pero es
'' la 'esquina' inferior derecha del rectangulo
'' formado por las filas y columnas con datos
'
''----- siguiendo con End -----------
Dim UltCelda As Range
Set UltCelda = .Cells(.Cells(.Rows.Count, 1).End(xlUp).Row, _
.Cells(1, .Columns.Count).End(xlToLeft).Column)
'
''----- con CurrentRegion ---------
Dim UltCelda As Range
Set UltCelda = .Cells(.[a1].CurrentRegion.Rows.Count, _
.[a1].CurrentRegion.Columns.Count)
'
''******** rango de la lista completa *******
''
''---- con currentregion ----------
''
'' OJO: siempre que uses CurrentRegion, ten en cuenta que
'' para obtener el nº de la ultima fila y/o columna
'' respecto a la hoja hay que sumarle a el numero de
'' filas/columnas devuelto el nº de la 1ª fila/columna
'' menos 1. +/- asi =>
Dim uF As Long, uC As Integer, Rango_Lista As Range
With Range("d100").CurrentRegion
uF = .Rows.Count + .Cells(1).Row - 1
uC = .Columns.Count + Cells(1).Column - 1
Set Rango_Lista = Range(.Cells(1), .Cells(uF, uC))
End With
'
''***** y por ultimo obtener la ref. en estilo A1 ****
''
''-- con Address la absoluta y con Address(0,0) la relativa -
'' Pej. si Rango lista fuese de A1 a F3350
Dim RefAbs As String, RefRel As String
RefAbs = Rango_Lista.Address ' devolveria "$A$1:$F$3350"
RefRel = Rango_Lista.Address(0, 0) ' devolveria "A1:F3350"
'' bueno, son solo algunas de las posibilidades. Unas veces viene
'' mejor una y otras otra
End Sub Cita:
|
Empezado por Claudia ..y tambien que me muestre el cuadro de dialogo para guardar mi archivo |
tambien hay bastantes opciones. Algunas de ellas
opcion a) podrias usar la coleccion Dialogs con su parametro xlDialogSave (creo que mas o menos es asi, pero compruebalo en la ayuda con F1) para mostrar el cuadro de dialogo original y guardarlo,
Código:
Application.Dialogs (xlDialogSaveAs)
opcion b) si vas a trabajar con versiones posteriores al 98 (creo que para esta tambien vale pero no estpy seguro) puedes usar el metodo 'GetSaveAsFileName', que te muestra el mismo cuadro de dialog, pero no lo guarda, sino que te devuelve el nombre elegido/introducido con la ruta completa donde hayas elegido guardarlo. Despues tu puedes ecidir que hacer.
hay bastantes mas opciones, pero creo que ya me he pasado.
de todas formas, y a riesgo de saturarte/os te pongo un ej. completo desgajado en varios procedimientos para cada una de las cosas que comentas.
pega los codigos en un modulo 'normal' (no de Hoja ni en Thisworkbook ni en uno de clase) y para probar llama a la macro testCrearTxtConRango desde excel (pej. Alt+F8 -> la seleccionas -> y ejecutas)
Código:
'
''******** Devuelve el rango de una lista pasandole ******
' una de sus celdas como argumento.
' OJO: conviene pasarle una celda que sepamos que no
' esta aislada (rodeada de celdas vacias). Lo mas seguro
' es pasarle una de la fila de titulos o de la columna que
' sepamos que tiene mas registros. El argumento es opcional.
' Si se omite toma la celda activa
'
Public Function RangoLista( _
Optional ByVal Celda As Range = Nothing) As Range
Dim rng As Range
If Celda Is Nothing Then Set Celda = ActiveCell
Set Celda = Celda.CurrentRegion.Cells(1)
Set rng = Celda.Parent.Range(Celda, Celda.Offset( _
Celda.CurrentRegion.Rows.Count - 1, _
Celda.CurrentRegion.Columns.Count - 1))
If Not rng Is Nothing Then Set RangoLista = rng
Set Celda = Nothing: Set rng = Nothing
End Function
'
''******** Devuelve un nombre y ruta completo a un archivo '.txt', ***
' seleccionando la ruta en un cuadro de dialogo y escribiendo
' el nombre en este cuadro, que es igual que el de guardar como,
' pero que te devuelve la ruta completa, pero sib guardar realmente
' el archivo. El argumento NombreL [opcional] es por si queremos
' que aparezca un nombre por defecto al abrir el cuadro de dialogo.
' Si se omite se toma el nombre de la hoja activa. Si el nombre ya
' existe en el directorio elegido, lo avisa y vuelve a mostrar enl
' cuadro de dialogo (el usuario puede cancelar el proceso)
' OJO: este cuadro (GetSaveAsFileName) no esta disponible en todas
' las versiones. Creo que a partir de la '2000' seguro, y posiblemente
' tambien desde la '98', pero no estoy seguro del todo.
' Es un poco rebuscada, y quizas se excede en comprobar posibles
' errores, pero solo por si acaso. Se puede 'extractar'.....
'
Public Function NombreConRuta( _
Optional NombreL As String = "") As String
Dim nL As Variant
inicio:
If NombreL = "" Then
NombreL = ActiveSheet.Name
Else
If InStr(NombreL, "\") > 0 Then NombreL = Right(NombreL, _
Len(NombreL) - InStrRev(NombreL, "\"))
If InStr(NombreL, ".") > 0 Then NombreL = Left(NombreL, _
InStr(NombreL, ".") - 1)
End If
nL = Application.GetSaveAsFilename(NombreL, _
"Archivos de texto (*.txt), *.txt")
If nL = False Or nL = "" Then Exit Function
If Dir(nL) <> "" Then
MsgBox "El nombre seleccionado ya existe."
GoTo inicio
End If
NombreConRuta = CStr(nL)
End Function
'
''********** una forma sencilla de crear un archivo de texto. Se le
' pasan el nombre con que guardarlo, y el rango que se va a guardar
'
Sub CrearTxtConRango(NombreArchivo As String, Rango As Range)
With Workbooks.Add
Rango.Copy
.Worksheets(1).Range("a1").PasteSpecial xlPasteValues
.SaveAs Filename:=NombreArchivo, FileFormat:=xlCurrentPlatformText
.Close False
End With
End Sub
'
''************ para probar todo lo anterior **********************
'
Sub testCrearTxtConRango()
Dim nombre As String, r As Range
Application.ScreenUpdating = False
nombre = NombreConRuta
If nombre = "" Then MsgBox "El proceso ha sido " & _
"cancelado por el usuario.": Exit Sub
Set r = RangoLista
If Not r Is Nothing Then
CrearTxtConRango nombre, r
Set r = Nothing
Else
MsgBox "El rango no es valido"
End If
End Sub
espero no haberte liado mucho y que te sirva de algo (y disculpas por la extension, supongo que como llevaba tiempo sin poder entrar pues me he desahogado)
un saludo
Ivan