sábado, noviembre 25, 2006

Algoritmos y dígitos de control

Hoy tengo el día tonto y no quiero hablar de problemas sino de matemáticas, aunque en el fondo, ¿Qué son las matemáticas sin problemas y los problemas sin matemáticas?

Bueno. Pues me puse a destripar los dígitos de control de la referencia catastral que nos aparece en los recibos del IBI, antes contribución. (El destripado del digito de control del DNI se puede encontrar en Internet con lo que no tenía ninguna gracia dedicarle tiempo).

Con la ayuda de ovc.catastro.meh.es para consultar diferentes parcelas y ver los dígitos calculados he llegado al siguiente algoritmo:

Para el primer digito de control tómese las 7 primeras posiciones de la referencia catastral y el numero de cargo sobre 4 posiciones justificado a la derecha (p. ej. 0027).

Para el segundo digito, tómese la segunda parte de la referencia (posiciones 8 a 14) y las 4 posiciones del cargo.

Remplácese en su caso las letras por números según la siguiente conversión:

A=1, B=2, C=3, D=4, E=5, F=6, G=7, H=8, I=9, J=10, K=11, L=12, M=13, N=14, Ñ=15, O=16, P=17, Q=18, R=19, S=20, T=21, U=22, V=23, W=24, X=25, Y=26 y Z=27

Multipliquese cada digito (o en su caso el valor correspondiente de la letra) por los siguientes valores según su posición:

1º=13, 2º=15, 3º=12, 4º=5, 5º=4, 6º=17, 7º=9, 8º=21, 9º=3, 10º=7, 11º=1

Súmense todos los valores obtenidos y divídase por 23, obteniendo un resto (entre 0 y 22).

Conviertase dicho resto a letra según la siguiente tabla:

0 =M, 1 =Q, 2 =W, 3= E, 4 =R, 5= T, 6 =Y, 7= U, 8= I, 9= O, 10= P, 11= A, 12= S, 13= D, 14= F, 15= G, 16= H, 17= J, 18= K, 19= L, 20= B, 21= Z, 22= X
Y ya lo tenemos. Otro dia me entretendre con alguna otra curiosidad.

40 comentarios:

Anónimo dijo...

Hola,

Es muy interesante. Por mucho que he buscado este algoritmo no he visto ninguna descripción hasta ahora.

No entiendo cómo se calcula el primer dígito de control. Tengo las siguientes dudas:

* ¿Qué dígitos son los de número de cargo? (posiciones dentro de los 20 caracteres).
* ¿Cómo se calcula a partir de las 7 primeras posiciones de la referencia y las cuatro del número de cargo?

También ayudaría mucho si pudieras poner un ejemplo.

Gracias.

Anónimo dijo...

- tema cargo:
el cargo son las 4 posiciones justo antes de los dígitos de control. las posi. son 15-16-17-18, la posi 19 y 20 son los d.c.

el cargo es un número secuencial que identifica recibos dentro de una finca

Anónimo dijo...

Si señor, mi enhorabuena !!! Pero hay un problema, cuando las referencias catastrales son rústicas, el algoritmo no sirve. ¿Sabría decirme que algoritmo utilizan las referencias catastrales no urbanas también llamadas rústicas?

Gracias, de nuevo mis felicitaciones.

Anónimo dijo...

Enhorabuena, el algoritmo me funciona perfectamente para calcular el primer carácter de control, sin duda porque solo usa dígitos numéricos; pero no consigo que me funcione cuando aparecen letras, es decir, para el cálculo del segundo carácter.

Analizando, por ejemplo, la referencia catastral 001500100UF97B0001QI, para el segundo carácter de control, tendríamos...

0 -> 0 * 13 = 0
0 -> 0 * 15 = 0
U -> 22 * 12 = 264
F -> 6 * 5 = 30
9 -> 9 * 4 = 36
7 -> 7 * 17 = 119
B -> 2 * 9 = 18

Sumando las cantidades, obtenemos 467.

