VBA Copy row and column headers which has specific values - vba

I am very new to Visual basic, I have an excel sheet in the following format as shown in the image below.
I need to write a VB code to create a spreadsheet in the format as shown in the image below. The model name should be printed for every country that has row and column value '1' in the excel sheet. In other words just need to print Model name and Country name that has value '1' in the spreadsheet. If the cell is empty or value '0' then we need not print the model name for that particular country.
How do I go about it? I have been watching videos to do this but to no avail.
Can anyone please tell me how to do this? Any kind of help would be greatly appreciated. thanks in advance.
Edited: The current output after using the below code is in this screenshot

This should work smoothly, it will created a new sheet at every run to display the output! ;)
Sub test_Dazzler()
Dim wB As Workbook, _
wBNeW As Workbook, _
wSSrC As Worksheet, _
wSDesT As Worksheet, _
LastRow As Long, _
LastCol As Integer, _
WrintingRow As Long, _
ModeL As String
Set wB = ThisWorkbook
Set wSSrC = wB.ActiveSheet
LastRow = wSSrC.Range("A" & wSSrC.Rows.Count).End(xlUp).Row
LastCol = wSSrC.Range("A1").End(xlToRight).Column
Set wSDesT = wB.Sheets.Add
wSDesT.Cells(1, 1) = "Model": wSDesT.Cells(1, 2) = "Countries"
With wSSrC
For i = 2 To LastRow
ModeL = .Range("A" & i).Value
For j = 2 To LastCol
If .Cells(i, j) <> 1 Then
Else
WrintingRow = wSDesT.Range("A" & wSDesT.Rows.Count).End(xlUp).Row + 1
wSDesT.Cells(WrintingRow, 1) = ModeL
wSDesT.Cells(WrintingRow, 2) = .Cells(1, j)
End If
Next j
Next i
DoEvents
WsDest.Copy
End With
Set wBNeW = ActiveWorkbook
Dim intChoice As Integer
Dim strPath As String
'make the file dialog visible to the user
intChoice = Application.FileDialog(msoFileDialogSaveAs).Show
'determine what choice the user made
If intChoice <> 0 Then
'get the file path selected by the user
strPath = Application.FileDialog(msoFileDialogSaveAs).SelectedItems(1)
If strPath <> False Then wBNeW.SaveAs strPath
'displays the result in a message box
Call MsgBox(strPath, vbInformation, "Save Path")
End If
MsgBox "I'm done!"
End Sub

Related

Loop through Named Range

