Simplified Excel Code:
Public MyFile As String
Public varSheetA As Variant
Public SelRangeA As Range
Public wsCopy As Excel.Worksheet
Sub SelectFile_Click()
MyFile = Application.GetOpenFilename() 'Aquire filepath from user
If (MyFile <> "False") Then
Range("B1").Value = "File Found"
End If
End Sub
Sub LoadFile_Click()
Dim WbOne As Workbook
Dim strRangeToCheck As String
strRangeToCheck = "A1:T2000"
Set WbOne = Workbooks.Open(MyFile) 'Open that file
Set wsCopy = WbOne.Worksheets(1) 'Try to copy
Set varSheetA = wsCopy.Range(strRangeToCheck) 'Try to copy
Set SelRangeA = wsCopy.Range(strRangeToCheck) 'Try to copy
WbOne.Close 'This is where we lose the references & values
End Sub
Sub DisplayFile_Click()
Range("A4").Value = varSheetA(1, 1)
End Sub
The end result of this program is to have the values from WorkSheet(1) in a Range or Variant Array so that I can edit and display them as needed and eventually copy the values back into the original file. However when I run this code, all the Public variables I initialize are empty when LoadFile_Click exits (more specifically when WbOne closes.
Previously my code looked like varSheetA = WbOne.Worksheet(1).Range(strRangeToCheck) although I'm currently in the process of testing different methods because that way didn't seem to work.
Anyone see any fundamental problems with what I'm trying to do? Thanks!
Option Explicit
Public MyFile As String
Public varSheetA As Variant
Sub SelectFile_Click()
MyFile = Application.GetOpenFilename() 'Aquire filepath from user
If (MyFile <> "False") Then
Range("B1").Value = "File Found"
End If
End Sub
Sub LoadFile_Click()
Const strRangeToCheck As String = "A1:T2000"
With Workbooks.Open(MyFile)
varSheetA = .Worksheets(1).Range(strRangeToCheck).Value
.Close False
End With
End Sub
Sub DisplayFile_Click()
Range("A4").Value = varSheetA(1, 1)
End Sub
Related
I have a while loop that parses a csv file, and inserts the variables into a series of arrays. This is called by a button on my main form.
These variables are used for a chart (which is in the same sub) and also for a datagrid, which is on a separate form.
The first time I click the button, everything works as normal, however if I click it a second time, the datagrid on the separate form is not populated, as I am losing the variables.
So within the while loop which parses the CSV file, I have this:
frmNumericChart.DataGridView1.Rows.Add(freq, dBu, dbnorm, ScaleFactor)
I have tried making the variables public, however because they are arrays, and constructed from the while loop, I can't seem to make them publicly accessible.
My code (edited for brevity)
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim sFile As String = strFileName
' get the minimum and maximum frequencies
Dim Lines As Collections.Generic.IEnumerable(Of String) = File.ReadLines(strFileName)
Dim Line0 As String = Lines.FirstOrDefault
Dim LineN As String = Lines.LastOrDefault
Dim lowestFreq As String() = Line0.Split(New Char() {","c})
Dim highestFreq As String() = LineN.Split(New Char() {","c})
Dim lowFreq As String = lowestFreq(0)
Dim highFreq As String = highestFreq(0)
Dim refFrequencyX = Lines(18)
Dim refFreq As String() = refFrequencyX.Split(New Char() {","c})
Dim ScaleFactor As String = refFreq(1)
Using sr As New StreamReader(sFile)
While Not sr.EndOfStream
Dim sLine As String = sr.ReadLine()
If Not String.IsNullOrWhiteSpace(sLine) Then
sData = sLine.Split(","c)
arrName.Add(sData(0).Trim())
arrValue.Add(sData(1).Trim())
End If
Dim freq As Decimal = sData(0)
Dim dBu As Decimal = sData(1)
Dim voltage As Decimal = sData(1)
' dbnorm - normalise output to 0dBu ref 1kHz
Dim dbnorm = Math.Round(dBu - ScaleFactor, 4)
frmNumericChart.DataGridView1.Rows.Add(freq, dBu, dbnorm, ScaleFactor)
Chart1.Series(0).Points.AddXY(freq, dbnorm)
End While
End Using
' ( chart is constructed here )
end sub
How can I make these array variables global?
Please excuse my shoddy code - I am doing this as a hobby and learning as I go along.
I solved this by adding a public class into a module.
Inside the 'Public Class' I have 'Public Shared Sub' for the subs I want access to from anywhere within the code.
Example:
Public Module Module1
<various public variables here>
Public Class MyData
Public Shared Sub debugTempFile()
' DEBUG
Dim mytempFolder As String = Path.GetTempPath()
Dim MyOutFile As String = mytempFolder + "outfile.txt"
Dim myfile As System.IO.StreamWriter
myfile = My.Computer.FileSystem.OpenTextFileWriter(MyOutFile, True)
myfile.WriteLine(debugdata)
myfile.Close()
' END DEBUG
End Sub
End Class
End Module
This Public Sub can be called from anywhere using the call statement:
Call MyData.debugTempFile()
I hope this is of use to other beginners like myself.
i have some array and a combobox in excel vba, when from is active program set hozelistname value to combobox1. arrays is like below:
hozelistname=("zahedan","zabol")
hozezahedan=(1,2,3,4)
hozezaol=(5,6,7)
now when combobox1 change, i want it show the list of selected array. for example when i select zahedan from list i want it alert the value of zahedan array named hozezahedan and also for zabol.
i wrote the below code but not working! any body to help me?
Private Sub ComboBox1_Change()
dim arrayname,str as string
dim i as integer
arrayname = "hoze" & ComboBox1.text
for i= lbound(arrayname) to ubound(arrayname)
msgbox(arryname(i))
next
End Sub
Option Explicit
Private dicArrays As Scripting.Dictionary
Sub SetUP()
Dim arrTestOne(5) As String
Dim arrTestTwo(10) As String
Set dicArrays = New Scripting.Dictionary
dicArrays.Add "TestOne", arrTestOne
dicArrays.Add "TestTwo", arrTestTwo
End Sub
Sub Reference_Example()
Dim a() As String
a = dicArrays("TestTwo")
End Sub
I hope this explains a little better.
Its unclear what you are after but does the below help you through it?
'This block of code goes right at the top of the form
Option Explicit
Dim hozelistname(1) As String
Dim hozezahedan(3) As String
Dim hozezabol(2) As String
Private Sub ComboBox1_Change()
Dim i As Integer
Dim AryLocal() As String
'set the local array based on the combobox
Select Case Me.ComboBox1
Case "zahedan"
AryLocal = hozezahedan
Case "zabol"
AryLocal = hozezabol
Case Else
ReDim AryLocal(0)
End Select
'show the local array
For i = 0 To UBound(AryLocal, 1)
MsgBox (AryLocal(i))
Next
End Sub
Private Sub UserForm_Activate()
Dim LngCounter As Long
'Set up the lists
hozelistname(0) = "zahedan"
hozelistname(1) = "zabol"
'Set up each result
hozezahedan(0) = "1"
hozezahedan(1) = "2"
hozezahedan(2) = "3"
hozezahedan(3) = "4"
hozezabol(0) = "5"
hozezabol(1) = "6"
hozezabol(2) = "7"
'set the combobox
For LngCounter = 0 To UBound(hozelistname, 1)
Me.ComboBox1.AddItem hozelistname(LngCounter)
Next
End Sub
The next steps would be populating the ComboBox and arrays based on list written in Excel and not hardcoded ones.
If I wanted to read the following from a CSV file into 4 separate arrays how would I proceed?
Ex:
John,Doe,100,98
Jane,Smith,90,90
I need to take a student's First & Last Name. The first grade is their midterm, the second is their final.
Dim Name As String = ""
Dim inFile As StreamReader
Dim outFile As StreamWriter
inFile = File.OpenText("grades.csv")
outFile = File.CreateText("report.txt")
Do While (Not inFile.EndOfStream)
Name = CStr(inFile.ReadToEnd)
outFile.WriteLine(Name)
Loop
inFile.Close()
outFile.Close()
I see a million different ways to split things, I only output the file to see what I'm getting. Can someone help me split these into separate arrays? Thanks
Try this..... An example that might give you some ideas....
Imports System.Data.OleDb
Public Class Form1
Private dt As New DataTable
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Dim folder = "<Path to the folder of your grades.csv file (don't include the file name, just the path up to the folder)>"
Dim CnStr = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & folder & ";Extended Properties=""text;HDR=No;FMT=Delimited"";"
' in the next line replace grades.csv with the name of your file....
Using Adp As New OleDbDataAdapter("select F1 + ' ' + F2 as FirstSecondName, F3 as MidTerm, F4 as Final from [grades.csv] ", CnStr)
Try
Adp.Fill(dt)
Catch ex As Exception
End Try
End Using
Me.ListBox1.DataSource = dt
ListBox1.DisplayMember = "FirstSecondName"
ListBox1.ValueMember = "FirstSecondName"
AddHandler ListBox1.SelectedIndexChanged, AddressOf ListBox1_SelectedIndexChanged
End Sub
Private Sub ListBox1_SelectedIndexChanged(sender As Object, e As EventArgs)
Dim senderListBox As ListBox = sender
If senderListBox.SelectedIndex <> -1 Then
Dim SelectedData As DataRowView = senderListBox.SelectedItem
MessageBox.Show(String.Format("Selected - {0} :: Mid-Term Result = {1} :: Final Result = {2}", SelectedData("FirstSecondName").ToString, SelectedData("MidTerm").ToString, SelectedData("Final").ToString))
End If
End Sub
End Class
I want to make use of dynamic arrays in VBA in order to save the found strings and use the FileSystemObject to find the files.
The code I currently use is this one
Private Sub cmdStartSearch_Click()
Dim resultList(0) As String
Call FindFile(resultList, ".png", "Q:\", True)
End Sub
Private Sub FindFile(ByRef resultList() As String, target As String, ByVal aPath As String, useSubfolders As Boolean)
Dim myFileSystemObject As FileSystemObject, curFolder As folder, folder As folder
Dim folColl As Folders, file As file, fileColl As Files
Set myFileSystemObject = New FileSystemObject
Set curFolder = myFileSystemObject.GetFolder(aPath)
Set folderList = curFolder.SubFolders
Set fileList = curFolder.Files
For Each file In fileList
ReDim Preserve resultList(1 To UBound(resultList) + 1) As String
If InStr(file.Name, target) > 0 Then
resultList(UBound(resultList)) = file.Name
Debug.Print file.Name
End If
Next
If useSubfolders Then
For Each folder In folderList
DoEvents 'Yield execution so other events may be processed
If Not foundTarget Then
FindFile resultList, target, folder.Path, useSubfolders
End If
Next
End If
Set myFileSystemObject = Nothing
Set curFolder = Nothing
Set folderList = Nothing
Set fileList = Nothing
End Sub
This fails however with Array is fixed or or temporarily locked.
How can I get around this problem, or solve the original one?
I feel this has a far better/easier solution. What you do is loop through the file list as you did but then return a long string with the file names and then finally break it using the Split function which will yield you a String array anyway.
Your code could simply change as,
Private Sub cmdStartSearch_Click()
Dim resultList() As String
resultList = Split(FindFile(".png", "Q:\", True), ";")
End Sub
Private Function FindFile(target As String, ByVal aPath As String, useSubfolders As Boolean) As String
Dim retStr As String
Dim myFileSystemObject As FileSystemObject, curFolder As folder, folder As folder
Dim folColl As Folders, file As file, fileColl As Files
Set myFileSystemObject = New FileSystemObject
Set curFolder = myFileSystemObject.GetFolder(aPath)
Set folderList = curFolder.SubFolders
Set fileList = curFolder.Files
For Each file In fileList
If InStr(file.Name, target) > 0 Then
retStr = retStr & ";" & file.Name
Debug.Print file.Name
End If
Next
If useSubfolders Then
For Each folder In folderList
DoEvents 'Yield execution so other events may be processed
If Not foundTarget Then
retStr = retStr & ";" & FindFile(target, folder.Path, useSubfolders)
End If
Next
End If
Set myFileSystemObject = Nothing
Set curFolder = Nothing
Set folderList = Nothing
Set fileList = Nothing
If Len(retStr) > 0 Then retStr = Right(retStr, Len(retStr)-1)
FindFile = retStr
End Function
Why are the variables folderList, fileList, foundTarget not declared in the context?
I am trying to develop code to unzip file from the zip file in Silverlight 5. The files are in a directory within the zip file.
I translated this code I found elsewhere from c# to VB since we are a VB shop. It is failing on the fourth line "Object reference not set to an instance of an object.".
I realize now that the problem is that the third line is expecting a relative uri and I am passing it a file, but I don't know how to fix this.
Can you tell me what is wrong with this code. I will also welcome other ideas.
Thanks.
Public Shared Function GetZipContents(ByVal filename As String) As String()
Try
Dim zipStream As System.IO.Stream = New System.IO.MemoryStream()
Dim zipInfo As New StreamResourceInfo(zipStream, Nothing)
Dim streamInfo As StreamResourceInfo = Application.GetResourceStream(zipInfo, New Uri(filename, UriKind.Relative))
Dim fileStream As Stream = streamInfo.Stream
Dim names As New List(Of String)()
Dim reader As New BinaryReader(fileStream)
Do While reader.ReadUInt32() = &H4034B50
' Skip the portions of the header we don't care about
reader.BaseStream.Seek(14, SeekOrigin.Current)
Dim compressedSize As UInteger = reader.ReadUInt32()
Dim uncompressedSize As UInteger = reader.ReadUInt32()
Dim nameLength As Integer = reader.ReadUInt16()
Dim extraLength As Integer = reader.ReadUInt16()
Dim nameBytes() As Byte = reader.ReadBytes(nameLength)
names.Add(Encoding.UTF8.GetString(nameBytes, 0, nameLength))
reader.BaseStream.Seek(extraLength + compressedSize, SeekOrigin.Current)
Loop
' Move the stream back to the begining
fileStream.Seek(0, SeekOrigin.Begin)
Return names.ToArray()
Catch ex As Exception
MessageBox.Show(ex.Message)
Return Nothing
End Try
End Function
There is quick and dirty way to unzip in Silverlight.
Use Application.GetResourceStream Method.
http://msdn.microsoft.com/en-us/library/cc190632(v=vs.95).aspx
Check out my blogpost on this: http://www.sharpgis.net/post/2010/08/25/REALLY-small-unzip-utility-for-Silverlight-e28093-Part-2.aspx
Sorry I would have time to explore the suggestions. I did find a way to accomplish my goal on my own. See the code below. I would be using this code either because the Technical Leader here prefers I do it a different way using a WCF service. Warning I was not able to test this code 100% since I am not planning to use it, but it is close to being right.
Imports ICSharpCode.SharpZipLib.Zip
Public Shared Sub UnZip(ByVal SrcFile As String, ByVal DstFile As String, ByVal BufferSize As Integer)
Try
Dim _FileName As String
Dim _ZipEntry As ZipEntry
Dim _FileStreamOut As FileStream = Nothing
Dim _Done As Boolean = False
Dim _FileStreamIn As New FileStream(SrcFile, FileMode.Open, FileAccess.Read)
Dim _ZipInStream As New ZipInputStream(_FileStreamIn)
Do Until _Done = True
_ZipEntry = _ZipInStream.GetNextEntry()
If IsNothing(_ZipEntry) Then
_Done = True
Exit Do
End If
_FileName = DstFile & "\" & _ZipEntry.Name
_FileName = _FileName.Replace("/", "\")
If Right(_FileName, 1) = "\" Then
If Directory.Exists(_FileName) = False Then
Directory.CreateDirectory(_FileName)
End If
Else
_FileStreamOut = New FileStream(_FileName, FileMode.Create, FileAccess.Write)
Dim size As Integer
Dim buffer(BufferSize - 1) As Byte
Do
size = _ZipInStream.Read(buffer, 0, buffer.Length)
_FileStreamOut.Write(buffer, 0, size)
Loop While size > 0
End If
Loop
_ZipInStream.Close()
_FileStreamOut.Close()
_FileStreamIn.Close()
Catch ex As Exception
MessageBox.Show(ex.Message)
End Try
End Sub