El resto de dividir por 23 nos da 7.

El carácter que corresponde al 7, según la tabla de sustitución, es "U", pero en la referencia catastral figura "I".

Dado que con dígitos numéricos el algoritmo es correcto, el fallo puede estar en el reemplazo de letras por números.

Si hago algo mal, por favor, indícamelo pues me sería muy útil este algoritmo. Y si necesitas algunas referencias catastrales para cotejo, te las puedo hacer llegar.

Gracias

El autor dijo...

Efectivamente parece que hay algún problema con la segunda parte de la referencia y con las rústicas. Lo estudiaré.

El autor dijo...

Bueno. Solucionado el error. En negrita en el post lo que faltaba.

Anónimo dijo...

Ahora sí...

Enhorabuena y muchas gracias.

ENRIQUE LLADO dijo...

A PARTIR DE LAS OPERACIONES SEÑALADAS POR EL AUTOR HE HECHO UNA HOJA DE CALCULO QUE ME SIRVE ADEMAS DE PARA CALCULAR LOS DIGITOS DE CONTROL DE UNA REFERENCIA CATASTRAL, TAMBIEN PARA CALCULAR A PARTIR DE LA DEL SOLAR LA DE TODOS LOS NUMEROS DE ORDEN DE LA FINCA CONSTRUIDA SOBRE EL SOLAR (DIVISION ADMINISTRATIVA). MUCHAS GRACIAS AL AUTOR

El autor dijo...

Pues un paso mas. Un programita en BASIC (si, el qbasic funciona en XP)


ON ERROR GOTO SIGUE
DIM valor(20)

CADENA$ = "MQWERTYUIOPASDFGHJKLBZX"
OPEN "entrada.txt" FOR INPUT AS #1
OPEN "salida.txt" FOR OUTPUT AS #2

DO WHILE NOT EOF(1)
INPUT #1, rec$
segmento$ = MID$(rec$, 1, 2)
r1$ = MID$(rec$, 3, 28)
parcela$ = MID$(rec$, 31, 18)
dc$ = MID$(rec$, 49, 2)
r2$ = MID$(rec$, 51, 950)
IF segmento$ = "15" OR segmento$ = "46" OR segmento$ = "49" OR segmento$ = "48" THEN GOSUB calcula

PRINT #2, segmento$; r1$; parcela$; dc$; r2$
LOOP
CLOSE #1
CLOSE #2
END


calcula:

FOR posicion = 1 TO 18