I have a named range for list of report files I have created. They are stored in a folder that matches their file name.
like this - -
List of file is a Named Range called order
a
b
c
and they are stored in a folder like this:
\folder\a\a_support.xls
\folder\b\b_support.xls
\folder\c\c_support.xls
I am trying to copy each xls file into a master sheet. The list is not in alphabetical order so I need to run through the list and import in the order I currently have.
I tried making a loop but I couldn't get my named ranges or objects correct.
How would I make a loop using 'i' to run through my list? I will be using the 'i' value to dynamically reference the directory
here's my code as it stands
Sub Move_reports()
Dim day As String
Dim FromPath As String
Dim i As Long
Dim wsname As String
Dim order As Range
Dim c As Range
day = Sheets("data").Cells(1, 2).Value
FromPath = "\local\shared\"& day &"DOCUMENTS\" & i & "\"
Set c = Worksheets("data").Range(order) _
For Each c In order
If c.Value <> "" Then
wsname = c.Value
Workbooks.Open Filename:= _
FromPath & i & "_support.xls" _
, UpdateLinks:=0
Sheets(i).Select
Sheets(i).Copy After:=Workbooks("SEP_FINAL.xlsm").Sheets("BEG")
ActiveWindow.Close
SaveChanges = True
End If
Next
End Sub
ok, if you have a named range called order to loop through it from top to bottom to keep the order of opening the files you should use something like this in your loop:
Dim rng As Range
Set rng = Worksheets("Sheet1").Range("order").Columns(1) 'change the name of sheet per you need
For i = 1 To rng.Rows.Count
wsname = rng.Cells(i, 1)
Next i
suggestion: you don't need to keep the name and order of the files in a named range because if the list increases then you have to also modify your named range. You can easily pick up the names of whatever number from a sheet column. Let's say you are keeping the names and order in column A of Sheet1 so do this:
Dim rng As Range
Set rng = Worksheets("Sheet1").Range("A1").CurrentRegion.Columns(1)
For i = 1 To rng.Rows.Count
wsname = rng.Cells(i, 1)
Next i
Heres my finished working code for those looking for the same answer as me
Thank you again Lbo!
all thats left is an 'IfError , next i'
Sub Move_reports()
Dim day As String
Dim FromPath As String
Dim i As Integer
Dim wsname As String
Dim rng As Range
day = Sheets("data").Cells(1, 2).Value _
Set rng = Worksheets("data").Range("A2").CurrentRegion.Columns(1)
For i = 2 To rng.Rows.Count
wsname = rng.Cells(i, 1)
FromPath = "\SUPPORT\" & day & "\DOCUMENTS\" & wsname & "\" _
Workbooks.Open Filename:= _
FromPath & wsname & "_support.xls" _
, UpdateLinks:=0
Sheets(wsname).Select
Sheets(wsname).Copy After:=Workbooks("SEP_FINAL.xlsm").Sheets("BEG")
ActiveWindow.Close
SaveChanges = True
Next i
End Sub

Excel copy specific data cell from multiple workbooks to a master file

