-
Posts
2,982 -
Joined
Community Answers
-
ribeiro55's post in Dados introduzidos na posição errada was marked as the answer
Contagem de registos para controlar um ID é, no mínimo, má ideia.
Imagina que adiciono 10 registos. O próximo ID aqui seria o 11.
Por alguma razão, apago os 5 primeiros com ID 1,2,3,4 e 5. Fico com os ID 6,7,8,9 e 10.
Com o teu método de construír ID, o próximo ID seria o 6, porque só tinha 5 registos.
Vai-se gerar um conflito entre os novos 6,7,8,9 e 10 e os que já lá estavam.
Deverias apanhar o máximo desse campo e não a contagem.
Quanto ao resto, se usas um tipo de dados numérico, só precisas de terminar o teu comando select com um ORDER BY ID.
-
ribeiro55's post in Rodar Texto was marked as the answer
Olá Chamuanza,
Basta trocares o contexto do Graphics para um objecto que implemente o Image, como o Bitmap:
Dim Bmp As New Bitmap(Panel1.ClientSize.Width, Panel1.ClientSize.Height) Dim g As Graphics = Graphics.FromImage(Bmp)
E depois no fim, dás ao background do panel a imagem:
Panel1.BackgroundImage = Bmp
Também podes usar a PictureBox para o mesmo efeito. Até é mais rápida que o Panel a desenhar.
No entanto, e atenção, só vais conseguir transparência caso essas "cores diferentes" sejam background do FORM.
Em WinForms, transparência entre dois controlos não é pêra doce. Só consegues facilidade transparência entre num controlo relativamente ao form.
-
ribeiro55's post in Filelistbox drag and drop? was marked as the answer
Dá uma espreitadela em https://wiki.portugal-a-programar.pt/dev_net/vb.net/dragdrop/ e vê se consegues extrair daí algo que te seja útil.
-
ribeiro55's post in Listview Subitems text was marked as the answer
SubItems é uma colecção que contém os valores de todas as colunas, incluíndo a primeira.
Com isto, SelectedItems.SubItems(X).Text, vai-te apanhar o texto da coluna no (zero-based) índice X da linha seleccionada.
Também podes ir lá por nome, mas isso implica teres que ter criado a coluna como deve de ser.
https://wiki.portugal-a-programar.pt/dev_net/vb.net/listviews_36_utilidades_directas/#7---referenciar-o-valor-de-uma-coluna-em-todos-os-itens-da-lista
-
ribeiro55's post in Obter um valor the uma ListView was marked as the answer
https://wiki.portugal-a-programar.pt/dev_net/vb.net/listviews_36_utilidades_directas/#5---referenciar-o-valor-de-uma-coluna-num-item-seleccionado
Vai por o índice se não tiveres a usar keys. 😄
-
ribeiro55's post in Como "obrigar" utilizar na textbox (email) a meter "@." was marked as the answer
Podes usar o operador LIKE.
https://wiki.portugal-a-programar.pt/dev_net/vb.net/operadorlike/
Com um padrão, por exemplo:
[A-za-z0-9]*@[A-za-z0-9]*.??* If "um.email.qualquer@um.provider.qualquer.com" Like "[A-za-z0-9]*@[A-za-z0-9]*.??*" Then 'Email válido! Else 'Email inválido End If -
ribeiro55's post in listview para string exception was marked as the answer
Estavas a iterar a listview considerando cada item uma String.
Os items são ListViewItem.
https://wiki.portugal-a-programar.pt/dev_net/vb.net/listviews_36_utilidades_directas/#7---referenciar-o-valor-de-uma-coluna-em-todos-os-itens-da-lista
-
ribeiro55's post in Ficheiro Config was marked as the answer
Esse formato é horrível. É mesmo assim?
1ª
Se assumirmos que vão existir sempre pares de chave/valor, eu iteraria todas as linhas, fazendo pares de uma com a próxima e ignorar linhas em branco.
Por exemplo:
- Ler primeira linha, armazenar em variável como chave
- Ler segunda linha, criar entrada no dictionary com a chave anterior e este valor
- Limpar variável da chave
- Linha em branco, ignorar
- Chave limpa? Então esta linha é a nova chave
- Ler segunda linha, criar entrada no dictio (......)
Como é que lês as linhas? https://wiki.portugal-a-programar.pt/dev_net/vb.net/stream_readers_writers/
Podes armazenar os pares num Dictionary(Of String,String)
O que é um Dictionary(Of)? https://wiki.portugal-a-programar.pt/dev_net/vb.net/dictionaryof/
2º
Já os tens num dictionary. O dictionary armazena dados em par. Basta iterar todos os pares:
- Escrever chave numa linha
- Escrever valor numa linha
- Escrever "" numa linha
- Repetir
Como é que iteras os pares de um dictionary? https://wiki.portugal-a-programar.pt/dev_net/vb.net/dictionaryof/#percorrer-todas-as-chaves-de-um-dicionario
3º
Podes verificar a existência de um ficheiro com
FileIO.FileSystem.FileExists(caminho) É te devolvido TRUE caso exista, FALSE caso não exista.
Para criar ficheiros podes utilziar, entre outras coisas, o StreamWriter.
Como? https://wiki.portugal-a-programar.pt/dev_net/vb.net/stream_readers_writers/#escrever-para-um-ficheiro
Escrever para o AppData é só uma questão de caminho. Para obteres o caminho para o AppData, mais imaginemos o ficheiro "zeca.txt":
FileIO.SpecialDirectories.CurrentUserApplicationData.TrimEnd("\") & "\zeca.txt" -
ribeiro55's post in Definir uma imagem como fundo do ambiente de trabalho? was marked as the answer
E precisamos lá nós de sair da comunidade? 😛
https://wiki.portugal-a-programar.pt/dev_net/vb.net/alterar_wallpaper_sistema_operativo/
-
ribeiro55's post in Relógio analógico em VB was marked as the answer
Tens um exemplo completo na Wiki 😉
Dá uma espreitadela.
https://wiki.portugal-a-programar.pt/dev_net/vb.net/relogio_analogico/
Hoje faria de forma diferente, mas já te ajuda bastante a começar. 😉
-
ribeiro55's post in Auto-Size font em textbox was marked as the answer
Deves primeiro analisar o comprimento da string desenhada, usando por exemplo os métodos da GDI como o MeasureString.
Com esse comprimento aplicas lógica ao tamanho da font em relação à diferença do comprimento da textbox com o comprimento da string.
Outro aspecto importante é que a textbox deve estar configurada sem AutoSize, para não mudar de altura com o tamanho da font.
Usa o MultiLine = True para resolver automaticamente o deslocamento da esquerda.
Um exemplo básico:
Private Sub TextBox1_TextChanged(sender As Object, e As EventArgs) Handles TextBox1.TextChanged Dim TamanhoNormal = 16.0F Dim MargemSuperior = 10.0F Dim MargemInferior = 20.0F Dim tb As TextBox = DirectCast(sender, TextBox) Dim g As Graphics = tb.CreateGraphics Dim s As SizeF = g.MeasureString(tb.Text, tb.Font, Integer.MaxValue) If s.Width >= (tb.Width - MargemSuperior) Then While s.Width > (tb.Width - MargemSuperior) And tb.Font.Size > 1 tb.Font = New Font(tb.Font.FontFamily, tb.Font.Size - 0.5F) s = g.MeasureString(tb.Text, tb.Font, Integer.MaxValue) End While ElseIf s.Width < (tb.Width - MargemInferior) And tb.Font.Size < TamanhoNormal Then tb.Font = New Font(tb.Font.FontFamily, tb.Font.Size + 0.5F) End If If tb.Font.Size > TamanhoNormal Then tb.Font = New Font(tb.Font.FontFamily, TamanhoNormal) End Sub Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load TextBox1.Multiline = True TextBox1.Height = 30 End Sub -
ribeiro55's post in Movimento do sol was marked as the answer
Trigonometria.
Podes calcular a posição do sol em função de um ângulo.
Se considerares que 0 graus é o teu sol da esquerda, 90 o sol de cima e 180 o sol da direita:
float dist_sol = 500f; //o que fizer sentido no teu mundo float ang_sol = 45f; sol.x = centro.x + Math.Cos(ang_sol * (Math.PI/180))*dist_sol sol.y = centro.y + Math.Sin(ang_sol * (Math.PI/180))*dist_sol
45 graus será uma posição a meio caminho do sol da esquerda e do sol de cima, a descrever um círculo.
Se aumentares o ang_sol, a posição do sol vai andando a descrever um círculo por aí fora.
O "centro" é o centro do teu mundo.
O "sol" é o centro do teu sol.
-
ribeiro55's post in Copiar um pedaço de string was marked as the answer
Olá Kadov,
Se o formato não mudar, se a separação por traços for constante e a posição de cada elemento, podes sacar o que precisas com um simples split e rank de array:
Dim Data As String = SearchString.Split("-")(2) -
ribeiro55's post in Erro ao copiar ficheiro para PenDrive was marked as the answer
Verifica a assinatura do método Copy. Tem 2 overloads:
System.IO.File.Copy(String,String) System.IO.File.Copy(String,String,Boolean) '<---- É este overload que está a fazer match 'esclarecendo: System.IO.File.Copy("caminho origem","caminho destino") System.IO.File.Copy("caminho origem","caminho destino","Se existir, escrever por cima?")
No teu caso, estás a passar uma String numa assinatura que esperava um Boolean no terceiro parametro, daí indicar que não é possível inferir um boolean de "E:\", e com razão.
Altera para:
File.Copy("D:\FileB.dbf", String.Format("{0}File1.txt", drive.Name), True)
Confirma sempre a assinatura.
-
ribeiro55's post in Como remover caracteres antes do @ no email was marked as the answer
a_tua_string.Substring(a_tua_string.IndexOf("@")+1)
Também podes optar por um split, se forem sempre emails:
a_tua_string.Split("@")(1) -
ribeiro55's post in Problema com Tooltip was marked as the answer
Olá CRLF,
ToolStripItems são casos especiais que não herdam do Forms.Control.
Como tal, as tooltips devem ser geridas com membros do container (esse sim, herda do Forms.Control).
O primeiro passo é passar True para o ShowItemToolTips, propriedade da StatusStrip, que por defeito está a False.
Esta propriedade diz à StatusStrip que deverá implementar uma ToolTip para cada ToolStripItem que tenha ToolTipText, o que nos leva ao segundo passo, que é definir directamente na ToolStripStatus a tooltip a mostrar, através da propriedade ToolTipText.
Deixo-te abaixo um exemplo, ligeiramente adaptado para funcionar com múltiplos disparos de eventos.
Private Sub ToolStripStatusLabel3_MouseHover(sender As Object, e As EventArgs) Handles ToolStripStatusLabel3.MouseHover Dim tssl As ToolStripStatusLabel = sender If tssl.Enabled = True Then tssl.ToolTipText = "Clique Aqui para alterar o Valor da Aposta" End If End Sub Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load StatusStrip1.ShowItemToolTips = True End Sub
Tem em conta que esta tua solução de definir a tooltip no MouseHover não é ideal e que pode resultar em não mostrar a tooltip sem que tenhas de tirar o rato e voltar a colocar.
Sugiro que definas a ToolTipText dos labels no mesmo sítio onde os pões activos e inactivos, tendo o cuidado de passar String.Empty à ToolTipText quando não queres mostrar.
-
ribeiro55's post in Redimensionar tamanho de imagem was marked as the answer
Não é assim que se faz referência a uma biblioteca 🙂
- Botão direito em cima do projecto, "WindowsApplication1"
- Procura e escolhe "Add Reference".
- Depois clica no botão que diz "Browse" no canto inferior direito.
- Procura a DLL no teu FS e clica em "Add"
- Clica em "OK" para terminar
A imago está agora em referência e já não te vai dar esse erro.
-
ribeiro55's post in Programar os meses was marked as the answer
Nem podia aparecer. ("dd-01-yy") é literal. Só te aparecia Janeiro se o que estivesse na TextBox1 fosse mesmo "dd-01-yy".
Tens de fazer outro tipo de validação. Sugiro o operador Like.
No teu caso:
If TextBox1.Text Like "??/01/??" Then TextBox3.Text = "Janeiro"
Vê mais informação no artigo da wiki da comunidade, mas basicamente o Like vai comparar o padrão ??/01/?? com o texto, onde o ? representa um qualquer caractere.
Agora, da forma como estás a fazer não pode funcionar nunca pois estás a comparar com uma string literal.
Deixo-te uma outra sugestão de implementação:
Public meses As String() = {"Janeiro", "Fevereiro", "Março", "Abril", "Maio", "Junho", "Julho", "Agosto", "Setembro", "Outubro", "Novembro", "Dezembro"} Private Sub TextBox1_TextChanged(sender As Object, e As EventArgs) Handles TextBox1.TextChanged Dim tx As TextBox = DirectCast(sender, TextBox) Dim mes As String = "desconhecido" For m As Integer = 0 To meses.Length If tx.Text Like "??/" & (m + 1).ToString().PadLeft(2, "0") & "/??" Then mes = meses(m) Exit For End If Next TextBox3.Text = mes End Sub -
ribeiro55's post in Cálculo de double was marked as the answer
O não conseguir somar, neste caso, deve ser um erro, ou um valor parvo.
Tens de te habituar a dar mais detalhe nos teus posts! A malta aqui é boa, mas não é adivinha 🙂
O "problema" do CDbl é que vai tentar inferir um double com base nas definições regionais do sistema, o que pode gerar problemas como 10,00 + 20,00 = 3000 ou até mesmo estoirar.
A resolução passa por normalizar as introduções das textboxes primeiro.
Dá uma vista de olhos no TryParse da classe Double (Double.TryParse).
Deixo-te uma sugestão que substituí vírgula ou ponto por o separador decimal da cultura actual (não compatível com decimais e separadores de milhar):
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click Dim final As Double Dim erro As Boolean = False For Each t As TextBox In {valor1, valor2, valor3, valor4, valor5, valor6} t.BackColor = Color.White Dim er As Boolean = False final += DblNormalizado(t.Text, er) If er Then erro = True t.BackColor = Color.Coral End If Next resultado.Text = final.ToString("##,##0.00") If erro Then MsgBox("Existe pelo menos um valor em erro") End Sub Private Function DblNormalizado(valorstr As String, ByRef erro As Boolean) As Double erro = False Dim valor As Double Dim d As String = System.Globalization.CultureInfo.CurrentCulture.NumberFormat.NumberDecimalSeparator() If Double.TryParse(valorstr.Replace(",", d).Replace(".", d), valor) Then Return valor End If erro = True Return 0 End Function -
ribeiro55's post in Erro no Load da Form was marked as the answer
Este tipo de problemas é facílimo de apanhar com step-debug.
Mete um breakpoint (F9) perto da linha que suspeitas estar com problema e vai executando instruções (F8)
StackOverflow deve-se tipicamente a um ciclo sem fim ou chamadas recursivas mal "guardadas".
Meto as minhas fichas todas na chamada recursiva que tens lá em cima, repara:
Estás a chamar a própria função sempre que a lista contenha um número que já saiu.
Isto já de si é mau porque num cenário verdadeiramente aleatório poderia nunca calhar um número que não estivesse na lista, e lá saia por StackOverflow de vez em quando.
A recursão condicionada por um acontecimento aleatório não é boa ideia. Sugiro algo bem mais simples, como um ciclo While:
randomNumber = distribuirCartas.Next(0, limit) While T.Contains(randomNumber) randomNumber = distribuirCartas.Next(0, limit) End While
Agora, até mesmo com o While (principalmente com um While) tens de te proteger daquilo que está potencialmente a "lixar-te" o esquema.
Se fizeres step-debug deverás chegar à conclusão que mesmo com a lista toda preenchida, ele continua a entrar no ciclo até morrer.
Repara que não estás a proteger-te contra o caso da lista T já ter tantos items quanto o valor na tua variável limit.
Quando o número de itens na lista que estás a passar por referência é igual ao valor de limit, não vai entrar mais nenhum, e já existem todos.
O teu T.contains vai avaliar sempre "True".
Resolves isto com um simples:
If T.Count = limit Then Exit Function
Algumas sugestões:
1. Se tens o array de pictureboxes, para quê o ciclo numérico e a conversão de tipo?
Podes obter o mesmo assim:
For Each pb As PictureBox In Cartas pb.Image = ImageList1.Images(getNextNewImage(imgs, ImageList1.Images.Count)) Next
2. Tira o New Random da função getNextNewImage e mete-o num âmbito geral, ou dá-lhe uma seed baseada na hora do sistema.
Como está, vai gerar sempre as mesmas sequências "aleatórias". Irias reparar que saiam sempre as mesmas cartas quando paravas e arrancavas a aplicação.
3. Não precisas de passar a lista imgs por referência: ela está fora do âmbito do método Form_Load e getNextNewImage. Não a precisas de passar de todo. Podes aceder-lhe normalmente.
-
ribeiro55's post in Erro Programa Trial Demo was marked as the answer
Usa antes o ReadAllText em vez do ReadAllLines. Este último devolve um array de String e não uma String.
O erro diz basicamente que não pode transformar um array numa string.
-
ribeiro55's post in Existe uma maneira de "pausar" a BackgroundWork? was marked as the answer
Deves, em primeiro lugar, questionar o propósito do backgroundworker.
Se a função está tão intimamente ligada a uma listbox (presumo), porque razão está a ser computada em outra thread?
De qualquer forma, o BackgroundWorker aceita um parametro do tipo Object, para passares o que quiseres para dentro.
Se criares uma classe wrapper para enviares a lista e o índice, podes alterar o fluxo como te for mais conveniente.
-
ribeiro55's post in Calcular valores de um ficheiro TXT was marked as the answer
Vários problemas com esse bloco de código, sendo o mais flagrante o facto de estares a iterar as linhas no Loop, mas a não fazer nada com elas.
E depois disso, fazes um ciclo For Each com a mesma variável no item e no iterador 🙂
Ali com a variável valor, também estás a fazer parse dela para o total não sei bem para que.
Por fim, em vez de colocares o total na Label, estás a colocar o texto da label no total...
Step debug e um pouco mais de atenção. Isto são erros que parecem que nem estás a tentar 😞
Para além disso, o POB já te deu uma solução. Em C#, mas uma solução fácil de traduzires.
Mas vá...
'O primeiro passo é criares uma variável Integer para guardar o valor total Dim TOTAL As Integer = 0 'Depois vamos criar um StreamReader (podias também fazer com ReadAllLines / ReadAllText, mas tens o exemplo do POB) Dim SR As New System.IO.StreamReader("e:\zag.txt") 'Enquanto o Reader não estiver no fim (enquanto houver informação no ficheiro) While Not SR.EndOfStream 'Lê uma linha Dim linha As String = SR.ReadLine 'Inicializa o valor a zero Dim valor As Integer = 0 'Tenta extraír o valor numérico da linha de texto e coloca na variável valor Integer.TryParse(linha, valor) 'Soma ao total a variável valor. Caso a linha não represente um número, o valor será zero (TOTAL+0 = TOTAL) TOTAL += valor End While 'Fecha o ficheiro SR.Close() 'Por fim, apresenta o resultado na label Label1.Text = TOTAL.ToString() -
ribeiro55's post in Converter String em Operador Matemático was marked as the answer
Bem, podes usar o CodeProvider e o Activator para compilar código em runtime, mas ia ficar muito mais linhas que essas que aí tens em cima.
Se só queres fazer parse de continhas dessas, e para ficar curto, podes fazer algo como:
Private Function Eval(exp As String) As String Dim tE As String() If exp.Contains("+") Then tE = exp.Split("+") : Return Double.Parse(tE(0)) + Double.Parse(tE(1)) If exp.Contains("-") Then tE = exp.Split("-") : Return Double.Parse(tE(0)) - Double.Parse(tE(1)) If exp.Contains("/") Then tE = exp.Split("/") : Return Double.Parse(tE(0)) / Double.Parse(tE(1)) If exp.Contains("*") Then tE = exp.Split("*") : Return Double.Parse(tE(0)) * Double.Parse(tE(1)) Return "Impossível avaliar, por uma razão qualquer que não interessa agora porque sim." End Function Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load MsgBox(Eval("250 / 2")) End Sub
Assim, basta usares o método Eval (chamei-lhe eval porque existe algo que faz exactamente isto em Javascript, e chama-se Eval (de Evaluate) ), cujo output é o resultado da avaliação bááásica.
No teu caso ficaria algo como:
TextBox1.Text = Eval("250 * 2")