IF MID$(parcela$, posicion, 1) = "A" THEN valor(posicion) = 1
IF MID$(parcela$, posicion, 1) = "B" THEN valor(posicion) = 2
IF MID$(parcela$, posicion, 1) = "C" THEN valor(posicion) = 3
IF MID$(parcela$, posicion, 1) = "D" THEN valor(posicion) = 4
IF MID$(parcela$, posicion, 1) = "E" THEN valor(posicion) = 5
IF MID$(parcela$, posicion, 1) = "F" THEN valor(posicion) = 6
IF MID$(parcela$, posicion, 1) = "G" THEN valor(posicion) = 7
IF MID$(parcela$, posicion, 1) = "H" THEN valor(posicion) = 8
IF MID$(parcela$, posicion, 1) = "I" THEN valor(posicion) = 9
IF MID$(parcela$, posicion, 1) = "J" THEN valor(posicion) = 10
IF MID$(parcela$, posicion, 1) = "K" THEN valor(posicion) = 11
IF MID$(parcela$, posicion, 1) = "L" THEN valor(posicion) = 12
IF MID$(parcela$, posicion, 1) = "M" THEN valor(posicion) = 13
IF MID$(parcela$, posicion, 1) = "N" THEN valor(posicion) = 14
IF MID$(parcela$, posicion, 1) = "¥" THEN valor(posicion) = 15
IF MID$(parcela$, posicion, 1) = "O" THEN valor(posicion) = 16
IF MID$(parcela$, posicion, 1) = "P" THEN valor(posicion) = 17
IF MID$(parcela$, posicion, 1) = "Q" THEN valor(posicion) = 18
IF MID$(parcela$, posicion, 1) = "R" THEN valor(posicion) = 19
IF MID$(parcela$, posicion, 1) = "S" THEN valor(posicion) = 20
IF MID$(parcela$, posicion, 1) = "T" THEN valor(posicion) = 21
IF MID$(parcela$, posicion, 1) = "U" THEN valor(posicion) = 22
IF MID$(parcela$, posicion, 1) = "V" THEN valor(posicion) = 23
IF MID$(parcela$, posicion, 1) = "W" THEN valor(posicion) = 24
IF MID$(parcela$, posicion, 1) = "X" THEN valor(posicion) = 25
IF MID$(parcela$, posicion, 1) = "Y" THEN valor(posicion) = 26
IF MID$(parcela$, posicion, 1) = "Z" THEN valor(posicion) = 27
IF MID$(parcela$, posicion, 1) = "0" THEN valor(posicion) = 0
IF MID$(parcela$, posicion, 1) = "1" THEN valor(posicion) = 1
IF MID$(parcela$, posicion, 1) = "2" THEN valor(posicion) = 2
IF MID$(parcela$, posicion, 1) = "3" THEN valor(posicion) = 3
IF MID$(parcela$, posicion, 1) = "4" THEN valor(posicion) = 4
IF MID$(parcela$, posicion, 1) = "5" THEN valor(posicion) = 5
IF MID$(parcela$, posicion, 1) = "6" THEN valor(posicion) = 6
IF MID$(parcela$, posicion, 1) = "7" THEN valor(posicion) = 7
IF MID$(parcela$, posicion, 1) = "8" THEN valor(posicion) = 8
IF MID$(parcela$, posicion, 1) = "9" THEN valor(posicion) = 9
NEXT posicion

valor(1) = valor(1) * 13
valor(2) = valor(2) * 15
valor(3) = valor(3) * 12
valor(4) = valor(4) * 5
valor(5) = valor(5) * 4
valor(6) = valor(6) * 17
valor(7) = valor(7) * 9
valor(8) = valor(8) * 13
valor(9) = valor(9) * 15
valor(10) = valor(10) * 12
valor(11) = valor(11) * 5
valor(12) = valor(12) * 4
valor(13) = valor(13) * 17
valor(14) = valor(14) * 9
valor(15) = valor(15) * 21
valor(16) = valor(16) * 3
valor(17) = valor(17) * 7
valor(18) = valor(18) * 1
total1 = 0
total2 = 0

FOR X = 1 TO 7
total1 = total1 + valor(X)
total2 = total2 + valor(X + 7)
NEXT X

FOR X = 15 TO 18
total1 = total1 + valor(X)
total2 = total2 + valor(X)
NEXT X
PRINT total1, total2
resto1 = total1 - (FIX(total1 / 23) * 23)
resto2 = total2 - (FIX(total2 / 23) * 23)

dc1$ = MID$(CADENA$, resto1 + 1, 1)
dc2$ = MID$(CADENA$, resto2 + 1, 1)

dc$ = dc1$ + dc2$


RETURN

SIGUE:
RESUME NEXT

El autor dijo...

Evidentemente entrada es un FIN2006 sin los DC y salida es un FIN2006 con ellos.

Anónimo dijo...

me podríais facilitar la hoja de cálculo para calcular las letras de la referencia castastral

Pedro L. dijo...

Me parece muy intersante el algorismo referente a conocer los digitos de control de una referencia catastral concretamente de una parcela rustica, conociendo los 20 digitos. Tm, poligono, parcela etc. pero si habeis conseguido una hoja de calculo con una formula para poder hacer los calculos, por favor alguien me los puede hacer llegar? gracias

Anónimo dijo...

He confeccionado una hoja excel. Podéis decirme cómo la subo? (unoquebusca@telefonica.net)

Anónimo dijo...

Creo que no deja subir archivos en los post. Subela a un gestor online de archivos y pon el link