I have various workbooks with different employee names containing different projectnumbers and hours worked on these projects. I'm trying to get these project numbers filtered out to a master file (zmaster) containing the entire row(s) of a specific project number. I need Excel to filter through the directory (specific folder cointaining all employee hours files) for matches and copy these matches into the zmaster file. The filter is cell A1 of the master file (eg. 300000 in linked picture example). Picture 1 is the master file and picture 2 is an example of the employee hours file.
https://i.stack.imgur.com/OKs68.png (1)
https://i.stack.imgur.com/va2Yn.png (2)
Also, it would be great if Excel would filter out duplicates (eg. week 30 with the exact same hours and employee name already in the master file is most likely duplicate and should be ignored).
I'm pretty new to Excel vba and found/adjusted the following macro's. The first one copies all data from the directory and places it into the master file. The second one filters out the projectnumber matching with cell A1. However, this requires 2 steps and when I run my first macro for the second time it will also collect data already entered into the master file. Also, my second macro places matches in the same row number as where they're placed in the employee hours file and therefore removing earlier observations in the master file placed in the same row (eg. projectnumber 100000 is placed in row 2 of the employee hours file therefore copying to row 2 in the master file, removing the indicator row of the master file).
First macro:
Sub LoopThroughDirectory()
Dim MyFile As String
Dim erow
Dim Filepath As String
Filepath = ("C:\test\”)
MyFile = Dir(Filepath)
Do While Len(MyFile) > 0
If MyFile = "zmaster.xlsx" Then
Exit Sub
End If
Workbooks.Open (Filepath & MyFile)
Range("A2:L9").Copy
ActiveWorkbook.Close
erow = Blad1.Cells(Rows.Count, 1).End(xlUp).Offset(1, 0).Row
ActiveSheet.Paste Destination:=Worksheets("Sheet1").Range(Cells(erow, 1), Cells(erow, 4))
MyFile = Dir
Loop
End Sub
Second macro:
Sub finddata()
Dim projectnumber As Integer
Dim finalrow As Integer
Dim i As Integer
Sheets("Blad1").Range("A1:H9").ClearContents
projectnumber = Sheets("Blad1").Range("A1").Value
finalrow = Sheets("Blad1").Range("A30").End(x1Up).row
For i = 1 To finalrow
If Cells(i, 1) = projectnumber Then
Range(Cells(i, 1), Cells(i, 12)).Copy
Range("A100").End(x1Up).Offset(1, 0).PasteSpecial x1pasteformulasandnumberformats
End If
Next i
Range("A1").Select
End sub
Hopefully everything is clear and thanks in advance!
This should work.
Open each file in directory
check that the file name is not zmaster and that it contains xlsx
run through each row in the current file and then combine the range for copying to master file
copy to master file last row plus 1, which is the first empty row
Option Explicit
Sub CopyToMasterFile()
Dim MasterWB As Workbook
Dim MasterSht As Worksheet
Dim MasterWBShtLstRw As Long
Dim FolderPath As String
Dim TempFile
Dim CurrentWB As Workbook
Dim CurrentWBSht As Worksheet
Dim CurrentShtLstRw As Long
Dim CurrentShtRowRef As Long
Dim CopyRange As Range
Dim ProjectNumber As String
FolderPath = "C:\test\"
TempFile = Dir(FolderPath)
Dim WkBk As Workbook
Dim WkBkIsOpen As Boolean
'Check is zmaster is open already
For Each WkBk In Workbooks
If WkBk.Name = "zmaster.xlsx" Then WkBkIsOpen = True
Next WkBk
If WkBkIsOpen Then
Set MasterWB = Workbooks("zmaster.xlsx")
Set MasterSht = MasterWB.Sheets("Blad1")
Else
Set MasterWB = Workbooks.Open(FolderPath & "zmaster.xlsx")
Set MasterSht = MasterWB.Sheets("Blad1")
End If
ProjectNumber = MasterSht.Cells(1, 1).Value
Do While Len(TempFile) > 0
'Checking that the file is not the master and that it is a xlsx
If Not TempFile = "zmaster.xlsx" And InStr(1, TempFile, "xlsx", vbTextCompare) Then
Set CopyRange = Nothing
'Note this is the last used Row, next empty row will be this plus 1
With MasterSht
MasterWBShtLstRw = .Cells(.Rows.Count, "A").End(xlUp).Row
End With
Set CurrentWB = Workbooks.Open(FolderPath & TempFile)
Set CurrentWBSht = CurrentWB.Sheets("Sheet1")
With CurrentWBSht
CurrentShtLstRw = .Cells(.Rows.Count, "A").End(xlUp).Row
End With
For CurrentShtRowRef = 1 To CurrentShtLstRw
If CurrentWBSht.Cells(CurrentShtRowRef, "A").Value = ProjectNumber Then
'This is set to copy from Column A to Column L as per the question
If CopyRange Is Nothing Then
'If there is nothing in Copy range then union wont work
'so first row of the work sheet needs to set the initial copyrange
Set CopyRange = CurrentWBSht.Range("A" & CurrentShtRowRef & _
":L" & CurrentShtRowRef)
Else
'Union is quicker to be able to copy from the sheet once
Set CopyRange = Union(CopyRange, _
CurrentWBSht.Range("A" & CurrentShtRowRef & _
":L" & CurrentShtRowRef))
End If ' ending If CopyRange Is Nothing ....
End If ' ending If CurrentWBSht.Cells....
Next CurrentShtRowRef
CopyRange.Select
'add 1 to the master file last row to be the next open row
CopyRange.Copy MasterSht.Cells(MasterWBShtLstRw + 1, 1)
CurrentWB.Close savechanges:=False
End If 'ending If Not TempFile = "zmaster.xlsx" And ....
TempFile = Dir
Loop
End Sub

Create a summary sheet based on multiple worksheets

I have number of worksheets containing the same structure and same number of rows. Now I would like to create a master sheet to have an overview of all the worksheets using VBA.
It is like a balance sheet showing the performance over several years, which Years are on the headings and items are on rows.
Now the yearly data are put on multiple worksheets named "2012", "2013" and "2014".
Column B on sheet 1 ("2012") will be copied onto col B on "master" but for the following sheets ("2013", "2014"), data will be placed onto the next column on "master" (ie 2013 data on col C, 2014 data on col D).
I would like to have a workable macro which can count numbers of worksheets and copy paste specific data on a right column of master sheet.
1) create in a sheet a table like that: where the first column is where the destination cell in your Master report. And the 2nd column is where the data will be copied.
2) Put all your Worksheets in a folder
3) Run this macro, which need to be placed in Master module
Option Explicit
'assuming that:
'- "Excel Column Code" is in column A
'- "Form Cell Code" is in column B
'in zmaster.xlsm!Sheet2
Sub UpdateData()
Dim sFile As String, sPath As String
Dim srcWbk As Workbook, dstWbk As Workbook
Dim srcWsh As Worksheet, dstWsh As Worksheet, infoWsh As Worksheet
Dim i As Long, j As Long, k As Long
On Error GoTo Err_UpdateData
Set dstWbk = ThisWorkbook
Set dstWsh = dstWbk.Worksheets("Sheet1")
Set infoWsh = dstWbk.Worksheets("Sheet2")
sPath = "C:\Desktop\New folder\"
sFile = Dir(sPath)
Do While Len(sFile) > 0
If sFile = "zmaster.xlsm" Then
GoTo SkipNext
End If
Set srcWbk = Workbooks.Open(sPath & sFile)
Set srcWsh = srcWbk.Worksheets(1)
i = 2
'loop through the information about copy-paste method
Do While infoWsh.Range("A" & i) <> ""
'get first empty row, use "Excel Column Code" to get column name
j = GetFirstEmpty(dstWsh, infoWsh.Range("A" & i))
'copy data from source sheet to the destination sheet
'use "Form Cell Code" to define destination cell
srcWsh.Range(infoWsh.Range("B" & i)).Copy dstWsh.Range(infoWsh.Range("A" & i) & j)
i = i + 1
Loop
srcwbk.Close SaveChanges:=False
SkipNext:
sFile = Dir
Loop
Exit_UpdateData:
On Error Resume Next
Set srcWsh = Nothing
Set dstWsh = Nothing
Set srcWbk = Nothing
Set dstWbk = Nothing
Exit Sub
Err_UpdateData:
MsgBox Err.Description, vbExclamation, Err.Number
Resume Exit_UpdateData
End Sub
'returns first empty row in a destination sheet based on column name
Function GetFirstEmpty(ByVal wsh As Worksheet, Optional ByVal sCol As String = "A") As Long
GetFirstEmpty = wsh.Range(sCol & wsh.Rows.Count).End(xlUp).Row + 1
End Function