pensanteaburrido dijo...

tengo una inquietud que no he podido resolver y es este algoritmo...
9/0000/0007/03124581521/483765= 69PYSD6, me podrian ayudar a solucionarlo no se de donde salen estos numeros, se los agradeceria mucho.

pensanteaburrido dijo...

aca tengo otra secuencia con un numero de casa igual, de verdad que me gustaria que me ayudaran. 3/0000/0007/04403082814/073810=9EJPDHY
1/0000/0007/04403082814/073870=SEJPDHK
6/0000/0007/04403082814/073875=LFTRIY9

El autor dijo...

Pensanteaburrido. No entiendo lo que pones ni lo que pides.

Anónimo dijo...

Public Function ReferenciaCatastral(ByVal Referencia As String) As String

Dim Ref1 As String, Ref2 As String, Car As String, DC1 As String, DC2 As String

Ref1 = Mid(Referencia, 1, 7)
Ref2 = Mid(Referencia, 8, 7)
Car = Mid(Referencia, 15, 4)
DC1 = Mid(Referencia, 19, 1)
DC2 = Mid(Referencia, 20, 1)

Dim sRef1 As String, sRef2 As String

sRef1 = Ref1 & Car
sRef2 = Ref2 & Car

Debug.Print ObtenerDigitoControl(sRef1) & ObtenerDigitoControl(sRef2)

End Function

Private Function ObtenerDigitoControl(ByVal Referencia As String) As String

Const Restos As String = "MQWERTYUIOPASDFGHJKLBZXCVÑN"
Const Pesos As String = "ABCDEFGHIJKLMNÑOPQRSTUVWXYZ"

'On Error Resume Next

Dim nIndex As Integer, sBuffer As String, nBuffer As Long, nResultado As Double

For nIndex = 1 To Len(Referencia)
sBuffer = Mid(Referencia, nIndex, 1)
If IsNumeric(sBuffer) Then
nBuffer = Val(sBuffer)
Else
nBuffer = InStr(Pesos, sBuffer)
End If
nResultado = nResultado + (nBuffer * (7 ^ (11 - nIndex)))
Next nIndex

nResultado = DoubleMOD(nResultado, 23)
'nResultado = nResultado Mod 23

ObtenerDigitoControl = Mid(Restos, nResultado + 1, 1)

End Function

Public Function DoubleMOD(ByVal Dividendo As Double, ByVal Divisor As Double) As Double

DoubleMOD = Dividendo - (Fix(Dividendo / Divisor) * Divisor)

End Function

Anónimo dijo...

Public Function ReferenciaCatastral(ByVal Referencia As String) As String

Dim Ref1 As String, Ref2 As String, Car As String, DC1 As String, DC2 As String

Ref1 = Mid(Referencia, 1, 7)
Ref2 = Mid(Referencia, 8, 7)
Car = Mid(Referencia, 15, 4)
DC1 = Mid(Referencia, 19, 1)
DC2 = Mid(Referencia, 20, 1)

Dim sRef1 As String, sRef2 As String

sRef1 = Ref1 & Car
sRef2 = Ref2 & Car

ReferenciaCatastral = ObtenerDigitoControl(sRef1) & ObtenerDigitoControl(sRef2)

End Function

Private Function ObtenerDigitoControl(ByVal Referencia As String) As String

Const Restos As String = "MQWERTYUIOPASDFGHJKLBZXCVÑN"
Const Pesos As String = "ABCDEFGHIJKLMNÑOPQRSTUVWXYZ"

On Error Resume Next

Dim nIndex As Integer, sBuffer As String, nBuffer As Long, nResultado As Double

For nIndex = 1 To Len(Referencia)
sBuffer = Mid(Referencia, nIndex, 1)
If IsNumeric(sBuffer) Then
nBuffer = Val(sBuffer)
Else
nBuffer = InStr(Pesos, sBuffer)
End If
nResultado = nResultado + (nBuffer * (7 ^ (11 - nIndex)))
Next nIndex

nResultado = DoubleMOD(nResultado, 23)

ObtenerDigitoControl = Mid(Restos, nResultado + 1, 1)

End Function

Public Function DoubleMOD(ByVal Dividendo As Double, ByVal Divisor As Double) As Double

DoubleMOD = Dividendo - (Fix(Dividendo / Divisor) * Divisor)

End Function

Unknown dijo...

Buenas tardes,

siguiendo el algoritmo propuesto en su explicación, no me funciona para la referencia catastral: 2339507DG6023N0009FO.
No sé si estoy haciendo algo mal para el primer dígito:
2*13=26
3*15=45
3*12=36
9*5=45
5*4=20
0*17=0
7*9=63
0*21=0
0*3=0
0*7=0
9*1=0
+244/23=10,608

Entiendo que no debería dar un número decimal. Si estoy equivocado, aunque redondeemos al alza/baja, no funciona.

¿a qué es debido?

Muchas gracias de antemano!!

Anónimo dijo...

Debe multiplicarse por algo las posiciones 12, 13 y 14?
Tengo una rustica que no me da:
33037a006002210000ye
gracias ....

El autor dijo...

Son las 7 primeras con las cuatro ultimas y de la 8 a la 18

El autor dijo...

Hay que usar el resto, no el cociente.

Anónimo dijo...

Gracias por contestar; como no me da para mi CC, probe con el ejemplo, reproduzco el caso:
33037a006002210000ye (es bueno, puedes comprobarlo en el catastro)

Para hacer el ejemplo completo,seria:
Primer digito:
33037a0 (de 1 a 7) mas el cargo 0000
a->1
3303710-0000
3x17+3x15+0x12+3x5+7x4+1x17+0x9+0+0+0+0 (no hay pesos para el cargo...) 0 s.e.u.o. 156
156 modulo 23 = 18
18->K (y no sale la Y que corresponde)

Segundo digito:
0600221-0000
0x21+6x3+0x7+0x1+2+2+1+0+0+0+0
(no hay pesos para 12,13 y 14) = 23
23 modulo 23 = 0
0->M (y no la E que debe ser)

Que no entiendo?
Gracias de nuevo

El autor dijo...

Repasa los coeficientes. Los sumandos son 39/45/15/18/17 y 90/8/34/9 que dan como resultado YE

Anónimo dijo...

Muchas gracias, aclarado, ahora lo entendí, y sí, efectivamente da. (ojo, los sumandos son 39/45/15/28/17)

Además de haberme equivocado en un coeficiente, no había entendido que se empezaba a contar para los pesos desde el primer digito de cada "desglose".

Repito el ejemplo para que nadie reproduzca mi "síntoma":

33037A006002210000 (sabemos que da YE).

Primer digito:
33037A0 (posiciones de 1 a 7) más el cargo (las cuatro ultimas) 0000 con A->1 : 33037100000
3x13+3x15+0x12+3x5+7x4+1x17+0x9+0x21+0x3+0x7+0x1 = 144
144 modulo 23 = 6 -> Y
(144/23 = 6 + 6/23 , y la Y sale de la tabla de conversión)

Segundo digito:
0600221 (posiciones de 8 a 14) más el cargo 0000 : 06002210000
0x13+6x15+0x12+0x5+2x4+2x17+1x9+0x21+0x3+0x7+0x1 = 141
141 modulo 23 = 3 -> E
(141/23 = 6 + 3/23)

MaGaO dijo...

He preparado una hoja de Google con el algoritmo. Podéis acceder a ella a través de este enlace. He protegido todas las celdas que no necesitáis tocar (creo), así que no debería haber errores: basta con reemplazar la referencia catastral de ejemplo (en la celda B8) y poner la que os interesa. Si ponéis una referencia catastral completa ignorará los códigos de control de la misma y los generará automáticamente.
Nota: no pongáis espacios en la referencia, saldrán resultados erróneos.

Anónimo dijo...

Hola a todos,