Excel VBA, Paste special adds trailing zeroes

I have raw data from ANSYS mechanical exported as .xml with the following format (2 rows, x number of columns):
Steps Time [s] [A] C1 (Total) [N]
1 1 1, 4,4163e+005
I have a lot of files and I'm trying to combine these into one table in Excel using VBA. The script works fine with one exception, it does not interpret the scientific format correctly. My result is as follows:
Steps 1
Time [s] 1
[A] C1 (Total) [N] 4,42E+09
Code looks as follows:
Private Sub CommandButton1_Click()
Dim directory As String, fileName As String, sheet As Worksheet, total As Integer
Dim wb1 As Excel.Workbook
Dim wb2 As Excel.Workbook
Set wb1 = ThisWorkbook
wb1.Sheets("Sheet1").Cells.ClearContents
'define table headers on row 1
wb1.Sheets("Sheet1").Range("A1:A1").Value = "Load Case"
wb1.Sheets("Sheet1").Range("B1:B1").Value = "Load Case"
wb1.Sheets("Sheet1").Range("C1:C1").Value = "Load Case"
Application.ScreenUpdating = False
Application.DisplayAlerts = False
'directory of source files
directory = "C:\Users\xxxxxxx\Ansysxls\"
fileName = Dir(directory & "*.xl??")
'Define the last used row in the target sheet
LastRow = wb1.Sheets("Sheet1").Cells(wb1.Sheets("Sheet1").Rows.Count, "B").End(xlUp).Row + 1
Do While fileName = "Asymmetric.xls"
'define which workbook to open
Set wb2 = Workbooks.Open(directory & fileName)
'loop through sheets in source file
For Each sheet In Workbooks(fileName).Worksheets
'Select range in source file
wb2.Sheets(sheet.Name).Range("A1").CurrentRegion.Select
'Replace commas with dot
Selection.Replace What:=",", Replacement:=".", LookAt:=xlPart, _
SearchOrder:=xlByRows, MatchCase:=False
Selection.Copy
'Paste Special to target file <-----Smth wrong in my paste special???
wb1.Sheets("Sheet1").Range("B" & LastRow).PasteSpecial _
Paste:=xlPasteValuesAndNumberFormats, SkipBlanks:=True, Transpose:=True
wb2.Sheets(sheet.Name).Activate
Next sheet
'define first row and last row of last import and add from what file the came
FirstRow = LastRow
LastRow = wb1.Sheets("Sheet1").Cells(wb1.Sheets("Sheet1").Rows.Count, "B").End(xlUp).Row + 1
'remove file ending ".xls" from column
wb1.Sheets("Sheet1").Range("A" & FirstRow & ":" & "A" & LastRow).Value = Left(fileName, Len(fileName) - 4)
Workbooks(fileName).Close
fileName = Dir()
Loop
Application.ScreenUpdating = True
Application.DisplayAlerts = True
'Create Table
wb1.Sheets("Sheet1").ListObjects.Add(xlSrcRange, Sheets("Sheet1").Range("A1").CurrentRegion, , xlYes, Header = xlYes).Name = "myTable1"
End Sub
Can anybody help me understand why it changes with from e+5 to e+9?
Excel will 'interpret' the Total [N]) value (which has the comma in it) depending on the numbering system of your Excel application.
I believe if you paste a value of 4,4163e+005 into your worksheet, you will see a value of 4416300000, assuming your thousands are comma separated. In your case, however, you seem to want to convert the comma to a decimal point so that the true value is 441630. This can only be done if the value is a string, but yours probably isn't, it's most likely a number. I'm afraid I rather suspect your search and replace line makes no changes at all.
Although I can't see the values themselves, my bet would be that you need to divide each value by 10000 and then set the number format of your cells to "0.0000E+00".
I've put some code below that will loop through the values and make that change for you. You'll see that I've assumed each sheet only contains the 2 x 4 cell size, so adjust this if you need to.
Other comments about your code:
I think you need to put your last row update within the sheet loop. At a quick glance it looks as though you might be overwriting previous sheet data (ie the only data being written to your target is the source's last sheet data).
I'm not sure what you're intentions are with the Dir() function and then checking for a unique filename. It looks to me as if that will only loop once on a file called "Asymmetric.xls". If this is what you want then just define that workbook as an object. If you want to read all the workbooks in the directory then you need to run the Dir() loop until filename = "". That's what I've assumed in my code.
Private Sub CommandButton1_Click()
Dim directory As String
Dim fileName As String
Dim source As Workbook
Dim sht As Worksheet
Dim targetRng As Range
Dim rawValues As Variant
Dim revisedValues() As Variant
Dim rDimension As Long
Dim cDimension As Integer
Dim r As Long
Dim c As Integer
Application.ScreenUpdating = False
Application.DisplayAlerts = False
'define table headers on row 1
With ThisWorkbook.Sheets("Sheet1")
.Cells.ClearContents
.Cells(1, 1).Resize(, 3).Value = _
Array("Filename", "Item", "Value")
Set targetRng = .Cells(2, 2) 'ie "B2"
End With
'Directory of source files
directory = "C:\Users\xxxxxxx\Ansysxls\"
fileName = Dir(directory & "*.xl??")
Do Until fileName = ""
'define which workbook to open
Set source = Workbooks.Open(directory & fileName)
'loop through sheets in source file
For Each sht In source.Worksheets
'Select range in source file
If Not IsEmpty(sht.Range("A1")) Then
rawValues = sht.Range("A1").CurrentRegion.Value2
' Manipulate the acquired data
rDimension = UBound(rawValues, 1)
cDimension = UBound(rawValues, 2)
' Transpose the dimensions and manipulate the totalN value
ReDim revisedValues(1 To cDimension, 1 To rDimension)
For r = 1 To rDimension
For c = 1 To cDimension
If r = 2 And c = 4 Then ' it's totalN
' Convert the data to a LongLong and divide by 10000
revisedValues(c, r) = CLngLng(rawValues(r, c)) / 10000
Else
revisedValues(c, r) = rawValues(r, c)
End If
Next
Next
'Populate the target sheet with revised values
Set targetRng = targetRng.Resize(cDimension, rDimension)
targetRng.Value2 = revisedValues
' Define the scientific format
targetRng.Cells(4, 2).NumberFormat = "0.0000E+00"
' Add the filename to column "A"
targetRng.Offset(, -1).Resize(, 1).Value2 = _
Left(fileName, (InStrRev(fileName, ".", -1, vbTextCompare) - 1))
' Move the targetRng to the bottom of this range
Set targetRng = targetRng.Offset(targetRng.Rows.Count)
End If
Next
source.Close
fileName = Dir()
Loop
Application.ScreenUpdating = True
Application.DisplayAlerts = True
End Sub

Using VBA - Insert VLOOKUP depending on certain values

I am trying to retrieve data from another file using the VLOOKUP function however this is only to happen depending on if any of the 3 items of data appear in column 8(H)
OLY
OLY - QUO
OLY - PRO
I have the following and know this is not correct
Sub BlockAllocationsVlookupAll()
Dim x As Long
For x = 1 To 65536
If InStr(1, Sheet1.Range("$H$" & x), "OLY") > 0 Then
Sheet1.Range("$I$" & x) = Sheet1.Range("$I$" & x) & "sometext"
End If
Next
End Sub
I know the above doesn't do exactly what I need can anyone help as to what needs to be edited to include the Vlookup below
=VLOOKUP(A21,'[001 - Allocations - Blocks.xls]CurrentDayAll'!$1:$65536,9,FALSE)
The other issue is that the cell the VLOOKUP points to first will also change due to the varying length of the report
Thank you for any help given
UPD:
As follows up from comments,
column H is in Allocations.xls workbook
there are a set of criterias
formula should be placed in cell only if corresponding cell in column H matches any of thouse criterias.
Working code:
Sub BlockAllocationsVlookupAll()
Dim x As Long
Dim lastrow As Long
Dim searchCriterias As String
Dim wb As Workbook
Dim ws As Worksheet
'specify correct path to your workbook
Set wb = Workbooks.Open("C:\Allocations.xls")
'If workbook is already opened use next line
'Set wb = Workbooks("Allocations.xls")
Set ws = wb.Worksheets("Current Day")
searchCriterias = "|OLY|SVC|SVC-PRO|SVC-QUO|EUR|EUR-PRO|EUR-QUO|"
With ws
lastrow = .Cells(.Rows.Count, "H").End(xlUp).Row
For x = 4 To lastrow
If InStr(1, searchCriterias, "|" & .Range("H" & x) & "|") > 0 Then
.Range("I" & x).Formula = "=VLOOKUP(A" & x & ",'[001 - Allocations - Blocks.xls]CurrentDayAll'!$A:$I,9,FALSE)"
End If
Next
End With
'Comment next line if you don't want to close wb
wb.Close (True)
Set wb = Nothing
End Sub