En primer lugar agradecer el aporte tan útil.

En segundo lugar, alquien sabe el algoritmo para validar la referencia catastral rústica?

Salu2.

Coito de Llano dijo...

https://github.com/juanato/referenciacatastral


RefCastastral dijo...

Buenas a todos! Quizás llego un par de años tarde pero el tema sigue siendo bastante actual, gracias a El Divagante por descifrar el algoritmo de los dígitos de control, muy útil.
Queda únicamente una duda, alguien sabe a que hace referencia la letra en la posición 6? Según la web de catastro es el SECTOR, pero no encuentro información relacionada en ninguna parte.

Quiero calcular la referencia catastral completa a partir del código de municipio, masa y parcela, pero para ello es necesario conocer también el sector (ya que no siempre es A), alguien me podría ayudar?
Muchas gracias

luis dijo...

Una versión mas compacta en Python...
def calcdc(str11):

resto = 'MQWERTYUIOPASDFGHJKLBZX'
orden = '0123456789ABCDEFGHIJKLMNÑOPQRSTUVWXYZ'
valor = [0,1,2,3,4,5,6,7,8,9,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27]
pesos = [13,15,12,5,4,17,9,21,3,7,1]
suma = 0
for i in range(0,11):
suma += pesos[i]*valor[orden.find(str11[i])]
return resto[suma%23]

ref18 = input("Referencia Catastral 14 posiciones: ").upper()
if (len(ref18) == 18 ):
print(ref18+calcdc(ref18[0:7]+ref18[14:18])+calcdc(ref18[7:18]))
else:
print('Debe introducir una referencia de 18 posiciones')

luis dijo...

Al publicar el código se come los espacios en blanco, necesarios en Python.
Quien lo maneje seguro que los puede reponer

Emil ase dijo...
Este comentario ha sido eliminado por el autor.
Emil ase dijo...
Este comentario ha sido eliminado por el autor.
Emil ase dijo...
Este comentario ha sido eliminado por el autor.
Emil ase dijo...
Este comentario ha sido eliminado por el autor.
Emil ase dijo...
Este comentario ha sido eliminado por el autor.
Emil ase dijo...

Muchas gracias por la explicación.
Aporto un aplicativo en java para urbana y rústica.
saludos a tod@s.
package DigitsControlCad;
import javax.swing.JOptionPane;
public class digitsControl extends javax.swing.JFrame {
public digitsControl() {
initComponents();
}
private void accio() {
int Sumapd1 = 0;
int Sumasd2 = 0;
int mixte1 = 0;
String referenciaCatastral = jT1.getText();
referenciaCatastral = referenciaCatastral.toUpperCase().replace(" ", "");
jT1.setText(referenciaCatastral);
int[] posicio = new int[]{13, 15, 12, 5, 4, 17, 9, 21, 3, 7, 1};
referenciaCatastral = referenciaCatastral.toUpperCase();
char[] cadenaSeparada = referenciaCatastral.toCharArray();
String Ordreresidu = "MQWERTYUIOPASDFGHJKLBZX";
if (referenciaCatastral == null || referenciaCatastral.length() != 20) {
JOptionPane.showOptionDialog(null, "LA REFERENCIA DEBE CONTENER 20 CARACTERES ", //contenido de la ventana
"Avís ", //titulo de la ventana
JOptionPane.YES_NO_CANCEL_OPTION, //para 3 botones si/no/cancel
JOptionPane.PLAIN_MESSAGE, //tipo de ícono
null, // null para icono por defecto.
new Object[]{"ACEPTAR"},//objeto para las opciones
//null para YES, NO y CANCEL
"ACEPTAR");
} else {
for (int i = 0; i < 7; i++) {
if (Character.isDigit(cadenaSeparada[i])) {
Sumapd1 = Sumapd1 + (posicio[i] * (cadenaSeparada[i] - 48));
} else {
if (cadenaSeparada[i] > 78) {
Sumapd1 = Sumapd1 + (posicio[i]) * ((cadenaSeparada[i]) - 63);
} else {
Sumapd1 = Sumapd1 + (posicio[i]) * ((cadenaSeparada[i]) - 64);
}
}
}
for (int i = 0; i < 7; i++) {
if (Character.isDigit(cadenaSeparada[i + 7])) {
Sumasd2 = Sumasd2 + (posicio[i] * (cadenaSeparada[i + 7] - 48));
} else {
if (cadenaSeparada[i + 7] > 78) {
Sumasd2 = (Sumasd2 + (posicio[i]) * ((cadenaSeparada[i + 7]) - 63));
} else {
Sumasd2 = (Sumasd2 + (posicio[i]) * ((cadenaSeparada[i + 7]) - 64));
}
}
}
for (int i = 0; i < 4; i++) {
mixte1 = mixte1 + (posicio[i + 7] * (cadenaSeparada[i + 14] - 48));
}
int Primerdigit = (Sumapd1 + mixte1) % 23;
int Segondigit = (Sumasd2 + mixte1) % 23;
char primdgt = Ordreresidu.charAt(Primerdigit);
char segdgt = Ordreresidu.charAt(Segondigit);
String proba;
if (Character.isDigit(cadenaSeparada[5])) {
proba = "DE URBANA";
} else {
proba = "DE RÚSTICA";
}

Emil ase dijo...

if (primdgt == cadenaSeparada[18] && segdgt == cadenaSeparada[19]) {

JOptionPane.showOptionDialog(null, "LA REFERENCIA " + proba + " ES VÁLIDA", //contenido de la ventana
"Avís ", //titulo de la ventana
JOptionPane.YES_NO_CANCEL_OPTION, //para 3 botones si/no/cancel
JOptionPane.PLAIN_MESSAGE, //tipo de ícono
null, // null para icono por defecto.
new Object[]{"ACEPTAR"},//objeto para las opciones
//null para YES, NO y CANCEL
"ACEPTAR");
} else {
JOptionPane.showOptionDialog(null, "LA REFERENCIA " + proba + " NO ES VALIDA", //contenido de la ventana
"Avís ", //titulo de la ventana
JOptionPane.YES_NO_CANCEL_OPTION, //para 3 botones si/no/cancel
JOptionPane.PLAIN_MESSAGE, //tipo de ícono
null, // null para icono por defecto.
new Object[]{"ACEPTAR"},//objeto para las opciones
//null para YES, NO y CANCEL
"ACEPTAR");
}
}
}
@SuppressWarnings("unchecked")
//
private void initComponents() {

button1 = new java.awt.Button();
jT1 = new javax.swing.JTextField();

setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
setTitle("Validar Ref. Catastral");

button1.setActionCommand("Validar Dígitos Control");
button1.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N
button1.setLabel("Validar Dígitos Control");
button1.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
button1ActionPerformed(evt);
}
});

jT1.setHorizontalAlignment(javax.swing.JTextField.CENTER);
jT1.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
jT1ActionPerformed(evt);
}
});

Emil ase dijo...

javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
getContentPane().setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addContainerGap(70, Short.MAX_VALUE)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(button1, javax.swing.GroupLayout.DEFAULT_SIZE, 172, Short.MAX_VALUE)
.addComponent(jT1))
.addContainerGap(70, Short.MAX_VALUE))
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
.addContainerGap(26, Short.MAX_VALUE)
.addComponent(jT1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addGap(20, 20, 20)
.addComponent(button1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addContainerGap(28, Short.MAX_VALUE))
);

pack();
setLocationRelativeTo(null);
}//
private void jT1ActionPerformed(java.awt.event.ActionEvent evt) {
// TODO add your handling code here:
}
private void button1ActionPerformed(java.awt.event.ActionEvent evt) {
accio();
}
public static void main(String args[]) {

java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
new digitsControl().setVisible(true);

}
});
}
// Variables declaration - do not modify
private java.awt.Button button1;
private javax.swing.JTextField jT1;
// End of variables declaration
}